ios - Metal makeComputeCommandEncoder 断言失败

标签 ios metal compute-shader metalkit

我正在尝试设置和执行计算内核并将其输出提交给 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()
}

最佳答案

您可以将计算和渲染工作编码到同一个命令缓冲区中,但您不能在现有命令编码器编码时启动另一个命令编码器。在您的情况下,您创建渲染命令编码器,然后调用一个函数来创建计算命令编码器而不结束渲染命令编码器。相反,您应该调用您的计算函数,然后创建并使用您的渲染命令编码器。

关于ios - Metal makeComputeCommandEncoder 断言失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50141522/

相关文章:

css - Cordova 闪屏

ios - 如何仅针对 UIControlEvent.allEditingEvents 覆盖 UITextField 中的 addTarget?

ios - 无法从导航栏中删除阴影图像

ios - 如何将 CVPixelBuffer 设置为顶点着色器的输入?

ios - iOS 上的 Metal : when to read visibilityResultBuffer?

directx-11 - 在directx 11中一次渲染到多个纹理

directx - 具有 numthreads (1,1,1) 的计算着色器运行速度极慢

ios - 由于此错误 "Receiver (<ViewController: ) has no segue with identifier",Segue 将无法执行,但已识别出 segue

ios - 将16位 float 的MTLTexture转换为cv::Mat 32位 float 类型

c++ - 跨多个 gpu 同步原子计数器