Direct3D 12 圖形 (子資源)
描述如何將資源分割成子資源,以及如何參考單一、多個或子資源配量。
範例子資源
如果資源包含緩衝區,則它只會包含一個索引為 0 的子資源。 如果資源包含紋理 (或紋理陣列) ,則參考子資源會更加複雜。
某些 API 會存取整個資源 (,例如 ID3D12GraphicsCommandList::CopyResource 方法) ,其他 API 則會存取部分資源 (,例如 ID3D12Resource::ReadFromSubresource 方法) 。 存取部分資源的方法通常會使用檢視描述 (,例如 D3D12_TEX2D_ARRAY_SRV 結構) 來指定要存取的子資源。 如需完整清單,請參閱 子資源 API 一節。
子資源索引編制
若要編制特定子資源的索引,Mip 層級會先編制索引,因為每個陣列專案都會編制索引。
Mip 配量
Mip 配量包含陣列中每個紋理的一個 Mipmap 層級,如下圖所示。
陣列配量
假設紋理陣列,每個具有 mipmap 的紋理,陣列配量會包含一個紋理及其所有 Mip 層級,如下圖所示。
平面配量
通常平面格式不會用來儲存 RGBA 資料,但在 (24bpp RGB 資料) 的情況下,一個平面可以代表紅色影像、一個綠色影像,另一個是藍色影像。 雖然一個平面不一定是一種色彩,但兩個或多個色彩可以合併成一個平面。 更常見的平面資料會用於子取樣的 YCbCr 和Depth-Stencil資料。 Depth-Stencil是唯一支援 mipmap、陣列和多個平面的格式, (樣板) 通常為平面 0,而平面 1 則為樣板) 。
兩個Depth-Stencil影像陣列的子資源索引,各有三個 mip 層級,如下所示。
子取樣的 YCbCr 支援陣列和具有平面,但不支援 mipmap。 YCbCr 影像有兩個平面,一個用於人類眼睛最敏感的亮度 (Y) ,另一個 (用於 Cb 和 Cr 和 Cr,交錯) 人眼較不敏感。 此格式可壓縮 chrominance 值,以壓縮影像而不會影響亮度,而且是基於該原因而常見的視訊壓縮格式,雖然它用來壓縮仍然影像。 下圖顯示 NV12 格式,指出 chrominance 已壓縮成亮度解析度的一分之一,這表示每個平面的寬度都相同,而 chrominance 平面是亮度平面的一半高度。 平面會以與上述Depth-Stencil範例相同的方式,以子資源的形式編制索引。
平面格式存在於 Direct3D 11 中,但無法個別處理個別平面,例如複製或對應作業。 這在 Direct3D 12 中已變更,讓每個平面都收到自己的子資源識別碼。 比較下列兩種方法來計運算元資源識別碼。
Direct3D 11
inline UINT D3D11CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT MipLevels )
{
return MipSlice + (ArraySlice * MipLevels);
}
Direct3D 12
inline UINT D3D12CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize )
{
return MipSlice + (ArraySlice * MipLevels) + (PlaneSlice * MipLevels * ArraySize);
}
大部分的硬體假設平面 N 的記憶體一律會在平面 N-1 之後立即配置。
使用子資源的另一個替代方式是,應用程式可以為每個平面配置完全個別的資源。 在此情況下,應用程式會瞭解資料是平面資料,並使用多個資源來表示資料。
多個子資源
著色器資源檢視可以使用上述其中一個配量來選取子資源的任何矩形區域,並在檢視結構中使用欄位 (,例如 D3D12_TEX2D_ARRAY_SRV) ,如下圖所示。
轉譯目標檢視只能使用單一子資源或 mip 配量,而且不能包含來自多個 Mip 配量的子資源。 也就是說,轉譯目標檢視中的每個紋理都必須相同大小。 著色器資源檢視可以選取子資源的任何矩形區域,如下圖所示。
子資源 API
下列 API 參考並使用子資源:
列舉:
下列結構包含 PlaneSlice 索引,大部分都包含 MipSlice 索引。
- D3D12_TEX2D_RTV
- D3D12_TEX2D_ARRAY_RTV
- D3D12_TEX2D_SRV
- D3D12_TEX2D_ARRAY_SRV
- D3D12_TEX2D_UAV
- D3D12_TEX2D_ARRAY_UAV
下列結構包含 ArraySlice 索引,大部分都包含 MipSlice 索引。
- D3D12_TEX1D_ARRAY_DSV
- D3D12_TEX2D_ARRAY_DSV
- D3D12_TEX2DMS_ARRAY_DSV
- D3D12_TEX1D_ARRAY_RTV
- D3D12_TEX2D_ARRAY_RTV
- D3D12_TEX2DMS_ARRAY_RTV
- D3D12_TEX1D_ARRAY_SRV
- D3D12_TEX2D_ARRAY_SRV
- D3D12_TEX2DMS_ARRAY_SRV
- D3D12_TEX1D_ARRAY_UAV
- D3D12_TEX2D_ARRAY_UAV
下列結構包含 MipSlice 索引,但 ArraySlice 或 PlaneSlice 索引都不是。
下列結構也會參考子資源:
- D3D12_DISCARD_REGION :用來準備捨棄資源的結構。
- D3D12_PLACED_SUBRESOURCE_FOOTPRINT :將位移新增至資源的基本使用量。
- D3D12_RESOURCE_TRANSITION_BARRIER :描述不同使用方式之間的子資源轉換 (著色器資源、轉譯目標等。) 。
- D3D12_SUBRESOURCE_DATA :子資源資料報含資料本身,以及資料列和配量間距。
- D3D12_SUBRESOURCE_FOOTPRINT :使用量包括子資源的格式、寬度、高度、深度和資料列間距。
- D3D12_SUBRESOURCE_INFO :包含子資源的位移、資料列間距和深度間距。
- D3D12_SUBRESOURCE_TILING :描述磚子資源磁片區 (請參閱磁片區 並排資源) 。
- D3D12_TEXTURE_COPY_LOCATION :描述紋理的一部分,以便進行複製。
- D3D12_TILED_RESOURCE_COORDINATE :描述並排資源的座標。
方法:
- ID3D12Device::GetCopyableFootprints :取得資源的相關資訊,以便建立複本。
- ID3D12Device::GetResourceTiling :取得磚化資源如何細分成磚的相關資訊。
- ID3D12GraphicsCommandList::ResolveSubresource :將多重取樣子資源複製到非多重取樣子資源。
- ID3D12Resource::Map :傳回資源中指定資料的指標,並拒絕對子資源的 GPU 存取。
- ID3D12Resource::ReadFromSubresource :從子資源或子資源的矩形區域複製資料。
- ID3D12Resource::Unmap :取消對應指定的記憶體範圍,並使資源的指標失效。 恢復子資源的 GPU 存取權。
- ID3D12Resource::WriteToSubresource :將資料複製到子資源或子資源的矩形區域。
紋理必須處於 D3D12_RESOURCE_STATE_COMMON 狀態,才能透過 WriteToSubresource 和 ReadFromSubresource 進行 CPU 存取,才能合法;但緩衝區則不行。 資源的 CPU 存取通常是透過對應/Unmap來完成。
相關主題