I get OpenGL error 1282 when I try to run fragment shader with a function that returns struct with uint array initialized from function argument and integer literal.
When I run my program with the fragment shader below everything works and the result I get is white screen
#version 460
uniform uint param;
out vec4 color;
struct A {
uint content[2];
};
A createA1(const uint data) { return A( uint[2](data, data) ); }
A createA2(const uint data) { return A( uint[2](data, 0 ) ); }
A createA3(const uint data) { return A( uint[2](data, 0u ) ); }
A createA4(const uint data) { return A( uint[2](0 , 0 ) ); }
void main() {
const uint o = param;
const A a0 = A( uint[2](o, 0) );
const A a1 = createA1(o);
//const A a2 = createA2(o);
const A a3 = createA3(o);
const A a4 = createA4(o);
color = vec4(1);
}
But when I uncomment the line with a2 I get OpenGL error 1282.
I tried glslangValidator on the code and it printed no errors. What is also strange for me is that a4 that also uses the same literal zero does not produce any errors. And it seems to matter that o is initialized from the uniform because if I replace the uniform with some literal value the error goes away.
If it is actually a bug (which it seems to me) and not some glsl peculiarity, the program I tested the shader in was run on Windows with Nvidia graphics card.
UPD: So I didn't clarify the problem enough: the shader is compiled without errors but the program doesn't link and I get 1282. I called glCreateProgram, for both fragment and vertex shaders I called glCreateShader, glShaderSource, glCompileShader, glGetShaderiv with GL_COMPILE_STATUS, printed the param value (for both shaders the result was 1), glAttachShader and glLinkProgram afterwards with no other calls in between.
When I checked GL_LINK_STATUS though the result was 0.
When I printed information log for the program object it said
Fragment info
-------------
0(11) : error C7011: implicit cast from "int" to "uint"
which was expected because a3 was the solution to the problem. But I don't understand two things:
- why a0 works and a2 doesn't since the same implicit cast is present in both of them, and why the error disappears if I assign some integer constant instead of uniform value to o.
- why the shader status after compilation is 1 while program object says there is an error in the shader.
And for completeness here is the entire program:
#include <GLEW/glew.h>
#include <GLFW/glfw3.h>
#include<iostream>
void check_(int line) {
GLenum error;
while ((error = glGetError()) != GL_NO_ERROR) {
std::cout << "Error on line " << line << ": " << error << std::endl;
}
}
#define check() check_(__LINE__)
int main() {
if (!glfwInit()) return -1;
GLFWwindow *window = glfwCreateWindow(50, 50, "", NULL, NULL);
if (!window) return (glfwTerminate(), -1);
glfwMakeContextCurrent(window);
GLenum err = glewInit();
if (err != GLEW_OK) {
std::cout << "GLEW error: %s\n" << glewGetErrorString(err) << '\n';
glfwTerminate();
return -1;
}
GLuint prog = glCreateProgram();
GLuint shader_vert = glCreateShader(GL_VERTEX_SHADER);
GLuint shader_frag = glCreateShader(GL_FRAGMENT_SHADER);
char const *source_vert = R"(#version 460
void main() {
const vec2 verts[] = {vec2(-1),vec2(1, -1),vec2(-1, 1),vec2(1)};
gl_Position = vec4( verts[gl_VertexID], 0, 1 );
}
)";
char const *source_frag = R"(#version 460
uniform uint param;
out vec4 color;
struct A {
uint content[2];
};
A createA1(const uint data) { return A( uint[2](data, data) ); }
A createA2(const uint data) { return A( uint[2](data, 0 ) ); }
A createA3(const uint data) { return A( uint[2](data, 0u ) ); }
A createA4(const uint data) { return A( uint[2](0 , 0 ) ); }
void main() {
const uint o = param;
const A a0 = A( uint[2](o, 0) );
const A a1 = createA1(o);
const A a2 = createA2(o);
const A a3 = createA3(o);
const A a4 = createA4(o);
color = vec4(1);
}
)";
glShaderSource(shader_vert, 1, &source_vert, nullptr);
glCompileShader(shader_vert);
glShaderSource(shader_frag, 1, &source_frag, nullptr);
glCompileShader(shader_frag);
GLint result_vert;
glGetShaderiv(shader_vert, GL_COMPILE_STATUS, &result_vert);
std::cout << "result_vert: " << result_vert << '\n';
GLint result_frag;
glGetShaderiv(shader_frag, GL_COMPILE_STATUS, &result_frag);
std::cout << "result_frag: " << result_frag << '\n';
//check(); //additional checks were ommited after the problem was found
glAttachShader(prog, shader_vert);
glAttachShader(prog, shader_frag);
glLinkProgram(prog);
GLint progStatus;
glGetProgramiv(prog, GL_LINK_STATUS, &progStatus);
std::cout << "Program status: " << progStatus << '\n';
{
int length;
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &length);
GLchar *msg = new GLchar[length + 1];
msg[0] = '\0';
glGetProgramInfoLog(prog, length, &length, msg);
std::cout << "Program error:\n" << msg;
delete[] msg;
}
glValidateProgram(prog);
GLint progValidate;
glGetProgramiv(prog, GL_VALIDATE_STATUS, &progValidate);
std::cout << "Program valid: " << progValidate << '\n';
//check();
glUseProgram(prog);
check();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
return 0;
}