在glsl计算着色器中复制组之间的边界值

在glsl计算着色器中复制组之间的边界值,glsl,gpu,gpgpu,vulkan,compute-shader,Glsl,Gpu,Gpgpu,Vulkan,Compute Shader,有人问了很多这样的问题,但在我的情况下,我需要分享数据 这是我的情况。我有一个程序,它的目标是用从上到下的值填充3D纹理。该程序填充了一种瀑布模型 一种函数,用于获取3D纹理中与单元相关的值及其相对于当前单元的位置,即f(x,位置),并生成添加到当前单元的新值。你可以把它想象成一场洪水 现在,如果我只需要相邻的值,我可以使用重影点,问题是单个值从当前位置向外扩散,因此相邻值将在我操作的当前块之外更新 现在我不需要从相邻块传输整个数据块,我只需要在每一步,当前网格周围相邻块的值。我仍将使用重影点

有人问了很多这样的问题,但在我的情况下,我需要分享数据

这是我的情况。我有一个程序,它的目标是用从上到下的值填充3D纹理。该程序填充了一种瀑布模型

一种函数,用于获取3D纹理中与单元相关的值及其相对于当前单元的位置,即
f(x,位置)
,并生成添加到当前单元的新值。你可以把它想象成一场洪水

现在,如果我只需要相邻的值,我可以使用重影点,问题是单个值从当前位置向外扩散,因此相邻值将在我操作的当前块之外更新

现在我不需要从相邻块传输整个数据块,我只需要在每一步,当前网格周围相邻块的值。我仍将使用重影点,但我需要将“新”值传入以使用它们

我的问题是,似乎每个人都说“使用另一个计算着色器调用”来解决这个问题。这是不可接受的,没有足够的工作来证明内核启动成本的合理性

我看到的唯一选择是:

  • 使用原子整数跨组通信,让组知道它们可以使用某些全局内存中与这些边界数据项对应的值
  • 通过将相邻单元格的值复制到一个单独的缓冲区中,然后再次运行整个过程来计算每侧的新相邻值(立方体中有6个),从而对运行时进行六次分组
  • 对整个事件只使用一个组调用。GPU正在做的其他事情可能足以证明这一点
  • 对3D纹理的每个“层”使用多个计算着色器调用,这需要将值转储到全局内存中,然后为每个层读回这些值,有效地将全局内存读取和调用内核开销的成本加倍,因为每个内核都需要按顺序启动。如果我可以在内核调用之间的共享内存中保留相同的内存,而不必重新读入,这将缓解双重延迟问题
真的没有其他方法可以在计算着色器中复制边界吗

真的没有其他方法可以在计算着色器中复制边界吗

在一般情况下,没有

无法保证何时执行相邻边界组,因此如何复制可能还不存在的内容

您可能能够阻止和等待,但这是低效的(GPU将只是忙着等待),并且可能实际上处于活动锁定状态,因为所有正在运行的组都被阻止等待,而新组无法启动(因为被阻止的组使用了着色器核心的所有线程容量)


如果我正确理解了你的算法,更糟糕的是你有一个循环依赖关系(边界在相邻块之间双向传播),因此除非你能同时生成整个问题空间,否则它就保证是活锁。

我能同时生成整个问题空间。。。这样就不会有活锁了。假设您使用原子通信方法,您只需确保线程A在线程B可以继续执行下一步之前,其当前步骤有输出,但两个线程都可以继续执行其当前步骤,而彼此没有输入。出于您的目的,只需将其视为洪水填充,但多个洪水点可能会混合在一起。如果在每次迭代中作为单独的内核启动程序,只要存在上一步的内存依赖项,该程序仍然可以工作。