Сбой iOS: значение MTLRenderPassDescriptor null после поворота

Я пишу приложение для iOS с помощью Metal. В какой-то момент во время рисования MTKViewDelegate я создаю дескриптор прохода рендеринга и визуализирую вещи на экране,

let encoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor)
encoder.setViewport(camera.viewport)
encoder.setScissorRect(camera.scissorRect)

В начале моей функции рисования у меня есть семафор, тот же код, что и в шаблоне игры Metal, найденный в Xcode, а затем проверка, чтобы убедиться, что представление не изменило размер. Если это так, я воссоздаю свои буферы,

    let w = _gBuffer?.width ?? 0
    let h = _gBuffer?.height ?? 0
    if let metalLayer = view.layer as? CAMetalLayer {
        let size = metalLayer.drawableSize
        if w != Int(size.width) || h != Int(size.height ){
            _gBuffer = GBuffer(device: device, size: size)
        }
    }

Все работает нормально, и на моем iPhone6 ​​вращение работало нормально. Однако, когда я пробовал на iPad Pro, он всегда генерировал SIGABRT, когда я пытаюсь повернуть устройство. Отладчик сообщает мне, что кодировщик обнулен. Я также получаю это исключение в консоли,

MTLDebugRenderCommandEncoder.mm:2028: failed assertion `(rect.x(1024) + rect.width(1024))(2048) must be <= 1536'

Исключение должно произойти, потому что я обновляю "камеру" внутри mtkView,

func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
    camera.setBounds(view.bounds)
}

Когда я запускаю без подключенного отладчика, он не дает сбоев. Я предполагаю, что mtkView вызывается асинхронно, и я должен что-то сделать, чтобы остановить рендеринг на полпути, когда вызывается mtkView, но мьютекс должен быть в библиотеке, а не в моем коде? Хотя и draw, и mtkView вызываются из одного и того же потока (поток 1 в отладчике) ... Если я пошагово отлаживаю, помещая точки останова в рисование и mtkView, кажется, что я вручную синхронизирую, и он не падает. Я немного заблудился ...

Полный исходный код находится здесь: https://github.com/endavid/VidEngine

Любые идеи?


person endavid    schedule 05.11.2016    source источник


Ответы (2)


Сообщение об исключении было подсказкой. Меня отвлекло то, что кодировщик обнулен. Я предполагаю, что после создания исключения он становится нулевым, но проблема была не в кодировщике.

Код в camera.setBounds (view.bounds) не обновлял scissorRect ... У меня есть CADisplayLink, который обновляет объекты ЦП с другой скоростью, и scissorRect обновлялся там, когда обнаруживал изменение.

Я добавил вызов к полному обновлению камеры внутри mtkView (), и сбой исчез :)

person endavid    schedule 05.11.2016

Я могу решить эту проблему, сняв флажок «Отладка исполняемого файла» в схеме  введите описание изображения здесь

person Jorge Paiz    schedule 29.08.2017