I'm getting some strange behavior where two seemingly equivalent expression in the fragment shader end up with totally different results.
I was able to condense the problem down to the test case below where "gl_FragColor = vec4(vec3(a * a *0.3), 1);" produces the result in the picture while "gl_FragColor = vec4(vec3(0.3 * a * a), 1);" works correctly and just outputs gray in the left half and black in the right half.
Looks like those artifacts happen around non uniform shader execution.
#include "GL/glew.h"
#include "GL/glut.h"
#include <vector>
const char* vs_source =
R"(
#version 130
void main(void)
{
gl_Position = gl_Vertex;
}
)";
const char* fs_source =
R"(
#version 130
void main(){
float y;
for(y = 1; y < 42; y++)
{
float x = gl_FragCoord.x;
if(x > 300) break;
}
float a = y / 43;
gl_FragColor = vec4(vec3(a * a *0.3), 1); // broken
//gl_FragColor = vec4(vec3(0.3 * a * a), 1); // works
}
)";
void printObjLog(GLuint obj){
GLint logLength = 0;
glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logLength);
if(logLength > 0){
std::vector<GLcharARB> errorLog(logLength,0);
glGetInfoLogARB(obj, logLength,0,&errorLog[0]);
fprintf(stderr, &errorLog[0]);
}
}
GLuint compileShader(GLuint type, const char* src)
{
GLint compile_ok = GL_FALSE;
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &src, NULL);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_ok);
if (0 == compile_ok){
fprintf(stderr, "Error in shader:\n");
printObjLog(shader);
return 0;
}
return shader;
}
int init_resources(){
GLuint program = glCreateProgram();
GLuint vs = compileShader(GL_VERTEX_SHADER, vs_source);
GLuint fs = compileShader(GL_FRAGMENT_SHADER, fs_source);
glAttachShader(program, vs);
glAttachShader(program, fs);
GLint link_ok = GL_FALSE;
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
if (!link_ok) {
fprintf(stderr, "glLinkProgram:");
printObjLog(program);
return 0;
}
glUseProgram(program);
return 1;
}
void onDisplay()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex3f(-1,-1,0);
glVertex3f(1,-1,0);
glVertex3f(-1,1,0);
glEnd();
glBegin(GL_TRIANGLES);
glVertex3f(-1, -1, 0);
glVertex3f(4, -1, 0);
glVertex3f(-1, 4, 0);
glEnd();
glutReportErrors();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
glutInitWindowSize(600, 600);
glutCreateWindow("gltestcase");
GLenum glew_status = glewInit();
if (glew_status != GLEW_OK)
{
fprintf(stderr, "Error: %s\n", glewGetErrorString(glew_status));
return EXIT_FAILURE;
}
if (1 == init_resources()) {
glutDisplayFunc(onDisplay);
glutMainLoop();
}
return 0;
}
Hi @nke ,
Thank you for reporting it and providing the reproducible test-case. Please share the setup information like OS, GPU, driver version etc.
Thanks.
Edition Windows 10 Enterprise
Version 21H2
OS build 19044.2006
Experience Windows Feature Experience Pack 120.2212.4180.0
Radeon RX 580
Driver Version 22.20.19.16-221003a-384125E-AMD-Software-Adrenalin-Edition
AMD Windows Driver Version 31.0.12019.16007
Thanks for providing the setup information. I will report the issue to the OpenGL team.
A bug ticket has been created to track this issue. I will notify you if I get any update on this.
Thanks.
As I have come to know, the issue has been fixed and it is no longer reproducible with the latest internal driver builds.
Thanks.