描述如何将资源划分为子资源,以及如何引用单个、多个或子资源的切片。
示例子资源
如果资源包含缓冲区,则它只包含一个索引为 0 的子资源。 如果资源包含纹理(或纹理数组),则引用子资源更为复杂。
某些 API 访问整个资源(如 ID3D12GraphicsCommandList::CopyResource 方法),其他 API 访问资源的一部分(例如 ID3D12Resource::ReadFromSubresource 方法)。 访问某个资源部分的方法通常使用视图说明(如 D3D12_TEX2D_ARRAY_SRV 结构)来指定要访问的子资源。 有关完整列表,请参阅 子资源 API 部分。
子资源索引
若要为特定子资源编制索引,mip 级别首先编制索引,因为每个数组项都已编制索引。
Mip 切片
mip 切片包括数组中每个纹理的一个 mipmap 级别,如下图所示。
subresource mip slices子资源 mip 切片
数组切片
给定纹理数组,每个具有 mipmap 的纹理,数组切片包括一个纹理及其所有 mip 级别,如下图所示。
subresource array slices子资源数组切片
平面切片
通常,平面格式不用于存储 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 中已更改,以便每个平面都收到了自己的子资源 ID。 比较以下两种方法来计算子资源 ID。
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 访问通常通过 映射/取消映射来完成。
相关主题