• Advertisement
Sign in to follow this  

How to keep variables between passes in shader ?

This topic is 2650 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have declared global shader variable as static.
Here is HLSL code fragment :

static float minVal = 1.f;

PS_OUTPUT myFunc0PS(VS_OUTPUT In)
{
if(In.Position.z > minVal)
minVal = In.Position.z;
...
}

PS_OUTPUT myFunc1PS(VS_OUTPUT In)
{
if(In.Position.z > minVal)
// do something here;
...
}

technique MyTech
{
pass P0
{
...
PixelShader = myFunc0PS;
}
pass P1
{
...
PixelShader = myFunc1PS;
}
}

you see, technique has two passes and both access the global static variable,
I want this value stay persistent,
but it is initialized at 1.0f each pass. Why?
Is there any trick that can keep value between passes in HLSL?

Share this post


Link to post
Share on other sites
Advertisement
sorry, I make a mistake...
the code :

if(In.Position.z > minVal)
minVal = In.Position.z;

should be :

if(In.Position.z < minVal)
minVal = In.Position.z;

The situation I mentioned before still exist.

Share this post


Link to post
Share on other sites
static float minVal = 1.f;
...
if(In.Position.z > minVal)
minVal = In.Position.z;
You can't do this... Each execution of the pixel shader is completely independent of every other executions. Each time the shader is run, it could be happening on a completely different processor. There minVal variable is not shared between each pixel -- it's recreated for each pixel.

Newer versions of HLSL do have support for shared memory though...


To implement your algorithm, you could render all your values to a render target, then have a shader that finds the min-value in that RT, and writes the value to another RT.
Then your second pass can read the min-value from the above RT.

Share this post


Link to post
Share on other sites
In versions of Direct3D older than 11, this isn't possible. However, in D3D11 you have access to unordered access views that could be used to communicate over all of the invocations within a draw call (in your case for each pixel shader invocation). However, this is not a simple operation and would require you to use an atomic function write to write the value, and then perform a group synch memory barrier. On top of all that, you will also need to create the buffer resource being used with a special flag to indicate that it should sync across thread groups (the flag itself escapes me at the moment, but is listed in the SDK docs...).

Probably the best way to do what you are trying is to do a first pass in a compute shader to determine where your threshold is found, and then set that information as either a constant buffer (requiring CPU interaction with the data) or a shader resource view (everything stays on the GPU) in the next pass.

What exactly are you trying to accomplish with this mechanism? Perhaps there is another way to do it that wouldn't require global access to the parameter?

Share this post


Link to post
Share on other sites
I was able to do that on a per frame basis inside of the begin/present section. As far as multiple frames I saw no reason to attempt that since the scene changes every frame.
Also, set minVal externally, with that set to 1.0 it will reset to 1.0 in the next begin/present. Lose the 'static' declaration as well since it really isn't static (you mentioned you are changing it), 'static' means it doesn't change, not that it will stay in memory.

Share this post


Link to post
Share on other sites
I just want to find out the minVal & maxVal in depthMap,
then I met this question, and wonder the HLSL mechanism :)
thank you~
What I did is to get RT data to a surface and lock it,
access with CPU to find out that vals.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement