Looks like a bug.
In my application I use two different threads (and two shared contexts) to upload and render data.
The app sometimes crashes (it seems when the workload is higher than average) when the main thread renders (glMultiDrawArraysIndirect), using buffers (the problem is with GL_DRAW_INDIRECT_BUFFER, I suppose) uploaded in another thread.
(Exception thrown at 0x000001CD7121F302 in viewer.exe: 0xC0000005: Access violation reading location 0x0000000000000100)
if I use debug mode there are no GL errors.
some simplified pseudocode:
Working thread:
{
…
uploadContext->makeCurrent();
glCreateBuffers(1, &tile.geometryBuf);
glNamedBufferStorage(tile.geometryBuf, geometryBuffer.size(), geometryBuffer.constData(), 0);
glCreateBuffers(1, &tile.indirectBuffer);
glNamedBufferStorage(tile.indirectBuffer, indirectBuffer.size(), indirectBuffer.constData(), 0);
glCreateBuffers(1, &tile.settingsBuffer);//);
glNamedBufferStorage(tile.settingsBuffer, settingsBuffer.size(), settingsBuffer.constData(), 0);
//need this for syncronization between threads
tile.sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
emit tileReady(tile); //send a signal to the main thread
}
Main thread:
{
…
renderingContext->makeCurrent();
///sync
GLenum waitReturn = glClientWaitSync(tile.sync, 0, 0);
if (waitReturn != GL_ALREADY_SIGNALED && waitReturn != GL_CONDITION_SATISFIED)
return;
glDeleteSync(tile.sync);
//binding should validate the buffer in this context according to specs (but seems that it doesn’t)
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, tile.indirectBuffer);
//vao is defined during initialization
//now only change arrayVertexBuffer
glVertexArrayVertexBuffer(vao, 0, tile.geometryBuf, 0, 2 * sizeof(float));
glBindVertexArray(vao);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, tile.settingsBuffer);
glMultiDrawArraysIndirect(GL_TRIANGLES, 0, tile.counts, 0);
…
}
So it crashes sometimes if like this.
It does NOT crash if:
- I use another GPU (Nvidia Geforce 980 Titan X)
or - I change glFlush() to glFinish() in the upload thread
or - I comment glMultiDrawArraysIndirect
or - Before rendering with GL_DRAW_INDIRECT_BUFFER i insert these lines of code:
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, tile.indirectBuffer);
qint64 sz;
glGetBufferParameteri64v(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_SIZE, &sz);
(and it takes about 0.4 ms)
it seems like there’s no problem with SSBO and VertexArrayBuffer.
Config:
Windows 10 Pro, 64 bit
GeForce GTX 1060
driver version 416.81