///

帧分析概述

借助 Android GPU Inspector (AGI),您可以分析您的 Android 应用程序的特定帧,并使用它对应用程序的 GPU 使用情况进行深入分析。与单独进行系统分析相比,此分析数据可以让您更深入地了解应用程序的 GPU 使用情况。

使用 AGI 进行帧分析首先要收集跟踪和其他性能数据,然后对其进行测量和显示以供分析。

可用的帧分析数据包括以下内容:

  • Vulkan API 调用

  • 帧缓冲内容

  • 渲染网格绘制调用

  • 命令的 RAM 和 GPU 内存值

  • 渲染事件的 GPU 性能数据

  • 管道数据

  • 渲染状态数据

  • 纹理和着色器资源

开始使用

AGI快速入门介绍了如何设置 AGI、捕获帧配置文件数据,然后打开生成的跟踪文件。下一节将更详细地描述配置选项。

分析选项

本节介绍捕获帧配置文件时可用的主要选项。

图形 API 选项

图形 API 选项指示您的应用程序使用的图形 API。这些选项在“捕获系统配置文件”对话框的“类型”列表中可用。这些是可用的选项:

  • Vulkan:适用于直接使用 Vulkan API 的应用程序。
  • OpenGL on ANGLE:适用于使用 OpenGL ES 的应用程序。

AGI 直接跟踪 Vulkan 命令。但是,如果您的应用程序使用 OpenGL ES,AGI 会在跟踪应用程序之前使用自定义ANGLE构建将命令转换为 Vulkan 命令。

附加论点

Additional Arguments字段用于将其他标志传递给 adb命令am start-activity,该命令将发送到您的设备以在分析期间启动您的应用程序。有关详细信息,请参阅 adb 命令。

开始和持续时间选项

开始和持续时间部分,您可以指定 AGI 如何捕获帧以进行分析。可以使用以下选项:

  • 开始:AGI 捕获从应用程序启动到第一个渲染帧结束的所有命令。

  • 手动:按下跟踪对话框中的按钮以手动捕获帧。

  • Time:AGI 在给定的秒数过去后自动捕获一帧。

  • :AGI 自动捕获指定的帧。

跟踪选项

跟踪选项部分包含配置跟踪标志的设置。这些是可用的设置:

  • 禁用缓冲:捕获数据时禁用设备上的内存缓冲。此选项对于调试应用程序崩溃很有用,因为它确保所有跟踪数据都序列化到崩溃为止。但是,它会稍微增加分析期间 AGI 的开销。

  • 隐藏未知扩展:隐藏设备上 AGI 不支持的扩展。如果您的应用使用 AGI 不支持的扩展,则在重放跟踪时可能会遇到错误。

  • 清除包数据:使用pm clear adb 命令请求设备在启动前清除您的应用程序的用户数据。

输出设置

输出部分包含跟踪文件存储的设置,例如:

  • 指定存储跟踪文件的目录。

  • 修改自动生成的跟踪文件的文件名。

查看结果

当您打开包含帧分析数据的跟踪文件时,AGI 会在 Frame Profiler UI 中显示数据以进行分析。

Frame Profiler 是一个 AGI 组件,它管理用于分析单个帧的 UI 和工具。Frame Profiler 在以下 UI 元素中显示数据:

  • 命令窗格:Vulkan API 调用。

  • 帧缓冲区窗格:帧缓冲区内容。

  • 几何窗格:网格绘制调用的渲染。

  • 内存窗格:命令的 RAM 和 GPU 内存值。

  • 性能窗格:渲染事件的 GPU 性能数据。

  • 管道窗格:管道内容。

  • 着色器窗格:着色器内容。

  • 状态窗格:提交命令的渲染状态。

  • 纹理窗格:与命令关联的纹理资源列表。

  • 纹理窗格:选定纹理资源的内容。

  • 报告窗格:分析错误列表。

分析结果

这些主题描述了如何使用 AGI 分析帧分析数据:

  • 分析渲染通道
  • 分析着色器性能
  • 分析顶点格式

///

确定最昂贵的渲染通道

AGI Frame Profiler 可让您检查用于构成应用程序单个帧的各个渲染通道。它通过拦截和记录执行每个图形 API 调用所需的所有状态来做到这一点。在 Vulkan 上,这是使用 Vulkan 的分层系统本地完成的。在 OpenGL 上,使用 ANGLE 拦截命令,它将 OpenGL 命令转换为 Vulkan 调用,以便它们可以在硬件上执行。

肾上腺素装置

要确定昂贵的渲染通道,首先查看窗口顶部的 AGI 时间线视图。这显示了按时间顺序组成给定帧的所有渲染通道。如果您有 GPU 队列信息,这与您在 System Profiler 中看到的视图相同。它还提供了有关渲染通道的基本信息,例如被渲染到的帧缓冲区的分辨率,这可以提供对渲染通道本身发生的情况的一些了解。

您可以用来调查渲染通道的第一个标准是它们花费了多少时间。最长的渲染通道很可能是具有最大改进潜力的渲染通道,因此请从查看该通道开始。

与相关渲染通道相关的 GPU 切片已经显示了有关渲染通道中发生的情况的一些信息:

  1. Binning:根据它们在屏幕上的位置将顶点放置到 bin 中的位置
  2. 渲染:像素或片段被着色的地方
  3. GMEM 加载/存储:当帧缓冲区的内容从内部 GPU 内存加载或存储到主内存时

