Efficiently copying Swift Array to memory buffer for iOS Metal

后端 未结 3 446
再見小時候
再見小時候 2021-02-04 18:23

I am writing an iOS application using Apple\'s new Metal framework. I have an array of Matrix4 objects (see Ray Wenderlich\'s tutorial) that I need to pass in to a shader via

3条回答
  •  误落风尘
    2021-02-04 19:03

    Obviously the point of using shared memory and MTLDevice.makeBuffer(bytesNoCopy:...) is to avoid redundant memory copies. Therefore, ideally we look for a design that allows us to easily manipulate the data after it's already been loaded into the MTLBuffer object.

    After researching this for a while, I've decided to try and create a semi-generic solution to allow for simplified allocation of page-aligned memory, loading your content into that memory, and subsequently manipulating your items in that shared memory block.

    I've created a Swift array implementation called PageAlignedArray that matches the interface and functionality of the built-in Swift array, but always resides on page-aligned memory, and so can be very easily made into an MTLBuffer. I've also added a convenience method to directly convert PageAlignedArray into a Metal buffer.

    Of course, you can continue to mutate your array afterwards and your updates will be automatically available to the GPU courtesy of the shared-memory architecture. However, keep in mind that you must regenerate your MTLBuffer object whenever the array's length changes.

    Here's a quick code sample:

      var alignedArray : PageAlignedContiguousArray = [matrixTest, matrixTest]
      alignedArray.append(item)
      alignedArray.removeFirst() // Behaves just like a built-in array, with all convenience methods
    
      // When it's time to generate a Metal buffer:
      let testMetalBuffer = device?.makeBufferWithPageAlignedArray(alignedArray)
    

    The sample uses matrix_double4x4, but the array should work for any Swift value types. Please note that if you use a reference type (such as any kind of class), the array will contain pointers to your elements and so won't be usable from your GPU code.

提交回复
热议问题