0
votes

Recently I got a segfault when reading atomic counters via glMapBuffer. Here is the code:

GLuint atomicCounter[2];

inline void getAtomicCounters()
{
    glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, ATOMIC_COUNTER_INDEX, acBuffer);
    CHECK_FOR_GL_ERRORS();
    static GLuint* data = (GLuint*)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_READ_ONLY);
    CHECK_FOR_GL_ERRORS();
    atomicCounter[0] = data[0];
    atomicCounter[1] = data[1];
    glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
    CHECK_FOR_GL_ERRORS();
}

The problem seems to be that data is a static pointer. When I remove the static keyword, everything works perfectly. I know that I don't need a static pointer, it was just a test and I'm quite surprised that it won't work with a static pointer. Does anybody know why a segfault occurs at "atomicCounter[0] = data[0];"?

1

1 Answers

1
votes

This is not at all surprising.

Do you understand how a variable declared with the static qualifier in the body of a function works in C++? It will be initialized with that value the first time the function (getAtomicCounters (...)) runs, but each subsequent execution will skip-over the initialization:

 static GLuint* data =
   (GLuint*)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_READ_ONLY);
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //This is only evaluated the first time you call this function!

So every subsequent call is going to use the value of data you initialized the first time. The elephant in the room is that the value of data became invalid when you made this call: glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);

You can fix this simply by assigning data the return value of glMapBuffer (...) on a separate line from the one where you declare the variable. Then it will always execute glMapBuffer (...) when you call this function.

However, to be completely honest, I can see no reason why you would need or even want static storage for your data pointer.