片段着色器使用两个原子计数器。它可能会或可能不会增加第一个,可能会或可能不会增加第二个(但绝不会同时增加)。然而,在如此修改计数器之前,它们的当前值总是被读取,并且——如果后来修改了计数器——那些先前读取的用于某些自定义逻辑的值。所有这些都发生在一个(很可能是不可滚动的)循环中。
设想一个大致如下的流程:
- 在一些小的不可滚动循环中,比如 FOR 0-20 (compile-time resolvable const) ...
- 获取 AC1 和 AC2 的计数器值
- 检查一些值:
- 如果 x:在索引 AC1 处设置 uimage1D_A 中的纹素,增加 AC1
- else: 设置 uimage1D_B 中的纹理像素 (imgwidth-AC2-1),增加 AC2
问题:着色器查询当前的计数器值——它总是得到“最新”的值吗?我是否在这里失去了片段着色器的大规模并行性(仅就当前和未来的 GPU 和驱动程序而言)?
至于分支(如果 x)——我将另一个 ( readonly restrict uniform
)uimage1D
中的纹素与 ( uniform
)进行比较uint
。所以一个操作数肯定是一个统一的标量,但另一个是一个imageLoad().x
虽然图像是统一的——这种分支是否仍然“完全并行化”?您可以看到两个分支都恰好是两个几乎相同的指令。假设一个“完美优化”的 GLSL 编译器,这种分支是否可能会导致停顿?