Falcor icon indicating copy to clipboard operation
Falcor copied to clipboard

unroll doesn't supported in Shader

Open bryan05 opened this issue 6 years ago • 3 comments

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

bryan05 avatar Nov 20 '18 22:11 bryan05

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.

tangent-vector avatar Nov 20 '18 22:11 tangent-vector

Thanks for the answer. We have several shades with gradient instructions, which must use [unroll].

bryan05 avatar Nov 20 '18 22:11 bryan05

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 breaks, though.

tangent-vector avatar Nov 20 '18 23:11 tangent-vector