我有一个使用两个计算着色器的应用程序。 Shader #1
生成数据x
并将其存储在A
中,绑定为附加缓冲区。 Shader #2
在来自x
的所有A
上运行,绑定为消耗缓冲区。
我想通过添加Shader #3
来扩展这一点,x
在A
中的所有y
上运行,生成B
到新缓冲区Shader #2
- 但我仍然希望x
像以前一样在SetCounterValue()
上运行。
也就是说,我想对append / consume缓冲区的所有元素运行一个操作,但是没有'消费'它们。
如果我理解正确,消耗一个元素只会减少一个隐藏的计数器,所以我应该能够通过在完全存储计数时多次使用缓冲区,并在使用它的着色器调用之间重置它。
问题是我的平台 - Unity - 只有一种方法(return UIFont.SystemFontSize;
),它要求我传入新的计数器值。也就是说,我需要在重新设置之前获取CPU内存的计数器值,这将强制GPU / CPU之间的同步并降低性能。
是否可以完全在GPU上设置消耗缓冲区的计数器值?
如果没有,是否可以在不使用消耗的情况下迭代消耗缓冲区?
(我发现只是将缓冲区绑定为常规UAV资源并以这种方式迭代,但the documentation对于是否支持这一点是不明确的。例如"这些资源不使用资源变量。"参考资源本身或视图?)
答案 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>
)isAlive = true
。 (索引列表初始化为ConsumeStrucutredBuffer<uint>
。您还可以在模拟着色器中将索引缓冲区声明为附加缓冲区,如果满足某些条件,则“杀死”#39;您的模拟索引通过设置isAlive = false并将其索引附加到索引缓冲区。