2016-09-08 45 views
6

我想知道memoryBarrierShared的用处。glsl memoryBarrierShared用处

事实上,当我在寻找屏障功能的文档:我读:

对于计算着色器屏障的任何给定的静态实例,一个工作组内的所有调用必须进入它之前的任何有允许继续超越它。这可以确保在一个给定的屏障静态实例之前,通过一次调用写入的值可以在调用相同的静态屏障实例后由其他调用安全地读取。由于调用可能会在这些屏障调用之间以未定义的顺序执行,因此在许多情况下,每个顶点或每个补丁输出变量或任何共享变量的值都将不确定。

所以,如果我们可以安全地使用屏障后读取值,为什么我们看到在一些代码

memoryBarrierShared(); 
barrier(); 

或有毛病像

barrier(); 
memoryBarrierShared(); 

所以,我的问题是:什么是memoryBarrier {Shared,...}的目的,如果使用障碍足够了吗?

对于memoryBarrierBuffer /图片我可以理解,如果我们使用多级,但共享,我没有任何想法...

回答

7

这实际上是在争目前。

GLSL 4.50清楚地表明显式记忆障碍是不必要的。计算着色器中的barrier包含所有内存障碍。

然而,GLSL ES 3.20使它同样十分清楚,barrier包括任何种类的存储器障碍:

对于计算着色器,一个屏障仅影响控制流和由本身不确实同步内存访问。特别是,它不能确保在给定静态实例barrier()之前,通过一个调用写入的值可以在调用相同静态实例barrier()之后由其他调用安全地读取。要实现这一点,需要同时使用 barrier()和内存屏障。

值得注意的是,离线glslang编译器将总是使用GLSL ES措辞。因此,如果您要生成SPIR-V来支持Vulkan,那么您必须在此处遵循ES的规则。那么,until they get that fixed, one way or another

这就是说,ES的措辞使得更多的意义,作为全部内存障碍一切是相当昂贵的。特别是如果你想要做的就是同步对共享变量的访问。

我会建议使用barrier调用旁边的内存屏障。这样,即使在某些实现中它可能稍微慢一点,你的着色器也是正确的。但是,如果您打算使用内存屏障以及barrier调用,则内存屏障必须先到达。同步执行后执行内存屏障不正确。