我遇到了同样的问题,并在WWDC 15上询问了Metal开发人员。
MTKView
工作原理:可 MTKView
绘制对象的数量有限(可能是 3 个),因此当您对帧进行编码时,可以绘制的可绘制对象很少。
你在做什么:你的场景可能很简单,所以你的 CPU 可以非常快地编码帧。所以看起来,当 CPU 比 GPU 领先 4 帧时,您要求下一个可绘制对象,并且由于所有 (3) 个可绘制对象都在使用中,所以它失败了。
解决方案:当没有空闲的时候,你需要使用信号量等待drawable 。
这是要使用的代码:
let inflightSemaphore = dispatch_semaphore_create(3)
func drawInView(view: MTKView) {
// use semaphore to encode 3 frames ahead
dispatch_semaphore_wait(inflightSemaphore, DISPATCH_TIME_FOREVER)
self.update()
let commandBuffer = commandQueue.commandBuffer()
let renderEncoder = commandBuffer.renderCommandEncoderWithDescriptor(view.currentRenderPassDescriptor!)
renderEncoder.drawPrimitives()
// use completion handler to signal the semaphore when this frame is completed allowing the encoding of the next frame to proceed
commandBuffer.addCompletedHandler{ [weak self] commandBuffer in
if let strongSelf = self {
dispatch_semaphore_signal(strongSelf.inflightSemaphore)
}
return
}
commandBuffer.presentDrawable(view.currentDrawable!)
commandBuffer.commit()
}
这在任何地方都没有记录!唯一书面提及的是在GameViewController
.
我已经对此进行了调查(还没有回复),如果您也这样做,我将不胜感激https://bugreport.apple.com
您也可能会发现我的 github 存储库https://github.com/haawa799/RamOnMetal很有用