Search code examples
iosmetalmetalkitmtlbuffer

Metal newBufferWithBytes usage


I have a basic question about allocating new Metal device buffers. Most of the sample codes I see create MTLBuffer at setup time and do not modify it. But I wonder if the vertex data is changing at every render call, is it okay to every time create a new MTLBuffer (using -[MTLBuffer newBufferWithBytes:length:option]) for sending data to shaders running on GPU, OR, should MTLBuffer of given size be created once but it's bytes modified on every render call? What's the recommended way as per best practices?


Solution

  • If it is a small amount of data (under 4K) I believe you can use setVertexBytes() and setFragmentBytes(): https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515846-setvertexbytes

    For larger amounts of data that changes every frame, they recommend that you use a triple-buffered approach so that successive frames' access to the buffer do not interfere: https://developer.apple.com/library/content/documentation/3DDrawing/Conceptual/MTLBestPracticesGuide/TripleBuffering.html

    This tutorial shows how to set up triple buffering: https://www.raywenderlich.com/146418/metal-tutorial-swift-3-part-3-adding-texture

    That's actually like the third part of the tutorial but it is the part that shows the triple-buffering setup, under "Reusing Uniform Buffers".

    What I am unsure about is whether it is better/faster to use triple-buffering on small amounts of data as well -- they do it in that tutorial for only a couple of matrices, so maybe it is better to always triple buffer.