"bind slots vs. registers" concern

Started by
6 comments, last by Jason Z 9 years, 2 months ago

Hi,

I have 2 questions, that I haven't found answers for in the internet. Maybe someone could help.

1) On MSDN I read:

HLSL registers

t - for texture and texture buffer,

c - for buffer offset

Normally I used c for "Buffer<>" and t for "Texture2D", but I've found that if I use t for "Buffer<>" for instance, it compiles and works. My question - what are the different register types for, then?

2) I bound two SRVs, buffer_srv to slot 0 and texture_srv to slot 0. In hlsl I had:


Buffer<float4> buffer : register(c0);
Texture2D tex : register(t0);

Well it didn't work, so I've changed it, and I bind buffer_srv to slot 0 and texture_srv to slot 1. In hlsl I have:


Buffer<float4> buffer : register(c0);
Texture2D tex : register(t1);

and now it works. I thought different registers have different counters, but now I see it's rather one counter per shader per srv type (UAVs have different counter etc.). Question - can someone explain the input slot-register relation or refer me to some online materials, please?

Thanks!

Advertisement

You've got a lot of moving parts going on in your question.

It appears you have a constant buffer as a shader resource view. I.e., constant buffers should be created with CreateBuffer and D3D11_BIND_CONSTANT_BUFFER, and bound to a shader stage with VS(GS,PS)SetConstantBuffers. Textures SRVs are created from texture data and CreateShaderResourceView, and bound to a shader stage with (e.g.) PSSetShaderResources.

With constant buffers and SRVs defined/created separately as mentioned above, then, for a single stage (e.g., the pixel shader), PSSetConstantBuffers( 0, ... ) and PSSetShaderResources( 0, ... ) is valid.

IF you have all your shaders (VS, GS, PS, etc.) in a single file, and compile the shaders separately from that one file, that may be causing you some confusion. You may want to start out with separate files for each shader stage and see how things work out. E.g., shaderVS.hlsl, shaderPS.hlsl, etc., define in each file only the code and buffers you need for that stage, and compile each shader from its own file.

That approach may have other advantages, also. If you ever get into a situation where (e.g.) you need 12 constant buffers in the VS stage, and 12 different constant buffers in the PS stage, you'll have difficulty doing that in a single file because the number of constant buffers in a single stage is limited, but confusion may reign if you define them all in a single file. With separate files, that wouldn't be a problem.

Another advantage to the separate file approach, if you save compiled blobs, rather than compiling a shader for each start of your app, you can compare write times between the hlsl file and the blob file, and recompile the hlsl only if it's newer than the blob. With a single hlsl file for all the stages, you'll have to recompile the PS, even if you've only revised the VS.

EDIT: If you must have a single file for all the shaders, you can fill the file with lots of #ifdef / #endif pairs surrounding each stage and add a stage-specific #define to the D3DCompileFromFile call. Note, however, that if you save blobs, you'll still recompile every stage each time the file is edited.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

I have always found that compiling the shader with FXC.exe is a useful learning tool. This command line tool requires you to tell it the file and the function you are compiling, along with the shader type and target model. You can create an html output file, which gives you lots of information about the shader, its input resources, and the shader's input and output signatures.

That will tell you about the shader, but you can also programmatically access the same data through the reflection interfaces. There is examples in my engine (linked in my signature below) about how to use the reflection interface, so feel free to take a look and borrow code as needed.

Hi, thanks for your responds.

I have separate files for each shader, mostly because I can then debug shaders in VS Graphics Analyzer nicely. Anyway, my "buffer_srv" is not a constant buffer, it's just a regular buffer - vertex buffer, non-vertex buffer, it doesn't matter, it's an array of values, bound to one CS as uav and to another CS as srv.

The HLSL compiler accepts bogus register assignments, and will just silently ignore them. So in your first example it will ignore the "c0" assignment, and just assign it the first available t# register (which would be t1 in your case).

Here's a quick cheat cheat for register assignments in D3D11:

t# - shader resource views (Texture2D/Buffer/StructuredBuffer/ByteAddressBuffer/etc.)

b# - constant buffers (cbuffer)

u# - unordered access views (RWTexture2D/RWBuffer/RWStructuredBuffer/etc.)

c# - manual variable offsets within a constant buffer

MJP, that's exactly what I was looking for. Thanks a lot!!!

I have always found that compiling the shader with FXC.exe is a useful learning tool. This command line tool requires you to tell it the file and the function you are compiling, along with the shader type and target model. You can create an html output file, which gives you lots of information about the shader, its input resources, and the shader's input and output signatures.

That will tell you about the shader, but you can also programmatically access the same data through the reflection interfaces. There is examples in my engine (linked in my signature below) about how to use the reflection interface, so feel free to take a look and borrow code as needed.

I just wanted to say thanks for mentioning this! I didn't know such a feature existed within the fxc tool. I had so many questions about the output of shaders and I just answered them all myself (was going to write a long question on gamedev.net).

Goes to show it's sometimes quicker testing things out yourself than asking.

Edit: For others who don't know what I am talking about, it's the /Fc command in fxc.exe.


I just wanted to say thanks for mentioning this! I didn't know such a feature existed within the fxc tool. I had so many questions about the output of shaders and I just answered them all myself (was going to write a long question on gamedev.net).

Goes to show it's sometimes quicker testing things out yourself than asking.

That's the best possible outcome :)

This topic is closed to new replies.

Advertisement