在GPU上设置追加/消耗缓冲区的计数器?

时间:2017-01-01 14:42:07

标签: unity3d gpgpu directcompute

我有一个使用两个计算着色器的应用程序。 Shader #1生成数据x并将其存储在A中,绑定为附加缓冲区。 Shader #2在来自x的所有A上运行,绑定为消耗缓冲区。 我想通过添加Shader #3来扩展这一点,xA中的所有y上运行,生成B到新缓冲区Shader #2 - 但我仍然希望x像以前一样在SetCounterValue()上运行。

也就是说,我想对append / consume缓冲区的所有元素运行一个操作,但是没有'消费'它们。

如果我理解正确,消耗一个元素只会减少一个隐藏的计数器,所以我应该能够通过在完全存储计数时多次使用缓冲区,并在使用它的着色器调用之间重置它。

问题是我的平台 - Unity - 只有一种方法(return UIFont.SystemFontSize; ),它要求我传入新的计数器值。也就是说,我需要在重新设置之前获取CPU内存的计数器值,这将强制GPU / CPU之间的同步并降低性能。

是否可以完全在GPU上设置消耗缓冲区的计数器值?

如果没有,是否可以在不使用消耗的情况下迭代消耗缓冲区?

(我发现只是将缓冲区绑定为常规UAV资源并以这种方式迭代,但the documentation对于是否支持这一点是不明确的。例如"这些资源不使用资源变量。"参考资源本身或视图?)

1 个答案:

答案 0 :(得分:0)

执行此操作的常规方法(根据我的理解,我绝对不是DirectCompute专家!)是有两个缓冲区 - 您的数据缓冲区,在Unity中创建为ComputeBufferType.Default缓冲区并在您的着色器为RWStrucutedBuffer<YourStruct>,您的索引缓冲区在Unity中创建为ComputeBufferType.Append,并在着色器中声明为ConsumeStrucutredBuffer<uint>AppendStructuredBuffer<uint>

索引缓冲区是主缓冲区中的索引引用列表,用于指定哪些元素处于非活动状态。

您还要在您的数据结构中添加一个名为&#39; isAlive&#39;什么的。

然后你要创建三个着色器:

  • 您的模拟着色器,您可以对主要数据进行所有工作,除了在执行大量工作之前有if(isAlive < 1) return之类的内容之外,这些数据不会从正常情况发生变化。
  • 您的索引设置着色器,您使用索引填充索引缓冲区(所以indexBuffer[932] = 932等(索引列表初始化为AppendStructuredBuffer<uint>
  • 您的发射着色器,您在其中创建&#39;主要元素是从可用索引列表中使用它们并设置isAlive = true。 (索引列表初始化为ConsumeStrucutredBuffer<uint>

您还可以在模拟着色器中将索引缓冲区声明为附加缓冲区,如果满足某些条件,则“杀死”#39;您的模拟索引通过设置isAlive = false并将其索引附加到索引缓冲区。