我正在使用 Metal 在 OS X Sierra 上制作应用程序。我正在做的事情是导致屏幕开始出现严重故障,在各个地方闪烁黑色,这很快升级为整个屏幕变黑。
在 XCode 中,如果我使用 GPU 帧捕获,则暂停的帧看起来是正确的——它突然从黑色深渊返回。我在 GPU 帧信息中看不到任何错误或警告。但是,我对 Metal 比较陌生,对框架调试器没有经验,所以我可能不知道要寻找什么。
通常没有打印到控制台,但偶尔我会得到其中之一:
由于执行期间出现错误,命令缓冲区的执行被中止。内部错误(IOAF 代码 1)
相同的应用程序在 iOS 设备上运行没有这个问题——到目前为止它只发生在 OS X 上。这听起来很熟悉吗?关于我应该检查什么的任何建议?
如果有帮助,我可以发布一些代码,但现在我不确定程序的哪一部分是问题所在。
编辑:响应诺亚威瑟斯彭 - 似乎问题是由我的场景绘图和 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 绘图有很多组件 - 很多要在此处列出 - 但我会尝试将它们一一取出,看看是否可以缩小范围。如果这些看起来都没有问题,我会编辑并发布其中的一些......
谢谢!