循环内计算着色器统一更新

Compute Shader uniform updates within a loop

我有一个 OpenGL 计算着色器,它在循环的每次迭代中分派工作组。有一个唯一的统一值,表示需要传递的 ID。每个 ID 对于从每个调度调用生成的着色器调用集都是唯一的。

是否可以通过在循环中使用指向 UBO 的映射指针重新分配一个值来保持每个着色器调用集中的值唯一?从测试来看,似乎只有一个可能的值可以传递给单个帧内的所有着色器调用集。如有错误请指正

是否有其他方法可以在不牺牲性能的情况下将唯一值传递给整个工作组集?如果不是,如果不关心性能,有什么方法可以解决这个问题?

有关更多上下文,我正在尝试使用 OpenGL 而不是 DirectX 来实现类似于下面 link 中的循环的内容:

https://github.com/GPUOpen-LibrariesAndSDKs/GPUParticles11/blob/master/gpuparticles11/src/GPUParticleSystem.cpp#L1163

在上面的示例中,在更新常量缓冲区之前有一个映射和取消映射操作。也许这需要使用 OpenGL 而不是使用持久地图来完成?或者我可以缺少标志吗?

Is it possible to keep the value unique within each shader invocation set simply by re-assigning a value using a mapped pointer to a UBO within the loop?

是的,如果您将该内存的修改与 OpenGL 同步。 Persistent mapped memory 意味着主机更改和 GPU 之间的同步现在是 你的责任

为了执行您的建议,您需要在每次循环迭代后有效地发出 glFinish 调用,以便 CPU 不会尝试修改该内存,直到 GPU读完了。

这显然是个坏主意,所以不要那样做。在每次调度之间进行一堆 map/unmap 调用也是性能杀手。很有可能在某些时候,它必须做与在每次迭代中发出 glFinish 相同的事情。即使那没有发生,实现也必须在幕后做大量的分配工作以使其性能友好。

对于简单的数字标识符,每次迭代只需使用 glUniform 调用。