Search Home Members Contacts
About Us
Products
Downloads
Community
Support
Pages: [1]
  Print  
Author Topic: Changing global variables inside a shader function.  (Read 627 times)
MiloDC
Community Member
*
Posts: 129


WWW
« on: November 18, 2007, 06:19:17 PM »

I'm pretty much a HLSL n00b, and what I'm trying to do is alter a global (uniform) variable inside a shader, and get the post-render value using TVShader.GetEffectParamBoolean(string).

Apparently, I mistakenly thought that I could do this like so:

Code:
// HLSL

bool myBool = false;

float4 ps_main(PS_INPUT input) : COLOR0 {
myBool = true;

return float4(0.0f, 0.0f, 0.0f, 0.0f);
}

Code:
// C#

// ... render some stuff using shader above...

bool result = myTVShader.GetEffectParamBoolean("myBool");


... But no matter what, result always evaluates to false.

The same thing happens if I do this:

Code:
// HLSL

bool myBool = true;

float4 ps_main(PS_INPUT input) : COLOR0 {
myBool = true;

return float4(0.0f, 0.0f, 0.0f, 0.0f);
}

Code:
// C#

myTVShader.SetEffectParamBoolean("myBool", false);

// ... render some stuff using shader above...

bool result = myTVShader.GetEffectParamBoolean("myBool");


In other words, I'm able to get the value of myBool only as defined during its declaration, or via TVShader.SetEffectParamBoolean(string, bool) -- which actually seem to be effectively one and the same.

How can I pass a change to myBool from within the pixel shader function to my C# code?
Logged

Zaknafein
Customers
Community Member
*****
Posts: 2670


WWW
« Reply #1 on: November 18, 2007, 07:57:04 PM »

Put simply... you can't. Smiley

Shader variables are input parameters. The only output of a pixel shader is the pixel's color (and alternatively the Multiple Render Target colors, but it ends up being the color of each RT you render on, COLOR0/1/2/3...).

So if you need to get data out of your shader, use textures and readback the texture with texture reading mechanisms. (I'm thinking of Texture.GetData<T> but that's in XNA... D'oh!)

BUT readback from GPU to CPU is generally a bad idea unless it's unavoidable, because it's slow. So rule of thumb, if you can keep everything on the GPU side without the CPU interfering in some places along the chain, do it.
Logged

zaknafein.
>> the instruction limit : my blog & samples repository! <<
MiloDC
Community Member
*
Posts: 129


WWW
« Reply #2 on: November 18, 2007, 08:54:55 PM »

Put simply... you can't. Smiley

Bummer.  Sad

Shader variables are input parameters. The only output of a pixel shader is the pixel's color (and alternatively the Multiple Render Target colors, but it ends up being the color of each RT you render on, COLOR0/1/2/3...).

So if you need to get data out of your shader, use textures and readback the texture with texture reading mechanisms.

That's going to be very problematic.  I'm going to have to find some way to extremely quickly read a texture for the presence of particular colors.

Looks like I've got some researching to do.  Thanks again, Zaknafein.
Logged

BlindSide
Customers
Community Member
*****
Posts: 759


WWW
« Reply #3 on: November 19, 2007, 01:16:04 AM »

Unfortuntely, there really *is* no fast way to read a texture. The problem stems from the textures residing on video ram - so they must be copied from video memory to system memory, locked, read (sloooow), unlocked, and released from system memory. Pretty gross.

Using the GPU to return values is known as GPGPU (general-processing on the GPU). Waterman does it for his nice ship-ocean physics. But again, it's a slow thing, and not recommended. Keep in mind that you often have to wait for the GPU and the CPU to sync up as well.. so best bet is to grab a texture, and wait a frame before trying to read from it (to hide the syncing delay).

Latency occurs as well in SM4.0 where some people use the pixel shader to calculate pixel velocities, output to a texture, which is then read in in the geometry shader. To counter act the latency (because it is not a dependant read), they do math before trying to use the texture's value.

What is it you're trying to do? Maybe we can help come up with another approach.
« Last Edit: November 20, 2007, 03:40:10 AM by BlindSide » Logged

Blind's Dev Blog - www.smithbower.com/devblog/

Irc.Desolation.Org :: #TV3DLicensed :: Moderated IRC channel for all your TV3D needs :: Non-Licensed users welcome.
MiloDC
Community Member
*
Posts: 129


WWW
« Reply #4 on: November 19, 2007, 02:29:27 AM »

Unfortuntely, there really *is* no fast way to read a texture.

*Nod* I figured as much.

What is it you're trying to do? Maybe we can help come up with another approach.

I'm trying get the 2D union Boolean (i.e. X and Y dimensions only) of two groups of 3D objects, by superimposing one render target (the first group) over another (the second group).

I noticed essentially no frame hit having the GPU take on the work; everything was beautiful, until I started trying to pass the result to my C# code.

Logged

Pages: [1]
  Print  
 
Jump to:  

Powered by SMF 1.1.3 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks