状态对象
借助着色器模型 6.3 及更高版本,除了使用 Direct3D 12 API 之外,应用程序还能够方便地灵活地直接在 HLSL 着色器代码中定义 DXR 状态对象。
在 HLSL 中,状态对象使用以下语法声明:
Type Name =
{
Field1,
Field2,
...
};
项目 | 描述 |
---|---|
类型 |
标识子对象的类型。 必须是受支持的 HLSL 子对象类型之一。 |
名称 |
唯一标识变量名称的 ASCII 字符串。 |
Field[1, 2, ...] |
子对象的字段。 下面介绍了每种子对象类型的特定字段。 |
子对象类型的列表:
- StateObjectConfig
- GlobalRootSignature
- LocalRootSignature
- SubobjectToExportsAssocation
- RaytracingShaderConfig
- RaytracingPipelineConfig
- TriangleHitGroup
- ProceduralPrimitiveHitGroup
StateObjectConfig 子对象类型对应于 D3D12_STATE_OBJECT_CONFIG 结构。
它有一个字段,一个按位标志,即一个或两个
- STATE_OBJECT_FLAGS_ALLOW_LOCAL_DEPENDENCIES_ON_EXTERNAL_DEFINITONS
- STATE_OBJECT_FLAGS_ALLOW_EXTERNAL_DEPENDENCIES_ON_LOCAL_DEFINITIONS
或者,对于这两个都不是零。
例:
StateObjectConfig MyStateObjectConfig =
{
STATE_OBJECT_FLAGS_ALLOW_LOCAL_DEPENDENCIES_ON_EXTERNAL_DEFINITONS
};
GlobalRootSignature 对应于 D3D12_GLOBAL_ROOT_SIGNATURE 结构。
这些字段由描述根签名部分的一些字符串组成。 有关此方面的参考,请参阅 在 HLSL中指定根签名。
例:
GlobalRootSignature MyGlobalRootSignature =
{
"DescriptorTable(UAV(u0))," // Output texture
"SRV(t0)," // Acceleration structure
"CBV(b0)," // Scene constants
"DescriptorTable(SRV(t1, numDescriptors = 2))" // Static index and vertex buffers.
};
LocalRootSignature 对应于 D3D12_LOCAL_ROOT_SIGNATURE 结构。
与全局根签名子对象一样,字段包含描述根签名部分的一些字符串。 有关此方面的参考,请参阅 在 HLSL中指定根签名。
例:
LocalRootSignature MyLocalRootSignature =
{
"RootConstants(num32BitConstants = 4, b1)" // Cube constants
};
默认情况下,仅与导出相同的库中声明的子对象可以应用于该导出。 但是,应用程序能够替代该对象,并获取与导出相关的子对象的具体内容。 在 HLSL 中,此“显式关联”是使用 SubobjectToExportsAssocation 完成的。
SubobjectToExportsAssocation 对应于 D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION 结构。
此子对象使用语法声明
SubobjectToExportsAssocation Name =
{
SubobjectName,
Exports
};
项目 | 描述 |
---|---|
名称 |
唯一标识变量名称的 ASCII 字符串。 |
SubobjectName |
标识导出的子对象的字符串。 |
导出 |
包含以分号分隔的导出列表的字符串。 |
例:
SubobjectToExportsAssociation MyLocalRootSignatureAssociation =
{
"MyLocalRootSignature", // Subobject name
"MyHitGroup;MyMissShader" // Exports association
};
请注意,这两个字段都使用导出 名称。 如果应用程序选择进行导出重命名,则导出的名称可能与 HLSL 中的原始名称不同。
RaytracingShaderConfig 对应于 D3D12_RAYTRACING_SHADER_CONFIG 结构。
此子对象使用语法声明
RaytracingShaderConfig Name =
{
MaxPayloadSize,
MaxAttributeSize
};
项目 | 描述 |
---|---|
名称 |
唯一标识变量名称的 ASCII 字符串。 |
MaxPayloadSize |
关联光线跟踪着色器的光线有效负载中标量的最大存储(每个字节计为 4 个字节)的数值。 |
MaxAttributeSize |
可用于关联光线跟踪着色器中的属性的最大标量数(每个标量计为 4 个字节)的数值。 该值不能超过 D3D12_RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES。 |
例:
RaytracingShaderConfig MyShaderConfig =
{
16, // Max payload size
8 // Max attribute size
};
RaytracingPipelineConfig 对应于 D3D12_RAYTRACING_PIPELINE_CONFIG 结构。
此子对象使用语法声明
RaytracingPipelineConfig Name =
{
MaxTraceRecursionDepth
};
项目 | 描述 |
---|---|
名称 |
唯一标识变量名称的 ASCII 字符串。 |
MaxTraceRecursionDepth |
用于光线跟踪管道中光线递归的数字限制。 它是介于 0 和 31 之间的数字,包括 0 和 31。 |
例:
RaytracingPipelineConfig MyPipelineConfig =
{
1 // Max trace recursion depth
};
由于光线跟踪递归会产生性能成本,因此应用程序应使用所需结果所需的最低递归深度。
如果着色器调用尚未达到最大递归深度,则可以调用 TraceRay 任意次数。 但是,如果它们达到或超过最大递归深度,则调用 TraceRay 会将设备置于已删除状态。 因此,如果跟踪着色器满足或超过最大递归深度,应注意停止调用 TraceRay。
TriangleHitGroup 对应于一个 D3D12_HIT_GROUP_DESC 结构,其 Type 字段设置为 D3D12_HIT_GROUP_TYPE_TRIANGLES。
此子对象使用语法声明
TriangleHitGroup Name =
{
AnyHitShader,
ClosestHitShader
};
项目 | 描述 |
---|---|
名称 |
唯一标识变量名称的 ASCII 字符串。 |
AnyHitShader |
命中组的 anyhit 着色器的字符串名称或空字符串。 |
最接近的HitShader |
命中组最近的命中着色器或空字符串的字符串名称。 |
例:
TriangleHitGroup MyHitGroup =
{
"", // AnyHit
"MyClosestHitShader", // ClosestHit
};
请注意,这两个字段都使用导出 名称。 如果应用程序选择进行导出重命名,则导出的名称可能与 HLSL 中的原始名称不同。
ProceduralPrimitiveHitGroup 对应于类型字段设置为 D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE的 D3D12_HIT_GROUP_DESC 结构。
此子对象使用语法声明
ProceduralPrimitiveHitGroup Name =
{
AnyHitShader,
ClosestHitShader,
IntersectionShader
};
项目 | 描述 |
---|---|
名称 |
唯一标识变量名称的 ASCII 字符串。 |
AnyHitShader |
命中组的 anyhit 着色器的字符串名称或空字符串。 |
最接近的HitShader |
命中组最近的命中着色器或空字符串的字符串名称。 |
IntersectionShader |
命中组的交集着色器的字符串名称或空字符串。 |
例:
ProceduralPrimitiveHitGroup MyProceduralHitGroup
{
"MyAnyHit", // AnyHit
"MyClosestHit", // ClosestHit
"MyIntersection" // Intersection
};
请注意,这三个字段使用 导出 名称。 如果应用程序选择进行导出重命名,则导出的名称可能与 HLSL 中的原始名称不同。
子对象具有“关联”或“哪个子对象与哪个导出”的概念。
通过着色器代码指定子对象时,选择“哪个子对象随导出一起”遵循 DXR 规范中所述的规则。 具体而言,假设应用程序有一些导出。 如果应用程序通过着色器代码将导出与根签名 A 相关联,并通过应用程序代码将根签名 B 与根签名 B 相关联,则 B 是要使用的。 使用 B 而不是“生成错误”的设计使应用程序能够方便地使用应用程序代码替代 DXIL 关联,而不是被迫重新编译着色器来解决不匹配的问题。