通过查看每个在渲染过程中花费的时间,您可以很好地了解潜在的瓶颈可能在哪里。例如:

  • 如果分箱占用大部分时间,这表明顶点数据存在瓶颈,这表明顶点过多、顶点大或与顶点相关的其他问题。
  • 如果渲染占用大部分时间,这表明着色是瓶颈。可能的原因可能是复杂的着色器、太多的纹理提取、在不需要时渲染到高分辨率帧缓冲区或其他相关问题。

GMEM 加载和存储也是需要牢记的。将内容从图形内存转移到主内存是很昂贵的,因此最小化加载或存储操作的数量也将有助于提高性能。一个常见的例子是有一个 GMEM 存储深度/模板,它将深度/模板缓冲区写入主内存;如果您在以后的渲染过程中不使用该缓冲区,则可以消除此存储操作,您将节省帧时间和内存带宽。

大型渲染通道调查

要查看在渲染过程中发出的所有单独的绘制命令:

  1. 单击时间轴中的渲染过程。这会在Frame Profiler的Commands窗格中打开层次结构中的渲染过程。

  2. 单击渲染通道的菜单,该菜单显示在渲染通道期间发出的所有单独的绘制命令。如果这是一个 OpenGL 应用程序,您可以进一步挖掘并查看 ANGLE 发出的 Vulkan 命令。

选择其中一个绘图调用。这将打开Framebuffer窗格,其中显示了在此绘制期间绑定的所有帧缓冲区附件,以及在附加帧缓冲区上绘制的最终结果。在这里你也可以使用 AGI 同时打开前一个和下一个绘制调用,并比较两者的区别。如果它们在视觉上几乎相同,这表明有机会消除对最终图像没有贡献的绘制调用。

打开此绘制的管道窗格显示图形管道用于执行此绘制调用的状态。

Input Assembler提供有关顶点数据如何绑定到此绘图的信息。如果您注意到分箱占用了渲染通道的大部分时间,那么这是一个很好的研究领域;在这里,您可以获得有关顶点格式、绘制的顶点数量以及顶点在内存中的布局方式的信息。有关这方面的更多信息,请参阅分析顶点格式。

Vertex Shader部分提供了有关您在此绘制期间使用的顶点着色器的信息,并且也可以是调查分箱是否被确定为问题的好地方。您可以查看使用的着色器的 SPIR-V 和反编译的 GLSL,并调查此调用的绑定统一缓冲区。有关详细信息,请参阅分析着色器性能。

Rasterizer部分向您显示有关管道的更多固定功能设置的信息,并且可以更多地用于固定功能状态的调试目的,例如视口、剪刀、深度状态和多边形模式。

片段着色器部分提供了许多与顶点着色器部分相同的信息,但特定于片段着色器。在这种情况下,您实际上可以通过单击手柄查看正在绑定的纹理并调查它们。

较小的渲染通道调查

您可以用来提高 GPU 性能的另一个标准是查看较小的渲染通道组。通常,您希望尽可能减少渲染通道的数量,因为 GPU 将状态从一个渲染通道更新到另一个渲染通道需要时间。这些较小的渲染通道通常用于生成阴影贴图、应用高斯模糊、估计亮度、进行后期处理效果或渲染 UI。其中一些可能会合并到一个渲染通道中,如果它们对整体图像的影响不足以证明成本合理,甚至可以完全消除它们。

///

分析顶点格式

您可以通过使用帧分析来诊断一些可能的与顶点相关的性能问题。使用命令窗格查看游戏在给定帧中执行的所有绘制调用以及每个绘制调用绘制的图元计数。这可以给出单个帧中提交的顶点总数的近似值。

顶点属性压缩

您的游戏可能面临的一个常见问题是较大的平均顶点大小。大量提交的平均顶点大小较高的顶点导致GPU读取时的顶点内存读取带宽较大。

要观察给定绘图调用的顶点格式,请完成以下步骤:

  1. 选择感兴趣的抽奖。

    这可以是场景的典型绘制调用、具有大量顶点的绘制调用、复杂角色模型的绘制调用或某些其他类型的绘制调用。

  2. 导航到Pipeline窗格,然后单击IA进行输入程序集。这定义了进入 GPU 的顶点的顶点格式。

  3. 观察一系列属性及其格式;例如, R32G32B32_SFLOAT是一个 3 分量 32 位有符号浮点数。

通常,可以压缩顶点属性,而对所绘制模型的质量降低最少。特别是,我们建议:

  • 将顶点位置压缩为半精度 16 位浮点数
  • 将 UV 纹理坐标压缩为 16 位无符号整数 ushorts
  • 通过使用四元数对法线、切线和副法线向量进行编码来压缩切线空间

对于低精度类型,也可以根据具体情况考虑其他杂项属性。

顶点流分裂

您还可以调查顶点属性流是否被适当拆分。在诸如移动 GPU 之类的平铺渲染架构上,顶点位置首先在分箱过程中使用,以创建在每个平铺中处理的图元箱。如果顶点属性交错到单个缓冲区中,则所有顶点数据都被读入缓存以进行分箱,即使只使用顶点位置也是如此。

为了减少顶点读取内存带宽并提高缓存效率,从而减少在 binning pass 上花费的时间,顶点数据应该分成两个单独的流,一个用于顶点位置,一个用于所有其他顶点属性。

