Ios 在哪里正确初始化MTLCommandBuffer?

Ios 在哪里正确初始化MTLCommandBuffer?,ios,swift,metal,Ios,Swift,Metal,使用GPU捕获按钮进行调试后,将显示一条警告:“您的应用程序在GPU工作期间创建了MTLBuffer对象。请在加载时创建缓冲区以获得最佳性能。” 在我的代码中,唯一与MTLBuffer相关的是每次调用draw时创建MTLCommandBuffer: override func draw(_ rect: CGRect){ let commandBuffer = commandQueue.makeCommandBuffer() guard var image =

使用GPU捕获按钮进行调试后,将显示一条警告:“您的应用程序在GPU工作期间创建了MTLBuffer对象。请在加载时创建缓冲区以获得最佳性能。”

在我的代码中,唯一与MTLBuffer相关的是每次调用draw时创建MTLCommandBuffer:

override func draw(_ rect: CGRect){

    let commandBuffer = commandQueue.makeCommandBuffer()

    guard var
        image = image,
        let targetTexture:MTLTexture = currentDrawable?.texture else
    {
        return
    }

    let customDrawableSize:CGSize = drawableSize

    let bounds = CGRect(origin: CGPoint.zero, size: customDrawableSize)

    let originX = image.extent.origin.x
    let originY = image.extent.origin.y

    let scaleX = customDrawableSize.width / image.extent.width
    let scaleY = customDrawableSize.height / image.extent.height

    let scale = min(scaleX*IVScaleFactor, scaleY*IVScaleFactor)
    image = image
        .transformed(by: CGAffineTransform(translationX: -originX, y: -originY))
        .transformed(by: CGAffineTransform(scaleX: scale, y: scale))

    ciContext.render(image,
                     to: targetTexture,
                     commandBuffer: commandBuffer,
                     bounds: bounds,
                     colorSpace: colorSpace)


    commandBuffer?.present(currentDrawable!)

    commandBuffer?.commit()

}
我的第一个想法是将其移动到另一个范围,在这里我可以将命令缓冲区定义为变量,然后在初始化帧时使其等于commandQueue.makeCommandBuffer()。这会立即使应用程序崩溃

我不知道如何在没有警告或崩溃的情况下正确初始化它。MTLCommandQueue是一个惰性变量

以下是使其崩溃的更改:

class MetalImageView: MTKView
{
    let colorSpace = CGColorSpaceCreateDeviceRGB()

    var textureCache: CVMetalTextureCache?

    var sourceTexture: MTLTexture!

    var commandBuffer: MTLCommandBuffer?

    lazy var commandQueue: MTLCommandQueue =
        {
            [unowned self] in

            return self.device!.makeCommandQueue()
            }()!
    ...




override init(frame frameRect: CGRect, device: MTLDevice?)
{
    super.init(frame: frameRect,
               device: device ?? MTLCreateSystemDefaultDevice())



    if super.device == nil
    {
        fatalError("Device doesn't support Metal")
    }

    CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, self.device!, nil, &textureCache)

    framebufferOnly = false

    enableSetNeedsDisplay = true

    isPaused = true

    preferredFramesPerSecond = 30

    commandBuffer = commandQueue.makeCommandBuffer()

}

然后,我当然删除了绘图函数中commandBuffer的定义。

此警告与
MTLBuffer
s有关,而不是
MTLCommandBuffer
s

您当然不应该在初始值设定项中主动创建命令缓冲区。在您即将对GPU工作进行编码时,精确地创建命令缓冲区(即,正如您最初在
draw
方法中所做的那样)

至于诊断消息,可能是Core Image在渲染图像时代表您创建了一个临时缓冲区。对此您无能为力,但根据缓冲区的大小和绘图频率,这可能不是什么大问题