GLSL连贯imageBuffer访问在单阶段(片段着色器),单通道场景



我有一个片段着色器,使用图像加载/存储操作在imageBuffer上执行处理。我只关心以下情况:

  • 我有一个单一的片段着色器(没有多级(例如。顶点然后片段着色器)考虑,并且没有多通道渲染)
  • imageBuffer变量被声明为一致的。只对相干imageBuffers感兴趣。

为了让事情更清楚,我的场景是这样的:

// Source code of my sole and unique fragment shader:
coherent layout(1x32) uniform uimageBuffer data;
void main()
{
  ...
  various calls to imageLoad(data, ..., ...);
  ...
  various calls to imageStore(data, ..., ...);
  ...
}

我主要看了规范

ARB_shader_image_load_store

尤其是这一段:

"使用声明为"coherent"的变量保证商店将立即可见的着色器调用使用similarly-declared变量;调用MemoryBarrier是必需的确保存储对其他操作可见。"

注意:我的"coherent uniform imageBuffer data;"声明是一个"类似声明"的变量。我的场景是单通道,单阶段(片段着色器)。

现在,我已经看了各种网站和绊倒(像大多数人一样,我认为)在stackoverflow.com上的这个线程:

GLSL's "是如何"连贯"的?内存限定符解释的GPU驱动程序的多通道渲染?

,更具体地说,这一段:

"你的着色器甚至不能假设发出一个负载之后,store会获取刚刚存储在这里的内存非常着色(是的,真的。你得放个记忆屏障进去才能拉把那个关掉)。"

我的问题是:

与连贯限定符指定,在我的单着色器,单通道处理场景,我可以是或否确定imageStore()的将立即可见的所有调用我的片段着色器(例如。(当前调用以及其他并发调用)?

通过阅读ARB_shader_image_load_store规范,在我看来:

    这个问题的答案是肯定的,我不需要任何类型的memoryBarrier(),
  • 上面引用的stackoverflow线程中的引用句可能确实是误导和错误的。

使用内存屏障。

一方面,GPU可以优化和获取整个内存块来读取,并有单独的内存来写入。

换句话说,如果你的着色器总是修改单个位置只有一次,那么它是可以的,但如果它依赖于邻居值后,一些计算应用,那么你需要内存屏障。

与连贯限定符指定,在我的单着色器,单通道处理场景,我可以是或否确定imageStore()的将立即可见的所有调用我的片段着色器(例如。(当前调用以及其他并发调用)?

如果每个片段着色器写入图像中的单独位置,并且每个片段着色器仅读取它写入的位置,那么您甚至不需要coherent。然而,如果一个片段着色器实例想要读取其他片段着色器实例写的数据,你就错了。没有你可以为它做什么。

如果它是一个计算着色器,你可以发出barrier调用来同步工作组内的操作。这将确保您想要读取的写入发生(您仍然需要memoryBarrier调用来使它们可见)。但是,这只能确保来自该工作组中的实例的写入已经发生。来自其他实例的写入仍然未定义。

,更具体地说,这一段:

顺便说一句,那一段是错的。大错特错。可惜写这段话的人永远不会被认出来;)

相关内容

  • 没有找到相关文章