2
\$\begingroup\$

HLSL/Cg do not allow texture fetching inside conditional blocks. To get around this I am first checking a variable and performing some computations, afterwards I set a float flag to 0.0 or 1.0, depending on the computations. I'd like to trigger a texture fetch only if the flag is 1.0 or not null. I kind of hoped this would do the trick:

float4 TU0_atlas_colour=pseudoBool*tex2Dlod(TU0_texture, float4(tileCoord, 0, mipLevel));

I want to know if pseudoBool is 0, will the texture fetch function still be called and produce overhead? I was hoping to prevent it from getting executed via this trick that usually works in plain C/C++.

\$\endgroup\$
4
  • \$\begingroup\$ So, this works and you're only worried about performance? \$\endgroup\$
    – House
    Commented Mar 27, 2012 at 17:11
  • 2
    \$\begingroup\$ Have you tried using PIX or some higher level shader analyzer to see if this line is optimized away sometimes? \$\endgroup\$
    – Roy T.
    Commented Mar 27, 2012 at 18:25
  • 2
    \$\begingroup\$ Definitely second the recommendation to check the generated assembly in PIX, although my feeling is that - since the compiler doesn't know or can't infer the value of pseudoBool in advance - it won't be optimized out. Note that this might actually be the fast path here as the cost of a branch may be more expensive than the cost of just doing a lookup anyway. Also remember that GPUs are designed and work very different to CPUs so tricks, etc that work on one aren't necessarily going to be applicable to the other. \$\endgroup\$ Commented Mar 27, 2012 at 21:29
  • \$\begingroup\$ I did try analyzing it with nvPerfHud and it seems that using if clauses on "runtime" variables that can be zero produces the same overhead as if that code was executed. So, regardless of the value of the if statement's expression, the block does occupy execution time. It's as if that block is ran first, and then the if condition gets evaluated. \$\endgroup\$
    – teodron
    Commented Mar 28, 2012 at 10:44

1 Answer 1

6
\$\begingroup\$

Firstly you can do texture fetching inside conditional blocks in HLSL. tex2Dlod() and tex2Dgrad() will work fine inside one. It's just tex2D() that won't compile, and you can work round that by computing ddx() and ddy() outside the conditional and using tex2Dgrad().

To reliably stop the texture fetch (or any other block of code) being executed in HLSL, use an if statement prefixed with the [branch] attribute. This requires shader model 3 or higher.

You can also of course also make two separate shaders and switch between them from the calling code, but that isn't as flexible. Where it's possible it will be quicker though.

Also note that unless the branch is skipping over significantly more lines of code than a single texture read you will probably lose performance and not gain it. If in doubt test with both [branch] and [flatten] and compare performance between the two. Without either attribute the compiler will guess at which option is best.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ +1; the cost of the branch may very well be more expensive than the cost of just doing the lookup anyway. \$\endgroup\$ Commented Mar 27, 2012 at 21:25
  • \$\begingroup\$ I'll have to try it out, there are shader regions that can be "shunted" using [branch] . Thanks for the replies. \$\endgroup\$
    – teodron
    Commented Mar 28, 2012 at 10:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .