I am using a metal performance shader(MPSImageHistogram
) to compute something in an MTLBuffer
that I grab, perform computations, and then display via MTKView
. The MTLBuffer
output from the shader is small (~4K bytes). So I am allocating a new MTLBuffer
object for every render pass, and there are atleast 30 renders per second for every video frame.
calculation = MPSImageHistogram(device: device, histogramInfo: &histogramInfo)
let bufferLength = calculation.histogramSize(forSourceFormat: MTLPixelFormat.bgra8Unorm)
let buffer = device.makeBuffer(length: bufferLength, options: .storageModeShared)
let commandBuffer = commandQueue?.makeCommandBuffer()
calculation.encode(to: commandBuffer!, sourceTexture: metalTexture!, histogram: buffer!, histogramOffset: 0)
commandBuffer?.commit()
commandBuffer?.addCompletedHandler({ (cmdBuffer) in
let dataPtr = buffer!.contents().assumingMemoryBound(to: UInt32.self)
...
...
}
My questions -
Is it okay to make a new buffer every time using
device.makeBuffer(..)
, or better to statically allocate few buffers and implement reuse those buffers? If reuse is better, what do we do for synchronizing CPU/GPU data write/read on these buffers?Another unrelated question, is it okay to draw in
MTKView
the results on a non-main thread? OrMTKView
draws must only be in main thread (even though I read Metal is truly multithreaded)?