调查顶点属性是否被适当分割:

  1. 选择感兴趣的抽奖电话,并记下抽奖电话号码。

    这可以是场景的典型绘制调用、具有大量顶点的绘制调用、复杂角色模型的绘制调用或某些其他类型的绘制调用。

  2. 导航到Pipeline窗格,然后单击IA进行输入程序集。这定义了进入 GPU 的顶点的顶点格式。

  3. 观察你的顶点属性的绑定;通常这些可能会线性增加(0、1、2、3 等),但情况并非总是如此。顶点位置通常是列出的第一个顶点属性。

  4. 状态窗格中,找到LastDrawInfos并展开匹配的绘制调用编号。然后,展开BoundVertexBuffers此绘图调用。

  5. 观察给定绘制调用期间绑定的顶点缓冲区,其索引与之前的顶点属性绑定相匹配。

  6. 展开绘图调用的顶点属性的绑定,并展开缓冲区。

  7. 观察VulkanHandle缓冲区,它表示顶点数据来源的底层内存。如果VulkanHandles 不同,这意味着属性来自不同的底层缓冲区。如果VulkanHandles 相同但偏移量很大(例如,大于 100),则属性可能仍然来自不同的子缓冲区,但这需要进一步调查。

有关顶点流拆分以及如何在各种游戏引擎上解决它的更多详细信息,请参阅我们关于该主题的博客文章。

//

分析着色器性能

AGI Frame Profiler 允许您通过从我们的一个渲染通道中选择一个绘制调用,并通过Pipeline 窗格的Vertex Shader部分或Fragment Shader部分来研究您的着色器。

在这里,您会发现有用的统计数据来自对着色器代码的静态分析,以及 我们的 GLSL 已编译成的标准可移植中间表示(SPIR-V) 程序集。还有一个选项卡用于查看使用 SPIR-V Cross 反编译的原始 GLSL(具有编译器生成的变量、函数等名称)的表示,为 SPIR-V 提供额外的上下文。

静态分析

使用静态分析计数器查看着色器中的低级操作。

  • ALU 指令:此计数显示了在着色器中执行的 ALU 操作(加法、乘法、除法等)的数量,并且可以很好地反映着色器的复杂程度。尝试最小化这个值。

    重构常见计算或简化在着色器中完成的计算有助于减少所需的指令数量。

  • 纹理说明:此计数显示纹理采样在着色器中发生的次数。

    • 纹理采样可能会很昂贵,具体取决于从中采样的纹理类型,因此将着色器代码与“描述符集”部分中的绑定纹理交叉引用可以提供有关正在使用的纹理类型的更多信息。
    • 采样纹理时避免随机访问,因为这种行为不适合纹理缓存。
  • 分支指令:此计数显示着色器中的分支操作数。最小化分支是 GPU 等并行处理器的理想选择,甚至可以帮助编译器找到额外的优化:

    • 使用 、 和 等函数minmax避免clamp需要对数值进行分支。
    • 测试分支的计算成本。因为一个分支的两条路径都在许多架构中执行,所以在很多情况下,总是进行计算比使用分支跳过计算要快。
  • 临时寄存器:这些是快速的核心寄存器,用于保存 GPU 计算所需的中间操作的结果。在 GPU 不得不溢出到使用其他核外内存来存储中间值之前,可用于计算的寄存器数量是有限的,从而降低了整体性能。(此限制因 GPU 型号而异。)

    如果着色器编译器执行诸如展开循环之类的操作,使用的临时寄存器的数量可能会高于预期,因此最好将该值与 SPIR-V 或反编译的 GLSL 交叉引用以查看代码在做什么。

着色器代码分析

调查反编译的着色器代码本身以确定是否有任何潜在的改进是可能的。

  • 精度:着色器变量的精度会影响应用程序的 GPU 性能。

    • mediump尽可能尝试对变量使用精度修饰符,因为中等精度 ( ) 16 位变量通常比全精度 ( ) 32 位变量mediump更快且更节能。highp
    • 如果在变量声明的着色器中或在着色器顶部没有看到任何精度限定符 precision precision-qualifier​ type​,则默认为全精度 ( highp)。确保也查看变量声明。
    • mediump出于上述相同的原因,使用顶点着色器输出也是首选,并且还具有减少内存带宽和可能需要进行插值的临时寄存器使用的好处。
  • Uniform Buffers:尽量保持Uniform Buffers的大小尽可能小(同时保持对齐规则)。这有助于使计算与缓存更加兼容,并可能允许将统一数据提升到更快的核心寄存器。
  • 移除未使用的顶点着色器输出:如果您发现片段着色器中未使用顶点着色器输出,请将它们从着色器中移除以释放内存带宽和临时寄存器。

  • 将计算从片段着色器移动到顶点着色器:如果片段着色器代码执行的计算独立于被着色片段特定的状态(或可以正确插值),则将其移动到顶点着色器是理想的。原因是在大多数应用程序中,顶点着色器的运行频率远低于片段着色器。

性能窗格

性能窗格显示不同渲染事件的GPU 性能。

此窗格中包含三个组件:

  • 工具栏:包含用于自定义性能表 或启动实验的功能按钮。
  • 性能表性能选项卡的主表格视图。每行代表一个渲染事件,每一列代表一个 GPU 指标(GPU 时间或 GPU 计数器)。通过这种方式,特定的数字单元代表特定 GPU 指标在特定渲染事件中的性能。
  • GPU 计数器详细信息图:详细显示 GPU 指标在渲染事件发生期间如何波动。该图表仅刷新 GPU 计数器指标,但不刷新 GPU 时间指标,因为时间指标是不言自明的并且不随时间波动。

