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. 屏障是必要的,因为两个调度命令可能同时运行。

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

4

1 回答 1

1

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

技术上是的,但更恰当的理由是“因为 OpenGL ES 规范说这是必要的”。

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

屏障的意思是,如果后面有读/写操作试图访问之前写入的数据,这些读/写操作将读取/覆盖屏障之前的命令写入的数据。

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

于 2016-04-27T16:42:33.080 回答