0
\$\begingroup\$

I'm learning DirectX11 and since I'm beginning to write some shader code I don't understand the difference between binding slots and HLSL registers. The shader model 5.0 introduced the keyword register, that I assumed is a synonym for slot but it's not.

What I know: I know that a register is 4 floats (16 bytes), and that a variable cannot straddle two registers so padding is added according to HLSL packing rules. I also know that if I compile two shaders (say, vertex and pixel shader) in from the same file the register specified are by shader usage so if I use register b0 two times everything compiles fine if resources are accessed by each shader indipendently.

but what about this:

cbuffer Transform : register(b0)
{
    float4x4 worldMatrix;
};

cbuffer clipPlane : register(b1)
{
    float4 clipPlane;
};

I bind my resources to the shader like this:

Game::GetInstance()->GetDeviceContext()->PSSetConstantBuffers(0, 1, &mCameraConstantBuffer);
Game::GetInstance()->GetDeviceContext()->PSSetConstantBuffers(1, 1, &mLightsConstantBuffer); 

But if a register is 4 floats shouldn't the two resource overlap? What about sampler and shader resource registers?

Can someone provide me with a reference about the structure of these registers? MSDN documentation is really of no help sometimes.

\$\endgroup\$
1
\$\begingroup\$

You are confused in the meaning of the "register" keyword in HLSL. With that keyword you are only defining a binding slot for the DX11 API. It has no relation with register such as a float4 on which you can execute instructions (General Purpose Register, GPR).

So your example is perfectly valid, register(b0) will only say that that whole constant buffer will be bound with PSSetConstantBuffers(0, ...) The other constant buffer will be bound on slot 1.

They will not overlap, because they are not even necessarily nearby in memory. Binding a constant buffer (or any other resource) only moves around their "descriptors" which point to the main resource.

In DX11, you are given a fixed amount of slots that you can bind resources onto. You can bind up to 15 constant buffers, 16 samplers, ~128 textures, 8 render targets/UAVs. In Vulkan/DX12 this decision is left to the developer.

\$\endgroup\$
  • \$\begingroup\$ I will add to what is said here. A Buffer is what you bind to your pipeline, that data can be in any order you like, BUT, you mustn't have data that straddles the 16 byte alignment. that is, if you have a float3 then following by a float2, then you will be crossing that border. If I recall, that this actually causes a performance issue more than anything, but you should be be padding the space between alignments in your constant buffer. Register is related to the data passed through in your pipeline definitions such as Vertex or pixel shader. \$\endgroup\$ – ErnieDingo May 20 '18 at 22:12

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.