状态对象

借助着色器模型 6.3 及更高版本,除了使用 Direct3D 12 API 之外,应用程序还能够方便地灵活地直接在 HLSL 着色器代码中定义 DXR 状态对象。

在 HLSL 中,状态对象使用以下语法声明:

Type Name = 
{ 
    Field1,
    Field2,
    ...
};
项目 描述
类型
标识子对象的类型。 必须是受支持的 HLSL 子对象类型之一。
名称
唯一标识变量名称的 ASCII 字符串。
Field[1, 2, ...]
子对象的字段。 下面介绍了每种子对象类型的特定字段。

子对象类型的列表:

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_DESC 结构,其 Type 字段设置为 D3D12_HIT_GROUP_TYPE_TRIANGLES

此子对象使用语法声明

TriangleHitGroup Name = 
{ 
    AnyHitShader,
    ClosestHitShader
};
项目 描述
名称
唯一标识变量名称的 ASCII 字符串。
AnyHitShader
命中组的 anyhit 着色器的字符串名称或空字符串。
最接近的HitShader
命中组最近的命中着色器或空字符串的字符串名称。

例:

TriangleHitGroup MyHitGroup =
{
    "",                    // AnyHit
    "MyClosestHitShader",  // ClosestHit
};

请注意,这两个字段都使用导出 名称。 如果应用程序选择进行导出重命名,则导出的名称可能与 HLSL 中的原始名称不同。

ProceduralPrimitiveHitGroup

ProceduralPrimitiveHitGroup 对应于类型字段设置为 D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVED3D12_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 关联,而不是被迫重新编译着色器来解决不匹配的问题。

DirectX 开发人员博客文章“D3D12 中的新增功能 - DirectX 光线跟踪(DXR)现在支持库子对象”

DirectX 光线跟踪(DXR)功能规范

示例:D3D12RaytracingLibrarySubobjects