Direct3D 9 到 Direct3D 11 的重大變更
摘要
- 規劃 DirectX 移植
- Direct3D 9 到 Direct3D 11 的重大變更
- 功能對應
本主題概要說明 DirectX 9 與 DirectX 11 之間的差異。
基本上,Direct3D 11 與 Direct3D 9 是同類型 API,屬於圖形硬體的低階虛擬化介面。 透過 Direct3D 11,您仍可在各種硬體實作上執行圖形繪製作業。 自 Direct3D 9 後,圖形 API 的版面配置已變更;除了延伸裝置內容的概念,也特別新增適用於圖形基礎結構的 API。 儲存於 Direct3D 裝置的資源採用適用於資料多型的全新機制,稱為「資源檢視」。
Core API 函式
在 Direct3D 9 中,您必須先建立 Direct3D API 的介面才能開始使用。 在 Direct3D 11 的通用 Windows 平台 (UWP) 遊戲中,呼叫名為 D3D11CreateDevice 的靜態函式,以建立裝置和裝置內容。
裝置和裝置內容
Direct3D 11 裝置代表虛擬化圖形介面卡。 用來在視訊記憶體中建立資源,例如:將紋理上傳至 GPU、建立紋理資源和交換鏈結的檢視,以及建立紋理取樣器。 如需 Direct3D 11 裝置介面用途的完整清單,請參閱<ID3D11Device>和<ID3D11Device1>。
Direct3D 11 裝置內容用來設定管線狀態及產生轉譯命令。 例如,Direct3D 11 轉譯鏈結會使用裝置內容,以設定轉譯鏈結並繪製場景 (請參閱下文)。 裝置內容可用來存取 Direct3D 裝置資源所用的視訊記憶體;也會用來更新子資源資料,例如:常數緩衝區資料。 如需 Direct3D 11 裝置內容的完整清單,請參閱<ID3D11DeviceContext>和<ID3D11DeviceContext1>。 請注意,我們大部分的範例是以即時內容直接轉譯至裝置,但 Direct3D 11 也支援延遲裝置內容,主要用於多執行緒。
在 Direct3D 11 中,裝置控制代碼和裝置內容控制代碼都是透過呼叫 D3D11CreateDevice 取得。 您也可透過此方法,要求一組特定硬體功能,並針對圖形介面支援的 Direct3D 功能層級擷取相關資訊。 請參閱<Direct3D 11 中的緩衝區簡介>瞭解更多有關裝置、裝置內容和執行緒考量的資訊。
裝置基礎結構、畫面格緩衝區和轉譯目標檢視
在 Direct3D 11 中,我們是使用 IDXGIAdapter 和 IDXGIDevice1 COM 介面,透過 DirectX Graphics Infrastructure (DXGI) API 設定裝置配接器和硬體組態。 緩衝區及其他視窗資源 (可見或幕後頁面) 是由特定的 DXGI 介面建立和設定;IDXGIFactory2 處理站模式實作可取得 DXGI 資源,例如:畫面格緩衝區。 由於 DXGI 擁有交換鏈結,因此 DXGI 介面可用來將畫面格呈現至螢幕,請參閱<IDXGISwapChain1>。
使用 IDXGIFactory2 建立與遊戲相容的交換鏈結。 您必須為核心視窗建立交換鏈結,或針對組合建立交換鏈結 (XAML Interop),而不是為 HWND 建立交換鏈結。
裝置資源和資源檢視
Direct3D 11 支援視訊記憶體資源中額外的多型層,稱為「檢視」。 基本上,原本您有一個適用於紋理的 Direct3D 9 物件,現在會有兩個物件:保存資料的紋理資源,以及指示檢視如何用於轉譯的資源檢視。 以資源為基礎的檢視可將該資源用於特定目的。 例如,2D 紋理資源會建立為 ID3D11Texture2D,然後在其上建立著色器資源檢視 (ID3D11ShaderResourceView),以在著色器中當作紋理使用。 您也可以在同一個 2D 紋理資源上建立轉譯目標檢視 (ID3D11RenderTargetView),以當作做繪圖介面使用。 在另一個範例中,相同的像素資料會以 2 種不同的像素格式表示,方法是在單一紋理資源上使用 2 個不同的檢視。
建立基礎資源時使用的屬性,必須相容於之後將由此建立的檢視類型。 例如,如果 ID3D11RenderTargetView 套用至介面,則該介面應使用 D3D11_BIND_RENDER_TARGET 旗標建立。 介面也必須具有與轉譯相容的 DXGI 介面格式 (請參閱 DXGI_FORMAT)。
用於轉譯的大部分資源都繼承自 ID3D11Resource 介面 (其繼承自 ID3D11DeviceChild)。 頂點緩衝區、索引緩衝區、常數緩衝區和著色器都是 Direct3D 11 資源。 輸入配置和取樣器狀態直接繼承自 ID3D11DeviceChild。
資源檢視會使用 DXGI_FORMAT 列舉值表示像素格式。 有部分 D3DFMT 不支援使用 DXGI_FORMAT。 例如,DXGI 中沒有相當於 D3DFMT_R8G8B8 的 24bpp RGB 格式。 此外,也不是每個 RGB 格式都有 BGR 對等項目 (DXGI_FORMAT_R10G10B10A2_UNORM 是 D3DFMT_A2B10G10R10 的對等項目,但無法直接對應至 D3DFMT_A2R10G10B10)。 請規劃將舊版格式內容轉換成建置階段支援的格式。 如需 DXGI 格式的完整清單,請參閱<DXGI_FORMAT>列舉。
在轉譯場景之前,先建立 Direct3D 裝置資源 (和資源檢視)。 裝置內容可用來設定轉譯鏈結,請參閱下文。
裝置內容和轉譯鏈結
在 Direct3D 9 和 Direct3D 10.x 中,有一個負責管理資源、建立、狀態和繪製的 Direct3D 裝置物件。 在 Direct3D 11 中,Direct3D 裝置介面仍會管理資源建立,但所有狀態和繪製作業將使用 Direct3D 裝置內容進行處理。 以下範例說明如何使用裝置內容 (ID3D11DeviceContext1 介面) 設定轉譯鏈結:
- 設定與清除轉譯目標檢視 (以及深度樣板檢視)
- 設定輸入組合器階段 (IA 階段) 的頂點緩衝區、索引緩衝區和輸入配置
- 將頂點和像素著色器繫結至管線
- 將常數緩衝區繫結至著色器
- 將紋理檢視和取樣器繫結至像素著色器
- 繪製場景
呼叫 ID3D11DeviceContext::Draw 方法可在轉譯目標檢視上繪製場景。 完成所有繪製作業後,使用 DXGI 介面卡呼叫 IDXGISwapChain1::Present1 呈現完成的畫面格。
狀態管理
Direct3D 9 是透過一大組的個別切換來管理狀態設定 (使用 SetRenderState、SetSamplerState 和 SetTextureStageState 方法)。 由於 Direct3D 11 不支援舊版固定函式管線,因此將以寫入像素著色器 (PS) 取代 SetTextureStageState。 其中沒有 Direct3D 9 狀態區塊的對等項目。 Direct3D 11 改用 4 種狀態物件管理狀態,進一步簡化分組轉譯狀態的方式。
例如,我們不是使用 SetRenderState 搭配 D3DRS_ZENABLE,而是建立 DepthStencilState 物件,搭配狀態及其他相關的狀態設定,然後轉譯時用來變更狀態。
請注意,將 Direct3D 9 應用程式移植到狀態物件時,各種狀態組合會以不可變的狀態物件表示。 建立一次即可重複使用 (只要狀態仍有效)。
Direct3D 功能層級
Direct3D 有一個用於判斷硬體支援的新機制,稱為「功能層級」。 透過功能層級,您可要求一組定義完善的 GPU 功能,簡化了圖形介面卡可執行的工作。 例如,9_1 功能層級會實作 Direct3D 9 圖形介面卡提供的功能,包括著色器模型 2.x。 由於 9_1 是最低功能層級,因此可預期所有裝置都支援頂點著色器和像素著色器,這個階段與 Direct3D 9 可程式化著色器模型支援的相同。
遊戲將使用 D3D11CreateDevice 建立 Direct3D 裝置和裝置內容。 呼叫此函式時,可提供遊戲支援的功能層級清單。 其會從該清單傳回支援的最高功能層級。 例如,如果遊戲可使用 BC4/BC5 紋理 (DirectX 10 硬體功能),則支援的功能層級清單至少會包含 9_1 和 10_0。 如果遊戲是在 DirectX 9 硬體上執行,且無法使用 BC4/BC5 紋理,則 D3D11CreateDevice 會傳回 9_1。 然後遊戲即可回復到不同的紋理格式 (和較小的紋理)。
如果您決定延伸 Direct3D 9 遊戲,以支援更高的 Direct3D 功能層級,建議先將現有的 Direct3D 9 圖形程式碼移植完成。 遊戲開始在 Direct3D 11 中運作之後,使用增強的圖形新增其他轉譯路徑就會比較容易。
如需功能層級支援的詳細說明,請參閱<Direct3D 功能層級>。 如需 Direct3D 11 功能的完整清單,請參閱<Direct3D 11 功能>和<Direct3D 11.1 功能>。
功能層級和可程式化的管線
硬體自 Direct3D 9 後持續升級,且已在可程式化圖形管線中新增多個選擇性階段。 圖形管線選項隨 Direct3D 功能層級而有所不同。 功能層級 10.0 包含幾何著色器階段,以及 GPU 上的 multipass 轉譯串流輸出 (選擇性)。 功能層級 11_0 包含輪廓著色器和網域著色器,可搭配硬體鑲嵌使用。 功能層級 11_0 也包含 DirectCompute 著色器的完整支援,功能層級 10.x 只包含有限形式的 DirectCompute 支援。
所有著色器都是使用對應至 Direct3D 功能層級的著色器設定檔,以 HLSL 撰寫。 著色器設定檔向上相容,因此使用 vs_4_0_level_9_1 或 ps_4_0_level_9_1 編譯的 HLSL 著色器可運作於所有裝置。 著色器設定檔無法向下相容,因此使用 vs_4_1 編譯的著色器只能在功能層級 10_1、11_0 或 11_1 的裝置上運作。
Direct3D 9 使用與 SetVertexShaderConstant 和 SetPixelShaderConstant 共用的陣列,管理著色器的常數。 Direct3D 11 使用常數緩衝區,也就是頂點緩衝區或索引緩衝區等資源。 常數緩衝區專為提升更新效率而設計。 您不是將所有著色器常數彙整到單一全域數組中,而是將常數組織到邏輯分組中,並透過一個或多個常數緩衝區管理它們。 將 Direct3D 9 遊戲移植到 Direct3D 11 時,請規劃常數緩衝區以便適當更新。 例如,如果是不會每畫面格更新的著色器常數,則劃分至不同的常數緩衝區,這樣就不需要持續將該資料與動態著色器常數,一起上傳至圖形介面卡。
注意大部分 Direct3D 9 應用程式都廣泛使用著色器,但偶爾會混合使用舊版的固定函式行為。 請注意,Direct3D 11 只使用可程式化的著色模型。 Direct3D 9 的舊版固定函式功能已遭取代。