【譯】Import Changes from Direct3D 11 to Direct3D 12

 

譯者:林公子編程

出處:木木的二進制人生windows

轉載請註明做者和出處,謝謝!多線程

 

       這是微軟公佈的Direct3D 12文檔的其中一篇,此翻譯留做學習記錄備忘,水平有限,錯漏不免,還望海涵。   

  原文連接是https://msdn.microsoft.com/en-us/library/windows/desktop/dn899194(v=vs.85).aspxide

 

Direct3D 12到Direct3D 11的重大改變函數

Direct3D 12是對Direct3D 11編程模型的一個巨大顛覆。Direct3D 12讓應用程序比以往更接近硬件底層。經過接近底層,Direct3D 12更加的快速和高效。不過你的應用程序使用Direct3D 12帶來的速度和效率提高相應的代價是你要比使用Direct3D 11負責更多的工做。性能

Direct3D 12是底層編程的迴歸。經過引入這些新特性,它給予你對遊戲和應用程序中圖形元素的更多的控制: 用於表明管線總體狀態的的對象,用於任務提交的command list和bundles,用於資源訪問的descriptor heap/table。學習

 

Direct3D 12 vs Direct3D 11的取捨編碼

使用Direct3D 12你的應用程序的速度和效率獲得了提高,不過你要負責相對與Direct3D 11更多的工做。spa

l  在Direct3D 12中,CPU-GPU的同步明確由應用程序負責,再也不像Direct3D 11中由運行時隱式執行。這也意味着Direct3D 12沒有對pipeline hazard的自動檢查,所以這也成爲了應用程序的職責。線程

l  在Direct3D 12中,應用程序負責管線數據更新。也就是Direct3D 11中的"Map/Lock-Discard"模式在Direct3D 12中必須手動進行。在Direct3D 11中,當你使用D3D11_MAP_WRITE_DISCARD標識調用ID3D11DeviceContext::Map時,運行時返回一個新內存區塊的指針代替舊的緩衝數據。這讓GPU可以在應用程序往新緩衝填充數據的同時使用舊的數據。應用程序不須要額外的內存管理。舊的緩衝在GPU使用完後會自動銷燬或重用。

l  在Direct3D 12中,全部的動態更新(包括constant buffer,dynamic vertex buffer,dynamic textures等等)明確由應用程序來控制。這些動態更新包括任何請求的GPU fence和buffer。應用程序有責任保證內存在使用完以前是有效的。

l  Direct3D 12只將COM風格的引用計數用於interface的生命週期(經過Direct3D的弱引用模型關聯到device的生命週期)。全部的resource和description內存生命週期由應用程序來負責保證適當的存活時間,並且它們都沒有使用引用計數。Direct3D 11也使用引用計數來管理interface相關的對象。

 

管線狀態對象

Direct3D11容許使用大量獨立的對象的集合來操縱管線狀態。例如,input assembler state,pixel shader state,rasterizer state和output merge state都可以獨立的進行修改。這種設計提供了便利性和相對高層的圖形管線表示。可是沒有利用現代硬件的能力。主要是各類各樣的state一般是互相關聯的。例如,不少GPU將pixel shader和output merger state合併爲一個硬件表示。然而由於Direct3D 11 API這些管線階段狀態被分別設置,顯示驅動不能決議管線狀態直到狀態最後肯定下來,而這要等到繪製的時候。這種規劃延遲了硬件的狀態設置,也就意味着額外的開銷和更少的每幀DP

Direct3D 12經過將大部分管線狀態統一到不可變的管線狀態對象(PSOs)來解決這個問題,PSOs在建立的時間就決定了。硬件和驅動可以當即將PSO轉換爲用來驅動GPU工做的硬件本地指令和狀態。你仍然能夠動態切換使用的PSO。這麼作硬件只須要直接拷貝最少的預計算狀態到硬件寄存器,而不是實時計算硬件狀態。經過使用PSOs,DP的開銷顯著的減小,而後每幀能夠有更多的DP。更多關於PSOs的信息見Managing graphics pipeline state in Direct3D 12

 

命令列表和集合(bundle)

在Direct3D 11中,全部的任務提交都經過immediate context完成,immediate context表明了一條送往GPU的指令流。要實現多線程,遊戲還有deferred context可使用。Direct3D 11中的Deferred Context不能完美的映射到硬件,因此它們能作的事情有限。

Direct3D 12引入了給予命令列表的任務提交模型。命令列表包含了在GPU上執行一個具體工做所需的全部信息。每一個命令列表包含的信息有使用哪一個PSO,須要什麼紋理和緩衝資源和全部DP的參數。由於每一個命令列表是自包含的而且沒有狀態繼承。驅動可以預先計算全部須要的GPU命令,而且是以一種自由線程化(free-threaded)的方式。接下來惟一須要進行的處理是經過命令隊列將命令列表最終提交到GPU。

除了命令列表,Direct3D 12還引入了一個二級的任務預計算方式:bundle。不像命令列表,徹底的自包含,通常性的被構造,提交一次而後丟棄,bundle提供了某種形式的狀態繼承來容許複用。例如,若是遊戲想要用不一樣的紋理繪製兩個角色模型。一種方法是用一個命令列表記錄兩組完整同樣的DP。另外一種方法是記錄一個繪製單一角色模型的bundle,而後用不一樣的資源在命令列表上「回放」bundle兩次。在後一種狀況下,顯示驅動只須要計算相應的指令一次,而建立命令列表本質上至關於兩個低開銷的函數調用。

更多關於命令列表和bundle的信息,見Work Submission in Direct3D 12

 

描述符堆和表(Descriptor Heap and Table)

Direct3D 11中的資源綁定高度抽象和便利,卻留下不少現代硬件能力沒有被利用到。在Direct3D 11中,遊戲建立資源的視圖對象,而後綁定這些視圖到管線中不一樣shader階段的slot中。而後Shader從顯式綁定的 slot讀取數據,這些綁定slot在繪製時是固定的。這個模型意味着每當遊戲使用不一樣的資源繪製,它必須從新綁定不一樣的視圖到不一樣的slot,而後再次調用繪製函數。這種狀況也表現出額外的開銷可以經過徹底利用硬件能力來消除。

Direct3D 12改變了綁定模型來匹配現代硬件並顯著的提高了性能。和須要獨立的資源視圖和顯式的綁定到slot相反,Direct3D 12提供了一個descriptor heap用來建立遊戲中不一樣的資源。這個方案提供了一種機制讓GPU預先直接寫入硬件本地資源描述(descriptor)到內存。由於descriptor heap已經被恰當的特定於硬件的descriptor數據填充,改變descriptor table是消耗至關低的操做

除了由descriptor heap和table帶來的性能提高。Direct3D 12還容許資源在shader裏被動態的索引,這提供了空前的靈活性並開啓了新渲染技術的大門。舉例來講,現代延遲渲染引擎通常將一個某種形式的材質或物體標識符編碼到中間的G-Buffer。在Direct3D 11中,這些引擎必須當心的避免使用太多的材質,由於在一個G-Buffer中包含太多會極大的影響最終渲染pass的速度。有了能動態索引的資源,一個有上千材質的場景可以最終和只有十個材質的場景同樣快。

更多關於descriptor head和table的信息,見Resource Binding

相關文章
相關標籤/搜索