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)
out vec2 outVS_TexCoord0;
const vec4 verts = 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;
// 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
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.
Please disregard; this issue seems to be fixed in Catalyst 12.10.