3

I'm using OpenGL 3.3 on Mac OSX 11.5.2. I have 6 fragment shaders, 3 that works and 3 that crashes with EXC_BAD_ACCESS. They all use the same vertex shader. There have been many questions about this problem, but I've made sure to:

  1. Unbind my previous state.
  2. Made sure attribute arrays enabled and used.
  3. Am only using a single-thread, i.e. no concurrency.

The shaders that crash are all using one array of offsets and a kernel to do post-processing effects. If I replace texture_coordinate.st + offsets[i] with just texture_coordinate.st, it'll work just fine. As this makes the offsets array unused and optimized out, I have a suspicion that it could be due to a register allocation bug as mentioned in the comments in this question, but can't confirm.

I've also checked for other problems, such as loading them in different orders, using different compiler flags, but the crashes are consistent.

Here's a minimal, reproducible example (dependent on glad and glfw3, compiled with c++17) with one of the problematic shaders.

#include <glad/glad.h>
#include <GLFW/glfw3.h>


const char VERTEX_POST[] = R"(
#version 330 core

layout (location = 0) in vec2 position;
layout (location = 1) in vec2 in_texture_coordinate;

out vec2 texture_coordinate;

void main()
{
    gl_Position = vec4(position.x, position.y, 0.0, 1.0);
    texture_coordinate = in_texture_coordinate;
}
)";

const char FRAGMENT_POST[] = R"(
#version 330 core

in vec2 texture_coordinate;

out vec4 FragColor;

uniform sampler2D image;

const float offset = 1.0 / 300.0;

void main()
{
    vec2 offsets[9] = vec2[](
        vec2(-offset,  offset),  // top-left
        vec2( 0.0f,    offset),  // top-center
        vec2( offset,  offset),  // top-right
        vec2(-offset,  0.0f),    // center-left
        vec2( 0.0f,    0.0f),    // center-center
        vec2( offset,  0.0f),    // center-right
        vec2(-offset, -offset),  // bottom-left
        vec2( 0.0f,   -offset),  // bottom-center
        vec2( offset, -offset)   // bottom-right
    );

    float kernel[9] = float[](
        -1, -1, -1,
        -1,  9, -1,
        -1, -1, -1
    );

    vec3 sample_texture[9];
    for(int i = 0; i < 9; i++)
        sample_texture[i] = vec3(texture(image, texture_coordinate + offsets[i]));

    vec3 color = vec3(0.0);
    for (int i = 0; i < 9; i++)
        color += sample_texture[i] * kernel[i];

    FragColor = vec4(color, 1.0);
}
)";


float vertices[] = {
        // Positions         // Texture coords
        -1.0f, -1.0f,  0.0f,     0.0f,  0.0f,
         1.0f,  1.0f,  0.0f,     1.0f,  1.0f,
        -1.0f,  1.0f,  0.0f,     0.0f,  1.0f,

        -1.0f, -1.0f,  0.0f,     0.0f,  0.0f,
         1.0f, -1.0f,  0.0f,     1.0f,  0.0f,
         1.0f,  1.0f,  0.0f,     1.0f,  1.0f
};

GLuint create_shader(const char* source, GLenum type)
{
    GLuint id = glCreateShader(type);
    glShaderSource(id, 1, &source, nullptr);
    glCompileShader(id);

    int success;
    glGetShaderiv(id, GL_COMPILE_STATUS, &success);
    assert(success);

    return id;
}


int main()
{
    // ---- INIT GLFW & GLAD ----
    glfwInit();

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE,        GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT,  GLFW_TRUE);

    GLFWwindow* window = glfwCreateWindow(800, 800, "Temp", nullptr, nullptr);

    if (window == nullptr) return -1;
    glfwMakeContextCurrent(window);
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) return -1;


    // ---- CREATE QUAD ----
    GLuint quad, vbo;
    glGenVertexArrays(1, &quad);
    glGenBuffers(1, &vbo);

    glBindVertexArray(quad);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(3 * sizeof(float)));

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);


    // ---- CREATE TEXTURE ----
    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);

    char data[800 * 800 * 4] = {};
    for (char& i : data) i = 127;
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 800, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);

    glBindTexture(GL_TEXTURE_2D, 0);

    // ---- CREATE SHADER PROGRAM ----
    GLuint vertex_shader   = create_shader(VERTEX_POST,   GL_VERTEX_SHADER);
    GLuint fragment_shader = create_shader(FRAGMENT_POST, GL_FRAGMENT_SHADER);
    GLuint program = glCreateProgram();

    glAttachShader(program, vertex_shader);
    glAttachShader(program, fragment_shader);
    glLinkProgram(program);
    glValidateProgram(program);

    int success;
    glGetProgramiv(program, GL_LINK_STATUS, &success);
    assert(success);


    // ---- MAIN LOOP ----
    while (!glfwWindowShouldClose(window))
    {
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glClear(GL_COLOR_BUFFER_BIT);

        glUseProgram(program);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture);
        glUniform1i(glGetUniformLocation(program, "image"), 0);
        glBindVertexArray(quad);
        glDrawArrays(GL_TRIANGLES, 0, 6);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    return 0;
}

The example gives me a grey image when not including offsets and otherwise exhibits the crash. What could be causing this?

genpfault
  • 51,148
  • 11
  • 85
  • 139
Ted Klein Bergman
  • 9,146
  • 4
  • 29
  • 50

0 Answers0