状态对象
使用着色器模型 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
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
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
LocalRootSignature 对应于 D3D12_LOCAL_ROOT_SIGNATURE 结构。
与全局根签名子对象一样,字段由描述根签名部分的一些字符串组成。 有关此方面的参考,请参阅 在 HLSL 中指定根签名。
示例:
LocalRootSignature MyLocalRootSignature =
{
"RootConstants(num32BitConstants = 4, b1)" // Cube constants
};
SubobjectToExportsAssocation
默认情况下,仅在与导出相同的库中声明的子对象能够应用于该导出。 但是,应用程序能够重写该对象,并获取与哪个导出一起的子对象的具体信息。 在 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
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
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
TriangleHitGroup 对应于类型字段设置为 D3D12_HIT_GROUP_TYPE_TRIANGLES 的D3D12_HIT_GROUP_DESC结构。
此子对象是使用 语法声明的
TriangleHitGroup Name =
{
AnyHitShader,
ClosestHitShader
};
项 | 说明 |
---|---|
名字 |
唯一标识变量名称的 ASCII 字符串。 |
AnyHitShader |
命中组的 anyhit 着色器的字符串名称,或空字符串。 |
ClosestHitShader |
命中组最近的命中着色器的字符串名称,或空字符串。 |
示例:
TriangleHitGroup MyHitGroup =
{
"", // AnyHit
"MyClosestHitShader", // ClosestHit
};
请注意,这两个字段都使用 导出 的名称。 如果应用程序选择执行导出重命名,导出的名称可能与 HLSL 中的原始名称不同。
ProceduralPrimitiveHitGroup
ProceduralPrimitiveHitGroup 对应于 type 字段设置为D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE 的D3D12_HIT_GROUP_DESC结构。
此子对象是使用 语法声明的
ProceduralPrimitiveHitGroup Name =
{
AnyHitShader,
ClosestHitShader,
IntersectionShader
};
项 | 说明 |
---|---|
名字 |
唯一标识变量名称的 ASCII 字符串。 |
AnyHitShader |
命中组的 anyhit 着色器的字符串名称,或空字符串。 |
ClosestHitShader |
命中组最近的命中着色器的字符串名称,或空字符串。 |
IntersectionShader |
命中组的交集着色器的字符串名称或空字符串。 |
示例:
ProceduralPrimitiveHitGroup MyProceduralHitGroup
{
"MyAnyHit", // AnyHit
"MyClosestHit", // ClosestHit
"MyIntersection" // Intersection
};
请注意,这三个字段使用 导出 的名称。 如果应用程序选择执行导出重命名,则导出的名称可能与 HLSL 中的原始名称不同。
备注
子对象具有“关联”或“哪个子对象与哪个导出一起”的概念。
通过着色器代码指定子对象时,“哪个子对象用于哪个导出”的选择遵循 DXR 规范中概述的规则。 具体而言,假设应用程序具有某种导出。 如果应用程序通过着色器代码将导出与根签名 A 关联,通过应用程序代码将根签名 B 关联,则 B 是被使用的签名。 “使用 B”而不是“生成错误”的设计使应用程序能够方便地使用应用程序代码替代 DXIL 关联,而不是被迫重新编译着色器来解决不匹配的问题。