HLSL switch attributes

This topic is 836 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

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!

Edited by zeo4

Share on other sites

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

Share on other sites

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~

Share on other sites

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.

Edited by N.I.B.

Share on other sites
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

Share on other sites

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

• What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 11
• 11
• 15
• 11
• 11
• Forum Statistics

• Total Topics
634149
• Total Posts
3015834
×