Search code examples
directxdirect3dhlsl

Direct3D11: "gradient instruction used in a loop with varying iteration, forcing loop to unroll", warning: X3570


I'm working on a graphics engine using Direct3D 11 and Visual Studio 2015. In the HLSL shaders for the main draw calls, I sample shadow maps for directional and point lights with percentage-closer-filtering, i.e. I sample a small square area around the target shadow map texel and average the results to get soft shadows. Now, every call to shadowMap_.Sample(...) creates a warning: "gradient instruction used in a loop with varying iteration, forcing loop to unroll" (X3570). I want to fix this or, if that is not possible, hide the warning as it completely floods my warning output.

I tried searching online for the error message and couldn't find any further descriptions. I couldn't even find an explanation what a gradient instruction is supposed to be. I checked the Microsoft documentation for a different sampler or sampling function that lets me replace the loop with native sampling functionality, but didn't find anything like that either. Here is the function I use for sampling my shadow cube maps for point lights:

float getPointShadowValue(in uint index, in float3 worldPosition)
{
    // (Half-)Radius for percentage closer filtering
    int hFilterRadius = 2;

    // Calculate the vector inside the cube that points to the fragment
    float3 fragToLight = worldPosition.xyz - pointEmitters_[index].position.xyz;

    // Calculate the depth of the current fragment
    float currentDepth = length(fragToLight);

    float sum = 0.0;
    for (float z = -hFilterRadius; z <= hFilterRadius; z++)
    {
        for (float y = -hFilterRadius; y <= hFilterRadius; y++)
        {
            for (float x = -hFilterRadius; x <= hFilterRadius; x++)
            {
                // Offset the currently targeted cube map texel and sample at that position
                float3 off = float3(x, y, z) * 0.05;
                float closestDepth = pointShadowMaps_.Sample(sampler_, float4(fragToLight + off, index)).x * farPlane_;
                sum += (currentDepth - 0.1 > closestDepth ? 1.0 : 0.0);
            }
        }
    }
    // Calculate the average and return the shadow value clamped to [0, 1]
    float shadow = sum / (pow(hFilterRadius * 2 + 1, 3));
    return min(shadow, 1.0);
}

The code still works fine as it is, but I get a huge amount of these warnings and don't know if this causes a relevant performance impact. Any further information about the warning and what can be done about it is greatly appreciated.

Thanks in advance.


Solution

  • As Chuck Walbourn already stated, adding an [unroll] statement before the for loops fixes the warnings. This type of warning is basically the compiler informing you that a loop can't be unrolled or it would be less performant to do so (as can be read in the Microsoft documentation for the HLSL for-loop). I assume this can be safely accepted.