首页 > 解决方案 > 在初始化 SSBO 存储和填充它之间是否需要内存屏障?

问题描述

我有如下代码:

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 之前通过,从而崩溃吗?

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

标签: openglopengl-4shader-storage-buffer

解决方案


两个调用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(...);
...

推荐阅读