UMA 優化:CPU 可存取紋理和標準 Swizzle

通用記憶體架構 (UMA) GPU 可提供一些效率優勢,特別是針對行動裝置進行優化時。 當 GPU 為 UMA 時提供資源 CPU 存取,可以減少 CPU 與 GPU 之間發生的複製數量。 雖然我們不建議應用程式在 UMA 設計上以盲目方式授與 CPU 存取權,但有機會藉由提供正確的資源 CPU 存取來提升效率。 不同于離散 GPU,CPU 可以技術上擁有 GPU 可存取之所有資源的指標。

CPU 可存取紋理的概觀

圖形管線中的 CPU 可存取紋理是 UMA 架構的功能,可讓 CPU 讀取和寫入紋理。 在較常見的離散 GPU 上,CPU 無法存取圖形管線中的紋理。

紋理的一般最佳做法建議是容納離散 GPU,這通常牽涉到遵循 透過緩衝區上傳紋理資料中的程式,摘要如下:

  • 沒有大部分紋理的任何 CPU 存取權。
  • 將紋理配置設定為 D3D12_TEXTURE_LAYOUT_UNKNOWN。
  • 使用 CopyTextureRegion將紋理上傳至 GPU。

不過,在某些情況下,CPU 和 GPU 可能會經常在相同的資料上互動,讓對應紋理有助於節省電源,或加速特定配接器或架構上的特定設計。 應用程式應該會偵測這些案例,並優化不必要的複本。 在此情況下,為了獲得最佳效能,請考慮下列事項:

  • 只有在 D3D12_FEATURE_DATA_ARCHITECTURE::UMA 為 TRUE 時,才開始提升對應紋理的效能。 然後,如果決定要在堆積上選擇要選擇的 CPU 快取屬性,請留意 CacheCoherentUMA

  • 利用紋理的 CPU 存取比緩衝區更複雜。 GPU 最有效率的紋理配置很少row_major。 事實上,某些 GPU 只能在複製紋理資料時支援row_major紋理。

  • UMA GPU 應該能從簡單的優化獲益,以減少層級負載時間。 辨識 UMA 之後,應用程式可以將初始 CopyTextureRegion 優化,以填入 GPU 將不會修改的紋理。 應用程式可以使用 WriteToSubresource 來避免瞭解實際的紋理配置,而不是在堆積中建立D3D12_HEAP_TYPE_DEFAULT,以及封送處理紋理資料。

  • 在 D3D12 中,使用 D3D12_TEXTURE_LAYOUT_UNKNOWN 建立的紋理,而且沒有 CPU 存取是經常 GPU 轉譯和取樣的最有效率。 當效能測試時,這些紋理應該與 CPU 存取D3D12_TEXTURE_LAYOUT_UNKNOWN進行比較,並使用 CPU 存取D3D12_TEXTURE_LAYOUT_STANDARD_SWIZZLE,以及交叉配接器支援D3D12_TEXTURE_LAYOUT_ROW_MAJOR。

  • 搭配 CPU 存取使用D3D12_TEXTURE_LAYOUT_UNKNOWN可讓 WriteToSubresourceReadFromSubresourceMap (排除應用程式對指標) 和 Unmap存取的方法;但可以犧牲 GPU 存取的效率。

  • 搭配 CPU 存取使用D3D12_TEXTURE_LAYOUT_STANDARD_SWIZZLE可讓 WriteToSubresourceReadFromSubresourceMap (傳回應用程式) 的有效指標,以及 Unmap。 它也可以犧牲 GPU 存取的效率,超過 CPU 存取D3D12_TEXTURE_LAYOUT_UNKNOWN。

標準 Swizzle 概觀

D3D12 (和 D3D11.3) 引進標準多維度資料配置。 這可讓多個處理單位在相同的資料上運作,而不需複製資料或在多個版面配置之間撥動資料。 標準化版面配置可透過網路效果提升效率,並允許演算法在假設特定模式時縮短。

如需紋理配置的詳細描述,請參閱 D3D12_TEXTURE_LAYOUT

不過請注意,此標準wizzle 是硬體功能,而且可能不受所有 GPU 支援。

如需雜亂的背景資訊,請參閱 Z 順序曲線

API

不同于 D3D11.3,D3D12 預設支援紋理對應,因此不需要查詢 D3D12_FEATURE_DATA_D3D12_OPTIONS。 不過,D3D12 不一定支援標準wizzle - 此功能必須透過呼叫CheckFeatureSupport並檢查D3D12_FEATURE_DATA_D3D12_OPTIONSStandardSwizzle64KBSupported欄位進行查詢。

下列 API 參考紋理對應:

列舉

  • D3D12_TEXTURE_LAYOUT :控制預設紋理的模糊模式,並在 CPU 可存取紋理上啟用地圖支援。

結構

方法

資源和父堆積具有對齊需求:

  • D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT (多重取樣紋理的 4MB) 。
  • D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT (單一樣本紋理和緩衝區的 64 KB) 。
  • 線性子資源複製必須對齊D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT (512 個位元組) ,且資料列間距對齊D3D12_TEXTURE_DATA_PITCH_ALIGNMENT (256 個位元組) 。
  • 常數緩衝區檢視必須對齊D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT (256 個位元組) 。

應該透過 CreateCommittedResource處理小於 64KB 的紋理。

使用動態紋理 (變更每個畫面格) CPU 會以線性方式寫入上傳堆積,後面接著 GPU 複製作業。

一般而言,若要建立動態資源,請在上傳堆積中建立大型緩衝區, (請參閱 緩衝區內的子位置) 。 若要建立預備資源,請在回寫堆積中建立大型緩衝區。 若要建立預設靜態資源,請在預設堆積中建立連續的資源。 若要建立預設別名資源,請在預設堆積中建立重迭的資源。

WriteToSubresourceReadFromSubresource 會在資料列主要版面配置與未定義的資源配置之間重新排列紋理資料。 作業是同步的,因此應用程式應該記住 CPU 排程。 應用程式一律可以將複製分成較小的區域,或在另一個工作中排程此作業。 這些 CPU 複製作業不支援具有不透明資源配置的 MSAA 資源和深度樣板資源,而且會導致失敗。 不支援沒有兩個元素大小的電源格式,也會導致失敗。 記憶體不足傳回碼可能會發生。

核心常數

ID3D12Heap

資源系結