All posts English version →

不碰遊戲怎麼數 FPS?我們 overlay 背後的 ETW 技術

你正在打遊戲,角落的 overlay 顯示你現在跑幾 FPS,腦中忽然冒出一個小問題:它到底是怎麼知道的?你沒在遊戲裡裝過幀數計數器,也沒往遊戲裡插任何東西。那這個數字,是從哪冒出來的?

真相會讓你意外:它根本沒碰遊戲,也不能碰。一個工具只要伸手進線上遊戲裡數幀,防作弊就會看到「家裡來了陌生人」——而最壞的結果不是當機,是你的帳號被標記。所以我們從外面數,而且你會發現,Windows 其實一直默默幫你記著這筆帳。

這篇就帶你看清楚這是怎麼辦到的:負責數幀的那個作業系統功能、為什麼它可以安心跟排位賽一起跑,還有那個超有教育意義的 bug——它曾經讓一款遊戲很自信地報出 600 FPS,而它其實只跑 200。

前提約束:絕不碰遊戲本體

量 FPS 的標準做法是「進到遊戲裡面量」:RTSS 這類工具把 DLL 注入遊戲程序、hook 它的 Present 呼叫——每攔到一次就是一幀。效果很好,但這正是防作弊系統的頭號獵物。對一個會跟線上遊戲一起跑的工具來說,注入不是選項:最壞情況不是當機,是使用者的帳號被標記。

所以需求變成:完全不碰目標程序,數別人的幀。

Windows 其實已經幫你數好了

答案是 ETW——Event Tracing for Windows,作業系統內建的全域遙測匯流排。圖形堆疊本身就有埋點:Microsoft-Windows-DXGI provider 會在任何程序送出一幀時發事件(Event 42,Present::Start)。從自己的程序訂閱這條流、用前景遊戲的 PID 過濾、每秒數事件數——就是 FPS,從外面量出來的。這跟 Intel 的 PresentMon 用的是同一個資料來源。老的 DirectX 9 遊戲走另一條路徑,所以我們同時聽 Microsoft-Windows-D3D9 的 Event 1,並用旗標防止同一幀從兩邊各算一次。

想像一棟有大廳警衛室的辦公大樓。要算某住戶進出大門幾次,你不會闖進他家、在門口偷裝攝影機——你只要調大廳的監視器畫面,因為每個從正門經過的人本來就都被錄下來了。ETW 就是這套全大樓的中央監視系統:Windows 早就把每一次「有一幀送出門」都記下來了,所以我們只要看錄影帶,不必硬闖進遊戲裡。

那個跑出 600 FPS 的 bug

第一版上線後,玩家回報:遊戲實際大約 200 幀,overlay 卻顯示 500–600。不是抖動——是穩定、自信地三倍於真相。

事後看原因很明顯:現代遊戲不是只有一條幀流。很多引擎內嵌 Chromium 做 UI(選單、商城、地圖介面),那個瀏覽器有自己的 swapchain、自己送自己的幀。我們的計數器把該 PID 的所有 Present 事件加總——主渲染約 200 幀,加上一個很忙的網頁 UI——報出總和。修法就是 PresentMon 的做法:按 swapchain 分桶,回報最忙的那一桶(主渲染),愛講話的 UI overlay 自己一桶,不再污染數字。

我們的計數器當初像在數高速公路車流:站在交流道口,把每條車道的車一次全算進去——主線加上一條從大賣場匯進來的繁忙匝道——然後報出一個超大數字。難怪會變成 600。修法就是分車道各算各的,只報主線。遊戲的選單和商城畫面就是那條賣場匝道:它有自己穩定的一股「車流」,跟遊戲本身跑多快其實一點關係都沒有。

然後第二個坑引爆:事件 payload 裡指向 swapchain 的欄位,在不同 Windows 版本叫不同名字(有的叫 pIDXGISwapChain,有的是變體)。讀錯欄位名,所有事件全進同一桶——悄悄重現原 bug。最後站穩的版本改成名稱無關掃描:找 payload 裡任何名字含「swap」的指標欄位,並每秒把逐 swapchain 的分桶明細寫進診斷 log——哪天某台機器的欄位又叫新名字,log 會直接告訴我們,不用猜。

這個做法做不到的事

站在程序外面的代價,誠實列出:

  • 跟著前景視窗走。Alt-Tab 切走,overlay 就改量你切過去的東西——設計如此,但多螢幕使用者會驚訝。
  • 數的是 present 次數,不是每幀耗時。FPS 數字紮實,但沒有 frametime 百分位數、沒有 1% low。要深度分析卡頓,請用 PresentMon 或 CapFrameX——那件事它們真的做得更好。
  • ETW session 需要管理員權限——PowerDoze 引擎本來就以系統管理員身分跑電源管理,overlay 搭便車不用多付。

電源工具為什麼需要這個數字

這個 overlay 存在的目的,是讓你一眼回答一個問題:我是不是在為看不到的幀付電費?165 Hz 的螢幕上選單跑 400 FPS,那是純發熱。FPS 和 Hz 並排放著,壓 GPU 功耗(power limit 那招幾乎不掉性能)就不再是賭注——你盯著數字,它撐住或撐不住,一翻兩瞪眼。

免費下載 PowerDoze →

Nisonxi

我是 Nisonxi,PowerDoze 的開發者。當初純粹因為我自己受夠了 Windows 桌機整天全速發呆吃電、卻找不到一個能「看懂情況、自動切換」的工具,乾脆自己做。這個部落格就是我一路上的筆記。

關於作者與 PowerDoze →