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

2 Compute shaders, 1 glMemoryBarrier = OK?

设置(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. 屏障是必要的,因为两者都有可能 调度命令可以同时运行。

  2. barrier的意思是没有imageStore会被执行 第二次分派直到第一次调用所有 imageStore 派送完毕

The barrier is necessary because it is possible that both dispatch commands could be running at the same time.

从技术上讲是的,但更恰当的原因是 "because the OpenGL ES specification says it is necessary."

The barrier means that no imageStore will be executed in the second dispatch until ALL imageStore calls in the first dispatch are finished.

屏障的意思是,如果后面有 read/write 操作试图访问先前写入的数据,那些 read/write 操作将 read/overwrite 屏障之前的命令写入的数据.

如何实施是一个实施细节。通过以某种方式使用某种排序操作,可能存在可以并发执行此类命令的硬件。诚然,大多数实现都会按照您所说的去做:等到先前的命令执行完毕并清除缓存,然后再执行后续命令。