Direct3D 11 on 12
D3D11On12 是一種機制,開發人員可以使用 D3D11 介面和物件來驅動 D3D12 API。 D3D11on12 可讓使用 D3D11 (撰寫的元件,例如,D2D 文字和 UI) 可與以 D3D12 API 為目標的元件搭配使用。 D3D11on12 也啟用從 D3D11 到 D3D12 的應用程式累加移植,方法是讓應用程式部分繼續以 D3D11 為目標,以求簡單起見,而其他應用程式則以 D3D12 為目標,同時一律具有完整且正確的轉譯。 D3D11On12 可讓您比使用 Interop 技術共用資源及同步處理兩個 API 之間的工作更簡單。
初始化 D3D11On12
若要開始使用 D3D11On12,第一個步驟是建立 D3D12 裝置和命令佇列。 這些物件是以初始化方法 D3D11On12CreateDevice的輸入的形式提供。 您可以將此方法視為使用虛構驅動程式類型建立 D3D11 裝置D3D_DRIVER_TYPE_11ON12,其中 D3D11 驅動程式負責建立物件,並將命令清單提交至 D3D12 API。
擁有 D3D11 裝置和立即內容之後,您可以 QueryInterface
關閉 ID3D11On12Device 介面的裝置。 這是用於 D3D11 與 D3D12 之間 Interop 的主要介面。 若要讓 D3D11 裝置內容和 D3D12 命令清單在相同的資源上運作,您必須使用 CreateWrappedResource API 建立「包裝的資源」。 這個方法會「升級」D3D12 資源,以在 D3D11 中瞭解。 包裝的資源會以「取得」狀態開始,這是 AcquireWrappedResources 和 ReleaseWrappedResources 方法所操作的屬性。
使用方式範例
D3D11On12 的一般用法是使用 D2D 來轉譯 D3D12 後端緩衝區上的文字或影像。 如需範例程式碼,請參閱 D3D11On12 範例。 以下是執行此動作所需採取之步驟的粗略概述:
- 建立 D3D12 裝置 (D3D12CreateDevice) 和 D3D12 交換鏈結, (ID3D12CommandQueue作為輸入) 。
- 使用 D3D12 裝置和輸入相同的命令佇列,建立 D3D11On12 裝置。
- 擷取交換鏈結回緩衝區,並為每個緩衝區建立 D3D11 包裝的資源。 使用的輸入狀態應該是 D3D12 (的最後一種方式,例如RENDER_TARGET) ,而輸出狀態應該是 D3D12 在 D3D11 完成之後使用它的方式 (,例如 PRESENT) 。
- 初始化 D2D,並將 D3D11 包裝的資源提供給 D2D 以準備轉譯。
然後,在每個畫面上執行下列動作:
- 使用 D3D12 命令清單轉譯至目前的交換鏈結背景緩衝區,然後執行它。
- 取得目前後端緩衝區的包裝資源 (AcquireWrappedResources) 。
- 發出 D2D 轉譯命令。
- (ReleaseWrappedResources) 釋放 包裝的資源。
- 排清 D3D11 立即內容。
- 目前 (IDXGISwapChain1::P resent1) 。
背景
D3D11On12 有系統地運作。 每個 D3D11 API 呼叫都會通過一般執行時間驗證,並讓驅動程式能夠使用。 在驅動程式層中,特殊 11on12 驅動程式會記錄狀態,並將轉譯作業發出至 D3D12 命令清單。 例如,這些命令清單會視需要提交 (,例如,查詢 GetData
或資源 Map
可能需要) 或排清所要求的命令。 建立 D3D11 物件通常會導致建立對應的 D3D12 物件。 D3D11 中的某些固定函式轉譯作業,例如 GenerateMips
D3D12 不支援或 DrawAuto
,因此 D3D11On12 會使用著色器和其他資源來模擬它們。
對於 Interop,請務必瞭解 D3D11On12 如何與應用程式所建立和提供的 D3D12 物件互動。 為了確保工作以正確的順序進行,必須先排清 D3D11 立即內容,才能將額外的 D3D12 工作提交至該佇列。 請務必確保提供給 D3D11On12 的佇列隨時都必須清空。 這表示,即使 D3D11 轉譯執行緒無限期地封鎖,佇列上的任何等候最終仍必須滿足。 當 D3D11On12 插入排清或等候時,請小心不要相依于,因為這可能會隨著未來的版本而變更。 此外,D3D11On12 會自行追蹤及操作資源狀態。 確保狀態轉換的一致性唯一方法是使用取得/發行 API 來操作狀態追蹤,以符合應用程式的需求。
清除
若要釋放 D3D11On12 包裝的資源,必須依此順序發生兩件事:
- 必須釋放資源的所有參考,包括資源的任何檢視。
- 必須進行延後解構處理。 確保發生這種情況的最簡單方式是叫用立即內容
Flush
API。
完成這兩個步驟之後,應該釋放包裝資源所採取的任何參考,而 D3D12 資源會變成 D3D12 元件獨佔擁有。 請注意,除非您已經確認 GPU 不再使用資源,否則 D3D12 仍然需要等待 GPU 完成,因此請務必在資源上保留參考,再執行上述兩個步驟。
當 GPU 使用 D3D111 的延後解構機制完成使用時,將會在適當的時間清除所有其他資源或物件。 不過,如果您在 GPU 仍在執行時嘗試釋放 D3D11On12 裝置本身,解構可能會封鎖直到 GPU 完成為止。
限制
D3D11On12 層會實作非常大型的 D3D11 API 子集,但除了實作中可能導致轉譯不正確) 的 Bug 之外,還有一些已知的間距 (。
自 Windows 10 版本 1809 (10.0 起;組建 17763) ,只要 D3D11On12 在支援著色器模型 6.0 或更新版本的驅動程式上執行,它就可以執行使用介面的著色器。 在舊版的 Windows 中,著色器介面功能不會在 D3D11On12 中實作,而嘗試使用此功能會導致錯誤和偵錯訊息。
自 Windows 10 版起,版本 1803 (10.0;組建 17134) ,D3D11On12 裝置支援交換鏈結。 在舊版 Windows 中,它們不是。
D3D11On12 尚未針對效能進行優化。 相較于標準 D3D11 驅動程式,可能會有中等 CPU 額外負荷、最小的 GPU 額外負荷,而且已知會有顯著的記憶體額外負荷。 因此不建議針對複雜的 3D 場景使用 D3D11On12,而是建議用於簡單場景或 2D 轉譯。
API
組成 11on12 層的 API 會在 11on12 參考中說明。
相關主題