Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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++.

share|improve this question
    
So, this works and you're only worried about performance? –  Byte56 Mar 27 '12 at 17:11
2  
Have you tried using PIX or some higher level shader analyzer to see if this line is optimized away sometimes? –  Roy T. Mar 27 '12 at 18:25
2  
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. –  Darth Satan Mar 27 '12 at 21:29
    
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. –  teodron Mar 28 '12 at 10:44

1 Answer 1

up vote 6 down vote accepted

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.

share|improve this answer
1  
+1; the cost of the branch may very well be more expensive than the cost of just doing the lookup anyway. –  Darth Satan Mar 27 '12 at 21:25
    
I'll have to try it out, there are shader regions that can be "shunted" using [branch] . Thanks for the replies. –  teodron Mar 28 '12 at 10:40

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.