為了獲得最佳效能,請使用 DXGI 翻轉模型
本主題提供開發人員指引,說明如何在新式 Windows 版本的簡報堆疊中將效能和效率最大化。 它會挑選 DXGI 翻轉模型、DirectX 12:Windows 10 中的簡報模式(影片),以及 Windows 10 中的簡報增強功能:早期外觀(影片) 關閉。
呼叫動作
如果您仍在使用 DXGI_SWAP_EFFECT_DISCARD 或 DXGI_SWAP_EFFECT_SEQUENTIAL (也就是 “blt” 目前模型),是時候停止了!
切換至 DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL 或 DXGI_SWAP_EFFECT_FLIP_DISCARD(也就是翻轉模型)可提供更佳的效能、較低的電源使用量,並提供更豐富的功能集。 (如需這些值的詳細資訊,請參閱 DXGI_SWAP_EFFECT 列舉。
相較於傳統「全螢幕獨佔」模式,翻轉模型呈現的方式是讓視窗模式有效地對等或更好。 事實上,您可能想要重新考慮您的應用程式是否真的需要全螢幕獨佔模式,因為翻轉模型無框線視窗的優點包括更快速的切換 Alt-Tab 切換,以及與現代顯示功能更好的整合。
為什麼現在? 在 2018 年 4 月更新之前,blt 模型在混合式 GPU 組態上使用時可能會導致可見撕裂,通常位於高端膝上型電腦中(請參閱 KB 3158621)。 在 2018 年 4 月的更新中,這種撕裂已經固定,代價是一些額外的工作。 如果您要在混合式 GPU 之間以高幀速率呈現blt,特別是在4K等高解析度時,此額外工作可能會影響整體效能。 若要在這些系統上維持最佳效能,請從blt切換至翻轉目前模型。 此外,請考慮減少交換鏈的解析度,特別是如果它不是用戶互動的主要點(就像 VR 預覽視窗的情況一樣)。
簡短歷程記錄
什麼是翻轉模型? 替代方式為何?
在 Windows 7 之前,呈現 D3D 內容的唯一方法是「blt」或將其複製到視窗或螢幕所擁有的表面。 從 D3D9 的 FLIPEX 交換效果開始,並透過 Windows 8 中的FLIP_SEQUENTIAL交換效果來到 DXGI,我們開發了更有效率的方式,將內容直接與桌面撰寫器共用,以最少的複本將內容放在螢幕上。 如需技術的高階概觀,請參閱 DXGI 翻轉模型。
由於 DWM(桌面視窗管理員),這是驅動 Windows 桌面的撰寫器,因此可能會進行此優化。
何時應該使用blt模型?
翻轉模型沒有提供一項功能:能夠產生多個不同的 API 來產生內容,而這些 API 會以目前為基礎,將所有圖層一起分層到相同的 HWND。 其中一個範例是使用 D3D 來繪製視窗背景,然後 Windows GDI 來繪製上方的東西,或使用兩個不同的圖形 API,或兩個來自相同 API 的交換鏈來產生交替畫面。 如果您不需要 HWND圖形元件之間的層級 Interop,則不需要 blt 模型。
原始翻轉模型設計中沒有提供第二個功能,但現已提供,這是在未受限制的幀速率中呈現的功能。 對於使用同步間隔 0 的應用程式,除非有 可用的 IDXGIFactory5::CheckFeatureSupport API,否則不建議切換為翻轉模型,以及報告對 DXGI_FEATURE_PRESENT_ALLOW_TEARING的支援。 這項功能幾乎無處不在於最新版本的 Windows 10 和現代化硬體上。
DirectFlip
如果您觀看了 DirectX 12:Windows 10中的簡報模式,您會看到談論「直接翻轉」和「獨立翻轉」。這些是針對使用翻轉模型交換鏈的應用程式啟用的優化。 視視窗和緩衝區組態而定,可以完全略過桌面組合,並以獨佔全螢幕相同的方式,直接將應用程式畫面傳送到畫面。
這些天,這些優化可以參與3個案例的其中一個,以增加功能:
- DirectFlip:您的交換鏈緩衝區會符合螢幕維度,而您的視窗用戶端區域則涵蓋畫面。 使用應用程式交換鏈,而不是使用 DWM 交換鏈在畫面上顯示。
- DirectFlip 與面板安裝器:您的視窗用戶端區域涵蓋螢幕,而您的交換鏈緩衝區位於螢幕的某些硬體相依縮放比例內(例如 0.25x 到 4x)。 GPU 掃描硬體可用來調整緩衝區,同時將它傳送至顯示器。
- 具有多平面重疊的 DirectFlip:您的交換鏈緩衝區位於視窗維度的某些硬體相依縮放比例內。 DWM 能夠為您的應用程式保留專用的硬體掃描平面,然後掃描出來,並可能伸展到螢幕的 Alpha 混合子區域。
透過視窗式翻轉模型,應用程式可以查詢不同 DirectFlip 案例的硬體支援,並透過使用 IDXGIOutput6::CheckHardwareCompositionSupport實作不同類型的動態調整。 要注意的一個注意事項是,如果利用面板安裝器,游標可能會遭受伸展副作用,這通過 DXGI_HARDWARE_COMPOSITION_SUPPORT_FLAG_CURSOR_STRETCHED表示。
一旦交換鏈「DirectFlipped」,DWM 就可以進入睡眠狀態,且只有在應用程式外部發生變更時才會喚醒。 您的應用程式畫面會以與全螢幕獨佔相同的效率,直接傳送到畫面。 這是「獨立翻轉」,而且可以參與上述所有案例。 如果其他桌面內容進入頂端,DWM 可以順暢地轉換回撰寫模式、有效率地「反向撰寫」應用程式上方的內容再翻轉,或利用MPO來維護獨立的翻轉模式。
請查看 PresentMon 工具,以深入瞭解使用上述專案。
翻轉模型中還有什麼新功能?
除了上述改進,適用於標準交換鏈,沒有任何特殊專案,有數個功能可供翻轉模型應用程式使用:
- 使用 DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT減少延遲。 當處於獨立翻轉模式時,您可以在最新版本的 Windows 上降低到 1 個延遲畫面,並在撰寫時適當地回復到可能的最低延遲。
- 注意:在 Windows 10 年度更新版和更早版本中,至少有兩個畫面格延遲的問題。 如需詳細資訊,請參閱 此論壇主題。 這是在 Fall Creator's Update 中修正的。
- DXGI_SWAP_EFFECT_FLIP_DISCARD 啟用直接翻轉的「反向組合」模式,導致整體工作較不顯示桌面。 DWM 可以在應用程式緩衝區上塗鴉,並將這些緩衝區傳送到畫面,而不是執行完整複本到自己的交換鏈。
- DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING 可以啟用比可等候物件低的延遲,即使在支援多平面重疊系統的視窗中也是如此。
- 應用程式可以使用交換鏈建立期間所設定 DXGI_SCALING 屬性,控制在視窗重設期間發生的內容調整。
- HDR 格式 (R10G10B10A2_UNORM 或 R16G16B16A16_FLOAT) 的內容不會受到限制,除非它是由 SDR 桌面所組成。
- 目前統計數據可在視窗模式中使用。
- UWP(通用 Windows 平臺)應用程式模型和 DX12 的相容性更高,因為這些與翻轉模型僅相容。
我該怎麼做才能使用翻轉模型?
翻轉模型交換鏈在blt交換鏈之上有一些額外的需求:
- 緩衝區計數必須至少為 2。
- Present 呼叫之後,後端緩衝區必須明確地重新系結至 D3D11 立即內容,才能再次使用。
- 呼叫 setFullscreenState 之後,應用程式必須先呼叫 resizeBuffers ,才能 Present。
- 翻轉模型中沒有直接支援 MSAA (多重取樣反別名)交換鏈,因此應用程式必須在發出 Present之前執行 MSAA 解析。
如何選擇正確的轉譯和簡報解析度
過去應用程式的傳統模式是為使用者提供當用戶選取獨佔全螢幕模式時所要選擇的解析度清單。 透過新式顯示器能夠順暢地開始調整內容,請考慮讓使用者能夠選擇轉譯解析度來進行效能調整,與輸出解析度無關,甚至是在視窗模式中。 此外,應用程式應該利用 IDXGIOutput6::CheckHardwareCompositionSupport 來判斷它們是否需要在呈現內容之前調整內容,或者它們是否應該讓硬體為其執行縮放。
您的內容可能需要從某個 GPU 移轉至另一個 GPU,作為目前或組合作業的一部分。 這通常適用於多 GPU 膝上型電腦,或已插入外部 GPU 的系統。 隨著這些組態變得更常見,而且隨著高解析度顯示器變得越來越常見,呈現完整解析度交換鏈的成本會增加。 如果您的交換鏈目標不是用戶互動的主要點,就像將 VR 場景的 2D 預覽呈現至次要視窗的 VR 標題的情況一樣,請考慮使用較低的解析度交換鏈,將需要跨不同 GPU 傳輸的頻寬量降到最低。
其他考慮
您第一次要求 GPU 寫入交換鏈回緩衝區,就是 GPU 將停止等候緩衝區可供使用的時間。 可能的話,請盡可能將這個點延遲到畫面。