Search code examples
c++openglcrashtimeoutdriver

glMapBufferRange freezing OpenGL driver


After generating a set of data using a compute shader and storing it in a Shader Storage buffer, I am attempting to read from that buffer to print out the data using the code:

#define INDEX_AT(x,y,z,i)   (xyzToId(Vec3i((x), (y), (z)),\
                                     Vec3i(NUM_RAYS_X,\
                                           NUM_RAYS_Y,\
                                           POINTS_ON_RAY))\
                             * 3 + (i))
PRINT_GL_ERRORS();
glBindBuffer(GL_SHADER_STORAGE_BUFFER, dPositionBuffer);
float* data_ptr = NULL;
for (int ray_i = 0; ray_i < POINTS_ON_RAY; ray_i++)
{
    for (int y = 0; y < NUM_RAYS_Y; y++)
    {
        int x = 0;
        data_ptr = NULL;
        data_ptr = (float*)glMapBufferRange(
            GL_SHADER_STORAGE_BUFFER,
            INDEX_AT(x, y, ray_i, 0) * sizeof(float),
            3 * (NUM_RAYS_X) * sizeof(float),
            GL_MAP_READ_BIT);
        if (data_ptr == NULL)
        {
            PRINT_GL_ERRORS();
            return false;
        }
        else
        {
            for (int x = 0; x < NUM_RAYS_X; x++)
            {
                std::cout << "("
                    << data_ptr[x * 3 + 0] << ","
                    << data_ptr[x * 3 + 1] << ","
                    << data_ptr[x * 3 + 2] << ") , ";
            }
        }

        glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
        PRINT_GL_ERRORS();
        std::cout << std::endl;
    }

    std::cout << "\n" << std::endl;
}

where the function xyzToId converts three dimensional coordinates into a one-dimensional index.

When I attempt to run this, however, the program crashes at the call to glMapBufferRange, giving the error message:

The NVIDIA OpenGL driver lost connection with the display driver due to exceeding the Windows Time-Out limit and is unable to continue.
The application must close.

Error code: 7
Would you like to visit
http://nvidia.custhelp.com/cgi-bin/nvidia.cfg/php/enduser/std_adp.php?p_faqid=3007
for help?

The buffer that I am mapping is not very large at all, only 768 floats, and previous calls to glMapBuffer on a different shader storage buffer (of only two floats) completed with no problems. I can't seem to find any information relevant to this error online, and everything that I have read about the speed of glMapBufferRange indicates that a buffer of this size should only take on the order of tens of milliseconds to map, not the two second timeout that the program is crashing on.

Am I missing something about how glMapBufferRange should be used?


Solution

  • It was an unrelated error. Today I learned that OpenGL sometimes buffers commands, and several actions (like mapping a buffer) forces it to finish all the commands in its queue. In this case, it was the action of actually dispatching the compute shader itself.

    Today I also learned that indexing a shader storage buffer out of bounds will cause the OpenGL driver to freeze up just like it would if it was taking to long to complete.

    All in all, this was largely a case of errors masquerading as different errors and popping up in the wrong spot.