【问题标题】:Do I understand GLSL's memoryBarrier correctly?我是否正确理解了 GLSL 的 memoryBarrier?
【发布时间】:2019-05-10 11:15:02
【问题描述】:

引用here:

当此函数返回时,使用调用之前执行的一致变量执行的任何内存存储的结果将对来自其他着色器调用的相同地址的任何未来一致内存访问可见。

好的,假设我想在片段着色器中执行此操作:

void main() {
    ivec2 fc = ivec2(gl_FragCoord.xy);
    vec4 f = imageLoad(image, fc);
    f *= 2;
    imageStore(image, fc, f);
}

我相信这不需要 imageLoad 和 imageStore 之间的 memoryBarrier()。以下是:

out vec4 OUT;

void main() {
    ivec2 fc = ivec2(gl_FragCoord.xy);
    imageStore(image, fc, vec4(5));
    vec4 f = imageLoad(image, fc);
    OUT = f * 2;
}

我是否正确理解了 GLSL 的 memoryBarrier?

【问题讨论】:

  • "我相信这不需要 imageLoad 和 imageStore 之间的 memoryBarrier()。" 这里的情况是什么?是否涉及重叠调用?多个调用能否获得相同的fc 值?
  • @NicolBolas:您能为我定义“重叠调用”吗?另外,我编辑了问题以包含fc 的定义。

标签: opengl synchronization glsl


【解决方案1】:

您在此处发布的场景依赖于未说明和未知的信息,您可能会假设有关渲染过程的性质的事情,而您在假设它们无关紧要的情况下没有说明这些信息。尽管他们非常喜欢,正如我们将在此处看到的那样。

那么,让我们从这里开始吧。如果我们假设您发出渲染调用,使得 没有两个片段 将具有相同的 gl_FragCoord 值(因此,没有两个着色器调用将尝试写入同一位置),那么这两种情况都是明确定义的,不需要内存屏障。对真的;来自 GLSL 规范:

在单个着色器调用中,该调用进行的写入的可见性和顺序是明确定义的。

请看,着色器内的memoryBarrier 函数和coherent 限定符是关于读取由单独 着色器调用写入的值。读取您的调用写入的值不是问题。因此,无论哪种情况,您都不需要coherent

因此需要初始假设。因为,如果该假设消失,如果片段之间存在任何重叠,以至于两个调用将尝试写入同一位置,那么这两种情况都是未定义memoryBarrier 不会改变这一点。为什么?

因为来自同一阶段的两个调用之间没有顺序。 GLSL 不保证同一阶段中的任何两个调用何时执行。它们可能同时执行,或者来自较晚原语的片段可能在来自早期原语的片段之前执行,尽管它们是无序的,或任何类型的。

memoryBarrier 和类似的函数只在适用于shader invocations have some kind of order dependency between them 的情况。这可能是计算或曲面细分控制着色器发出barrier 调用,或者它可能是一个顶点着色器,它编写了与该顶点关联的图元的片段着色器读取的数据,或者在调用之间有明确顺序的其他情况.

同一渲染命令(或该母材的不同渲染命令)中的两个片段着色器执行它们之间没有顺序。所以障碍不会有帮助。

您不希望多个片段着色器调用尝试写入同一内​​存。除非它们在不同的渲染命令中,并且它们之间有适当的glMemoryBarrier 调用。

【讨论】:

    猜你喜欢
    • 2016-05-03
    • 2020-09-30
    • 1970-01-01
    • 1970-01-01
    • 2011-12-07
    • 2014-10-17
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    相关资源
    最近更新 更多