If/then/else and for statements

are
if(condition){
Block1
}else{
Block2
}
statements true conditionnal statement ? or will it be translated into a serial of:
a=(condition?value1:value2)
a=(condition?value43:value12)
etc… repeated each line of block1 and invert condition for block2
wich would be sure less optimized than a true conditionnal statement with jump !

I’m wondering about that because I read than microsoft’s language HLSL was doing so for pixel shaders.

What about GLSlang for opengl ?
And does my Radeon 9800 support true conditionnal tests ?

Same question for the “for” statement: is it a true loop, or just a unroll of it ? (with, once again, is not very optimized)

There’s no way to tell, but there are some guidelines for modern hardware.

In general, for glslang vertex shaders, you can assume that the underlying hardware conforms to the DX9 VS 2.0, and thus has the capability for true loops. But, for fragment shaders, at the moment, you should assume that there is no actual branch instruction, and that conditionals and loops are emulated/unrolled if possible.

since conditionnal statements are translated into (test?value1:value2), given an example like:
var1=(3>5?sqrt(53.2)*879.2f:0);
will sqrt(53.2)*879.2f be computed, even it’s not used since the test return false ?
More generally, in what extend does the (? : ) statement has a branching ability ?

[This message has been edited by divide (edited 03-15-2004).]

[This message has been edited by divide (edited 03-15-2004).]

var1=(3>5?sqrt(53.2)*879.2f:0);
will sqrt(53.2)*879.2f be computed, even it’s not used since the test return false ?

No, at this statement the square root should not be computed (if the compiler is clever enough) because the expression “3>5” can be processed at compile time.

yes but more generally with unpredictable test, do we have to assume that both statements will be computed, whatever is the issue of the test ? and then one result of theses two computations stored in the final var ?

If your compiler will compile a statement which is dynamically processed then it both will be executed at runtime:

var1=(my_uniform_1>my_uniform_2?sqrt(53.2)*879.2:sqrt(12.3)*54.3);

Here both will be computed on current hardware (if the compiler is able to compile it). Only VS/PS 3.0 cards are able to determine this at runtime.

[This message has been edited by Corrail (edited 03-15-2004).]

In practice, it will be a combination of the hardware, the compiler, and even the particular case whether or not both paths of a selection are evaluated. Compilers will try to be smart based on what is happening in both paths and what hardware’s capability is.

However, this should not be detectable other than through performance measurements. Any side-effects in the false path are not allowed to become visible, so this is truly a performance only question.

JohnK

Any side-effects in the false path are not allowed to become visible
Really? So, if I call some function in the false path that sets some global variable, then the compiler will simply fail if can’t actually do branching?

Originally posted by Korval:

Really? So, if I call some function in the false path that sets some global variable, then the compiler will simply fail if can’t actually do branching?

The compiler is supposed to generate proper code for what you are trying to achieve. i.e. it is supposed to generate code that will not affect the global if the condition is false.

Originally posted by Korval:
[quote]Any side-effects in the false path are not allowed to become visible
Really? So, if I call some function in the false path that sets some global variable, then the compiler will simply fail if can’t actually do branching?
[/QUOTE]There are several ways of implementing that:

  • You can use predication, where the writes to a register are conditional on a flag.
  • Or if your hardware doesn’t support conditional writes, you can simulate them with conditional moves.

I will attempt to translate to ARBvp/fp the above code

It will be reordered to :

var1=(my_uniform_2<my_uniform_1?sqrt(12.3)*54.3:sqrt(53.2)*879.2);

Let’s assume uniforms are mapped to global param registers, var1 is a local temporary
sqrt(53.2)*879.2 is simplified and placed in a global param, sqrt(12.3)*54.3) is simplified and placed in a global param

TEMP var1, r0;

SLT r0, program.env[21], program.env[20];
MUL var1, r0, program.env[23];
MAD var1, 1-r0, program.env[22], var1;//or use LRP

I think that if you had a function call that sets some global value, the function call will be executed but the results would be stored in temporaries, and then something similar to the above would be executed to set the values in the global registers.

???I can’t put HTML tags anymore???

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.