【问题标题】:Do I need a memory barrier between initializing an SSBO storage and filling it?在初始化 SSBO 存储和填充它之间是否需要内存屏障?
【发布时间】:2019-06-10 06:44:35
【问题描述】:

我的代码如下所示:

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);


是否需要取消注释 glBufferData 和 glBufferSubData 之间的 glMemoryBarrier 调用?如果SSBO的东西不连贯,难道glBufferSubData会在glBufferData之前通过,从而崩溃吗?

我的应用程序正在运行,但我不确定它是否只是侥幸。

【问题讨论】:

    标签: opengl opengl-4 shader-storage-buffer


    【解决方案1】:

    不需要两次调用glMemoryBarrier。几乎所有的OpenGL函数(包括glBufferDataglBufferSubData)都遵循传统的OpenGL内存模型,自动保证同步。

    仅在少数情况下需要手动同步。例如,当着色器写入 SSBO 以保证所有进一步的操作都会看到这个写入:

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

    【讨论】:

    • 刚刚遇到这个答案。在这种情况下使用 GL_BUFFER_UPDATE_BARRIER_BIT 不是正确的障碍吗?因为障碍应该基于数据的使用方式,而不是数据的写入方式。
    猜你喜欢
    • 2011-10-12
    • 2016-03-01
    • 1970-01-01
    • 2012-09-08
    • 2017-01-05
    • 2014-01-20
    • 2018-08-24
    • 2014-09-01
    • 2011-03-30
    相关资源
    最近更新 更多