openglopengl-4shader-storage-buffer

Do I need a memory barrier between initializing an SSBO storage and filling it?


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.


Solution

  • 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(...);
    ...