Hi,
I am experiencing the following failure with my ATI GPU Drivers. This could be a problem with the GL Shader Compiler that is used by the ATI Drivers.
Configuration
OS - Microsoft Windows XP Professional with SP2
GPU - ATO Radeon HD 2600 Pro
Driver version - 10.4 (from ATI Website)
Shader Program
The following shader returns incorrect result.
const mat4 ones_mat = mat4(1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0);
const mat4 zeros_mat = mat4(0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0);
bool matrix_equal(const in mat4 value, const in mat4 reference);
bool elements_equal(const in mat4 par, const in float value);
void main()
{
mat4 var;
var = ones_mat;
if( matrix_equal(var, ones_mat ) )
gl_FragColor = vec4(0.4,0.4,0.8,1.0);
}
bool matrix_equal(const in mat4 value, const in mat4 reference)
{
if(value == reference)
return true;
else
return false;
}
In the above shader, gl_FragColor should always be set to vec4(0.4,0.4,0.8,1.0) as the comparison operations should return true. The comparison opeartion fails and hence the shader returns the uninitialized value (black color).
Comparing the matrices element by element returns the correct result. The complete fragment shader has been attached.
We have verified the shader with other GPUs (NVIDIA) and they return the expected ouput. The problem has also been found with the latest ATI Drivers for Linux.
Linux Configuration
ATI Proprietary Linux Driver - 8.723
GPU - ATI Radeon HD 2600 Pro
Please let me know if a formal bug report needs to be raised. I am unsure of the forum it needs to be raised and hence posting it here.
Regards
Karthik
const mat4 ones_mat = mat4(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0); bool matrix_equal(const in mat4 value, const in mat4 reference); bool elements_equal(const in mat4 par, const in float value); void main() { mat4 var; var = ones_mat; if( matrix_equal(var, ones_mat ) ) // if( elements_equal(var, 1.0) ) gl_FragColor = vec4(0.4,0.4,0.8,1.0); } bool matrix_equal(const in mat4 value, const in mat4 reference) { if(value == reference) return true; else return false; } bool elements_equal(const in mat4 par, const in float value) { bool ret = true; if(par[0][0] != value) ret = false; if(par[0][1] != value) ret = false; if(par[0][2] != value) ret = false; if(par[0][3] != value) ret = false; if(par[1][0] != value) ret = false; if(par[1][1] != value) ret = false; if(par[1][2] != value) ret = false; if(par[1][3] != value) ret = false; if(par[2][0] != value) ret = false; if(par[2][1] != value) ret = false; if(par[2][2] != value) ret = false; if(par[2][3] != value) ret = false; if(par[3][0] != value) ret = false; if(par[3][1] != value) ret = false; if(par[3][2] != value) ret = false; if(par[3][3] != value) ret = false; return ret; }
To add, this is a problem with mat2 and mat3 types as well. For example the following fragment shader program returns incorrect output.
varying vec4 color;
const int ar_size = 2;
void main (void)
{
const mat2 val1 = mat2(2.0, 2.0, 2.0, 2.0);
const mat2 val2 = mat2(4.0, 4.0, 4.0, 4.0);
mat2 array[ar_size];
float gray;
array[0] = val1;
array[1] = val2;
if((array[0] == val1) && (array[1] == val2))
gray = 1.0;
else
gray = 0.0;
gl_FragColor = vec4(gray, gray, gray, 1.0);
}
Some more bugs with the ATI Shader Compiler I guess. The following shader gives incorrect output.
void main (void){
struct nest2
{
float f1;
};
struct nest1
{
ivec3 vc3;
nest2 vnest2;
};
struct test_t
{
nest1 vnested;
};
test_t a = test_t( nest1( ivec3(73, 74, 75), nest2(144.0) ) );
float gray;
if( (a.vnested.vc3[0] == 73) && (a.vnested.vnest2.f1 == 144.0) )
// if( (a.vnested.vc3[0] == 73) )
gray=0.4;
else
gray=0.0;
gl_FragColor = vec4(gray, gray, gray, 1.0);
}
The variable gray should be set to 0.4. It is set to 0.0. We have checked with NVIDIA GPUs and this returns the expected result.
Continue statements dont work in some shaders;
Looks like the Shader Compiler has some more issues. In the following shader, the continue statement has no effect. When the continue statement is commented, the program runs fine. With the continue, it gives a wrong result.
void main (void)
{
int cnt1 = 0, cnt2 = 0;
int sum1 = 0, sum2 = 0;
for(int i=0;i<4;i++)
{
cnt1++;
cnt2 = 0;
for(int j=0;j<4;j++)
{
cnt2++;
if(cnt2 == 2){
cnt2 = cnt2;
continue;
}
else
sum2 += cnt2;
}
if(cnt1 == 2)
{
cnt1 = cnt1;
continue;
}
else
sum1 += cnt1;
}
float gray;
if( (sum2 == 32) )
gray=0.4;
else
gray=0.0;
gl_FragColor = vec4(gray, gray, gray, 1.0);
}
We have used the same shader with NVIDIA GPu and it gives the expected output.
Thanks for your feedback. Most of the bugs could be reproduced except the second one - matrix2 comparison. We will fix them as soon as possible.
Thanks
Frank
Thanks for your reply. With the matrix 2 comparison I am also not able to reproduce them. Will investigate further and let you know.
Also, theres one more issue I found with the drivers
When glBindAttribLocation is used with an invalid location (-1), then the error to be returned is GL_INVALID_VALUE. ATI Drivers accept what we give and return GL_NO_ERROR.
The attached code returns GL_INVALID_OPERATION when Texture Image is attached to a framebuffer object. When a renderbuffer object is attached to a framebuffer object no error is returned.
In other words, the first call to glGetFramebufferAttachmentParameteriv fails but the second call succeeds.
Given that this extension is supported by the ATI Drivers, this is incorrect bahavior. Please let me know if you need more information.
GLuint tex; GLuint fb, rb; GLint buf[10]; GLenum error = GL_NO_ERROR; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glGenFramebuffers(1, &fb); glBindFramebuffer(GL_FRAMEBUFFER, fb); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, buf); error = glGetError(); glGenRenderbuffers(1, &rb); glBindRenderbuffer(GL_RENDERBUFFER, rb); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, buf); error = glGetError();
The four shader related problems have been all fixed. I can't find the problems in the latest driver. You'd better wait for about two or three months to have a try.
We will take a look at the other problems. Thanks again for your great feedback.
Frank
Thanks for your reply. http://www.highnfljerseys.com
Hi,
I have now downloaded the latest driver from the website and I am happy to say that the previous issues that I reported have been fixed. But some new bugs are showing up (as is with the bug fixing process ). The attached shader doesn't compile on ATI. It does fine on NVIDIA.
void main() { const struct struct1 { int i; vec4 v4; } struct1_var = struct1(8, vec4(9, 10, 11,12)); struct struct2 { int i; }; struct struct3 { struct1 s1; struct2 s2; } struct3_var = struct3(struct1_var, struct2(6)) ; const int i1 = struct3_var.s1.i * struct3_var.s2.i; const vec4 field4 = struct3_var.s1.v4 ; // 49, 64, 81, 100 gl_Position = field4; }
The compiler given errors like
error(#206) Assigning non-constant to = const
This functionality seems to be broken for most variable types for the shading language.
It's a bug in the driver, we will fix it soon.
Thanks
As a workaround, you could remove "const" to make the shader pass first.