Где мне правильно инициализировать мой MTLCommandBuffer? - PullRequest
0 голосов
/ 31 января 2019

После отладки с помощью кнопки Capture GPU отображается предупреждение: «Ваше приложение создало объект MTLBuffer во время работы GPU. Создайте буферы во время загрузки для лучшей производительности».

Единственное, что связано с MTLBuffer вмой код - создание MTLCommandBuffer каждый раз, когда вызывается draw:

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 в моей функции рисования.

1 Ответ

0 голосов
/ 31 января 2019

Это предупреждение относится к MTLBuffer с, а не MTLCommandBuffer с.

Вы не должны заранее создавать буфер команд в инициализаторе.Создавайте буферы команд точно, когда вы собираетесь кодировать работу графического процессора (то есть, как вы делали изначально, в своем методе draw).

Что касается диагностического сообщения, то, вероятно, это тот случай, когда Core Image создаетвременный буфер от вашего имени при рендеринге вашего изображения.Вы ничего не можете с этим поделать, но в зависимости от размера буфера и частоты отрисовки, это, вероятно, не имеет большого значения.

...