Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 2 of 2

Thread: Compute shader related crash on AMD HD6000 series cards with basic example

  1. #1
    Junior Member Newbie
    Join Date
    Dec 2011
    Posts
    11

    Compute shader related crash on AMD HD6000 series cards with basic example

    My program crashes on AMD HD6000 series cards, both laptop and desktop, tested on Windows 10. The program is pretty simple:

    1. Write to an image from a compute shader
    2. Draw a triangle to a framebuffer object
    3. Draw a triangle to the default framebuffer

    All three passes are independent, meaning the results from one pass are not used by the other. And if any of the three passes are disabled, the program works.
    When run, there are no GL warnings or errors. On frame 1 it draws the white triangle from pass 3 and stutters, then gets to frame 2, then frame 3, then hangs forever.
    The code works on every NVIDIA card I've tried (GTX 460, GTX 1080, GTX 780TI) and also works on AMD HD7000 series cards. The computers that crash both say they have OpenGL 4.5 support. Unfortunately, they are not my computers so I can't go crazy installing development software on them. I'm running RenderDoc on the working computers and everything seems correct.

    The code is only 140 lines, and over half is boilerplate (syntax highlighted version here: https://hastebin.com/kakoranuta.cpp)

    Code :
    #include <glad/glad.c>
    #include <GLFW/glfw3.h>
    #include <stdio.h>
    #include <assert.h>
     
    static void glfwErrorCallback(int error, const char* description)
    {
        printf("GLFW: %s\n", description);
    }
    static void glErrorCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
    {
        printf("GL: %s\n", message);
    }
     
    struct ShaderData { GLenum type; const char* source; };
    GLuint BuildProgram(const ShaderData* datas, const uint32_t count)
    {
        GLuint program = glCreateProgram();
        for (uint32_t i = 0; i < count; i++)
        {
            GLuint shader = glCreateShader(datas[i].type);
            glShaderSource(shader, 1, &datas[i].source, NULL);
            glCompileShader(shader); 
     
            GLint compileStatus;
            glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
            if (compileStatus == GL_FALSE)
            {
                const uint32_t kInfoLogLengthMax = 1024;
                char infoLog[kInfoLogLengthMax];
                glGetShaderInfoLog(shader, kInfoLogLengthMax, 0, infoLog);
                printf("GL: Shader compilation failure - %s\n", infoLog);
                assert(false);
            }
     
            glAttachShader(program, shader);
        }
     
        glLinkProgram(program);
     
        GLint linkStatus;
        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
        if (linkStatus == GL_FALSE)
        {
            const uint32_t kInfoLogLengthMax = 1024;
            char infoLog[kInfoLogLengthMax];
            glGetProgramInfoLog(program, kInfoLogLengthMax, 0, infoLog);
            printf("GL: Program compilation failure - %s\n", infoLog);
            assert(false);
        }
     
        return program;
    }
     
    int main(void)
    {
        GLFWwindow* window;
        glfwSetErrorCallback(glfwErrorCallback);
        glfwInit();
        const uint32_t windowWidth = 640;
        const uint32_t windowHeight = 480;
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
        window = glfwCreateWindow(windowWidth, windowHeight, "HelloGL", NULL, NULL);
        glfwMakeContextCurrent(window);
        gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
        glfwSwapInterval(1);
     
        // Other state
        glEnable(GL_DEBUG_OUTPUT);
        glDebugMessageCallback(glErrorCallback, NULL);
        glCullFace(GL_BACK);
        glFrontFace(GL_CW);
     
        // Compute
        static const char* comp =
            "#version 430\n"
            "layout(local_size_x = 1, local_size_y = 1) in;\n"
            "layout(location = 0, rgba8) writeonly uniform image2D o_color;\n"
            "void main(){imageStore(o_color, ivec2(gl_GlobalInvocationID), vec4(1.0));}\n";
        ShaderData compShaders[] = { {GL_COMPUTE_SHADER, comp} };
        GLuint compProgram = BuildProgram(compShaders, 1);
        GLuint compRenderTarget; glGenTextures(1, &compRenderTarget);
        glBindTexture(GL_TEXTURE_2D, compRenderTarget);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, windowWidth, windowHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
        glBindImageTexture(0, compRenderTarget, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
     
        // Vert/Frag
        static const char* vert =
            "#version 330\n"
            "void main(){gl_Position = vec4(vec2((gl_VertexID >> 1) & 1, gl_VertexID & 1), 0.0, 1.0);}\n";
        static const char* frag =
            "#version 330\n"
            "layout(location = 0) out vec4 o_color;\n"
            "void main(){o_color = vec4(1.0);}\n";
        ShaderData triShaders[] = { {GL_VERTEX_SHADER, vert}, {GL_FRAGMENT_SHADER, frag} };
        GLuint triProgram = BuildProgram(triShaders, 2);
        GLuint triVao; glGenVertexArrays(1, &triVao);
        GLuint triFbo; glGenFramebuffers(1, &triFbo);
        GLuint triRenderTarget; glGenTextures(1, &triRenderTarget);
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, triFbo);
        glBindTexture(GL_TEXTURE_2D, triRenderTarget);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, windowWidth, windowHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, triRenderTarget, 0);
        assert(glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
     
        // Comment out any of the lines ending with // HERE to make the program not crash on HD6000 series cards
        uint32_t frameCount = 0;
        while (!glfwWindowShouldClose(window))
        {
            // Comp
            glUseProgram(compProgram);
            glDispatchCompute(windowWidth, windowHeight, 1); // HERE
     
            // Tri
            glViewport(0, 0, windowWidth, windowHeight);
            glUseProgram(triProgram);
            glBindVertexArray(triVao);
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, triFbo);
            glDrawArrays(GL_TRIANGLES, 0, 3); // HERE
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
            glDrawArrays(GL_TRIANGLES, 0, 3); // HERE
     
            glfwSwapBuffers(window);
            glfwPollEvents();
     
            assert(glGetError() == GL_NO_ERROR);
            printf("%d\n", frameCount++);
        }
     
        glfwDestroyWindow(window);
        glfwTerminate();
        return 0;
    }
    Last edited by Petwoip; 08-01-2018 at 10:24 AM. Reason: added win10

  2. #2
    Junior Member Newbie
    Join Date
    Dec 2011
    Posts
    11
    OK I had to put a glClear(GL_COLOR_BUFFER_BIT); after glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

    Seems like a driver bug... but glad there's a workaround

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •