原生引擎和专有引擎

开始在 Android 上使用 Vulkan

Vulkan 是 Android 上的主要底层图形 API。Vulkan 可为实现自己的游戏引擎和渲染程序的游戏提供最佳性能。

如需在游戏引擎中成功实现 Vulkan,您必须:

  • 确定要与 Vulkan 搭配使用的 Android 设备
  • 了解支持旧版 Android 设备的利弊
  • 将 Vulkan 添加到您的 Android 构建目标中
  • 选择一个着色器编译器来为 Vulkan 创建 SPIR-V
  • 在运行时确定可用的 Vulkan API 版本
  • 了解如何使用 Vulkan 配置文件、帧同步和预旋转来优化 Vulkan 渲染操作
  • 选择用于调试和性能分析的图形工具

针对 Vulkan 选择最低设备规格

Vulkan 从 Android 7.0(API 级别 24)开始便可在 Android 上使用。并非所有搭载 Android 7.0 或更高版本的 Android 设备都支持 Vulkan。您需要确定您的游戏支持哪些支持 Vulkan 的 Android 设备。

建议

请将以下规格作为支持 Vulkan 的最低要求:

  • 设备搭载 Android 10.0(API 级别 29)或更高版本
  • 设备支持 Vulkan API 1.1 或更高版本
  • 设备具有与 2022 年 Android 基准配置文件兼容的硬件功能和特性

支持旧款设备

如果您的游戏设计为可在具有不同图形功能级别的各种设备上运行,那么您可能需要支持版本低于针对 Vulkan 选择最低设备规格中建议值的设备。在构建对旧款设备的支持之前,请评估 Vulkan 是否为您的游戏带来优势。由于在 OpenGL ES 中进行绘制调用的成本较高,因此进行大量绘制调用并使用 OpenGL ES 的游戏可能会出现大量的驱动程序开销。这些游戏可能会因在图形驱动程序中花费大量帧时间而受到 CPU 限制。通过从 OpenGL ES 切换到 Vulkan,游戏还可以显著降低 CPU 和功耗。如果您的游戏具有复杂的场景,导致无法有效利用实例化来减少绘制调用次数,这一点尤其适用。以旧款设备为目标平台时,请添加 OpenGL ES 渲染支持作为后备选项,因为目标设备列表中的某些设备的 Vulkan 实现可能无法可靠地运行您的游戏。

您可能不希望支持能够采用 Vulkan 的旧版设备,因为它们缺少功能或性能不佳,或者存在稳定性问题。

性能和功能

支持 Vulkan 的旧版 Android 设备可能无法为运行您的游戏所需的功能提供渲染性能或硬件支持。如果您的游戏具有高保真图形,并且 Vulkan 是您在 Android 上唯一设定的目标 API,那么这种情况尤其常见。许多旧款设备仅限于 Vulkan API 1.0.3 版,并且往往缺少可在更现代的硬件上获得的广泛使用的 Vulkan 扩展。

稳定性

旧版 Android 设备使用的 Vulkan 驱动程序可能已过时。这些驱动程序版本可能包含影响游戏稳定性的 bug。解决驱动程序 bug 可能需要大量的测试和工程时间。

将 Vulkan 添加到项目中

如需将 Vulkan 添加到项目中,您需要:

  • 包含 Vulkan API 头文件
  • 将着色器代码编译为 SPIR-V
  • 在运行时调用 Vulkan API

包含 Vulkan API 头文件

您的游戏需要包含 Vulkan API 头文件,才能编译使用 Vulkan 的代码。您可以在 Android NDK 中找到 Vulkan 头文件的副本,或在 Vulkan SDK 版本中找到打包的 Vulkan 头文件。任何特定 NDK 版本仅包含 NDK 发布时可用的 Vulkan 头文件。如果您使用 NDK 中的 Vulkan 头文件,请使用 NDK 版本 25 或更高版本,其中包含支持 Vulkan 1.3 版本的头文件。Vulkan SDK 包含最新版本的头文件。

将着色器代码编译为 SPIR-V