工具栏

  • 估计/置信范围按钮:切换性能数字的显示方式。由于 GPU 计数器样本按照自己的节奏进行轮询,因此其时间范围可能与渲染事件的时间范围不完全一致。当它们部分重叠时,可能对计数器样本对渲染事件的贡献有多种解释,范围从零贡献到完全贡献。基于边缘情况,我们计算了Confidence Range;并基于重叠时间的权重,我们计算了Estimate
  • 实验:打开一个对话框以选择您要运行的实验。AGI 让您可以选择尝试一些常见的优化实践,而无需重新编译您的应用程序。当您开始实验时,AGI 会根据新设置重播帧,并相应地更新 GPU 性能表。
  • 筛选计数器:打开一个对话框,用于选择您希望在性能表中显示的指标列。
  • 预设栏:由添加新预设按钮和以下自定义预设按钮组成。预设是 GPU 指标的预定义组合。当您单击预设按钮时,性能表会显示预定义指标的过滤列表。您还可以在“ 添加新预设”对话框中管理预设。

性能表

此表与配置文件窗格和命令窗格链接。渲染事件在跟踪中具有三种表示格式:性能窗格中的行、配置文件窗格中的切片和命令窗格中的节点。为了便于浏览,当您选择其中一种格式时,其他两种格式也会突出显示。例如,如果您对Profile窗格中最长的切片感兴趣,您可以选择它,然后导航到突出显示的Performance行以查看此事件的详细 GPU 计数器性能。

GPU 计数器详细信息图

  • x 轴显示计数器样本的时间戳。请注意,时间基于第一个渲染事件的开始时间,因此有时您可能会在第一个计数器样本的计数器详细信息图中看到负时间戳,该时间戳与第一个渲染事件部分重叠。
  • y 轴显示计数器样本的指标性能值。
  • 每个条上方带括号的数字显示了计数器样本的权重,或者我们认为样本在估计的场景中对渲染事件的贡献程度。

//

命令窗格

命令窗格显示应用程序发出的调用,按帧和绘制调用或用户标记分组。

图 1: OpenGL 或 Vulkan 跟踪的初始视图

图 2:查看 OpenGL 跟踪

图 3:查看 Vulkan 跟踪

图 4:在 Vulkan 跟踪中搜索命令

运营

您可以在此窗格中执行以下操作:

手术 描述
显示结果 单击命令或组以更新其他窗格以反映选定命令或组之后的状态。
展开或折叠命令层次结构 单击分组左侧的灰色三角形或双击分组以展开或折叠它。
搜索 在窗格顶部的搜索栏中键入一个字符串,然后按 Return(参见上图)。要查找下一个匹配项,请确保选中该栏并再次按Return。 选择Regex框以使用正则表达式搜索模式。例如,同时匹配命令 和. 您还可以搜索命令参数值,例如 buffer: ,它用于glClear.*glClear()glClearColor()2glBindBuffer().
编辑 右键单击命令并选择编辑。在“编辑” 对话框中,更改一个或多个值,然后单击“确定” 。注意:这仅对 Vulkan 命令有效,对 OpenGL 命令无效。
查看状态或内存信息 单击引用状态参数的命令参数,例如纹理 ID。状态窗格显示附加信息。单击内存地址或指针以打开“内存”窗格。注意:这仅对 Vulkan 命令有效,对 OpenGL 命令无效。
复制命令 选择窗格中的项目并按 Control+C(或 Command+C)以复制命令及其参数值。您可以将此信息粘贴到文本文件中。
放大缩略图 缩略图显示在呼叫的左侧,如下图所示。将光标悬停在缩略图上以放大它。

OpenGL ES 命令层次结构

OpenGL ES命令被翻译成Vulkan,对Vulkan命令进行分析。因此,OpenGL ES 命令与扩展层次结构中显示的 OpenGL ES 和 Vulkan 命令一起显示。在前面的示例中,您可以glDrawElementRenderPass. 扩展了第二个 glDrawElements命令层次结构,并显示了OpenGL ES Commands 和DrawIndexed。您可以展开这两个层次结构以显示相关的 OpenGL ES 命令,以及它们被翻译成的 Vulkan 命令。

因为 OpenGL ES 和 Vulkan 之间没有一对一的关系,所以可能存在一些差异。例如,glClear出现在第一个命令之前的glDraw*命令出现在RenderPass. 如果您扩展 的层次结构glClear,将没有 Vulkan 命令。这是因为清除将被推迟并作为启动 Vulkan 的一部分完成RenderPass

调试标记

根据您的应用程序,“命令”窗格可以在一帧内包含很长的命令列表。为了更好的导航和可读性,您可以定义调试标记,将调用组合在树中的标题下。这可能包括一个分组,例如,名为“Setup”或“Render World”的分组。

如果启用了调试标记,请单击命令窗格以显示指向此信息的链接。OpenGL ES 具有以下 API 来对命令进行分组:

扩展/版本 流行音乐
KHR_debug glPushDebugGroupKHR() glPopDebugGroupKHR()
EXT_debug_marker String String
OpenGL ES 3.2 String String

Vulkan 具有以下 API 来对命令进行分组:

扩展/版本 流行音乐
VK_EXT_debug_marker glPushDebugGroupKHR() glPopDebugGroupKHR()

帧缓冲区窗格

Framebuffer窗格显示当前绑定的帧缓冲区的内容。根据您在“命令”窗格中选择的项目,“缓冲区” 窗格可以显示屏幕或屏幕外帧缓冲区。

