0
\$\begingroup\$

I've noticed that I cannot specify a root signature in the HLSL code of a DXR shader. For example, if I got a ray generation shader with the following declaration

[rootsignature(
    "RootFlags(LOCAL_ROOT_SIGNATURE),"  \
    "DescriptorTable("                  \
    "UAV(u0, numDescriptors = 1),"  \
    "SRV(t0, numDescriptors = 1))")]
[shader("raygeneration")]
void RayGen()
{}

CreateRootSignature yields the error message

No root signature was found in the dxil library provided to CreateRootSignature. [ STATE_CREATION ERROR #696: CREATE_ROOT_SIGNATURE_BLOB_NOT_FOUND].

I've noticed that even when I add a typo (for example, write roosignature instead of rootsignature), the compiler doesn't complain about this typo. So, it seems like the whole attribute declaration is simply ignored.

If I change the code to a simple rasterization shader, everything works as expected.

So, is the specification of a root signature in the HLSL code of a DXR shader not supported?

\$\endgroup\$
2
  • \$\begingroup\$ The syntax you're using does not seem to match this doc (It uses RootSignature in Pascal Case) \$\endgroup\$ – DMGregory Apr 1 at 14:57
  • \$\begingroup\$ @DMGregory You mean the capitalization of R and S? That's not the source of the problem. Changed it accordingly, the problem remains. (And as I wrote in the question, the compiler doesn't even complain about any typo inside the brackets.) \$\endgroup\$ – 0xbadf00d Apr 1 at 15:03
2
+50
\$\begingroup\$

The solution here is to build an explicit root signature binary and then use that one. The DXIL Library itself doesn't contain the signature, only references to it.

The actual command-line is a bit tricky and unintuitive, but it's much easier if you define your signature as a #define:

#define LocalRootSignature "RootFlags(LOCAL_ROOT_SIGNATURE),"  \
    "DescriptorTable("                  \
    "UAV(u0, numDescriptors = 1),"  \
    "SRV(t0, numDescriptors = 1))"

[rootsignature(LocalRootSignature)]
[shader("raygeneration")]
void RayGen()
{}

So you end up with a command-line like:

dxc /T rootsig_1_1 /E LocalRootSignature LocalRootSignature.hlsl -rootsig-define LocalRootSignature -Fo test.cso

The other problem is that the VS HLSL Properties dialog doesn't support this setup, so you have to use a CustomBuild command. Something like:

Command>dxc.exe /T rootsig_1_1 /E LocalRootSignature -rootsig-define LocalRootSignature /Fo"$(IntDir)\%(Filename).cso" "%(Fullpath)"</Command>
<Outputs>$(IntDir)%(Filename).cso</Outputs>

You can then load the LocalRootSignature.cso as a binary blob at runtime (using something like ReadData), and create the rootsig object from it :

#include "ReadData.h"

Microsoft::WRL::ComPtr<ID3D12RootSignature> m_rootSignature;

auto lrootsig = DX::ReadData(L"LocalRootSignature.cso");

DX::ThrowIfFailed(
    device->CreateRootSignature(0, lrootsig.data(), lrootsig.size(),
    IID_PPV_ARGS(&m_rootSignature)));
```
\$\endgroup\$
5
  • \$\begingroup\$ Thank you for your answer. (a) "The DXIL Library itself doesn't contain the signature." Why is that? It certainly does contain the signature for any rasterization shader. (b) I need to obtain the root signature from the HLSL file in code. So, how would I construct the root signature binary from the API? \$\endgroup\$ – 0xbadf00d Apr 4 at 13:57
  • \$\begingroup\$ I don't know the answer to (a), but if I find out I'll reply. Updated with answer to (b). \$\endgroup\$ – Chuck Walbourn Apr 5 at 1:36
  • \$\begingroup\$ Thank you for the edit, but if I'm not missing something, I still need to create the cso file from the command line. Isn't there any possibility to parse the root signature description from an HLSL file and compile it? In the same way as we can compile the actual shader binary using IDxcUtils::LoadFile and IDxcCompiler3::Compile? \$\endgroup\$ – 0xbadf00d Apr 5 at 13:50
  • \$\begingroup\$ As you can see from the sample code on GitHub, you just pass the same command-line arguments to the Compile method--DXC.EXE is just a command-line front-end for the DLL. \$\endgroup\$ – Chuck Walbourn Apr 5 at 19:05
  • \$\begingroup\$ Why do we need to specify both the "entry point" (is this an entry point at all) -E LocalRootSignature and the -rootsig-define LocalRootSignature? I wasn't able to find anything about the usage of dxc for compiling (local) root signatures in the docs. \$\endgroup\$ – 0xbadf00d Jun 2 at 13:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.