我的应用程序在第一帧上执行了几次渲染操作(我使用的是Metal,虽然我认为这同样适用于GLES)。例如,它渲染到后续帧中使用的目标,但之后不会更新。我正在尝试从这些渲染操作调试一些绘制调用,我想使用' GPU Capture Frame'这样做的功能。我过去曾用它来进行按需GPU帧调试,它非常有用。
不幸的是,我似乎找不到捕获第一帧的方法。例如,在调试器中断开时(在第一帧之前设置断点),此选项不可用。调试开始后,Xcode行为似乎也不允许捕获帧。在Metal API或CAMetalLayer中,甚至还没有用于执行GPU捕获的API。
是否有人成功完成了这项工作?
答案 0 :(得分:6)
我再次遇到过这个问题,现在正确地想出来了。我将此作为单独的答案添加,因为它与我的其他答案完全不同。
首先,一些背景知识。捕获GPU帧有三个组件:
MTLCommandBuffer presentDrawable:
的 next 出现时,会调用它来将帧缓冲区呈现给基础视图。MTLCommandBuffer presentDrawable:
的 next-but-one 次。在第一帧之前捕获 第一个 框架或活动时,只有第三个框架可用,所以我们需要一个替代框架执行前两项的方法:
要告诉 Xcode 开始捕获一个帧,请在 Xcode 中的代码中的之前的某处 中添加一个断点您想要开始捕获帧的点。右键单击断点,从弹出菜单中选择 编辑断点... ,然后将捕获GPU帧操作添加到断点:
要指示要捕获的帧的开始,在第一次出现MTLCommandBuffer presentDrawable:
之前,您可以使用MTLCommandQueue insertDebugCaptureBoundary
方法。例如,您可以在实例化MTLCommandQueue
后立即调用此方法,以立即开始捕获提交到队列的所有内容。确保在调用此代码之前触发第1项中的断点。
要指示捕获帧的结束,您可以依赖MTLCommandBuffer presentDrawable:
的第一次正常出现,也可以添加MTLCommandQueue insertDebugCaptureBoundary
的第二次调用。
最后,MTLCommandQueue insertDebugCaptureBoundary
方法实际上并不会导致捕获帧。它只是标记了一个边界点,因此您可以将其保留在代码中以供将来调试使用。如果您希望它从生产代码中删除,请将其包装在DEBUG
编译条件中。
答案 1 :(得分:0)
首先,在Metal中,我通常使用Metal进行并行计算,然后GPU Capture帧总是灰色的。所以,有两种方法,直到现在我发现是好的。
在iOS 11中
您可以使用[[MTLCaptureManager alloc] startCaptureWithDevice:m_Device];
捕获帧,以便分析计算着色器性能
低于iOS 11(MTLCaptureManager&&& MTLCaptureScope是iOS 11.0中的新功能)
您可以使用断点,然后编辑操作。Capture GPU Frame