当您在“命令”窗格中选择命令时,“缓冲区”窗格会在该调用完成后显示帧缓冲区的内容。如果您选择一个命令组,它会显示最能代表该组的帧缓冲区。通常,这是组中最后一次调用完成后的帧缓冲区。

首先选择帧内的第一个调用,然后单击每个连续调用以观察帧缓冲区组件一个接一个地绘制,直到帧结束。这些用于屏幕上和屏幕外图形的帧缓冲区显示可帮助您定位任何渲染错误的来源。

将光标移到图像上可在视图的左下角显示周围像素的放大预览,如上图所示。该窗格还显示图像宽度和高度以及图像上该点的xy坐标、标准化图像坐标(U 和 V 值)和 RBGA 十六进制值。

选择不同的附件

一个帧缓冲区可以包含多个附件。您可以选择要显示的附件,然后根据需要单击显示附件隐藏附件。附件缩略图标有附件类型(例如,颜色、深度和输入)及其索引。

选择附件后,主视图将显示在左上角。

运营

您可以使用以下按钮对帧缓冲区图像执行操作:

/

几何窗格

几何窗格呈现所选绘制调用的预转换网格。您可以使用鼠标或触摸板来旋转模型,并放大和缩小

下表描述了您可以使用工具栏按钮执行的操作:

//

报告窗格

报告窗格显示在捕获及其回放中发现的任何问题。这包括由不正确的参数使用、无效的命令序列或用于重放的驱动程序报告的错误引起的问题。

如果您使用 GAPID 来诊断不正确的渲染,请检查“报告”窗格是否有任何问题。

Vulkan 的注意事项

报告”窗格目前显示的 Vulkan 消息很少。此外,鉴于 Vulkan 的显式和低级性质,在与跟踪目标不同的目标上重放 Vulkan 跟踪不太可能对最直接的跟踪起作用。

///

着色器窗格

着色器窗格允许您查看跟踪中使用的各个着色器。

要使用此窗格,请在列表中选择一个着色器。这将创建一个新选项卡,显示着色器的源以及静态分析统计信息。

要查看绑定到管线中特定阶段的特定着色器,请在管线视图中查看该阶段。

选择着色器代码

您可以选择SPIR-V或(如果可能)GLSL。笔记:

  • 如果 SPIR-V 代码在其 OpSource 指令中提供原始 GLSL 代码,则GLSL选项卡仅显示相同的代码。如果没有,AGI 会尝试使用 SPIRV-Cross 将 SPIR-V 反编译为 GLSL。
  • 如果反编译发生错误,则显示 GLSL 源代码的选项不可用。

静态分析

AGI 提供来自 SPIR-V 着色器的静态分析的统计数据。以下是支持的统计信息:

统计 描述
ALU 指令 使用 ALU 的着色器中的指令数。
纹理说明 着色器中获取的纹理数量。
分支指令 着色器中的分支指令数。
峰值临时注册压力 最大数量的同时活动的临时寄存器。临时值的生命周期从它的定义开始,到它在着色器中的最后一次使用结束。该统计数据将p每个实时值使用的寄存器数相加(例如,4D 浮点数将是 4 个寄存器)。

///

内存窗格

内存窗格显示所选命令在 RAM 或 GPU 内存中的值。

此窗格显示所选命令读取和/或写入的内存位置。每个命令通常有多个读取或写入操作;从范围列表中选择一个。视图更新以显示操作的起始内存地址。绿色表示读操作,红色表示写操作。例如,上图中的命令包含从内存地址开始的 64 字节的读取操作0x000000728185be58您可以通过从类型列表中选择不同的数据类型来更改数据的显示方式 。

Pool字段设置为0以显示对应于应用程序内存的值。如果设置为任何其他数字,则窗格将显示 GPU 分配的内存的值。应用程序内存使用 RAM,而 GPU 分配的内存可能使用 RAM 或 GPU 内存。

单击“命令”窗格中的指针值可直接跳转到“内存”窗格中的特定地址。

您不限于在此窗格中查看特定地址范围。选择一个命令,然后选择状态窗格。选择DeviceMemories。(本部分由 Vulkan 跟踪的 Vulkan 句柄组织。)展开句柄并选择 Data。单击特定地址以将其显示在视图中。

/

检查 Vulkan 渲染状态

要在特定提交的命令后检查渲染状态,请单击命令窗格中的命令。状态窗格允许您使用以下项目检查渲染状态。

最后绑定队列(当前绑定队列)

LastBoundQueue节点包含用于提交相关命令的队列的 信息vkQueueSubmit。将VulkanHandle用于在 中查找当前渲染状态的绘制信息 LastDrawInfos

  1. 显示VulkanHandlelast used 的值VkQueue,它实际上是相关提交命令的当前绑定队列。

  2. 当前渲染状态的信息存储在 中LastDrawInfos,并由VkQueue值索引。

上次绘制信息(当前渲染状态信息)

LastDrawInfos节点包含每个 的最后一次绘图的信息 VkQueue并包含以下信息:

  • 帧缓冲信息
  • 渲染通行证信息
  • 绑定描述符集
  • 绑定顶点和索引缓冲区
  • 图形管道
  • 绘图参数

绑定帧缓冲区

  • Framebuffer节点:显示当前绑定的framebuffer的信息。vkCmdBeginRenderPass每次在同一队列上执行后,此节点都会更新。

  • 渲染通道节点:显示用于创建帧缓冲区的渲染通道信息。请注意,这不是当前绑定用于绘制的渲染通道。

  • ImageAttachments节点:列出所有VkImageViews绑定到帧缓冲区的图像附件 ( )。列表中的每一项都显示了图像视图的信息。

  • 图像节点显示绑定到图像视图的图像信息。

