提问人:scornflake 提问时间:10/26/2023 最后编辑:Hamid Yusifliscornflake 更新时间:10/30/2023 访问量:29
将 CARenderer 与 .private MTLTextuer 同步
Synchronize CARenderer with .private MTLTextuer
问:
在渲染到具有 storageMode = .private 的 MTLTexture 时,将 CARenderer 完成的工作同步的正确方法是什么?
在另一篇冗长且有点漫无边际的帖子中,我想我已经证明了当我使用纹理时,CARenderer 仍在工作。在那篇博文中,我通过使 MTLHeap 返回具有 .hazardTrackingMode = .tracks 的纹理来“解决”它。
但是,其他各种帖子(我现在找不到)表明同步是在堆级别完成的,这听起来不是性能最好的。为此,也因为我想了解更多,有没有办法同步 CARenderer 所做的工作,因为纹理有 mode == private?AFAIK 您不能在该纹理资源上使用 blit 编码器将命令缓冲区排队,因为这似乎不受支持。此外,文档指出这是为了同步 GPU<->CPU,如果纹理仅为 .private,则无关紧要。
调用 CARenderer 的相关代码如下:
if let renderCommandBuffer: MTLCommandBuffer = queue.makeCommandBuffer() {
let renderCommandEncoder: MTLRenderCommandEncoder = renderCommandBuffer.makeRenderCommandEncoder(descriptor: currentDescriptor)!
renderCommandEncoder.label = "Clear Target"
renderCommandEncoder.endEncoding()
renderCommandBuffer.commit()
renderCommandBuffer.waitUntilScheduled()
// A CARenderer; already bound to a CALayer root and using some MTLTexture as a target
rendererToUse.beginFrame(atTime: CACurrentMediaTime(), timeStamp: nil)
rendererToUse.addUpdate(rendererToUse.bounds)
rendererToUse.render()
rendererToUse.endFrame()
/*
Trying to sync texture (to get around the pink frame problem).
This works only for .managed targets, which we're not
*/
if let blitCommandBuffer: MTLCommandBuffer = queue.makeCommandBuffer(), target.storageMode == .managed {
let blitCommandEncoder: MTLBlitCommandEncoder = blitCommandBuffer.makeBlitCommandEncoder()!
blitCommandEncoder.synchronize(resource: target)
blitCommandEncoder.endEncoding()
blitCommandBuffer.commit()
blitCommandBuffer.waitUntilCompleted()
}
// HERE!
// Magical code to synchronize the work done by CARenderer to the MTLTexture
}
很抱歉,如果这被认为是一篇重复的帖子,我只是想更干净地问这个问题,而没有我上一篇文章中所有可能混乱的想法。
完整渲染代码:https://gist.github.com/scornflake/2bca7aa3e877f0db36836a0fb575d731
答: 暂无答案
评论