在 Vulkan 应用程序中启用 AFBC
此示例的源代码可以在 Khronos Vulkan 示例 github 存储库中找到。 |
概述
AFBC (Arm 帧缓冲区压缩) 是 Arm Mali GPU 中发现的一种实时无损压缩算法,旨在应对不断增长的更高分辨率图形需求。此格式应用于要写入 GPU 的帧缓冲区。这项技术可以提供高达 50% 的带宽减少。
该示例旨在演示通过切换 AFBC 的开关可以节省的带宽,并显示外部带宽的实时图表。在这种情况下,我们将重点关注交换链图像。
Vulkan API 允许开发人员控制 VkSwapchainKHR
的创建和格式化方式。我们希望确保以正确的方式创建和格式化它,以便我们从中查询的后续 VkImage
可以适当地应用 AFBC。
请务必注意,从设备角度来看,要在 Vulkan 上启用 AFBC,您至少需要 r16p0
驱动程序版本和 Mali G-51
或更高版本。要查找您的 GPU 和驱动程序版本,请打开 调试窗口 或按照此文章中的步骤操作。
已在以下设备上测试:Samsung Galaxy S10、Huawei P30
启用 AFBC
AFBC 在功能上对应用程序是透明的,并且会在每个 VkImage
的基础上自动应用 (前提是您的设备和图像的各种属性通过了多项检查)。
驱动程序将检查应用程序的状态以及 VkImage
的属性,以确定是否启用 AFBC 或只是继续而不启用它。本节将详细介绍这些要求。
VkImage
要求
-
VkSampleCountFlagBits
必须为VK_SAMPLE_COUNT_1_BIT
-
VkImageType
必须为VK_IMAGE_TYPE_2D
-
VkImageTiling
必须为VK_IMAGE_TILING_OPTIMAL
-
VkFormat
支持列表
除此之外,您的 VkImage
还需要遵守以下标志
-
VkImageUsageFlags
不得包含-
VK_IMAGE_USAGE_STORAGE_BIT
-
VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
-
(仅适用于驱动程序版本为
r16p0
的某些设备)VK_IMAGE_USAGE_TRANSFER_DST_BIT
-
-
VkImageCreateFlags
不得包含-
VK_IMAGE_CREATE_ALIAS_BIT
-
VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
-
AFBC 示例
该示例向用户展示了 Sponza,顶部有一个显示带宽的图表,底部有一个配置窗口。有一个来回振荡的摄像机,用于禁用任何针对相同帧的 GPU 优化。
配置本身很简单。有一个复选框 (标记为 “启用 AFBC”),当其值更改时将重新加载交换链。

这里,示例处于默认状态:AFBC 关闭。屏幕顶部有一个图表,显示外部写入带宽(从 L2_EXT_WRITE_BEATS
测量)。
它目前在交换链图像的 VkImageUsageFlags
中设置了 VK_IMAGE_USAGE_STORAGE_BIT
标志,导致驱动程序跳过对交换链图像应用 AFBC。
当我们启用复选框时,示例将重新加载具有正确用法标志的交换链,以使驱动程序启用 AFBC。

这是与之前相同的场景,只是现在启用了 AFBC。未设置 VK_IMAGE_USAGE_STORAGE_BIT
标志,并且交换链正在正确创建。
带宽已从 788.0 MiB/s 降至 528.6 MiB/s,这大约减少了 33%。
您还可以在 Streamline 中确认这些数字。以下是一些屏幕截图
格式支持
从 Mali-G77 开始的 GPU 支持每像素高达 32 位的格式,无论颜色通道排列或 sRBG 如何。
支持 AFBC 的早期版本仅支持格式的子集
格式 |
---|
VK_FORMAT_R4G4B4A4_UNORM_PACK16 |
VK_FORMAT_B4G4R4A4_UNORM_PACK16 |
VK_FORMAT_R5G6B5_UNORM_PACK16 |
VK_FORMAT_R5G5B5A1_UNORM_PACK16 |
VK_FORMAT_B5G5R5A1_UNORM_PACK16 |
VK_FORMAT_A1R5G5B5_UNORM_PACK16 |
VK_FORMAT_B8G8R8_UNORM |
VK_FORMAT_B8G8R8A8_UNORM |
VK_FORMAT_B8G8R8A8_SRGB |
VK_FORMAT_A8B8G8R8_UNORM |
VK_FORMAT_A8B8G8R8_SRGB |
VK_FORMAT_A8R8G8B8_SRGB |
VK_FORMAT_B10G10R10A2_UNORM |
VK_FORMAT_R4G4B4A4_UNORM |
VK_FORMAT_R5G6B5_UNORM |
VK_FORMAT_R5G5B5A1_UNORM |
VK_FORMAT_R8_UNORM |
VK_FORMAT_R8G8_UNORM |
VK_FORMAT_R8G8B8_UNORM |
VK_FORMAT_R8G8B8A8_UNORM |
VK_FORMAT_R8G8B8A8_SRGB |
VK_FORMAT_A8R8G8B8_UNORM |
VK_FORMAT_R10G10B10A2_UNORM |
VK_FORMAT_D24_UNORM_S8_UINT |
VK_FORMAT_D16_UNORM |
VK_FORMAT_D32_SFLOAT |
延伸阅读
-
Arm 帧缓冲压缩 - developer.arm.com
最佳实践总结
执行
-
确保按照 AFBC 的要求正确创建交换链。
-
AFBC 不能替代(它独立于)纹理压缩(如 ASTC),因此请尽可能压缩所有内容。
-
避免在运行时更改图像配置(使用具有无效 AFBC 要求的
vkCmdCopyImage
),因为它会触发解压缩。 -
在多重采样时,请确保使用
pResolveAttachments
解析图像。任何SAMPLE_COUNT > 1
的VkImage
都不会应用 AFBC。
不要
-
除非您确实需要(例如,在特定图像上进行计算),否则请勿使用图像用法标志,例如
VK_IMAGE_USAGE_STORAGE_BIT
。
影响
-
图像的配置不正确会导致所有表面
VkImage
变为未压缩状态,从而损失大量系统范围的带宽减少。
调试
-
要测试是否启用或禁用 AFBC,您可以使用诸如 Streamline 之类的分析器,并在启用 AFBC 或禁用 AFBC 时记录带宽值。
-
您还可以使用扩展
VK_EXT_image_compression_control
来查询是否启用了 AFBC。有关更多详细信息,请参阅图像压缩控制示例。