绑定渲染通道

  • 渲染通道节点:显示当前用于渲染的渲染通道信息。VkCmdBeginRenderPass每次在同一队列上执行后,它都会更新。

  • AttachmentDescriptions节点:列出所有VkAttachmentDescription当前正在使用的渲染通道。

  • SubpassDescriptions节点:列出VkSubpassDescription每个子通道的。

  • SubpassDependencies节点:列出VkSubpassDependency每个子通道的。

绑定描述符集

  • DescriptorSets节点:列出所有当前绑定的描述符集。有界描述符集列表反映了上次vkCmdBindDescriptorSets在同一个队列上滚出后的状态,原始描述符集信息将被覆盖或根据上次执行的参数添加新信息vkCmdBindDescriptorSets

  • Bindings:节点列出描述符集中所有当前绑定的描述符绑定。

    每个描述符绑定还列出了其绑定的描述符。

  • 布局节点:显示VkDescriptorSetLayout用于分配描述符集的信息。

绑定图形管道

GraphicsPipeline节点:包含有关最后绑定的图形管道的信息。VkCmdBindPipeline每次在当前队列上执行后,此节点都会更新。

绑定缓冲区

  • BoundVertexBuffers节点列出所有绑定的顶点缓冲区。对于每个绑定的顶点缓冲区,它显示后备缓冲区的信息。vkCmdBindVertexBuffers每次在同一队列上执行后,列表都会相应更新。

  • BoundIndexBuffernode 显示最后绑定的索引缓冲区,包括索引类型和后备缓冲区的信息。

绘制命令参数

CommandParameters节点:包含vkCmdDrawvkCmdDrawIndexedvkCmdDrawIndirect的参数vkCmdDrawIndirectIndexed。对于每种类型的绘图命令,都有一个相应的子节点来包含参数值。由于这四种绘图命令不能同时使用,因此一次只能填充四个子节点中的一个。在同一队列上执行四个绘图命令中的任何一个后, CommandParameters的内容会更新。

///

纹理窗格

Textures窗格显示所有创建的纹理资源,包括所选命令。

从列表中选择一个纹理资源以在纹理视图中查看它们。选择显示已删除的纹理复选框以在 UI 中显示纹理,即使它们已被删除。

//

纹理窗格

纹理窗格显示已在纹理视图中选择的纹理内容。

如果纹理具有 mip-map 链,您可以使用底部的滑块更改显示的 mip-map 级别(未图示)。默认情况下,将显示最高分辨率级别 0。

将光标移动到纹理图像上以在视图的左下角显示周围像素的放大预览,如上图所示。该窗格还将显示纹理宽度和高度以及图像上该点的 x 和 y 坐标、归一化纹理坐标(U 和 V 值)和 RBGA 十六进制值。

运营

您可以使用以下按钮对图像进行操作: | 按钮 | 说明 | 示例结果 | |:-------------:|:-------------:| :-----:| | | 调整图像以完全适合窗格。您也可以右键单击图像以调整缩放以适合图像。|

| |

| 以无比例显示图像,其中一个设备像素相当于一个屏幕像素。|

| |

| 放大图像。您还可以使用鼠标滚轮或触摸板上的两指滑动来放大和缩小。您可以用光标拖动图像。|

| |

| 缩小图像。您还可以使用鼠标滚轮或触摸板上的两指滑动来放大和缩小。|

| |

|显示图像的颜色直方图。您可以选择任一侧的控制手柄来限制显示的颜色值。|

| | |选择要渲染的颜色通道。选项有红色、绿色、蓝色和 Alpha(透明度)。

| | |为图像背景选择棋盘图案或纯色。| 

| | |垂直翻转图像。|

/

管道窗格

Pipeline窗格显示当前绑定的管道的内容。在命令窗格中选择一个有效的绘制或调度调用。如果您选择一组包含绘制或调度调用的命令,它将显示最后绑定的管道。

当前绑定管道的阶段位于窗格顶部。它们按照它们在各自管道中的使用顺序呈现。然而,并不是每个阶段都可以使用。如果一个阶段未被使用,则该阶段不是不可选择的,并且来自先前阶段的任何箭头都被绘制在它上面以指示它正在被跳过。当用户选择一个阶段时,窗格的其余部分仅显示与该阶段相关的数据。以下是当前支持的阶段:

阶段 全名 管道类型(调用类型)
IA 输入组件 图形(绘制)
VS 顶点着色器 图形(绘制)
TCS 镶嵌控制着色器 图形(绘制)
TES 细分评估着色器 图形(绘制)
GS 几何着色器 图形(绘制)
拉斯特 光栅化器 图形(绘制)
FS 片段着色器 图形(绘制)
混合 颜色混合 图形(绘制)
CS 计算着色器 计算(调度)

数据组织

每个阶段的数据以着色器代码、表格和键值对的形式组织。

着色器代码

此框包含当前选定阶段的着色器,但它只是一个着色器阶段。框顶部的选项卡允许您查看 SPIR-V 和 GLSL 中的着色器。请注意,GLSL 可能是从 SPIR-V 反编译的,而不是实际的原始源。

