共用方式為


Direct3D 12 Interop

D3D12 可用來撰寫元件化應用程式。

Interop 概觀

D3D12 非常強大,並允許應用程式以類似控制台的效率撰寫圖形程序代碼,但並不是每個應用程式都需要從頭開始重塑轉譯引擎並撰寫完整的轉譯引擎。 在某些情況下,另一個元件或連結庫已經做得更好,或者在其他情況下,部分程式代碼的效能與其正確性和可讀性並不那麼重要。

本節涵蓋下列 Interop 技術:

  • 相同裝置上的 D3D12 和 D3D12
  • 不同裝置上的 D3D12 和 D3D12
  • 相同裝置上的 D3D12 和 D3D11、D3D10 或 D2D 的任何組合
  • D3D12 和不同裝置上 D3D11、D3D10 或 D2D 的任何組合
  • D3D12 和 GDI,或 D3D12 和 D3D11 和 GDI

使用 Interop 的原因

應用程式想要與其他 API 的 D3D12 Interop 有數個原因。 一些範例:

  • 累加移植:想要將整個應用程式從 D3D10 或 D3D11 移植到 D3D12,同時在移植程式的中繼階段運作(以啟用測試和偵錯)。
  • 黑箱程式代碼:在移植其餘的程式代碼時,想要讓應用程式的特定部分 as-is。 例如,可能不需要移植遊戲的UI元素。
  • 不可變更的元件:需要使用應用程式未擁有的元件,這些元件不會寫入目標 D3D12。
  • 新的元件:不想移植整個應用程式,但想要使用使用 D3D12 撰寫的新元件。

D3D12 中的 Interop 有四個主要技術:

  • 應用程式可以選擇將開啟的命令清單提供給元件,該元件會將一些額外的轉譯命令記錄至已系結的轉譯目標。 這相當於將備妥的裝置內容提供給 D3D11 中的另一個元件,而且非常適合將 UI/文字新增至已系結的緩衝區等專案。
  • 應用程式可以選擇提供命令佇列給元件,以及所需的目的地資源。 這相當於在 D3D11 中使用 ClearStateDeviceContextState API,為另一個元件提供乾淨的裝置內容。 這就是 D2D 等元件的運作方式。
  • 元件可能會選擇模型,其中會產生命令清單,可能平行,應用程式會在稍後負責提交。 必須跨元件界限提供至少一個資源。 雖然 D3D12 中的效能更理想,但 D3D11 中的效能較可取,但 D3D11 中提供相同的技術。
  • 每個元件都有自己的佇列/或裝置,而且應用程式和元件需要跨元件界限共用資源和同步處理資訊。 這類似於舊版 ISurfaceQueue,而較現代化的 IDXGIKeyedMutex

這些案例之間的差異在於元件界限之間確切共享的內容。 裝置會假設為共用,但由於它基本上是無狀態的,所以它並不真正相關。 索引鍵對像是命令清單、命令佇列、同步對象和資源。 在共享它們時,每一個都有各自的併發症。

共用命令清單

Interop 最簡單的方法只需要與引擎的一部分共用命令清單。 轉譯作業完成後,命令列表擁有權會回到呼叫端。 命令清單的擁有權可以透過堆疊追蹤。 由於命令清單是單個線程,因此應用程式無法使用此技術執行唯一或創新的動作。

共用命令佇列

在相同進程中共用裝置的多個元件,可能是最常見的技術。

當命令佇列是共用的單位時,必須呼叫元件,讓它知道所有未處理的命令清單都必須立即提交至命令佇列(而且需要同步處理任何內部命令佇列)。 這相當於 D3D11 Flush API,也是應用程式提交自己的命令清單或同步處理基本類型的唯一方式。

共用同步處理基本類型

在自己的裝置和/或命令佇列上運作的元件預期模式是接受 ID3D12Fence 或共用句柄,並在開始工作時接受 UINT64 配對,然後等候第二個 ID3D12Fence 或共用句柄,以及 UINT64 配對,當所有工作完成時,都會發出信號。 此模式符合IDXGIKeyedMutex 和 DWM/DXGI 翻轉模型同步處理設計目前的實作。

共用資源

到目前為止,撰寫利用多個元件的 D3D12 應用程式,最複雜的部分就是如何處理跨元件界限共用的資源。 這主要是因為資源狀態的概念。 雖然資源狀態設計的某些層面是為了處理命令清單內的同步處理,但其他方面確實會影響命令清單、影響資源配置,以及存取資源數據的有效作業集或效能特性。

有兩種處理這種複雜狀況的模式,這兩種模式基本上都涉及元件之間的合約。

  • 合約可由元件開發人員定義並記載。 這可能很簡單,例如「資源必須在工作啟動時處於默認狀態,且會在工作完成時回到默認狀態」,或可能會有更複雜的規則,以允許共用深度緩衝區等專案,而不需要強制中繼深度解析。
  • 當資源跨元件界限共用時,應用程式可以在運行時間定義合約。 它是由相同的兩個資訊片段所組成: 資源在元件開始使用時的狀態,以及元件完成時應該將它留在的狀態。

選擇 Interop 模型

對於大部分的 D3D12 應用程式,共用命令佇列可能是理想的模型。 它允許建立和提交工作的完整擁有權,而不需要有備援佇列的額外記憶體額外負荷,而且不會對處理 GPU 同步處理基本類型的影響。

一旦元件需要處理不同的佇列屬性,例如類型或優先順序,或一旦共用需要跨越進程界限,就需要共用同步基本類型。

共用或產生命令清單並非由第三方元件廣泛使用,但可能廣泛使用於遊戲引擎內部的元件中。

Interop API

Direct3D 11 on 12 主題會逐步引導您使用與本主題所述的互作性類型相關的大部分 API 介面。

另請參閱 ID3D12Device::CreateSharedHandle 方法,您可以使用此方法在 Windows 圖形 API 之間共用介面。