When using index primitives is there a method to provide the indices using a temp buffer like setVertexBytes?
Right now I have to create a temp metal buffer even for a small number of vertices and toss it after rendering using drawIndexedPrimitives.
There is no setIndexBytes equivalent in Metal. The drawIndexedPrimitives method requires a MTLBuffer for the index data.
However, you don't need to create and discard a buffer each frame. Allocate a single MTLBuffer once, sized for the maximum number of indices you'll need, and write into it each frame:
// Allocate once (e.g. in setup)
let maxIndices = 256
let indexBuffer = device.makeBuffer(length: maxIndices * MemoryLayout<UInt16>.stride,
options: .storageModeShared)!
// Each frame: write indices, then draw
let indices: [UInt16] = ...
indices.withUnsafeBytes { ptr in
indexBuffer.contents().copyMemory(from: ptr.baseAddress!, byteCount: ptr.count)
}
renderEncoder.drawIndexedPrimitives(type: .triangle,
indexCount: indices.count,
indexType: .uint16,
indexBuffer: indexBuffer,
indexBufferOffset: 0)
This avoids the allocation overhead entirely. On Apple Silicon and iOS, .storageModeShared is the right choice since CPU and GPU share memory. On macOS with a discrete GPU, use .storageModeManaged and call didModifyRange(_:) after writing to sync the modified bytes to the GPU.