交換鏈是如何將渲染數據輸出到屏幕的不可或缺的一部分。它們通常由一組輸出就緒型緩沖區組成,每個緩沖區都可以旋轉渲染為一個緩沖區。在渲染到交換鏈的某個緩沖區的同時,交換鏈中的其他緩沖區通常被讀取以進行顯示輸出。
本文介紹了在 NVIDIA GPU 上使用交換鏈時的最佳實踐。要在您的應用中獲得穩定的高幀率,請參閱我們的高級 API 性能提示。
在尋求提高渲染性能時,通常會專注于渲染管線中更頻繁優化的部分。但是,交換鏈通常會被忽略,從而將潛在性能和延遲放在桌面上。
以下建議和注意事項可讓您更深入地了解確保最佳交換鏈性能的最佳方法。
推薦
- 使用翻轉模式交換鏈。這對于利用多平面疊加支持尤為重要,因為在窗口模式下運行時,多平面疊加支持可提供全屏性能和延遲。
- 使用
SetFullScreenState(TRUE)
(無邊框)全屏窗口和非窗口翻轉模型交換鏈,可切換到真正的即時獨立翻轉模式。- 這是唯一支持無限幀速率的模式,在調用 Direct 3D 12 時,該模式會導致 Direct 3D 12 出現撕裂,
Present(0,0)
. - 如需為支持可變刷新率的顯示器提供適當的無限幀率支持,您還必須使用
DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING
交換鏈標志,以及DXGI_PRESENT_ALLOW_TEARING
Present
標志
- 這是唯一支持無限幀速率的模式,在調用 Direct 3D 12 時,該模式會導致 Direct 3D 12 出現撕裂,
- 使用
DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
會有意識地顯示出來。- 如果窗口大小與當前屏幕分辨率相匹配,則無需使用該標志即可實現無限幀率(請參閱前面的注釋)
- 如果設置了此標志,請嘗試使用 ResizeTarget 更改分辨率,然后再調用
SetFullScreenState(TRUE)
工作正常,幀速率將無限 - 如果未設置此標志,請嘗試使用
ResizeTarget
然后再調用SetFullScreenState(TRUE)
不會導致顯示分辨率發生變化。您的目標已擴展到當前分辨率,且幀率受限。
- 如果不處于全屏狀態(真正的即時獨立翻轉模式),請仔細控制交換鏈中的延遲和緩沖區數量,以獲得所需的幀速率和延遲。
- 使用
IDXGISwapChain2::SetMaximumFrameLatency(MaxLatency)
來設置所需的延遲,MaxLatency
是一定數量的幀(按隊列中的幀數計算)Present
調用)。 - 要做到這一點,您必須使用
DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT
設置的標志。 - DXGI 開始阻塞
Present
在您擁有MaxLatency
當前調用的數量。 - 在此窗口狀態下,同步間隔為 0
Present
call 可確保所呈現的幀是可供下次進行桌面合成時使用的最新幀(將窗口渲染的幀與桌面的其余部分結合使用),并且丟棄之前完成的所有幀,轉而使用最新的幀。在合成發生之前不會顯示任何渲染幀,這發生在VSYNC
時間。這個最新完成的幀是所顯示的
- 使用
- 使用的交換鏈緩沖區比打算排隊的最大幀數多約 1-2 倍(就命令分配器、動態數據和關聯的幀圍欄而言)。通過將最大幀延遲設置為交換鏈緩沖區的這個數量,
IDXGISwapChain2::SetMaximumFrameLatency(MaxLatency)
.- 這可確保您可以從應用程序邏輯中以最佳方式明確限制隊列中的幀和延遲,而不是依靠操作系統在意外的時間阻止或阻止它。
不推薦
- 忘記了這一點,默認情況下,在 DXGI 開始阻塞之前,每個交換鏈限制為三個排隊幀
Present
.這意味著,如果當前有三個 Present 調用,它將在第四次 Present 調用中阻塞Present
呼叫排隊。- 設置
DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT
交換鏈創建和使用的標志IDXGISwapChain2::SetMaximumFrameLatency
來修改此默認值,
- 設置
- 忘記通話
ResizeBuffers
切換到真正的即時獨立翻轉模式后,SetFullScreenState(TRUE)
.
致謝
感謝 Cody Robson、Kumaresan Gnanasekaran、Adrian Muntianu 和 Meenal Nachnani 提供的建議和幫助。
?