Falcor
Falcor copied to clipboard
unroll doesn't supported in Shader
my shader looks like this:
[unroll] for(int i = 0; i < 5 ; i++) {
The error code is
error X3511: unable to unroll loop, loop does not appear to terminate in a timely manner (428 iterations) or unrolled loop is too large, use the [unroll(n)] attribute to force an exact higher number
I looked into the translated slang code, it looks like the following
[unroll]
for(;;)
{
bool _S264 = _S203 < (5);
if(_S264)
{
}
else
{
_S205 = _S204;
break;
}
I changed my code to [unroll(5)], I got another error
(2796): internal error 99999: unexpected condition encountered in Slang compiler: unhandled attribute
The second error message you are seeing is because Slang doesn't understand the [unroll(n)]
attribute; we will need to fix that.
The first error message is coming from fxc, because it fails to understand the form that the for
loop takes after Slang's control-flow transformations have been applied. The translated code matches the semantics of the original, but fxc is not clever enough to see that the loop is still unrollable. I do not expect that this problem will be fixed by Slang supporting the [unroll(n)]
attribute.
If possible, please consider working around the problem by eliminating the [unroll]
attribute entirely, if possible. If that is not possible we can try to find another alternative.
The right long-term solution here is for Slang to perform the loop unrolling itself, rather than pass the attribute through to the downstream compiler, but we won't be able to get to that feature right away.
Thanks for the answer. We have several shades with gradient instructions, which must use [unroll].
Okay, as a workaround for now, you could consider using a Slang-specific feature for "compile-time loops" that can guarantee unrolling. For example, here is some code that uses the Sample()
operations that require compile-time-constant offsets:
float4 result = 0;
$for(i in Range(0,5))
{
float4 v = t.Sample(s, uv, int2(i - 2, 0));
result += v;
}
A $for(v in Range(Lo,Hi))
construct requires that Lo
and Hi
be compile-time constant integers, and will then instantiate the body of the loop with v
taking on each value in the interval [Lo,Hi)
(that is, including Lo
, but excluding Hi
). The Falcor shader code uses $for
loops in a few places, so hopefully you will find code you can copy-paste.
You might elect to use a #if
to allow you to easily switch back to the original HLSL version once Slang can unroll the original loop properly.
One important limitation of $for
loops is that you can't break
out of them, so if your code has any early-exist cases you might need to rewrite them so that the body of the loop is wrapped in an if
. If you were planning to unroll the loop anyway, I wouldn't expect there to be such break
s, though.