cancel
Showing results for 
Search instead for 
Did you mean: 

OpenGL & Vulkan

nke
Adept I

glsl wrong fragment shader output with break in for loop

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.

actual.png
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;
}
0 Likes
5 Replies
dipak
Staff

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.

0 Likes

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

0 Likes

Thanks for providing the setup information. I will report the issue to the OpenGL team.

 

0 Likes

A bug ticket has been created to track this issue. I will notify you if I get any update on this.

Thanks.

0 Likes

As I have come to know, the issue has been fixed and it is no longer reproducible with the latest internal driver builds.

Thanks.

0 Likes