IOS图形调试的时候,用Xcode就行了,Xcode虽然不咋好用,但还是要啥有啥的。安卓图形调试,就比较纠结了,NV的frame debugger夜光,爽的不行,但只支持自家显卡。高通和Iimagination相同,PVR SDK体验一般,能用,高通的就很难用了。安卓图形debug以前真是不怎么样。但是今年,谷歌终于为大家带来了自家的图形调试器,Graphics API Debugger,简称GAPID

GAPID简介

       GAPID是谷歌推出的图形调试工具集,专注于安卓应用调试,可以调试安卓上的openGL ES程序和vulkan程序,最近的0.9.0版本添加了调试桌面上vulkan程序的功能。

       GAPID的编辑器是跨平台的,由GO语言写成,支持windows/mac/linux。并且在各个平台都使用原生的窗口程序开发(WIN32,Cocoa,X11)。我提一嘴这个是因为隔壁某用Qt编写的调试器,mac不支持,linux版的UI依旧各种小问题。

       GAPID由5个主要模块:

  • gapii: Graphics API Interceptor: 位于应用程序/游戏和 GPU 驱动程序之间的一层,记录所有调用和内存访问
  • gapis: Graphics API Server:分析报告不正确的捕获流 API 使用情况,处理在各种目标设备上重复过程的数据,并向客户端提供 RPC 接口
  • gapir: Graphics API Replay daemon:一个基于堆栈的 VM,用于回放捕获文件,模仿原始应用程序/游戏对 GPU 驱动程序的调用。支持读取任何缓冲区/帧缓冲区,并提供分析功能
  • gapic: Graphics API Client:前端用户界面应用。提供捕获数据、内存、资源和帧缓冲区内容的可视化检查
  • gapil: Graphics API Language:一种新的特定领域语言,用于全面描述图形 API。gapii、gapis和gapir的绝大部分都是依赖它结合模板生成的

GAPID简易教程

1. Capture a Trace

1.1 Tracing an Android application

Tracing an Android application

  1. 最低需要安卓5.0版本
  2. 必须是可调试的程序,或者是台root了的手机
  3. 需要已安装Android SDK,手机通过USB连接

1.2 Tracing a Desktop application

Tracing a Desktop application

  1. 桌面只支持vulkan,不支持OpenGL
  2. 被调试程序必须是64位的

2. 找到当前被绑定的shader

2.1 OpenGL ES

       在Command面板中找到glUseProgram()命令

找到glUseProgram()

       然后在State面板的Bound->Program中找到对应ID即可

找到对应ID

2.2 Vulkan

       先找到VkQueueSubmit调用的地方

VkQueueSubmit call

       然后找到LastDrawInfos-><ID of the Queue in VkQueueSubmit>->(Graphics|Compute)Pipeline->Stages-><Stage>->Module,能找到绑定shader的VulkanHandle

VulkanHandle sahder

3. 修改shader

       这也是GAPID最令我佩服的一点,不光能看shader,还能即使修改shader查看效果,看了开发一套gapil是值得的

  1. 打开shader面板
  2. 修改shader
  3. 点击Push Changes,等待结果

修改shader

对于vulkan,显示的shader为SPIRV反编译后的代码

4. 查看贴图

       查看贴图非常简单,打开Textures面板即可

查看贴图

5. 导出资源

       GAPID可以导出模型和贴图,比隔壁renderdoc贴心多了

5.1 导出模型

       在Geometry面板中找到对应的draw call,点击Save model as OBJ就能导出obj格式的模型

模型面板

5.2 导出贴图

       在Textures面板找到贴图,点击Save image to file就能导出贴图(PNG格式)

贴图面板

程序优化建议

通用

       无论什么情况下,减少贴图数量,减少模型面数,简化shader复杂度,都能提高程序效率

OpenGL ES

       OpenGL ES因为Draw CallsState Changes数量增多,性能会急剧下降

Vulkan

       Vulkan中Draw CallsState Changes数量并不和性能直接挂钩(不过最好还是减少两者),但是vulkan程序的性能受Render PassesSubpasses影响很大,也许vulkan更适合前向渲染而不适合延迟渲染吧。

附录:Metal程序调试

       反正也想写,一块写了吧

构建metallib

构建metallib

  1. 使用metal命令将.metal文件编译成.air文件
  2. [可选]使用metal-ar命令将多个.air文件打包为一个.metalar文件
  3. 使用metallib把多个.air文件或者.metalar文件构建为.metallib
xcrun -sdk macosx metal MyLibrary.metal -o MyLibrary.air
xcrun -sdk macosx metallib MyLibrary.air -o MyLibrary.metallib

       在程序中调用metallib

NSError *libraryError = NULL;
NSString *libraryFile = [[NSBundle mainBundle] pathForResource:@"MyLibrary" ofType:@"metallib"];
id <MTLLibrary> myLibrary = [_device newLibraryWithFile:libraryFile error:&libraryError];
if (!myLibrary) {
    NSLog(@"Library error: %@", libraryError);
}

开启调试

       修改启动配置

修改启动配置

调试界面

       调试界面如下

Xcode调试界面