broken-gl/main.c
2024-10-28 12:35:01 +02:00

143 lines
3.4 KiB
C

#define GLAD_GL_IMPLEMENTATION
#include"gl.h"
#include<assert.h>
#include<GLFW/glfw3.h>
void debug_callback(GLenum src, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *msg, const void *ud) {
puts(msg);
}
int main() {
assert(glfwInit() && "Failed to initialize glfw");
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_FALSE);
glfwWindowHint(GLFW_CONTEXT_DEBUG, GLFW_TRUE);
GLFWwindow *window = glfwCreateWindow(512, 512, "OpenGL Test", NULL, NULL);
assert(window && "Failed to create window");
glfwMakeContextCurrent(window);
assert(gladLoadGL(glfwGetProcAddress) && "Failed to load GL");
glDebugMessageCallback(debug_callback, NULL);
glEnable(GL_DEBUG_OUTPUT);
#if TEST == 0
// Fixed-function lighting cannot be enabled without crashing
glEnable(GL_LIGHTING);
#elif TEST == 1
// Fixed-function lighting cannot be disabled without crashing
// even though it's already disabled by default
glDisable(GL_LIGHTING);
#elif TEST == 2 || TEST == 3 || TEST == 4
// Expected result: draw a white triangle
// (TEST == 2)
// dFdx in a shader works
// (TEST == 3)
// dFdy in a shader will cause a crash in its draw call, even if
// the return value is unused
// (TEST == 4)
// Any GLSL image function will also cause a crash in its draw call,
// even if the return value is unused. Here I try imageLoad.
int status;
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &(const char*) {
"#version 430\n"
"\n"
"const vec4 positions[3] = vec4[3] (vec4(-1, -1, 0, 1), vec4(3, -1, 0, 1), vec4(-1, 3, 0, 1));\n"
"\n"
"out vec4 v_pos;\n"
"\n"
"void main() {\n"
" v_pos = positions[gl_VertexID];\n"
" gl_Position = v_pos;\n"
"}\n"
}, (GLuint[]) {-1});
glCompileShader(vs);
glGetShaderiv(vs, GL_COMPILE_STATUS, &status);
assert(status == GL_TRUE);
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, (const char*[]) {
"#version 430\n"
"\n"
"in vec4 v_pos;\n"
"\n"
"layout(r32ui, binding = 0) uniform uimage2D imgtest;\n"
"\n"
"void main() {\n"
#if TEST == 2
" dFdx(v_pos);\n"
#elif TEST == 3
" dFdy(v_pos);\n"
#elif TEST == 4
" imageLoad(imgtest, ivec2(0, 0));\n"
#endif
" \n"
" gl_FragColor = vec4(1, 1, 1, 1);\n"
"}\n"
}, (GLuint[]) {-1});
glCompileShader(fs);
glGetShaderiv(fs, GL_COMPILE_STATUS, &status);
assert(status == GL_TRUE);
GLuint program = glCreateProgram();
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &status);
assert(status == GL_TRUE);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glUseProgram(program);
#if TEST == 4
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, 128, 128, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL);
glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI);
#endif
// Here is where each crash happens (except for TEST == 2, because
// dFdx works just fine).
glDrawArrays(GL_TRIANGLES, 0, 3);
#else
#error No such test.
#endif
glfwSwapBuffers(window);
while(!glfwWindowShouldClose(window)) {
glfwPollEvents();
}
}