Access shader constants

Started by
9 comments, last by Bimble Bob 13 years, 9 months ago
I was wondering how you can access shader constants in Direct3D 9 without using the Effects framework. I know there is a D3DX function to get a constant table but is there a way to do it without D3DX? I'm also aware that in D3D10/11 you use shader reflection to get and set constant buffers. Is there an equivalent in D3D9?
I've been Googling and looking through the DXSDK docs and I can't seem to find what I'm looking for.
It's not a bug... it's a feature!
Advertisement
There's the various IDirect3DDevice9::Get[Pixel|Vertex]ShaderConstant[B|F|I]() functions.
D3D deals with compiled shaders though, after that it's up to you to deal with matching up variables names to types and registers.
So how do you know which constants have been mapped to which registers if you haven't explicitly done so in the shader?
It's not a bug... it's a feature!
You can use D3DXGetShaderConstantTable to get the constant layout from a compiled shader. If you compile your shader in your own code D3DXCompileShader can gives you the constant table, too.

Is there any way of getting such data without D3DX?
It's not a bug... it's a feature!
Only if you parse the compiled shader by your own. But the format for the constant table is not documented.

If you try to avoid D3DX I assume that you want to get your redist smaller. What you can do is write your own little shader compiler by using the D3DX functions. Precompile the shaders on your system, read and parse the constant table and store anything in your custom format that can be used by program without D3DX.
I'm looking at the HLSLWithoutFX10 example and I'm totally confused by this:

struct VS_CONSTANT_BUFFER{    D3DXMATRIX mWorldViewProj;      //mWorldViewProj will probably be global to all shaders in a project.    //It's a good idea not to move it around between shaders.    D3DXVECTOR4 vSomeVectorThatMayBeNeededByASpecificShader;    float fSomeFloatThatMayBeNeededByASpecificShader;    float fTime;                    //fTime may also be global to all shaders in a project.    float fSomeFloatThatMayBeNeededByASpecificShader2;    float fSomeFloatThatMayBeNeededByASpecificShader3;};


HLSL:

row_major float4x4 mWorldViewProj;  // World * View * Projection transformationfloat fTime;						// Time parameter. This keeps increasing


I understand that HLSL packs constants into 16 byte segments and so you may need some padding to make sure you get your constant data in the right place but here it seems like the matrix and the single float would be enough since the matrix takes up 4 16 byte segments and fTime would sit at the beginning of the next segment. Why is all that other stuff there?

Also I can't find where in this example the global constant buffer is mapped to the constant buffer object in the application. How is this done?
EDIT: I guess its the VSSetConstantBuffers(0, 1, pBuffers); Is the global buffer always in slot 0?
It's not a bug... it's a feature!
When it comes to shader constants Direct3D 9 and 10 works very different. While 10 use multiple constant buffers 9 have a constant register array per type.

The constant table will tell you the register slot that is used for a value and in the case of complex data types (matrix/arrays) how many slots are used. This arrays will not mapped to the memory. The setter functions will copy the values to them.

My previous post was referring to Direct3D 10 not 9. I understand how 9 works now.
It's not a bug... it's a feature!
Sorry. For Direct3D 10 the sample uses the shader in the HLSLwithoutFX10.vsh file. As you can see there it defines a constant buffer and maps the constant buffer in the code with packoffset.

If you define values outside a constant buffer the compiler will put them all in a global constant buffer. To check which constant buffer slot is used for a constant buffer you need to use the D3D 10 shader reflection functions (ID3D10ShaderReflection).

Yes, the XXSetConstantBuffer functions will assign a buffer resource to a constant buffer slot for the shader.

This topic is closed to new replies.

Advertisement