HLSL switch attributes

Started by
4 comments, last by zeo4 7 years, 6 months ago

Hi,

Can anyone give a little more details, than on MSDN, on what the below HLSL "switch" statement attributes do:

forcecase - ?

call - ?

Example:


[forcecase] switch(exp)
{
case 0:
    break;
case 1:
    break;
}

[call] switch(exp)
{
case 0:
    break;
case 1:
    break;
}

Many thanks!

Advertisement

Hi,

from looking at the MSDN documentation (https://msdn.microsoft.com/en-us/library/windows/desktop/bb509669(v=vs.85).aspx ), the comments are:

forcecase - force switch

call - subroutines

My understanding would be that with the latter, the code would explicitly use a subroutine, whereas the former would be inclined to have conditional execution. A subroutine call would come with (apparently - http://gamedev.stackexchange.com/questions/82988/how-does-an-sm5-shader-handle-loops-and-if-statements-hlsl-cg ) a ~5 cycle overhead whereas with the conditional execution, each instruction skipped would come at a cost of 1 cycle.

From that, I'm guessing that for larger case items and where all of the pixels to be processed are likely to go down the same path in the switch statement, I'd use 'call'.

Hope this is vaguely useful.

Cheers

Steve

forcecase would as you said force a switch statement. Something to note is that a switch statement differs from a series of if else conditional statements as it uses a lookup table or hash list, so all "branches" in a switch statement get the same access time, where in a list of if else statements, the further down an if or else is, the longer it will take to reach since it has to execute all previous if else statements

I'm still unclear about call though. In the docs it does say it turns each switch case into a subroutine and the entire switch case is then "a series of subroutine calls". That makes me think that a switch case that looks like this:


[call]switch(i) {
    case 0:
        break;
    case 1:
        break;
    case 2:
        break;
}

would be turned into something like this:


case1(i);
case2(i);
case3(i);

Where does the conditional or switch statement get executed then? i can't imagine it happens inside the subroutine because then your making a lot of unneeded jumps into subroutines. It must happen outside the subroutine to decide which one of many subroutines to jump into. In that case, is it still using a switch statement? or is it using an if else statement?

Since a switch statement is converted to a series of if else statements when no attribute is provided, is it the same for the call attribute? could you have both forcecase and call attributes on a switch statement?

Thinking about it now, it might be that it actually gets called like this:


casei();

I don't now how they would implement that in code exactly, but i suppose all this could be easily cleared up by looking at the assembly of a compiled shader. I would do that right now but i'm at work, so if anybody else wants to do the honors, or if you already know how this works, i for one would appreciate it~

FXC will generate


switch v1.x
  case l(5)
  call label0
  break
  default
  call label1
  break
endswitch
mov o0.xw, r0.xxxy
mov o0.yz, l(0,1.000000,1.000000,0)
ret
label label0
mov r0.xy, l(1.000000,1.000000,0,0)
ret
label label1
mov r0.xy, l(0,0,0,0)
ret

So there's still a 'switch' in the assembly. It just that the statement following the 'case' will be a subroutine call instead of the actual statement.

Thanks N.I.B., that answeres that question, so then the call attribute implicitly also uses the forcecase attribute since the switch case is used

Ok, I now see the ideas behind both options. Thanks for the help!

This topic is closed to new replies.

Advertisement