在Metal中,将顶点和片段缓冲区设置为相同的MTLBuffer只将它复制到GPU一次吗?

时间:2017-05-05 05:32:19

标签: swift metal

我将一个统一缓冲区传递给顶点和片段着色器。

let uniformBuffer = device.makeBuffer(length: 4096, options: [])
renderEncoder.setVertexBuffer(uniformBuffer, offset: 0, at: 1)
renderEncoder.setFragmentBuffer(uniformBuffer,offset:0, at: 1)

这会将uniformBuffer从CPU复制到GPU两次吗?然后我将把缓冲区从顶点着色器传递到片段着色器,它就发生在GPU内部。

2 个答案:

答案 0 :(得分:4)

没有专门针对setVertexBuffer()setFragmentBuffer()的副本。那些只将引用放入缓冲区到渲染编码器的缓冲表中。

您的代码和Metal只需要确保缓冲区的内容在GPU上是最新的,并从那里引用它。正如Matthjis所说,你如何做到这一点取决于storageMode。如果您正在使用托管模式,如果修改CPU上的缓冲区内容,则需要使用didModifyRange()告诉Metal。一旦这样做,Metal就知道在下次需要时将修改后的范围复制到GPU。无论编码器缓冲表引用缓冲区多少次,该单个副本就足够了。

请注意,setVertexBytes()setFragmentBytes()的工作方式不同。每次调用它们时都必须(并且确实)立即复制传入的字节数组。

答案 1 :(得分:2)

我认为这取决于平台。在iOS上,内存在CPU和GPU之间共享,因此根本不执行任何复制。在macOS上,它取决于缓冲区或纹理的storageMode是否涉及复制(但我不知道它是否在您的情况下复制缓冲区两次或只复制一次)。