2014-05-17 28 views
2

我有一个片段着色器,使用图像加载/存储操作在imageBuffer上执行处理。 我专门关注以下情形:单阶段(片段着色器),单通场景GLSL一致imageBuffer访问

  • 我有一个片段着色器(无多级(例如顶点然后片段着色器)的考虑,也没有多路渲染。)
  • 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, ..., ...); 
    ... 
} 

我基本上都看了规范

ARB_shader_image_load_store

特别是这个非常段落:

“使用声明的声明作为“一致”保证 商店的结果将立即可见,以着色器调用使用 类似声明的变量;调用内存屏障需要 确保专卖店是可见的其他业务“

注:我的‘连贯统一ImageBuffer的数据;’声明恰恰是一个‘类似声明的’变量我的情况是单通。 ,单级(片段着色器)

现在,我已经看过各种网站和跌跌撞撞(大多数人一样,我认为)在此线程stackoverflow.com:

How exactly is GLSL's "coherent" memory qualifier interpreted by GPU drivers for multi-pass rendering?

多SP ecifically,这一段:

“着色器甚至不能作一个假设,一个店之后发出负载 将得到刚存储在这个 很着色器中的内存(是真的。你必须在把内存屏障拉 一个关)“

我的问题是这样的:。

随着规定的一致预选赛中,在我的单着色器,单通处理的情况下,我可以肯定或不确定imageStore()对我的片段着色器的所有调用(例如当前的调用以及其他并发调用)是否立即可见?

通过阅读ARB_shader_image_load_store规范对我来说:

  • 在这个问题的答案是肯定的,
  • 我不需要任何类型的内存屏障()的,
  • 在计算器上面引用线程引用的句子可能确实是误导和错误的。

感谢您的见解。

+0

你是在一些重大的头痛,如果你不要在此着色器使用一个内存屏障,既*** ***负荷,稍后存储。如果你的抽牌只能得到一个单独的片段,你可能会安全地把它关闭。但对于任何更大的场景,您需要同步片段着色器调用之间的同步,否则其他片段可能会在另一个存储器之前加载。片段着色器可以按照驱动程序认为会产生理智结果的任何顺序进行安排,imageLoad/Store在考虑因素时被有效忽略,因为它假定您知道自己在做什么。 –

+0

@ AndonM.Coleman你没有回答我的问题。这个问题是:**我可以肯定或不确定imageStore()对于我的片段着色器的所有调用(例如当前的调用以及其他并发调用)都将立即可见吗?**换句话说,是在单一着色器阶段加载/存储连贯且类似声明的变量**保证**将按顺序执行?规范似乎说是的,一些论坛成员说不。您只是提及并发编程的一般问题。我知道我无法控制着色器调用的调度。 – fred54

+0

这是你的问题,然后没有。 –

回答

0

使用内存屏障。

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

换句话说,如果你的着色器随时修改单个位置只有一次,然后其确定,但如果将其转发邻居值之后,应用一些计算,那么你需要的内存屏障。

0

有了规定,在我的单着色器,单通处理场景的连贯预选赛,可我是或否确保imageStore()的将立即到我的片段着色器的所有调用可见的(例如, 。当前的调用以及其他并发调用)?

如果每个片段着色器写入图像在不同的地点,每个片段着色器只读取它写的位置,那么你甚至不需要coherent。但是,如果片段着色器实例想要读取其他片段着色器实例写入的数据,那么您就是SOL。有没有你可以为那个做。

如果它是一个计算着色器,你可以发出barrier呼叫到工作组内的同步操作。这将确保您想要阅读的写作发生(您仍然需要拨打memoryBarrier以使其可见)。但是,这只能确保在此工作组内的实例发生了写入。来自其他实例的写入仍未定义。

,更具体地说,本款:

顺便说一句,那款是错误的。非常非常错误。太糟糕了,是谁写的那款将永远不会被识别的人;)