標籤:學習 swap 問題 匹配 索引 get 沒有 路徑 refresh
今天要學習的這篇文章寫的算是比較早的了,大概在DX11時代就寫好了,當時龍書11版看得很潦草,並沒有注意這篇文章,現在看12,覺得是跳不過去的一篇文章,地址如下: https://msdn.microsoft.com/en-us/library/windows/desktop/ee417025(v=vs.85).aspx 。
我本意是記錄下學習筆記,但可能寫成了翻譯,但這也沒有辦法的事,MSDN的寫作風格就是簡單凝練,缺少參考索引,所以看MSDN往往也就是讀完本文,點點加有超連結的名詞,頂多再跑跑常式而已。
Microsoft DirectX Graphics Infrastructure(DXGI)是從WIndows Vista時代開始引入的一個子系統,它封裝了一些Direct3D 10, 10.1, 11和11.1需要的低層次(low-level)任務。對於使用Direct3D 9的程式員,DXGI包括絕大部分之前打包進Direct3D 9 的enumeration,產生swap-chain和presentation相關API。當你要把應用遷移到DXGI,Direct3D 10.x和Direct3D 11.x,你必須充分考察一些事項以保證程式正常運行。
這篇文章主要討論以下事項:
- 全屏相關瑣事
- 多顯示器
- 視窗樣式和DXGI
- 多線程和DXGI
- 伽馬(Gamma)和DXGI
- DXGI 1.1
- DXGI 1.2
全屏相關瑣事
從Direct3D 9遷移到DXGI、Direct3D 10.x或者Direct3D 11.x,會給視窗模式到全螢幕模式轉換的操作帶來很多狀況。這主要是因為Direct3D 9不像使用DXGI的程式那樣需要那麼多的手動操作,DXGI給開發人員提供了很多可以追蹤視窗樣式和狀態的細節操作。當古老的模式轉換程式在新平台啟動並執行時候,總是會引起一些意想不到的問題。
Direct3D 9通常通過設定front buffer解析度來轉換視窗模式到全螢幕模式,並強迫裝置進入全屏獨佔模式再設定back buffer與其匹配。還有一條單獨路徑用於處理視窗尺寸,因為它們必須處理視窗進程接收到的WM_SIZE訊號。
DXGI結合了兩種情況的處理,試圖簡化處理流程。例如視窗模式下邊緣被拉扯時,應用接收到WM_SIZE訊號。DXGI攔截該訊號,並修改front buffer。開發人員只需要針對back buffer調用IDXGISwapChain::ResizeBuffers調整尺寸與隨WM_SIZE訊號所傳入參數一致。當應用需要在全屏及視窗模式間切換時,只需調用IDXGISwapChain:SetFullscreenState。DXGI自動調整front buffer並發送WM_SIZE訊號。應用再次調用ResizeBuffers,就像視窗邊緣被拖拽時一樣。
上述解釋的方法論使用了一條獨特的路徑。DXGI預設設定案頭解析度為全屏解析度。但很多應用要為全屏切換到某個特殊解析度。DXGI為這種情況準備了IDXGISwapChain::ResizeTarget。在調用SetFullscreenState之前調用。雖然可以以相反的順序調用,但會多發送WM_SIZE一次,課程會引起閃爍。在調用SetFullScreenState之後還是要調用ResizeTarget,只不過參數DXGI_MODE_DESC的RefreshRate子項設為空白。這是個非操作指令,但這可以避免重新整理率相關的瑣事,我們接下來就聊聊這個。
全螢幕模式時,桌面視窗管理員是禁用的。此時DXGI不會像視窗模式那樣用blit,而是使用翻轉去顯示back buffer。如果特定的需求不滿足,效益是不明確的。為了確定DXGI會用翻轉代替blit,front buffer和back buffer必須保持一致。如果此前應用正確處理了WM_SIZE,兩個buffer格式必然一直,也就沒什麼好擔心的了。
DirectX Graphics Infrastructure(DXGI):最佳範例 學習筆記