“捕获GPU帧”iOS应用程序的第一帧

“捕获GPU帧”iOS应用程序的第一帧,ios,xcode,metal,Ios,Xcode,Metal,我的应用程序在我使用的第一帧金属上执行了几个渲染操作,尽管我认为这同样适用于GLES。例如,它将渲染到在后续帧中使用但此后不会更新的目标。我正在尝试调试这些渲染操作中的一些绘制调用,我想使用“GPU捕获帧”功能来完成这项工作。我过去曾在按需GPU帧调试中使用过它,它非常有用 不幸的是,我似乎找不到捕捉第一帧的方法。例如,如果在调试器中在第一帧之前设置断点,则此选项不可用。Xcode行为似乎也不允许在调试开始后捕获帧。在Metal API或CametLayer中,似乎甚至没有用于执行GPU捕获的A

我的应用程序在我使用的第一帧金属上执行了几个渲染操作,尽管我认为这同样适用于GLES。例如,它将渲染到在后续帧中使用但此后不会更新的目标。我正在尝试调试这些渲染操作中的一些绘制调用,我想使用“GPU捕获帧”功能来完成这项工作。我过去曾在按需GPU帧调试中使用过它,它非常有用

不幸的是,我似乎找不到捕捉第一帧的方法。例如,如果在调试器中在第一帧之前设置断点,则此选项不可用。Xcode行为似乎也不允许在调试开始后捕获帧。在Metal API或CametLayer中,似乎甚至没有用于执行GPU捕获的API

有人成功地做到了吗?

试试

[myMTLCommandEncoder insertDebugSignpost: @"com.apple.GPUTools.event.debug-frame"]. 
老实说,我自己也没试过,但它和类似的东西很相似

glInsertEventMarkerEXT(0, "com.apple.GPUTools.event.debug-frame")

为OpenGL ES编写的文档,在web上有一些提到它为金属工作。

我又遇到了这个问题,现在已经正确地解决了。我将把它作为一个单独的答案添加,因为它与我的另一个答案完全不同

首先是一些背景。捕获GPU帧有三个组件:

告诉Xcode您想要捕获GPU帧。在典型的有文档记录的使用中,您可以通过单击Xcode中的GPU Frame Capture camera按钮手动执行此操作。 指示要捕获的下一帧的开始。通常,下一次出现MTLCommandBuffer presentDrawable:时会发生这种情况,调用MTLCommandBuffer presentDrawable:,将帧缓冲区呈现给基础视图。 指示正在捕获的帧的结束。通常,这会在下一次出现MTLCommandBuffer presentDrawable:时发生。 在捕获第一帧或第一帧之前的活动时,只有第三帧可用,因此我们需要另一种方法来执行前两项:

要告诉Xcode开始捕获帧,请在代码中要开始捕获帧的点之前的某一行的Xcode中添加一个断点。右键单击断点,选择编辑断点。。。从弹出菜单中,将捕获GPU帧操作添加到断点:

要在第一次出现MTLCommandBuffer presentDrawable:之前指示要捕获的帧的开始,可以使用MTLCommandQueue InsertDebugCaptureBundary方法。例如,您可以在实例化MTLCommandQueue后立即调用此方法,以立即开始捕获提交到队列的所有内容。确保在调用此代码之前触发项目1中的断点

要指示捕获帧的结束,您可以依赖第一次正常出现的MTLCommandBuffer presentDrawable:,也可以添加第二次调用MTLCommandQueue InsertDebugCaptureBundary


最后,MTLCommandQueue insertDebugCaptureBoundary方法实际上不会导致捕获帧。它只是标记了一个边界点,所以您可以将其保留在代码中以供将来调试使用。如果您希望它从生产代码中消失,请将其包装在调试编译条件中。

首先,在Metal中,我通常使用Metal进行并行计算,然后GPU捕获帧总是灰色的。所以,直到现在我发现有两种方法是可以的

在iOS 11中

您可以使用[[MTLCaptureManager alloc]startCaptureWithDevice:m_Device];捕获帧以便可以分析计算着色器性能

低于iOS 11的MTLCaptureManager和MTLCaptureScope是iOS 11.0中新增的 您可以使用断点,然后编辑Action.Capture GPU帧


看起来很有希望,但似乎对金属不起作用,至少对我来说不是。