I've got code that looks like this:
uint ssboId;
glGenBuffers(1, &ssboId);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssboId);
//initialize
glBufferData(GL_SHADER_STORAGE_BUFFER, size, 0, GL_STATIC_DRAW);
// memory barrier here?
// glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
//start writes
glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset1, sourceSize1, data1);
glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset2, sourceSize2, data2);
...
// Ensure changes are applied before shader grabs it.
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
Do I need to uncomment the call to glMemoryBarrier that is between glBufferData and glBufferSubData? If SSBO stuff is incoherent, couldn't it be possible that glBufferSubData goes through before glBufferData, and thus crashes?
My application is working, but I'm not sure if it's just working by fluke.
Both calls to glMemoryBarrier
are not necessary. Almost all OpenGL functions (including glBufferData
and glBufferSubData
) follow the traditional OpenGL memory model where synchronization is automatically guaranteed.
Manual synchronization is only needed in a few cases. For example, when a shader writes to an SSBO to guarantee that all further operations will see this writes:
//Init SSBO
glBufferData(...);
glBufferSubData(...);
//No sync needed here
glDispatchCompute(...); //Shader which writes to the SSBO
//Sync here to make writes visible
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
//Read back SSBO memory
glMapBuffer(...);
...