【问题标题】:Metal 2 Multi Indirect DrawMetal 2 Multi 间接绘图
【发布时间】:2021-12-21 09:35:15
【问题描述】:

有没有一种基于 Metal 2 的方法可以像“Direct X”12 API“ExecuteIndirect”那样执行“Multi Indirect Draw”? Metal 2 有一些 API 可以进行单次间接绘制,但似乎找不到多次间接绘制。

【问题讨论】:

    标签: graphics 3d game-engine metal


    【解决方案1】:

    您可以使用MTLIndirectCommandBuffer 在 CPU 或 GPU 上对绘制或调度命令进行编码。

    您创建一个带有MTLIndirectCommandBufferDescriptorMTLIndirectCommandBuffer,该MTLIndirectCommandBufferDescriptor 具有最大数量的命令集,以及命令类型和其他属性,例如管道和缓冲区绑定继承。请记住,您不能混合和匹配不同“阶段”的命令。这意味着,您可以有两种不同类型的渲染命令,但不能在同一个缓冲区中同时拥有渲染和计算命令。

    之后,你有两种编码方式。

    首先是在 CPU 上进行。您可以通过indirectRenderCommandAtIndex: 调用或计算对象MTLIndirectComputeCommand 通过indirectComputeCommandAtIndex: 调用从ICB 请求MTLIndirectRenderCommand 对象。它有点像命令编码器,但只针对单个命令。

    第二种方法是在 GPU 上进行。您可以使用参数缓冲区将间接命令缓冲区传递到着色器。您将使用MTLArgumentEncoders setIndirectCommandBuffer:atIndex: 方法将其写入那里。之后,您可以使用类似于 CPU 端 API 的 API。您可以从着色器的参数缓冲区中的索引和command_buffer 对象创建render_commandcompute_command。这个command 结构有很多方法来设置缓冲区、管道状态和编码绘图或计算命令。然后,您将调度一个带有一些线程的内核,这些线程将使用它们在网格中的位置来计算命令缓冲区的索引并在那里对命令进行编码。

    尽管间接命令看起来有点像命令编码器,但请记住,索引处的单个命令仅包含一个实际命令,因此与编码器相比,您对绘制或计算命令所做的任何更改覆盖之前的内容。

    在 CPU 或 GPU 上对命令进行编码后,您必须执行它。根据您拥有的命令类型,您将在MTLRenderCommandEncoderMTLComputeCommandEncoder 上调用executeCommandsInBuffer:indirectBuffer:indirectBufferOffset:

    这应该涵盖基础知识。更深入的了解,有这两篇文章:Encoding Indirect Command Buffers on the CPU Encoding Indirect Command Buffers on the GPU ,还有这篇 Modern Rendering with Metal Sample 大量使用了这些 ICB。

    【讨论】:

    • 谢谢。可能是我没有明确指定,我想要的是:例如,有一个球体和一个立方体,我可以只调用一次 DX 12 API ExecuteIndirect 来在 Windows 平台上渲染这两个对象。现在是否可以在 iOS 平台上调用一些 API 来做同样的事情?
    • 也就是只用一个draw call来绘制球体和立方体。
    • 您对间接命令缓冲区进行编码,然后调用executeCommandsInBuffer。这是同一个概念。
    • 我的理解(不确定是否正确):在间接命令缓冲区中,球体一个命令,立方体一个命令,所以实际上executeCommandsInBuffer执行两个命令,两个绘制调用。
    • 那你怎么理解ExecuteIndirect呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    相关资源
    最近更新 更多