ios - Metal makeComputeCommandEncoder 断言失败
问题描述
我正在尝试设置和执行计算内核并将其输出提交给 MTKView 进行绘制。但我得到以下崩溃:
-[MTLDebugCommandBuffer computeCommandEncoder]:889: failed assertion `encoding in progress'
下面的代码有什么问题?是否使用相同的 commandBuffer 将计算着色器的输出馈送到渲染管道?
func computeKernel(_ texture:MTLTexture, commandBuffer:MTLCommandBuffer) {
let computeEncoder = commandBuffer.makeComputeCommandEncoder()
computeEncoder?.setComputePipelineState(computePipelineState!)
computeEncoder?.setTexture(texture, index: 0)
computeEncoder?.setTexture(texture, index: 1)
computeEncoder?.dispatchThreadgroups(threadgroupCount, threadsPerThreadgroup: threadgroupSize)
computeEncoder?.endEncoding()
/*
commandBuffer.commit()
commandBuffer.waitUntilCompleted()
*/
}
override func draw(_ rect: CGRect) {
guard let drawable = currentDrawable,
let currentRenderPassDescriptor = currentRenderPassDescriptor
else {
return
}
// Set up command buffer and encoder
guard let commandQueue = commandQueue else {
print("Failed to create Metal command queue")
return
}
guard let commandBuffer = commandQueue.makeCommandBuffer() else {
print("Failed to create Metal command buffer")
return
}
guard let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: currentRenderPassDescriptor) else {
print("Failed to create Metal command encoder")
return
}
commandEncoder.label = "Preview display"
let texture = ... //Grab a Metal texture
computeKernel(texture, commandBuffer: commandBuffer)
commandEncoder.setRenderPipelineState(defaultRenderPipelineState!)
commandEncoder.setFragmentTexture(texture, index: 0)
commandEncoder.setVertexBytes(vertices, length: vertices.count * MemoryLayout<AAPLVertex>.stride, index: 0)
commandEncoder.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4)
commandEncoder.endEncoding()
commandBuffer.present(drawable) // Draw to the screen
commandBuffer.commit()
}
解决方案
您可以将计算和渲染工作编码到同一个命令缓冲区中,但是当现有命令编码器正在编码时,您不能启动另一个命令编码器。在您的情况下,您创建渲染命令编码器,然后调用创建计算命令编码器的函数而不结束渲染命令编码器。相反,您应该调用您的计算函数,然后创建并使用您的渲染命令编码器。
推荐阅读
- html - Html 和 CSS 在文本编辑器中链接,但未在 Web 浏览器中显示
- networking - GSLB 和 ADC(应用交付控制器)有什么区别
- c - 为什么 int 函数即使没有在 C 中首先声明也能工作
- swift - 覆盖 hitTest SwiftUi?
- python - 在 Python 3/Jupyter 上生成列表会杀死内核
- php - 使用 PHP 正则表达式的字符集中至少出现两次或多次
- ruby - R电子表格宝石
- php - nginx 在加载 php 文件时给出“发生错误”
- c# - 如何将 Windows.Security.Credentials.UI 命名空间包含到 C# 项目中
- python - client.run(TOKEN) 命令阻止其他集团