2

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

也就是说,我想对追加/使用缓冲区的所有元素运行操作,但不“消耗”它们。

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

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

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

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

(我想到只是将缓冲区绑定为常规 UAV 资源并以这种方式进行迭代,但文档对于是否支持这一点模棱两可。例如,“这些资源不使用资源变量。”请参阅资源本身,还是观点?)

4

1 回答 1

0

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

索引缓冲区是主缓冲区的索引引用列表,并指定哪些元素是非活动的。

您还可以在您的数据结构中添加一个名为“isAlive”或其他内容的 int。

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

  • 您的模拟着色器,您可以在其中对主要数据进行所有工作,这不会改变正常情况,除非您if(isAlive < 1) return在完成大部分工作之前有类似的东西。
  • 您的索引设置着色器,您可以在其中使用索引填充索引缓冲区(indexBuffer[932] = 932等等(索引列表初始化为AppendStructuredBuffer<uint>
  • 您的发射着色器,您可以在其中通过使用可用索引和设置列表中的主要元素来“创建”主要元素isAlive = true。(索引列表初始化为ConsumeStrucutredBuffer<uint>.

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

于 2018-02-28T00:24:00.137 回答