我将一个统一缓冲区传递给顶点和片段着色器。
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内部。
答案 0 :(得分:4)
没有专门针对setVertexBuffer()
或setFragmentBuffer()
的副本。那些只将引用放入缓冲区到渲染编码器的缓冲表中。
您的代码和Metal只需要确保缓冲区的内容在GPU上是最新的,并从那里引用它。正如Matthjis所说,你如何做到这一点取决于storageMode
。如果您正在使用托管模式,如果修改CPU上的缓冲区内容,则需要使用didModifyRange()
告诉Metal。一旦这样做,Metal就知道在下次需要时将修改后的范围复制到GPU。无论编码器缓冲表引用缓冲区多少次,该单个副本就足够了。
请注意,setVertexBytes()
和setFragmentBytes()
的工作方式不同。每次调用它们时都必须(并且确实)立即复制传入的字节数组。
答案 1 :(得分:2)
我认为这取决于平台。在iOS上,内存在CPU和GPU之间共享,因此根本不执行任何复制。在macOS上,它取决于缓冲区或纹理的storageMode
是否涉及复制(但我不知道它是否在您的情况下复制缓冲区两次或只复制一次)。