Я использую металлический шейдер производительности (MPSImageHistogram
) для вычисления чего-то в MTLBuffer
, который я беру, выполняю вычисления, а затем отображаю через MTKView
. Вывод MTLBuffer
из шейдера мал (~ 4 Кбайт). Поэтому я выделяю новый объект MTLBuffer
для каждого прохода рендеринга, и для каждого видеокадра существует не менее 30 операций рендеринга в секунду.
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)
...
...
}
Мои вопросы -
Можно ли каждый раз создавать новый буфер, используя device.makeBuffer(..)
, или лучше статически распределять
несколько буферов и реализовать повторное использование этих буферов? Если повторное использование лучше, что мы делаем для синхронизации записи / чтения данных CPU / GPU в этих буферах?
Еще один не связанный вопрос, можно ли рисовать MTKView
результаты в неосновной ветке? Или MTKView
ничья должна быть только в основном потоке (даже если я читаю, что Металл действительно многопоточный)?