opengl - 在初始化 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 之前通过,从而崩溃吗?
我的应用程序正在运行,但我不确定它是否只是侥幸。
解决方案
两个调用glMemoryBarrier
都不是必需的。几乎所有 OpenGL 函数(包括glBufferData
和glBufferSubData
)都遵循自动保证同步的传统 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(...);
...
推荐阅读
- c++ - 对具有重复项的列表中的索引进行排序
- c - 我可以输入 int 或终止 scanf 函数吗?
- javascript - 如何同步 Highchart Sunburst 行为
- java - 在 ViewPager 中获取图像文件的名称并将其显示在 TextView 中
- javascript - 在 HTML 页面中使用 javascript 函数
- ios - 使用 swift 4 在 VIPER 中进行 dataTaskWithURL 崩溃单元测试
- zipkin - Spring cloud sleuth 如何仅允许某些 URL 模式将跟踪导出到 zipkin
- r - ggplot 中不同几何图形的 scale_color_manual()
- ffmpeg - 什么 ffmpeg 命令会产生类似于 Instagram 压缩的视频压缩?
- c# - C#:根据条件从集合中返回元素的通用函数