2计算着色器,1 glMemoryBarrier = OK?

时间:2016-04-27 13:11:01

标签: opengl-es glsl compute-shader opengl-es-3.1

设置(Android设备上的OpenGL ES 3.1):

Compute_shader_clear(在PROGRAM_A中):

layout (local_size_x = 8, local_size_y = 8) in;
layout(rgba32f, binding=0) writeonly uniform mediump image2D write00;
void main() {
 ...
 imageStore(write00, pixel, vec4(0.0));
}

Compute_shader_main(在PROGRAM_B中):

layout (local_size_x = 8, local_size_y = 8) in;
layout(rgba32f, binding=0) writeonly uniform mediump image2D write00;
void main() {
 ...
 imageStore(write00, pixel, final_color);
}

两个计算着色器都指向相同的纹理 (绑定零=图像单元零)

应用程序调用代码:

glUseProgram(PROGRAM_A);
glDispatchCompute(90, 160, 1);
glUseProgram(PROGRAM_B);
GLES31.glMemoryBarrier(GLES31.GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glDispatchCompute(3, 160, 1);
...

此设置似乎没有问题,但这种解释是否正确? :

  1. 障碍是必要的,因为两者都有可能 dispatch命令可以同时运行。

  2. 屏障意味着不会执行imageStore 第二次调度直到所有imageStore调用第一次 派遣已经完成。

1 个答案:

答案 0 :(得分:1)

  

屏障是必要的,因为两个调度命令可能同时运行。

技术上是的,但更合适的原因是"因为OpenGL ES规范说它是必要的。"

  

屏障意味着在第一次调度中的所有imageStore调用完成之前,第二次调度中不会执行imageStore。

屏障意味着,如果稍后有读取/写入操作尝试访问先前写入的数据,那些读/写操作将读取/覆盖屏障之前由命令写入的数据。

如何实现这是一个实现细节。通过某种方式使用某种排序操作,可能存在可以同时执行这些命令的硬件。当然,大多数实现都会按照你的说法做好事情:等到执行先前的命令并在执行后续命令之前清除缓存。