I tried to compile a hlsl shader with a switch statement with the [call] attribute like this:
for(uint i = 0; i < lightCount; ++i)
{
Light light = LightList[i];
[call] // With this specified it creates glitches
switch(light.type)
{
case POINT:
EvaluatePointLight(light, surface); // big function
break;
case SPOT:
EvaluateSpotLight(light, surface); // big function
break;
case DECAL:
EvaluateDecal(light, surface); // big function
break;
// etc...
}
}
MSDN says the [call] attribute will move the individual case bodies to hardware subroutine calls.
However, specifying this attribute makes my lights all glitchy and flickering. This is a tiled forward renderer by the way, and it loops through all the lights in a 16*16 pixel tile while rendering an object. Without this attribute, it renders correctly. It also renders correctly when specifying [branch], [forcecase] or [flatten] though the performance of each varies (forcecase is fastest and is the default, and flatten is the slowest). When it is flickering, it seems to be per-tile, so a whole tile's pixels flicker the same way, but different from an other tile near it for example.
I have found this article for OpenGL shader subroutines but it doesn't seem like my case.
So the question is, where should I use this [call] attribute, or subroutines in general in HLSL shaders? And why does it compile but generate faulty output?