表通常包含您已静态或动态定义的数据。如果数据是动态设置的,则会在表名称旁边显示一条消息。一些表,例如Stencil State,代表状态而不是用户定义的数据,例如缓冲区或描述符,并且在不活动时显示为灰色。这些表可能包含打开其他窗格的链接。例如,单击 描述符集表的视图标题下的任何句柄会打开描述符所代表的纹理的纹理选项卡。

键值对

键值对通常表示状态数据。着色器阶段中的静态分析统计数据除外 。具有动态设置的一对在其键旁边有一个星号。任何不活动的对都显示为灰色。用户可以将鼠标悬停在任何停用的对上以检查其他对停用它。

//

AGI 故障排除

本主题介绍如何解决使用 Android GPU Inspector (AGI) 时的常见问题。

重置 AGI 设置

AGI 将其设置存储在~/.agic文件中。删除此文件会删除所有 AGI 设置,包括最近打开的跟踪列表和设备验证结果。

AGI 在某些设备上失败

请确保您的设置满足所有 要求。

以下内容也可以提供帮助:

  • 停止任何可能通过 ADB 与设备交互的程序,例如 Android Studio。

  • 启用该Stay awake选项(在 Android 上的开发人员选项下)以防止设备屏幕因睡眠模式关闭时出现的问题。

系统分析器不报告 OpenGL ES 游戏的 GPU 活动

目前,当您跟踪 OpenGL ES 应用程序时,仅支持 GPU 计数器。OpenGL ES 应用程序的 GPU 活动信息正在积极开发中。

帧分析器在某些 Vulkan 游戏中失败

首先要验证的是您的游戏是否正确使用了 Vulkan。使用 Vulkan 验证层 并确保您的游戏不会引发错误或警告。

如果存在任何 Vulkan 验证错误,则 AGI 帧分析器预计不会工作。

创建帧分析器跟踪时游戏失败

如果游戏在没有 AGI 的情况下成功运行,但在创建帧配置文件跟踪时运行失败,则游戏可能在其启动序列期间分叉了不同的进程。在这种情况下,您需要在跟踪选项的“进程名称”字段中指定要跟踪的进程的名称。

要识别此问题,您可以在创建跟踪时检查 logcat 输出并验证是否正在启动不同的进程:

<span style="color:var(--devsite-code-color)"><code><span style="color:var(--devsite-code-comments-color)"># Clear the logcat output</span>
adb logcat -c<span style="color:var(--devsite-code-comments-color)">## Use AGI to attempt to create a frame profile trace</span><span style="color:var(--devsite-code-types-color)">Look</span> at the logcat output to identify the processes that are running AGI. adb logcat | grep <span style="color:var(--devsite-code-strings-color)">"this process name"</span>
I GAPID   : gapii [gapii/cc/spy.cpp:<span style="color:var(--devsite-code-numbers-color)">109</span>] this process name: com.example.mygame
I GAPID   : gapii [gapii/cc/spy.cpp:<span style="color:var(--devsite-code-numbers-color)">109</span>] this process name: com.example.mygame:<span style="color:var(--devsite-code-types-color)">GameProcess</span>
</code></span>

大多数游戏只有一个进程,上面的示例显示了对具有多个进程的游戏的期望。

游戏从一个名为 的主进程开始com.example.mygame,然后派生一个名为 的新进程com.example.mygame:GameProcess。如果实际的游戏渲染发生在第二个进程中,那么您必须告诉 AGI 这是您要跟踪的进程。您可以通过Process name在跟踪选项对话框的字段中输入进程的名称来执行此操作。

使用 AGI 后游戏失败

如果跟踪未正确终止,AGI 可能会使某些 Android 设置处于可能中断应用程序后续运行的状态。这些设置是:

  • Vulkan 层相关设置:

    • enable_gpu_debug_layers

    • gpu_debug_app

    • gpu_debug_layers

    • gpu_debug_layer_app

  • 角度相关设置:

    • angle_debug_package

    • angle_gl_driver_selection_values

    • angle_gl_driver_selection_pkgs

如果您的应用在使用 AGI 后有任何问题,您可以尝试使用以下 adb 命令清除这些设置:

<span style="color:var(--devsite-code-color)"><code><span style="color:var(--devsite-code-comments-color)"># Vulkan layers</span>
adb shell settings delete global enable_gpu_debug_layers
adb shell settings delete global gpu_debug_app
adb shell settings delete global gpu_debug_layers
adb shell settings delete global gpu_debug_layer_app
<span style="color:var(--devsite-code-comments-color)"># ANGLE</span>
adb shell settings delete global angle_debug_package
adb shell settings delete global angle_gl_driver_selection_values
adb shell settings delete global angle_gl_driver_selection_pkgs
</code></span>

通过 AGI 启动游戏并创建帧配置跟踪时,您的游戏看起来会有所不同

为了创建帧配置跟踪,AGI 会拦截游戏进行的图形 API 调用,这可能会影响游戏渲染。

AGI 捕获 Vulkan 调用。对于 OpenGL ES 游戏,AGI 依赖 ANGLE将 OpenGL ES 转换为 Vulkan。如果您的游戏在通过 AGI 启动时看起来不同(例如,某些颜色不是您所期望的),则可能是 AGI 或 ANGLE 中的错误。您可以通过尝试以下方法帮助我们更好地了解问题的根本原因。

Vulkan 游戏:支持所有 Vulkan 扩展的跟踪

Hide unknown extensions跟踪选项控制 AGI 是否应该过滤掉它不支持的 Vulkan 扩展。

