跳到主要内容

格式

Vulkan 格式用于描述内存的布局方式。本章旨在简要概述 Vulkan 中各种各样的格式变体,以及如何使用它们。更详细的信息请阅读 Vulkan Spec格式章节Khronos 数据格式规范

使用VkFormat最常见的场景是创建VkImage。由于VkFormat定义明确,因此它也用于描述诸如VkBufferView顶点输入属性SPIR-V 图像格式映射创建三角形几何图形的底层加速结构等内容的内存布局。

查询功能是否支持

这里所说的“格式支持”不是指每种格式的单个二进制值,而是每种格式都有一组 VkFormatFeatureFlagBits,用来描述格式支持哪些功能。

每个硬件厂商支持的格式可能会有差异,但必须保证支持最小的格式功能集。应用在使用前可以查询支持的格式属性。

提示

怎么查询格式特性

下面的代码展示了检查一个VkImageCreateInfo::tiling设置为VK_IMAGE_TILING_LINEARVkImage是否支持采样为VK_FORMAT_R8_UNORM格式。

代码将查询VK_FORMAT_R8_UNORMlinearTilingFeatures的标志,以查看设备是否支持VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT

// Using core Vulkan 1.0
VkFormatProperties formatProperties;
vkGetPhysicalDeviceFormatProperties(physicalDevice, VK_FORMAT_R8_UNORM, &formatProperties);
if ((formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0) {
// supported
} else {
// not supported
}
// Using core Vulkan 1.1 or VK_KHR_get_physical_device_properties2
VkFormatProperties2 formatProperties2;
formatProperties2.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
formatProperties2.pNext = nullptr; // used for possible extensions

vkGetPhysicalDeviceFormatProperties2(physicalDevice, VK_FORMAT_R8_UNORM, &formatProperties2);
if ((formatProperties2.formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0) {
// supported
} else {
// not supported
}
// Using VK_KHR_format_feature_flags2
VkFormatProperties3KHR formatProperties3;
formatProperties3.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR;
formatProperties3.pNext = nullptr;

VkFormatProperties2 formatProperties2;
formatProperties2.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
formatProperties2.pNext = &formatProperties3;

vkGetPhysicalDeviceFormatProperties2(physicalDevice, VK_FORMAT_R8_UNORM, &formatProperties2);
if ((formatProperties3.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR) != 0) {
// supported
} else {
// not supported
}

格式变体

格式有很多变体,大多数可以按格式名称进行分组。在处理图像时,VkImageAspectFlagBits 值用于表示数据的哪一部分用来执行清除和复制等操作。

颜色

一个格式具备 RGBA分量,可以通过VK_IMAGE_ASPECT_COLOR_BIT访问分量。

深度和模板

格式有DS分量。这些格式被视为不透明格式,并且在与深度/模板图像进行复制时有特殊规则。

某些格式同时具有深度和模板分量,可以使用VK_IMAGE_ASPECT_DEPTH_BITVK_IMAGE_ASPECT_STENCIL_BIT单独访问。

提示

VK_KHR_separate_depth_stencil_layoutsVK_EXT_separate_stencil_usage 都已升级到 Vulkan 1.2,可用来对深度和模板分量进行更精细的控制。

有关深度格式更详细的信息请参阅 深度章节

压缩

图像格式压缩表示多个像素相互依赖的编码在一个区域内。

表 1.Vulkan 压缩图像格式

格式如何启用
BC(块压缩)VkPhysicalDeviceFeatures::textureCompressionBC
ETC2 和 EACVkPhysicalDeviceFeatures::textureCompressionETC2
ASTC LDRVkPhysicalDeviceFeatures::textureCompressionASTC_LDR
ASTC HDRVK_EXT_texture_compression_astc_hdr
PVRTCVK_IMG_format_pvrtc

平面格式

VK_KHR_sampler_ycbcr_conversionVK_EXT_ycbcr_2plane_444_formats 向 Vulkan 添加了多平面格式功能。可以使用VK_IMAGE_ASPECT_PLANE_0_BITVK_IMAGE_ASPECT_PLANE_1_BITVK_IMAGE_ASPECT_PLANE_2_BIT单独访问这些平面。

打包格式

打包格式用于地址对齐。例如,VK_FORMAT_A8B8G8R8_UNORM_PACK32VK_FORMAT_R8G8B8A8_UNORM可能看起来非常相似,但是当使用规范的 Vertex Input Extraction 章节的公式:

attribAddress = bufferBindingAddress + vertexOffset + attribDesc.offset;

对于VK_FORMAT_R8G8B8A8_UNORMattribAddress必须是分量大小(8 比特位)的倍数,而VK_FORMAT_A8B8G8R8_UNORM_PACK32必须是打包大小(32 比特位)的倍数。

外部扩展

目前仅支持VK_ANDROID_external_memory_android_hardware_buffer扩展,此扩展允许 Android 应用导入自定义的外部格式,以便与 VkSamplerYcbcrConversion 一起使用,这些外部格式在规范文档中有许多限制。