比需要的时间早调用CAMetalLayer nextDrawable

时间:2019-06-17 02:16:06

标签: ios swift metal

GPU帧捕获警告:

your application called CAMetalLayer nextDrawable earlier than needed

在我完成所有其他GPU调用之后,我正要在提交命令缓冲区之前调用present(drawable)

guard let commandBuffer = commandQueue.makeCommandBuffer(),
let computeBuffer = commandQueue.makeCommandBuffer(),
let descriptor = view.currentRenderPassDescriptor else { return }

...

//First run the compute kernel
guard let computeEncoder = computeBuffer.makeComputeCommandEncoder() else { return }
computeEncoder.setComputePipelineState(computePipelineState)

dispatchThreads(particleCount: particleCount)

computeEncoder.endEncoding()
computeBuffer.commit()

//I need to wait here because I need values from a computed buffer first 
//and also why I am not just using a single pipeline descriptor
computeBuffer.waitUntilCompleted() 

//Next render computed particles with vertex shader to a texture
let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor0)!
renderEncoder.setRenderPipelineState(renderPipelineState)
...
renderEncoder.endEncoding()

//Draw texture (created above) using vertex shader:
let renderTexture = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor)
renderTexture?.setRenderPipelineState(renderCanvasPipelineState)
...
renderTexture?.endEncoding()

//Finally present drawable and commit command buffer:
guard let drawable = view.currentDrawable else { return }
commandBuffer.present(drawable)
commandBuffer.commit()

我不知道以后如何请求currentDrawable。我是在做错什么还是次优的事情?

我开始研究这个问题,因为大多数帧(基本上在做同样的事情),等待当前可绘制对象的时间约为3到10毫秒。有时等待时间为35-45毫秒。

我看到许多建议使用presentDrawable而不是present,但这似乎不是Swift的选择。

有什么方法可以在需要时请求当前可绘制对象并使警告消失吗?

1 个答案:

答案 0 :(得分:0)

您正在列出的代码顶部调用view.currentRenderPassDescriptor。渲染过程描述符必须引用可绘制对象的纹理作为颜色附件。这意味着获得可绘制对象并要求其纹理。因此,该行请求了drawable。

直到使用它创建渲染命令编码器(let renderTexture = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor))之前,都不要获取渲染过程描述符。