Как связать фильтры в Metal для iOS?
Я закончил этот урок Саймона Гладмана (@flexmonkey), чтобы сделать снимки с AVFoundation
и применить фильтр к выходу. Однако я изо всех сил пытаюсь найти способ заменить фильтр размытия моим собственным вычислительным шейдером. Другими словами, мне нужно объединить свой пользовательский шейдер после YCbCrColorConversion
упомянутый там фильтр.
let commandBuffer = commandQueue.makeCommandBuffer()
let commandEncoder = commandBuffer.makeComputeCommandEncoder()
// pipelineState has compiled YCbCrColorConversion filter
commandEncoder.setComputePipelineState(pipelineState)
commandEncoder.setTexture(ytexture, at: 0)
commandEncoder.setTexture(cbcrTexture, at: 1)
commandEncoder.setTexture(drawable.texture, at: 2) // out texture
commandEncoder.dispatchThreadgroups(threadGroups,threadsPerThreadgroup: threadGroupCount)
commandEncoder.endEncoding()
let inPlaceTexture = UnsafeMutablePointer<MTLTexture> .allocate(capacity: 1)
inPlaceTexture.initialize(to: drawable.texture)
// How to replace this blur with my own filter?????
blur.encodeToCommandBuffer(commandBuffer, inPlaceTexture: inPlaceTexture, fallbackCopyAllocator: nil)
commandBuffer.presentDrawable(drawable)
commandBuffer.commit();
Должен ли я создать новый commandBuffer, commandEncoder и отдельный pipeState, который компилирует вторую функцию ядра? Это будет принимать выходные данные первого фильтра как входные данные для второго. Есть ли более эффективный способ сделать это, или это оптимально?
Я новичок в Metal, поэтому любые объяснения того, как работает конвейер, высоко ценятся.
1 ответ
Вам не нужно создавать новый буфер команд или другой вычислительный кодер, но вам нужно создать состояние конвейерного вычисления, которое использует вашу собственную функцию ядра. Вы должны сделать это один раз, во время инициализации, где бы вы ни создавали состояние конвейера преобразования YCbCr.
Чтобы связать воедино эффекты, вам нужно создать промежуточную текстуру, которая действует как выходная текстура преобразования YCbCr и вход вашего ядра. Затем рисуемая текстура будет выходной текстурой вашей функции ядра. Вы можете отправить работу для своего собственного ядра точно так же, как вы в настоящее время отправляете работу для преобразования YCbCr (то есть с тем же числом потоков на группу потоков и количество групп потоков).
Промежуточная текстура, вероятно, должна иметь те же размеры и формат, что и отрисовка. Вы можете создать его лениво и удерживать ссылку на него, воссоздавая его при изменении размера рисунка.