0

我是 MSFT 和 DirectX 的新手,所以请放轻松。

如果 hlsl 着色器使用该[RootSignature(SignatureName)]属性,它会被代码中定义的根签名覆盖ID3D12RootSignature吗?

例如,在示例代码中,我在一个着色器包含的 .hlsli 文件中有这个:

    "RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), " \
    "CBV(b0, visibility = SHADER_VISIBILITY_VERTEX), " \
    "CBV(b0, visibility = SHADER_VISIBILITY_PIXEL), " \
    "DescriptorTable(SRV(t0, numDescriptors = 6), visibility = SHADER_VISIBILITY_PIXEL)," \
    "DescriptorTable(SRV(t64, numDescriptors = 6), visibility = SHADER_VISIBILITY_PIXEL)," \
    "RootConstants(b1, num32BitConstants = 2, visibility = SHADER_VISIBILITY_VERTEX), " \
    "StaticSampler(s0, maxAnisotropy = 8, visibility = SHADER_VISIBILITY_PIXEL)," \
    "StaticSampler(s1, visibility = SHADER_VISIBILITY_PIXEL," \
        "addressU = TEXTURE_ADDRESS_CLAMP," \
        "addressV = TEXTURE_ADDRESS_CLAMP," \
        "addressW = TEXTURE_ADDRESS_CLAMP," \
        "comparisonFunc = COMPARISON_GREATER_EQUAL," \
        "filter = FILTER_MIN_MAG_LINEAR_MIP_POINT)"

在着色器中:

[RootSignature(ModelViewer_RootSig)]
VSOutput main(VSInput vsInput)
{
    VSOutput vsOutput;

    vsOutput.position = mul(modelToProjection, float4(vsInput.position, 1.0));
    vsOutput.worldPos = vsInput.position;
    vsOutput.texCoord = vsInput.texcoord0;
    vsOutput.viewDir = vsInput.position - ViewerPos;
 <etc>

是否会被使用以下内容创建的根签名覆盖或覆盖: ASSERT_SUCCEEDED( g_Device->CreateRootSignature(1, pOutBlob->GetBufferPointer(), pOutBlob->GetBufferSize(), MY_IID_PPV_ARGS(&m_Signature)) );

4

1 回答 1

2

在 PC 上,如果您同时拥有“代码提供的”根签名和“着色器提供的”根签名,则代码一优先。通常,您应该使用其中一个,而不是两者都使用。

对于GitHub 上用于DX12 的 DirectX 工具包,我使用这两种工具都违反了我刚才所说的,但这是有充分理由的。一般来说,“代码风格”的根签名对于“新手”来说似乎更容易理解,因此我在工具包中使用它,因为它主要用于学习项目、示例等。我也支持 Xbox 开发,其中强烈建议始终使用基于着色器的根签名。

这是因为在 Xbox 上,着色器是“完全预编译的”,根签名的任何差异都会在运行时触发“重新编译”。如果我的代码和着色器签名不同步,Xbox 版本的运行时会生成调试输出,因此维护起来很容易。对于大多数人来说,情况并非如此。它还在代码和着色器表示法中提供了一堆相同根 sig 的示例,这对 deved 来说是件好事,但对于大多数项目来说可能不值得。

于 2021-02-17T01:26:48.310 回答