Vulkan API 要求着色器程序以 SPIR-V 二进制文件中间格式提供。此惯例与 OpenGL ES 不同,在 OpenGL ES 中,您可以将以 OpenGL 着色语言 (GLSL) 编写的源代码作为文本字符串提交。使用着色器编译器获取使用 GLSL 或高级着色器语言 (HLSL) 等着色器语言编写的代码,并将其编译成 SPIR-V 模块,以便与 Vulkan 搭配使用。

shaderc 编译器可用于将使用 GLSL 编写的着色器程序编译成 SPIR-V。如果您的游戏使用 HLSL,DirectXShaderCompiler 支持 SPIR-V 输出。通常,您可以在游戏的资源构建流程中离线编译着色器程序,并将 SPIR-V 模块添加到运行时资源中。

在运行时调用 Vulkan API

如需调用 Vulkan API,您的游戏需要获取指向 Vulkan API 调用的函数指针。最简单的方法是链接到 libvulkan.so 共享库(包含在 Android NDK 中)。链接到该库有两个缺点:存在额外的函数调度开销,并且关于自动解析哪个 Vulkan API 函数指针存在限制。

当您调用 Vulkan API 函数时,系统会通过一个由名为 Vulkan 加载程序的结构管理的调度表来传递控制权。Android 使用自己的 Vulkan 加载器实现,而不是 LunarG 加载器。此加载器系统是 Vulkan API 层架构的一部分。在构建时链接到系统库会导致为给定的 API 调用增加额外的调度级别。虽然开销很小,但对于执行大量 Vulkan 调用的游戏而言,开销还是很明显。

系统库通常仅解析指向被视为核心 API 一部分的 Vulkan 函数的指针。Vulkan 具有大量的扩展,用于定义额外的 Vulkan 函数,其中许多扩展都不会由系统库自动解析。您需要先手动解析指向这些 Vulkan 函数的指针,然后才能使用它们。

为了缓解这些问题,请动态解析指向您打算在运行时使用的所有 Vulkan 函数的指针。实现此目的的方法之一是使用 volk 等开源元加载器库。为此,AGDKTunnel 示例游戏集成了 volk。如果您使用的是元加载器库,请勿在构建脚本中链接到 libvulkan.so 共享库。

确定可用的 Vulkan API 版本

Android 支持以下 Vulkan API 版本:

  • 1.0.3
  • 1.1
  • 1.3

给定设备上可用的最高 Vulkan API 版本号由 Android 版本和 Vulkan 驱动程序支持决定。

Android 版本

对 Vulkan API 版本的平台支持取决于最低 Android 版本(API 级别):

  • 1.3 - Android 13.0(API 级别 33)及更高版本
  • 1.1 - Android 10.0(API 级别 29)及更高版本
  • 13.0 - Android 7.0(API 级别 24)及更高版本

支持 Vulkan 驱动程序

Android 平台对某个 Vulkan API 版本的支持并不能保证设备的 Vulkan 驱动程序支持该 API 版本。搭载 Android 13 的设备可能仅支持 Vulkan API 1.1 版本。

初始化 Vulkan 时,请勿请求高于以下版本的 API 版本:

以下是确定支持的最高 Vulkan API 版本的示例:

// Minimum Android API levels for Vulkan 1.3/1.1 version support
static constexpr int kMinimum_vk13_api_level = 33;
static constexpr int kMinimum_vk11_api_level = 29;

uint32_t GetHighestSupportedVulkanVersion(VkPhysicalDevice physical_device) {
  uint32_t instance_api_version = 0;
  vkEnumerateInstanceVersion(&instance_api_version);

  VkPhysicalDeviceProperties device_properties;
  vkGetPhysicalDeviceProperties(physical_device, &device_properties);

  // Instance and device versions don't have to match, use the lowest version
  // number for API support if they don't.
  const uint32_t driver_api_version =
      (instance_api_version < device_properties.apiVersion) ?
      instance_api_version : device_properties.apiVersion;

  const int device_api_level = android_get_device_api_level();
  if (device_api_level >= kMinimum_vk13_api_level &&
      driver_api_version >= VK_API_VERSION_1_3) {
    return VK_API_VERSION_1_3;
  } else if (device_api_level >= kMinimum_vk11_api_level &&
             driver_api_version >= VK_API_VERSION_1_1) {
    return VK_API_VERSION_1_1;
  }
  return VK_API_VERSION_1_0;
}

