AnsweredAssumed Answered

double-precision constant problem in GLSL

Question asked by cccccc on Oct 29, 2012
Latest reply on Oct 30, 2012 by cccccc

I was porting a GLSL shader from single-precision to double-precision, and found that nothing would render on the AMD cards I tested on (using Catalyst 12.8). I reduced the buggy program down to the following simple test case:

 

// Vertex shader -- draw a full-screen triangle with glDrawArrays(GL_TRIANGLES,0,3)

#version 150

out vec2 outVS_TexCoord0;

void main(void)

{

    const vec4 verts[3] = vec4[](

        vec4(-1, 1, 0, 0),

        vec4(-1,-3, 0, 2),

        vec4( 3, 1, 2, 0)

    );

     vec4 vert = verts[clamp(gl_VertexID,0,2)];

    gl_Position = vec4(vert.x, vert.y, 0, 1);

    outVS_TexCoord0 = vert.zw;

}

 

// Fragment shader -- draws a red circle on a green background

#version 330 core

#extension GL_ARB_gpu_shader_fp64 : enable

#extension GL_ARB_gpu_shader5 : enable

in vec2 outVS_TexCoord0;

out vec4 outFS_FragColor0;

void main()

{

    // Convert incoming texture coordinates [0..1] to the range [-1..1]

    double x = -1.0 + outVS_TexCoord0.x*2.0;

    double y = -1.0 + outVS_TexCoord0.y*2.0;

    //double radius = 1.0; // WORKS

    //const double radius = double(1.0); // WORKS

    //const double radius = 1.0LF; // WORKS

    const double radius = 1.0; // FAILS -- draws green to the whole screen.

    if (x*x+y*y < radius)

    {

        outFS_FragColor0 = vec4(1,0,0,1); // output red

    }

    else

    {

        outFS_FragColor0 = vec4(0,1,0,1); // output green

    }

}

 

So, declaring the circle radius as a "double" works correctly, but making it a "const double" causes the if() condition to always fail (unless I cast the 1.0 to a double, either using an explicit double() or by adding the "LF" suffix to the initial value).

 

So, I have three different ways I can fix my original code, but I still don't understand why the original "const double radius = 1.0" version doesn't work. Even if there was a precision mismatch somewhere, I'd expect the final comparison to behave correctly. Also, why would "const double" fail but "double" work correctly? I would at least expect a compiler error/warning, but the info log mentions nothing out of the ordinary.

 

Thanks!

-c

Outcomes