Hi,
I have two questions/problems dealing with specifying and using constant registers in .FX files. What I'm trying to do is tie common engine parameters to specific constant registers so I only update the constant registers when needed and not have to set them every time I change a shader.
- I declare a global variable in .FX file with an associated constant register (eg. float4x4 WorldViewProjection : register (c0);) And in the application I use pDevice->SetVertexShaderConstantF(0, worldViewProjMtx, 4); However, this does not set the parameter as expected. Instead, if I set it using the appropriate D3DXHANDLE it works. I assume an ID3DXEffect object maintain uniform parameter values, and sets the shader constants perhaps when calling Begin() or BeginPass(), and this is why SetVertexShaderConstant does not seem to be working, because it is being overwritten when activating the effect.
- I want to preserve certain registers for the application, even if the shader does not use the parameters. In shaders that do not use the variable associated with a register semantic, it appears the FXC compiler feels free to use the registers for its own use. Looking at the assembly output, it could list def c0, 1, 0, 0, 0, even though I want to preserve this register for application defined usage.
So is there a way to get SetVertexShaderConstantX() working when dealing with Effects And is there a way to let the compiler to not set certain registers
Thank you very much

Constant Register Semantic in Effects
manojamin
I recently found a utilities that may help see what's in your shader constant
it's the utility PIX.exe (probably other debugger too could do the same log)
You start this, you put the name of the DX program you want to test
and you press Start Experiment
Before you do this you can tell you need the Advance Option
In the Advanced Option you set a trigger in the Tree Element that is in Pink
You can set the Keyboard to F12
Then in the Function in Blue under it you can tell you want a Log of the DX Call
You set a name like c:\LogValue.htm
When you run with the Start Experiment button your application Launch
When your ready you click F12 and the LogValue1.htm will be created
Each time you press F12 you get a log
This is fun because you have in this log the value of your shader
I'm not sure it can help to solve your specific problem but you might want to
Set your constant with a Keyboard, Take one Log with F12
Then change the shader and do another log with F12
You could then see if the constant were erased or preserved
Anyhow this utility is nice to have
RogerLainson
If you look at my second post in this thread you will find a way to write to the register from your cpp code...
http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=337130&SiteID=1
I see that you want to write the Shader Constant from the cpp
That's not a bad idea, I will probably like to do that too.
But with my method I can assure you that it works
I will try to test if the Register Keep their value between call
The way I see it the register will only do what you tell him to do, I don't see
why the system would initialize 512 register just for the fun of it...
In DX the structure are never initialize and you have to provide the 0...
The HLSL compiler use DirectX inside and will use whatever registry is suitable to acheive the result and many times it's not what you want...
A better way is to compile the HLSL code in asm and tweek it in assembler
At least you will know where the code crash
I was trying to do sin and cos and variable in pixel shader and I kept crashing
and beleive me you cannot debug HLSL easily...if it crash for no apparent reason...
Once in asm you can comment any faulty code and see where the problem is...
you can experiment, by bypassing the output...basicly it help to see what's going on at low level...
One thing that took me a while to undestand is that you need to declare all registry
you want to use in assembler so if you want to have the register t0.x as an input you need to use decl function so this could be use as an input register...
Like this
decl t0.x
mov r0.w, t0.x
if you try to use t0.x without declaring the register as an input you crash...
Hope this could help
Skivan
Thanks for your reply.
Yes, I read that post before. However, it's opposite of what I wanted. In your example you wanted to set an effects parameter by name to be used in an assembly shader. On the other hand, I wanted to directly set the constant register to be used in an HLSL shader, using the Effects system.
To answer my own question, I have found that using D3DXCreateEffectEx allows me to specify which parameters I don't want the effects system to manage.
In my fx file I can specify
float4x4
WorldViewProjection : register (c0);...
Then when I create the effect I use
D3DXCreateEffectEx(g_pDevice, data, dataLen, NULL, NULL, "WorldViewProjection", flags, NULL, &effect, NULL);
And when I render, I can directly call SetVertexShaderConstantF() without the effects system overwriting the variable I set.
I would rather not have to specify the parameter when creating an effects objects, though. I would rather all parameters that have a register associated with them to not be handled by the effects system. There doesn't seem to be any reason why you would associate a parameter with a register, if you can't set the parameter using the register number.
My second concern that I had was that other shaders which did not use certain engine parameters (for example, a 2D shader doesn't use WorldViewProjection), could have application reserved registers be allocated by the effects compiler, and hence have the register data trampled on. I found that this does not seem to be a problem.
As a test, I set the WorldViewProjection matrix using SetVertexShaderConstantF(). I then rendered from a 2D shader that does not use the WorldViewProjection matrix, but does use registers associated with WorldViewProjection matrix, due to the effects compiler allocating them at compile time. I then render a 3D mesh that uses the WorldViewProjection matrix, without reseting the shader constants. Even though register c0 contained a different value in the 2D shader.
So now I'm wondering how DirectX deals with constant registers. Does DirectX restore the shader constants that were defined in the shader (i.e def c0, ...), when changing shaders Or does it reupload the constants it needs when a shader is set Perhaps this is more of a Display Driver detail, and not specified by DirectX how it is done.
Thanks,
David Edwards