[DX12] root constant and shader linkage question

Started by
7 comments, last by afroviking 8 years ago

So I have a root signature with a descriptor table with an SRV, and two float 3 constants afterwards.

Code looks like:


        D3D12_ROOT_PARAMETER param[3];
        param[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
        param[0].DescriptorTable.NumDescriptorRanges = 1;
        param[0].DescriptorTable.pDescriptorRanges = range;
        param[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;

        param[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
        param[1].Constants.Num32BitValues = 3;
        param[1].Constants.RegisterSpace = 0;
        param[1].Constants.ShaderRegister = 0;
        param[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;

        param[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
        param[2].Constants.Num32BitValues = 3;
        param[2].Constants.RegisterSpace = 0;
        param[2].Constants.ShaderRegister = 1;
        param[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;

Later on before I draw the objects I set the constants:


            gfx->SetGraphicsRoot32BitConstants(1, 3, constant1, 0);
            gfx->SetGraphicsRoot32BitConstants(2, 3, constant2, 0);

and in the shader I have something like this but it doesn't seem to work at all.


float3 constant1 : register(b0);
float3 constant2 : register(b1);

Whatever is in constant1 seems to work fine but constant2 doesn't have the correct values. What am I missing here? I assumed from the MSDN docs that the first constant in the root signature would be b0 and the second one would be b1. Is that not how it works or is there some kind of minimum alignment of 4 DWORDs?

Advertisement

Have you enabled the Debug layer to check there's no errors or warnings?

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

b0 means buffer zero, not register zero. You probably wanted c? https://msdn.microsoft.com/en-us/library/windows/desktop/dd607359(v=vs.85).aspx

b0 means buffer zero, not register zero. You probably wanted c? https://msdn.microsoft.com/en-us/library/windows/desktop/dd607359(v=vs.85).aspx

b is constant buffers, which is what he's after.

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

Yeah either way I tried c too but the fact that it's a separate entry in the root descriptor table would make it a separate buffer right? Maybe with the way the constants are loaded into the shader registers on the gpu for the global register file or something it could happen to work with Cs but that probably wouldn't be correct. I'm assuming the way everything is laid out based on the root descriptor above it would be something like [t0, b0, b1] right? It's hard to believe that it's an nvidia AND intel driver bug so I must be doing something wrong here.

Yeah whoops I was mistaken, I'm pretty sure b is right. Maybe try the visual studio graphics debugger? It should show the constant memory.

Ok I ran the graphics debugger. Pretty sweet. Makes sense why it's not working, but why does the shader compiler turn constants I declared as b0 and b1 into 1 constant buffer, is that a bug or is my syntax wrong?

It looks like the shader compiles

float3 constant1 : register(b0);
float3 constant2 : register(b1);

into something like this (which is not what I was expecting):


// cbuffer $Globals
// {
//
//   float3 constant1;                  // Offset:    0 Size:    12
//   float3 constant2;                  // Offset:   16 Size:    12
//
// }
//
//
// Resource Bindings:
//
// Name                                 Type  Format         Dim      ID      HLSL Bind  Count
// ------------------------------ ---------- ------- ----------- ------- -------------- ------
// $Globals                          cbuffer      NA          NA     CB0            cb0      1
//

While my root descriptor table looks like:

Root Descriptor Table
Descriptor Range Count 1 Descriptor Ranges
[0]
Descriptor Range Type D3D12_DESCRIPTOR_RANGE_SRV Descriptor Range Count 1 Descriptor Range Base Shader Register 0 Descriptor Range Register Space 0 Descriptor Range Offset 0
[1]
Root Parameter Type 32BIT_CONSTANTS Root Parameter Shader Visibility VERTEX Root Constants
Root Constants Shader Register 0 Root Constants Register Space 0 Root Constants Int32 Count 3
[2]
Root Parameter Type 32BIT_CONSTANTS Root Parameter Shader Visibility VERTEX Root Constants
Root Constants Shader Register 1 Root Constants Register Space 0 Root Constants Int32 Count 3

I've never tried declaring constant buffers like that before. I can look into whether that's even supposed to work.

Does it work if you declare each float3 in it's own 'cbuffer' a la:


cbuffer MyBuffer : register(b1)
{
  float3 constant2;
};

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

Yeah I think my syntax is just wrong for constant buffers. The syntax below works as expected with my root signature. Thanks for the help guys!


cbuffer MyBuffer1 : register(b0)
{
    float3 constant1;
};

cbuffer MyBuffer2 : register(b1)
{
    float3 constant2;
};

This topic is closed to new replies.

Advertisement