确定 Vulkan 配置文件兼容性

Vulkan 配置文件是 JSON 文件,用于定义 Vulkan 设备为了与配置文件兼容而必须支持的一组必需功能、扩展、capability 和最低参数限制。如需确定设备是否与特定 Vulkan 配置文件(例如 2022 Android 基准配置文件)兼容,请使用开源 Vulkan Profiles API 库。 您也可以自行解析配置文件 JSON 文件,并使用相关 Vulkan API 查询设备功能,以确定配置文件兼容性。

Vulkan 配置文件

Android 使用 Vulkan 配置文件,该配置文件定义了每个搭载 Android 系统的设备可用的功能和扩展。

Android 基准配置文件 (ABP) 是首次尝试构建 Vulkan 配置文件。ABP2021ABP2022 是向后兼容的配置文件,旨在覆盖当时超过 85% 的活跃设备。我们今后将不再提供新的 ABP。

适用于 Android 的 Vulkan 配置文件 (VPA) 是新推出的具有前瞻性的配置文件,旨在反映软件开发者的需求,并在硬件开发者能够提供相关功能后立即推动一致的功能。VPA15_minimums 是 Android 15 的第一个配置文件,每年都有一个新的 VPA 来涵盖每个主要 Android 版本。

实现帧同步

适当的帧同步是提供优质游戏体验的重要条件。Android Game Development Kit 包含 Frame Pacing 库,可帮助您的游戏实现最佳的帧同步。如需了解更多实现详情,请参阅将 Android Frame Pacing 集成到您的 Vulkan 渲染程序中

实现预旋转

Android 设备能以多种屏幕方向显示。设备方向可以与渲染 Surface 的方向不同。与 Android 上的 OpenGL ES 不同,Vulkan 不会处理两者之间的差异。如需了解使用 Vulkan 时屏幕方向处理流程的工作原理以及处理屏幕方向差异的最佳方法,请参阅通过 Vulkan 预旋转处理设备旋转

排查 Vulkan 渲染问题并分析渲染性能

我们提供了多种工具来帮助您诊断 Vulkan 渲染代码的渲染问题和性能问题。

如需详细了解 Vulkan 的调试和性能分析工具,请参阅工具和高级功能部分。

Vulkan 验证层

Vulkan 验证层是运行时库,可启用它来检查您对 Vulkan API 的调用,并提供有关不正确或非最佳使用的警告或错误。默认情况下,这些验证层处于非活动状态,因为验证过程会增加运行时开销并影响游戏的性能。如需了解如何在游戏中使用验证层,请参阅使用验证层进行调试

帧捕获工具

您可以使用帧捕获工具录制和重放在游戏帧期间进行的 Vulkan API 调用。通过这些工具,您可以:

  • 查看活跃图形资源的相关信息和可视化结果
  • 查看游戏执行的 API 调用的顺序,并查看 API 参数
  • 探索绘制调用期间图形管道的状态
  • 可视化帧中达到特定绘制调用的渲染结果

使用开源 RenderDoc 工具从在 Android 上运行的游戏中捕获帧。RenderDoc 支持 Vulkan 和 OpenGL ES 帧捕获。

也可使用 Android GPU 检查器 (AGI) 捕获 Vulkan 帧。

性能分析工具

请使用性能分析工具调查游戏中导致帧速率不佳的渲染问题。各个 GPU 供应商都提供了专门用于分析游戏性能的工具,并提供了特定于其 GPU 架构的性能数据。在不同供应商的 GPU(甚至是同一供应商的不同 GPU 版本)上渲染游戏时,游戏的性能特征和瓶颈可能会显著不同。

您还可以使用 Android GPU 检查器收集和分析性能数据。与供应商工具不同,Android GPU 检查器与不同供应商提供的多个 GPU 兼容。不过,Android GPU 检查器不支持旧版 Android 设备,并且可能与部分新设备不兼容。