您可以尝试禁用该选项并再次启动帧分析器跟踪。如果禁用该选项时游戏看起来还不错,则游戏可能依赖 AGI 不支持的 Vulkan 扩展。

OpenGL ES 游戏:仅使用 ANGLE 运行

您可以使用 ANGLE 但不使用 AGI 运行 OpenGL ES 游戏,以查看错误渲染是否来自 ANGLE 中的问题。

如果您已经尝试创建 OpenGL ES 游戏的帧配置文件跟踪,那么 AGI 已经在您的设备上安装了 ANGLE。AGI 使用的 ANGLE 包名为org.chromium.angle.agi.

要强制您的游戏在 ANGLE 上运行,请使用以下命令:

<span style="color:var(--devsite-code-color)"><code><span style="color:var(--devsite-code-comments-color)"># Make sure that the AGI capture layer will be ignored</span>
adb shell settings delete global enable_gpu_debug_layers
<span style="color:var(--devsite-code-comments-color)"># Force the package com.example.mygame to use ANGLE</span>
adb shell settings put global angle_debug_package org.chromium.angle.agi
adb shell settings put global angle_gl_driver_selection_values angle
adb shell settings put global angle_gl_driver_selection_pkgs com.example.mygame
</code></span>

如果游戏在这些设置下看起来不同,那么它可能是 ANGLE 中的错误,而不是 AGI。如果游戏在这些设置下看起来正确,但在创建 AGI 跟踪时看起来不同,那么它可能是 AGI 中的错误。

您可以通过创建 GitHub 问题来报告 AGI 错误。

//

Frame profiling相关推荐

  1. Android GPU 检查器 (AGI)

    // 使用这款强大的图形分析器分析您的游戏对 Android 设备的影响,以便您识别性能问题和需要优化的区域. https://developer.android.com/agi AGI 下载 AGI ...

  2. Spring Security中文文档

    Spring Security中文文档 来源:https://www.springcloud.cc/spring-security.html#overall-architecture 作者 Ben A ...

  3. 内存泄漏的定位与排查:Heap Profiling 原理解析

    系统长时间运行之后,可用内存越来越少,甚至导致了某些服务失败,这就是典型的内存泄漏问题.这类问题通常难以预测,也很难通过静态代码梳理的方式定位.Heap Profiling 就是帮助我们解决此类问题的 ...

  4. U3D性能分析 Profiling

    Ports that the Unity profiler uses: Unity分析器使用的端口如下: MulticastPort : 54998 组播端口:54998ListenPorts : 5 ...

  5. HOW UNREAL RENDERS A FRAME

    本文转自:https://interplayoflight.wordpress.com/2017/10/25/how-unreal-renders-a-frame/ This is part 1 of ...

  6. Embedded Linux S3C2440 Profiling

    文章目录 Summary OProfile Applications and driver Configure and Compile Busybox to support Oprofile Down ...

  7. GPU Profiling 101

    原文地址:http://www.reedbeta.com/blog/gpu-profiling-101/ GPU Profiling 101 October 12, 2011 · Coding, GP ...

  8. GPU Profiling

    提起优化,第一件事情要做的就是Profiling,因为没有经过Profiling谁都不知道瓶颈是什么,正确的Profiling是对游戏整体性能的全面认识.关于CPU的Profiling已经非常成熟,各 ...

  9. Android 逐帧动画(Frame)

    Android 逐帧动画(Frame)  很好理解就是将多张图片放到一个容器里面通过控制这些图片一帧一张图片从而形成动画 使用的使用通过AnimationDrawable 加载放好的图片 然后通过调用 ...

最新文章

  1. 互联网公司面试必问的Redis题目
  2. C语言科技感图片,科技感与运动范十足,几何C黑棚图曝出,年轻消费者又多了新选择...
  3. ERP的配置管理实践
  4. RabbitMQ安装FAQ(接前面一篇)
  5. 46个不可不知的生活小常识
  6. BZOJ1010:[HNOI2008]玩具装箱TOY(斜率优化DP)
  7. 091118 T 数组的继承
  8. Java项目导出为jar包+导出第三方jar包+使用命令行调用+传参
  9. SQLCODE 错误对照表
  10. 专利申请--权利要求书vs说明书
  11. visio软件接口流程图_绘制流程图——Visio可以让你事半功倍哦!
  12. netkeeper显示651_关于电信Netkeeper客户端升级的通知
  13. 观《蓝天铁翼-红旗军演》所想到的
  14. 华为交换机常用命令大全
  15. UI组件库Form表单_数字类型验证之坑实现数字框
  16. web前端的发展分析
  17. ubuntu 下蓝牙无法连接
  18. php中文网教程 百度云,网盘直链问题请教
  19. 武林外传电影版java,武林外传经典台词
  20. leetcode Rotate Image

热门文章

  1. 日常报错:关于tomcat默认端口被占用的问题
  2. 源码国际短信平台路由流程搭建后台软件定制-移讯云短信系统
  3. ubuntu 软件管理
  4. 【Unity学习笔记】[Unity中文课堂教程] C#中级编程代码
  5. 搭建个人的第一个服务器以及域名申请和绑定--阿里云服务器
  6. 浅谈对于封装、继承与多态的理解(Java)
  7. 基于卷积神经网络的句子分类模型【经典卷积分类附源码链接】
  8. [svn] TortoisSVN的Blam功能
  9. 学习笔记(01):Web前端与HTML5移动开发系列一:HTML篇-06,HTML基本构成和语法
  10. Linux进程与线程