如何交错 Kernel/Vertex METAL 着色器

How to interleave Kernel/Vertex METAL Shaders

我发现将 Metal 渲染循环部署为多个链 KCS (kernel/compute) 着色器和 VFS (vertex/fragment) 着色器:

texture -> [KCS -> VFS -> KCS -> VFS] --\
                                         --->[KCS -> KCS] --> presentable
texture -> [KCS -> VFS -> KCS -> VFS] --/

一个着色器的输出是下一个着色器的输入。两组 4 个交替着色器在接近尾声时组合在一起,如图所示。

如果我的考虑是正确的,我将需要多达 10 个不同的管道描述符来实现这一点,以及对将调度下一个着色器的完成处理程序的大量调用。

我也没有指出,但最后一次调用 presentable 也会将其输出的子区域馈送到单独的 MTKView(通过 vertex/fragment 着色器)。

如有任何提示,我们将不胜感激。

如果描述符具有不同的值,您只需要不同的描述符。也就是说,如果您显示的任何 KCS 步骤使用相同的计算着色器函数,那么它们通常可以共享一个描述符。 (MTLComputePipelineDescriptor 还有其他属性,但不太常用。)

对于 VFS 步骤,描述符更为复杂,因此它们必须在要共享的所有属性中相等。

当然,如果可以的话,您应该在应用程序的生命周期内创建一次管道状态对象。避免为每个渲染循环创建它们。

您绝对不想使用完成处理程序来分派下一步。这将使流水线严重停滞(使 CPU 和 GPU 反复相互等待)。只需将步骤按顺序编码到命令缓冲区中。在可能写入其输入的任何先前 draw/dispatch 完成之前,任何给定的绘制或调度都不会继续。