共用方式為


非同步程式設計 (DirectX 和 C++)

本主題涵蓋使用 DirectX 進行非同步程式設計與執行緒時,需要考慮的各種問題。

非同步程式設計與 DirectX

如果您只是瞭解 DirectX,或即使您有使用經驗,請考慮將所有圖形處理流程都放在一個執行緒上。 在遊戲中的任何特定場景中,都存在諸如點陣圖、著色器和其他需要獨佔存取權的資源。 這些相同的資源需要您同步跨平行執行緒對這些資源的任何存取。 渲染是一個跨多個執行緒進行並行化的困難過程。

但是,如果遊戲足夠複雜,或者希望獲得改進的效能,可以使用非同步程式設計來並行化一些並不特定於渲染流程的元件。 現代硬體擁有多核心與超執行緒 CPU,您的應用程式應該會利用這個優勢! 您可以針對遊戲中不需要直接存取 Direct3D 裝置內容的部分元件,使用非同步程式設計來確保這一點,例如:

  • 檔案 I/O
  • 物理學
  • AI
  • 網路功能
  • 音訊
  • 控制項
  • 基於 XAML 的 UI 元件

您的應用程式可以在多個並行執行緒上處理這些元件。 檔案 I/O,特別是資產載入,從非同步載入中獲益良多,因為您的遊戲或應用程式在載入或串流數個 (或數百) MB 的資產時,可以處於互動狀態。 建立和管理這些執行緒最簡單的方法是使用 Parallel Patterns Library,以及工作模式,如 PPLTasks.h 中所定義的併發性名稱空間中所包含。 使用 Parallel Patterns Library 可直接利用多核心與超執行緒 CPU,並可改善所有狀況,從感知的載入時間,到繁重的 CPU 計算或網路處理所導致的故障與延遲。

備註:在 Universal Windows Platform (UWP) 應用程式中,使用者介面完全在單執行緒公寓 (STA) 中執行。 如果您使用 XAML interop,建立 DirectX 遊戲的 UI,您只能使用 STA 存取控制項。

 

使用 Direct3D 裝置的多執行緒

只有在支援 11_0 或更新版本的 Direct3D 功能層級的圖形裝置上,才能使用裝置前後關聯的多執行緒。 但是,您可能希望將強大的 GPU 用於許多平台,例如專用遊戲平台。 在最簡單的情況下,您可能想要將平視顯示 (HUD) 重疊的彩現與 3D 場景彩現和投影分開,並使兩個元件使用單獨的平行配管。 但是,兩個執行緒必須使用相同的 ID3D11DeviceContext,以建立和管理資源對象 (紋理、網格、著色器和其他資源),該執行緒是單執行緒的,並且需要實現某種同步機制 (如關鍵部分)才能安全存取它。 此外,雖然您可以在不同的執行緒上為裝置前後關聯建立個別的命令清單 (用於延緩轉譯),但是您無法在相同的 ID3D11DeviceContext 執行個體上同時播放這些命令清單。

現在,您的應用程式也可以使用多執行緒安全的 ID3D11Device,來建立資源物件。 因此,為何不總是使用 ID3D11Device,ID3D11DeviceContext? 目前,某些圖形介面可能無法支援多執行緒的驅動程式。 您可以查詢裝置並瞭解它是否支援多執行緒,但是如果您希望接觸到最廣泛的受眾,則可能會堅持使用單執行緒 ID3D11DeviceContext ,進行資源對象管理。 也就是說,當圖形裝置驅動程式不支援多執行緒或命令清單時,Direct3D 11 會嘗試在內部處理對裝置背景內容的同步存取;並且如果命令清單不受支援,則它提供軟體實現。 因此,您可以撰寫多執行緒程式碼,該程式碼會在具有圖形介面的平台上執行,而這些圖形介面缺乏對多執行緒裝置內容存取的驅動程式支援。

如果您的應用程式支援處理命令清單和顯示影格的獨立執行緒,您可能想要讓 GPU 保持作用中,在及時顯示影格的同時處理命令清單,而不會造成明顯的結節或延遲。 在這種情況下,您可以為每個執行緒使用單獨的 ID3D11DeviceContext ,並使用 D3D11_RESOURCE_MISC_SHARED 標誌建立資源 (如紋理) 來共用資源。 在此案例中,必須在處理執行緒上呼叫 ID3D11DeviceContext::Flush,才能在顯示執行緒中顯示處理資源物件的結果之前,完成命令清單的執行。

延遲呈現

延遲轉譯會將圖形指令記錄在指令清單中,以便在其他時間可以播放,並且設計成可支援在一個執行緒上轉譯,同時記錄其他執行緒上轉譯的指令。 這些命令完成後,可以在產生最終顯示物件 (框架緩衝區、紋理或其他圖形輸出) 的執行緒上執行。

使用 ID3D11Device::CreateDeferredContext (而不是 D3D11CreateDevice D3D11CreateDeviceAndSwapChain,者會建立即時內容)來建立延遲內容。 如需詳細資訊,請參閱 Immediate and Deferred Rendering。