在 iOS 上的 Metal 中未触发 addPresentedHandler [英] addPresentedHandler not being triggered in Metal on iOS

查看:51
本文介绍了在 iOS 上的 Metal 中未触发 addPresentedHandler的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经尝试设置 addPresentedHandler 一段时间了,但没有成功.

I've been trying to set up a addPresentedHandler for some time now, but without luck.

我有一个 addCompletedHandler 处理命令缓冲区,其中包含要每帧执行的渲染工作.我已经通过查看代码块中的设置断点来验证 addCompletedHandler 是否正常工作.这些是在运行应用程序时触发的.然而,对于 addPresentedHandler,代码块内没有触发断点(我还通过修改代码块中的变量,并将 printfs 插入块中进行了验证).

I've got a addCompletedHandler working on the command buffers that contain the rendering work to be executed every frame. I've verified that the addCompletedHandler is working by seeing setting breakpoints within the code block. These are triggered when running the app. For the addPresentedHandler however, no breakpoint within the code block is triggered (I've also verified through modifying variables from the code block, and inserting printfs into the block).

我的渲染循环目前非常简单,看起来像这样(希望我已经提供了足够的信息):

My rendering loop is currently very simple, and looks like this (hopefully I've provided enough):

注意:我使用了 C++ 和 Objective-C++ 的强大组合.因此,下面提供的代码不是实际代码的直接表示.

NOTE: I'm using a strong combination of C++ and Objective-C++. The code presented below is therefore not a direct representation of the actual code.

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);

最后两个函数调用实现如下:

The two final function calls are implemented as follows:

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 代码块是......我错过了一些明显的东西吗?

I don't see why the addPresentedHandler code block isn't be triggered, while the addCompletedHandler block is...am I missing something obvious?

谢谢!

推荐答案

在我的问题中,我没有提到我在 iPhone 11 Pro Max (v13.3) 模拟器上运行.在尝试使用实际的 iPhone 11 (v13.3.1) 时,我的问题中实现的 addPresentHandler 成功触发.我试图确定模拟器上的这种功能限制是否记录在任何地方,但结果是空的.

In my question, I did not mention that I was running on the iPhone 11 Pro Max (v13.3) Simulator. Upon trying on an actual iPhone 11 (v13.3.1) the addPresentHandler as implemented in my question triggers successfully. I've tried to determine if this limitation in functionality on the simulator is documented anywhere, but have come up empty.

文档中所述,addPresentedHandler 需要 iOS 版本 10.3.这也反映在它在 MTLDrawable.h 中的定义中:

As specified in the docs, addPresentedHandler requires version iOS version 10.3. This is also reflected in it's definition in MTLDrawable.h:

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

我找不到任何提及模拟器版本限制的地方.

Nowhere can I find any mention of limitations for the simulator version.

这篇关于在 iOS 上的 Metal 中未触发 addPresentedHandler的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