目录

Metal Shader逐行调试方法

使用Xcode逐行Metal Shader

前言

对比其他图形学API,Metal的Shader调试是比较方便的,从WWDC2018开始,Metal就支持Shader的Profile和单行调试了。

官方相关视频可以参考 Metal Shader Debugging and Profiling,该视频介绍了相关技巧,附上该视频对应的 PPT下载地址

⚠️:Shader-Debug的抓帧调试都是适用于Online-Render,而非Offscreen-Render。

调试环境

⚠️:Xcode的版本升级或者SDK的升级,可能会导致Metal的Shader-Debug和CaptureFrame功能不可用,如果你目前的环境是Ok的,建议不要轻易升级。

本文档测试环境如下:

Mac 系统版本 iPhone-系统版本 Xcode版本 macOS-SDK版本 iOS-SDK
macOS 12.0.1 Monterey iOS 15.3 13.2 12.1 (21C46) 15.2 (19C51)

调试过程

情况A:metal以工程代码形式

Apple官方给出的Metal-Sample-Code就是以这种方式组织的,比如AAPLRender.metal文件处于Xcode工程目录树列表中,并且可以和Objective-C文件共享.h 头文件,直接和 Objective-C代码文件一起编译。

这种情况适用于自己写的简单Demo验证问题,非常方便,也非常推荐(不过缺点是CMake不支持这种形式直接configure)。

情况 A 以官方 Sample 工程 Creating And Sampling Textures为例子进行演示,且只讲述Mac过程,iOS平台也是类似的。

Step1: 设置Build-Setting

在Xcode的Build Settings中,先点击 左侧正确的target,搜索"produce debugging",在"Metal Compiler"下属的Debug设置,如下图,设置"Produce debugging information",选中到"Yes, include source code"。

Step2: 抓帧

以Debug模式运行后,单击 Capture Frame(Xcode13.0版本以前是照相机图标📷,从Xcode13.0起是个大写的M):

https://docs-assets.developer.apple.com/published/5d37f0c61d/3179308@2x.png

⚠️:如果遇到抓帧按键是灰色的,需要设置Run-Option (快捷键 Command + Shift + < ),设置GPU Frame Capture模式为 Metal

等待一会儿后自动跳转到抓帧界面,关注左边调用堆栈,依次点击 下拉 MyCommand -> MyRenderEncoder -> dr -> drawPrimitives 。

下拉菜单中,Geometry用于查看 vertex 阶段的顶点信息,Attachments 是用于查看fragements 信息,也是更常用的。

此处我们选Attachments,看到渲染的主画面, 鼠标左键长按 某个像素点,如下图所示:

如果Debug不顺畅,悬停于Debug按钮,若如果遇到SDK版本问题,可能会给出相关提示;

⚠️ :macOS-Deployment-SDK版本需要和使用的 Xcode 版本匹配,比如我的 Xcode13.2 要求至少为macOS-10.15。

若一切顺利,接上图步骤,单击 Debug 按钮,可以跳转到Shader,如下图所示:

Step3: 单行Shader-Debug

进入上述 Shader-Deubg 界面后,快捷键如下:

  • 鼠标双击切换行
  • 使用方向键 ⬆️ / ⬇️ 进行单行执行回放
  • 使用方向键 ⬅️ / ➡️ 进行单个函数的Step-out 和 Step-in

图中 Shader 右侧是变量观察栏,而且圈起的方框可点击预览Texture,还能调用系统Finder进行存储。

情况B:metal先自行编译metallib形式

使用 glsl 代码编译成 lib 后再导入 MTLLibrary ,适用于此类情况,使用起来更为麻烦一些。比如某个 *.metal 文件,直接调用命令行编译得到 metallib ,然后再让 metallib 参与 metal 应用的编译。

Step1: 设置Metal-Compile选项

需要在编译Metal-Lib时带上Symbol符号信息,才能启用Shader-Debug功能。在Xcode13.0之前,该编译选项是 -MO ,自 Xcode13.0 起,选项为 -frecord-sources=flat。命令示例如下:

1
2
3
4
5
6
7
#  假设以 RGBToYUV420 这个 shader 举例
#  这一行得到 air 中间文件(Apple Intermediate Representation)
xcrun -sdk macosx metal -c -frecord-sources RGBToYUV420.metal
#  这一行链接air中间文件,得到 metallib文件
xcrun -sdk macosx metal -frecord-sources -o RGBToYUV420.metallib RGBToYUV420.air
#  这一行分离metallib, 得到metallibsym符号文件, 在shader-debug的时候会提醒加载外部sym文件
xcrun -sdk macosx metal-dsymutil -flat  -remove-source RGBToYUV420.metallib
  • 更多命令选项可以在终端执行 xcrun -sdk macosx metal --help 查看。

Step2: 抓帧

在抓帧环节,如本节 Step1 所述,需要单独加载外部 metallibsym 符号,metal应用程序才能正确跳转到 metal 的shader 文件。

Step3: 单行Shader-Debug

和情况A一致,不赘述。

参考链接:

Apple: Developing and Debugging Metal Shaders

Apple: Generating and Loading a Metal Library Symbol File

Apple: Viewing Your GPU Workload with the Metal Debugger

All-Xcode-Release’s Download & SDK对照表