addPresentedHandler не запускается в металле на iOS - PullRequest
1 голос
/ 20 марта 2020

Я уже некоторое время пытаюсь установить addPresentedHandler, но без удачи.

У меня есть addCompletedHandler, работающий над буферами команд, которые содержат работу рендеринга, которая будет выполняется каждый кадр. Я проверил, что addCompletedHandler работает, увидев установку точек останова в блоке кода. Они запускаются при запуске приложения. Для addPresentedHandler, однако, ни одна точка останова в блоке кода не сработала (я также проверил путем изменения переменных из блока кода и вставки printf s в блок).

Мой рендеринг l oop в настоящее время очень прост и выглядит следующим образом (надеюсь, я предоставил достаточно):

ПРИМЕЧАНИЕ: я использую сильную комбинацию C ++ и Objective-C ++. Поэтому приведенный ниже код не является прямым представлением действительного кода.

dispatch_semaphore_wait(m_inFlightFramesSemaphore, DISPATCH_TIME_FOREVER);
m_drawables[m_currentFrameIndex] = [m_swapChain nextDrawable];
MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor new];
renderPassDescriptor.colorAttachments[0].texture = m_drawables[m_currentFrameIndex].texture;
renderPassDescriptor.colorAttachments[0].level = 0;
renderPassDescriptor.colorAttachments[0].slice = 0;
renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(1.0, 1.0, 1.0, 1.0);

id<MTLCommandBuffer> commandBuffer = [m_commandQueue commandBuffer];
id<MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor: renderPassDescriptor];
[renderEncoder setRenderPipelineState: m_pipelineState];
[renderEncoder setTriangleFillMode: MTLTriangleFillModeFill];
[renderEncoder setFrontFacingWinding: MTLWindingCounterClockwise];
[renderEncoder setCullMode: MTLCullModeBack];
/* set viewport and scissor (omitted here) */
[renderEncoder useResource: m_vertexBuffer usage: MTLResourceUsageRead stages: MTLRenderStageVertex];
[renderEncoder setVertexBuffer: m_vertexBuffer offset: 0 atIndex: 0];
[renderEncoder useResource: m_indexBuffer usage: MTLResourceUsageRead stages: MTLRenderStageVertex];
[renderEncoder drawIndexedPrimitives: MTLPrimitiveTypeTriangle indexCount: 6
  indexType: MTLIndexTypeUInt32 indexBuffer: m_indexBuffer indexBufferOffset: 0
  instanceCount: 1];
[renderEncoder endEncoding];
PresentDrawable(commandBuffer, m_drawables[m_currentFrameIndex]);
CommitFinalCommandBufferInFrame(commandBuffer);

Два последних вызова функций реализованы следующим образом:

void PresentDrawable(id<MTLCommandBuffer> commandBuffer, id<CAMetalDrawable> drawable)
{
    [drawable addPresentedHandler:^(id<MTLDrawable> dr) {
        m_framesPresented++;
        if (m_framesPresented == m_maxFrames)
        {
            dispatch_semaphore_signal(m_lastFramePresentedSemaphore);
        }
    }];

    [commandBuffer presentDrawable:drawable];
}

void CommitFinalCommandBufferInFrame(id<MTLCommandBuffer> commandBuffer)
{
    [commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> cb) {
        dispatch_semaphore_signal(m_inFlightFramesSemaphore);
    }];

    [commandBuffer commit];
    m_framesSubmitted++;
    m_currentFrameIndex = (m_currentFrameIndex + 1) % m_maximumDrawableCount;
}

Я не понимаю, почему Блок кода addPresentedHandler не запускается, а блок addCompletedHandler ... я что-то упускаю из виду?

Спасибо!

Ответы [ 2 ]

1 голос
/ 23 марта 2020

В своем вопросе я не упомянул, что работал на симуляторе iPhone 11 Pro Max (v13.3). При попытке примерить iPhone 11 (v13.3.1) addPresentHandler, как реализовано в моем вопросе, срабатывает успешно. Я пытался определить, задокументировано ли это ограничение в функциональности на симуляторе где-либо, но оно оказалось пустым.

Как указано в документах , addPresentedHandler требует версию iOS версия 10.3. Это также отражено в его определении в MTLDrawable.h :

- (void)addPresentedHandler:(MTLDrawablePresentedHandler)block
                             API_AVAILABLE(ios(10.3))
                             API_UNAVAILABLE(macos, macCatalyst);

Нигде я не могу найти упоминаний об ограничениях для версии симулятора.

1 голос
/ 20 марта 2020

Я не вижу проблем с вашим кодом, я проверил, что он работает.

void PresentDrawable(id<MTLCommandBuffer> commandBuffer, id<CAMetalDrawable> drawable)
{
    [drawable addPresentedHandler:^(id<MTLDrawable> dr) {

        printf("Handler \n");
        m_framesPresented++;
        if (m_framesPresented == m_maxFrames)
        {
            dispatch_semaphore_signal(m_lastFramePresentedSemaphore);
        }
    }];

    [commandBuffer presentDrawable:drawable];
}
...