我正在使用Metal在OS X Sierra上制作应用程序。我正在做的事情是导致屏幕开始出现故障,在各个地方闪烁黑色,很快升级到整个屏幕变黑。
在XCode中,如果我使用GPU帧捕获,则暂停的帧看起来是正确的 - 它突然从黑色深渊返回。我没有在GPU帧信息中看到任何错误或警告。但是,我对Metal来说相对较新,并且对帧调试器没有经验,所以我可能不知道该找什么。
通常没有任何东西打印到控制台,但偶尔我会得到其中一个:
由于执行期间的错误,命令缓冲区的执行被中止。内部错误(IOAF代码1)
同样的应用程序在没有此问题的iOS设备上运行 - 到目前为止它只发生在OS X上。这听起来很熟悉吗?关于我应该检查什么的任何建议?
如果它有用,我可以发布一些代码,但是现在我不确定该程序的哪个部分是问题。
编辑:回应Noah Witherspoon - 似乎问题是由我的场景绘图和UI绘图之间的某种交互引起的。如果我只显示由胖,模糊线组成的场景,那么问题就不会发生。如果我只显示UI,即正交投影,一堆圆角矩形和某种类型,也不会出现这种情况。问题只有在两者都显示时才会发生。这是很多代码,很多缓冲区和很多commandBuffer的用法,太多不能放入帖子中。但这里有一点点。
我的线条使用顶点缓冲区渲染,顶点缓冲区是浮点数组,每个顶点四个:
let dataSize = count * 4 * MemoryLayout<Float>.size
vertexBuffer = device.makeBuffer(bytes: points, length: dataSize, options: MTLResourceOptions())!
这些渲染如下:
renderEncoder.setVertexBuffer(self.vertexBuffer, offset: 0, index: 0)
renderEncoder.setRenderPipelineState(strokeNode.strokePipelineState)
renderEncoder.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: Int(widthCountEdge.count)*2-4)
renderEncoder.setRenderPipelineState(strokeNode.capPipelineState)
renderEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 12)
这是我使用命令Buffer绘制的主循环。
if let commandBuffer = commandQueue.makeCommandBuffer() {
commandBuffer.addCompletedHandler { (commandBuffer) -> Void in
self.strokeNode.bufferProvider.availableResourcesSemaphore.signal()
}
self.updateDynamicBufferState()
self.updateGameState(timeInterval)
let renderPassDescriptor = view.currentRenderPassDescriptor
renderPassDescriptor?.colorAttachments[0].loadAction = .clear
renderPassDescriptor?.colorAttachments[0].clearColor = MTLClearColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0)
renderPassDescriptor?.colorAttachments[0].storeAction = .store
if let renderPassDescriptor = renderPassDescriptor, let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) {
strokeNode.subrender(renderEncoder, parentModelViewMatrix: viewMatrix, projectionMatrix: projectionMatrix, renderer:self)
mainscreen.draw(renderEncoder);
renderEncoder.endEncoding()
if let drawable = view.currentDrawable {
commandBuffer.present(drawable)
}
}
commandBuffer.commit()
}
线条绘制发生在strokeNode.subrender中,然后我的UI绘图发生在mainscreen.draw中。 UI绘图有很多组件 - 这里列出很多 - 但我会尝试逐个取出它们,看看我是否可以缩小范围。如果这些看起来都不成问题,我会编辑并发布其中一些...
谢谢!