有没有办法基于 Metal 2 进行"多间接绘制",例如"Direct X"12 API "ExecuteIndirect"?Metal 2 有一些 API 可以进行单次间接抽取,但似乎找不到多次间接抽取。
您可以使用MTLIndirectCommandBuffer
在 CPU 或 GPU 上对绘制或调度命令进行编码。
创建一个MTLIndirectCommandBuffer
,其MTLIndirectCommandBufferDescriptor
具有最大数量的命令集,以及命令类型和其他属性,如管道和缓冲区绑定继承。请记住,您不能混合和匹配不同"阶段"的命令。这意味着,可以有两种不同类型的呈现命令,但不能在同一缓冲区中同时使用呈现命令和计算命令。
之后,您有两种方法对其进行编码。
首先是在CPU上做。您可以使用indirectRenderCommandAtIndex:
调用或计算调用(MTLIndirectComputeCommand
indirectComputeCommandAtIndex:
调用)从 ICB 请求MTLIndirectRenderCommand
对象。它有点像命令编码器,但适用于单个命令。
第二种方法是在 GPU 上执行此操作。可以使用参数缓冲区将间接命令缓冲区传递到着色器中。您将使用MTLArgumentEncoder
ssetIndirectCommandBuffer:atIndex:
方法将其写入其中。之后,您可以使用类似于 CPU 端 API 的 API。从着色器的参数缓冲区中的索引和command_buffer
对象创建render_command
或compute_command
。此command
结构具有一系列方法来设置缓冲区、管道状态以及编码绘制或计算命令。然后,您将调度一个包含一些线程的内核,这些线程将使用它们在网格中的位置将索引计算到命令缓冲区中,并在那里对命令进行编码。
尽管间接命令看起来有点像命令编码器,但最好记住,索引处的单个命令只包含一个实际命令,因此与编码器相反,对绘制或计算命令所做的任何更改都会覆盖之前的内容。
在 CPU 或 GPU 上对命令进行编码后,您必须执行它。根据您拥有的命令类型,您将在MTLRenderCommandEncoder
或MTLComputeCommandEncoder
上调用executeCommandsInBuffer:indirectBuffer:indirectBufferOffset:
。
这应该涵盖基础知识。为了更深入地了解,有以下两篇文章: 在 CPU 上编码间接命令缓冲区 并在 GPU 上编码间接命令缓冲区 ,以及这个使用金属样本的现代渲染,它大量使用这些 ICB。