子資源 (Direct3D 12 圖形)
描述如何將資源分割成子資源,以及如何參考單一、多個或子資源配量。
范例子資源
如果資源包含緩衝區,則它只會包含一個索引為0的子資源。 如果資源包含紋理(或紋理數位列),則參考子資源會比較複雜。
某些 API 會存取整個資源(例如 ID3D12GraphicsCommandList::CopyResource 方法),其他則存取資源的一部分(例如 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,交錯),人類眼睛對它不太敏感。 此格式可讓您壓縮 chrominance 值,以壓縮影像而不會影響亮度,而且是基於該原因的常見視訊壓縮格式,雖然它用來壓縮靜止影像。 下圖顯示 NV12 格式,指出色度已壓縮為亮度解析度的四分之一,這表示每個平面的寬度都相同,而色度平面是亮度平面的高度的一半。 平面會以與上述 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 存取 CPU,並 ReadFromSubresource 合法:但緩衝區不會。 資源的 CPU 存取通常是透過 Map/Unmap來完成。
相關主題