我有一个片段着色器,它使用图像加载/存储操作对imageBuffer执行处理。 我完全关注以下情况:
为了清楚地说明问题,我的方案如下:
// 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, ..., ...);
...
}
我基本上看了一下规范
尤其是这一段:
"使用声明为"相关的变量"保证结果 使用的着色器调用将立即显示商店 类似声明的变量;调用MemoryBarrier是必需的 确保商店对其他操作可见。"
注意:我的"连贯统一的imageBuffer数据;"声明恰恰是一个类似声明的声明"变量。我的场景是单遍,单阶段(片段着色器)。
现在,我已经在stackoverflow.com上的这个帖子中查看了各种网站并且发现了(就像我认为的大多数人一样):
更具体地说,这一段:
"您的着色器甚至无法假设发出负载 在商店将获得刚存储在此中的内存之后 非常着色(是的。你必须把memoryBarrier放进去 那一个)。"
我的问题如下:
在我的单着色器,单遍处理场景中指定了相干限定符,我可以肯定或不确定imageStore()将立即对我的片段着色器的所有调用可见(例如。当前调用以及其他并发调用)?
通过阅读ARB_shader_image_load_store规范,在我看来:
感谢您的见解。
答案 0 :(得分:0)
使用该记忆障碍。
一方面,GPU可以优化并获取整个内存块以读取FROM,并具有单独的内存来写入TO。
换句话说,如果您的着色器始终修改SINGLE位置JUST ONCE然后它的确定,但是如果它在应用某些计算后继续对邻居值进行,那么您需要内存屏障。
答案 1 :(得分:0)
在我的单着色器,单遍处理场景中指定了相干限定符,我可以肯定或不确定imageStore()将立即对我的片段着色器的所有调用可见(例如。当前调用以及其他并发调用)?
如果每个片段着色器写入图像中的不同位置,并且每个片段着色器仅读取它所写的位置,那么您甚至不需要coherent
。但是,如果片段着色器实例想要读取由其他片段着色器实例写入的数据,那么您就是SOL。你可以为那个人做 。
如果它是计算着色器,您可以发出barrier
调用来同步工作组中的操作。这将确保您想要读取的写入发生(您仍然需要memoryBarrier
调用才能使它们可见)。但这只会确保来自此工作组中的实例的写入已经发生。来自其他实例的写入仍未定义。
顺便说一句,这段话错了。非常非常错误。太糟糕了,编写该段的人永远不会被识别出来;)更具体地说,这一段: