直接在根签名中使用描述符
若要避免需要遍历描述符堆,可以将描述符直接放入根签名中。 这些描述符在根签名中占用了大量空间, (请参阅 根签名限制) ,因此建议谨慎使用它们。
例如,在根布局中放置一个常量缓冲区视图, (每次绘图都会更改的 CBV) 。 这样一来,应用程序不必按绘制 (分配描述符堆空间,并将指向描述符表保存在描述符堆) 的新位置。 通过将某些内容放入根签名中,应用程序只是将版本控制责任交给驱动程序;但这是驱动程序已经拥有的基础结构。
对于使用极少数资源的呈现,如果所有必需的描述符都可以直接放在根签名中,则可能根本不需要使用描述符表/堆。
这些是根签名中唯一支持的描述符类型。
- 常量缓冲区视图 (CBV) 。
- 着色器资源视图 (SRV) /无序访问视图 (UAV) 缓冲区资源,其中不需要格式转换 (非类型化缓冲区) 。 可与根描述符绑定的一些非类型化缓冲区的示例包括
StructuredBuffer<type>
、RWStructuredBuffer<type>
ByteAddressBuffer
和RWByteAddressBuffer
。 类型化缓冲区,如Buffer<uint>
和Buffer<float2>
不能。 - 光线跟踪加速结构的 SRV,位于本地或全局根签名中。
根中的 UAV 不能具有与之关联的计数器。 根签名中的每个描述符都显示为单独的描述符,它们无法动态编制索引。
struct SceneData
{
uint foo;
float bar[2];
int moo;
};
ConstantBuffer<SceneData> mySceneData : register(b6);
在上面的示例中, mySceneData
不能声明为数组,就像要映射到根签名中的描述符一样 cbuffer mySceneData[2]
。 这是因为根签名不支持跨描述符编制索引。 如果需要,可以定义单独的单个常量缓冲区,并将每个常量缓冲区定义为根签名中的单独条目。 请注意,在以上的 mySceneData
中,有一个数组 bar[2]
。 常量缓冲区中的动态索引是有效的 - 根签名中的描述符的行为就像通过描述符堆访问时同一描述符的行为一样。 这与直接在根签名中内联常量形成鲜明对比,后者看起来也类似于常量缓冲区,但存在不允许在内联常量中进行动态索引的约束,因此 bar[2]
不允许在其中进行。
这些 API (来自 ID3D12GraphicsCommandList 接口) 用于直接在根签名上设置描述符。
- SetComputeRootConstantBufferView
- SetGraphicsRootConstantBufferView
- SetComputeRootShaderResourceView
- SetGraphicsRootShaderResourceView
- SetComputeRootUnorderedAccessView
- SetGraphicsRootUnorderedAccessView
注意
Direct3D 12 中没有 根描述符数组 的概念。 描述符数组仅在描述符堆中受支持。