格式
Vulkan 格式用于描述内存的布局方式。本章旨在概述 Vulkan 中格式的各种变化以及如何使用它们的一些逻辑信息。所有详细信息都已在 Vulkan 规范格式章节 和 Khronos 数据格式规范 中进行了详细说明。
VkFormat
最常见的用例是创建 VkImage
时。由于 VkFormat
s 已被明确定义,它们也用于描述 VkBufferView
、顶点输入属性、映射 SPIR-V 图像格式、创建 底层加速结构中的三角形几何体等事物的内存布局。
特性支持
理解“格式支持”不是每个格式的单个二进制值非常重要,而是每个格式都有一组 VkFormatFeatureFlagBits,每个标志都描述了格式支持哪些特性。
支持的格式可能因实现而异,但保证了最少的一组格式特性。应用程序可以查询支持的格式属性。
VK_KHR_get_physical_device_properties2 和 VK_KHR_format_feature_flags2 都提供了另一种查询格式特性的方法。 |
格式特性查询示例
在此示例中,代码将检查 VK_FORMAT_R8_UNORM
格式是否支持从使用 VK_IMAGE_TILING_LINEAR
作为 VkImageCreateInfo::tiling
创建的 VkImage
中采样。为此,代码将查询 VK_FORMAT_R8_UNORM
的 linearTilingFeatures
标志,以查看实现是否支持 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 值来表示在执行清除和复制等操作时访问的数据的哪一部分。
深度和模板
具有 D
或 S
组件的格式。这些格式被视为不透明,并且在从深度/模板图像复制和复制到深度/模板图像时有特殊的规则。
某些格式同时具有深度和模板组件,可以使用 VK_IMAGE_ASPECT_DEPTH_BIT
和 VK_IMAGE_ASPECT_STENCIL_BIT
分别访问。
VK_KHR_separate_depth_stencil_layouts 和 VK_EXT_separate_stencil_usage(两者都已升级到 Vulkan 1.2)可以用于对深度和模板组件进行更精细的控制。 |
有关深度格式的更多信息也可以在深度章节中找到。
压缩
压缩图像格式表示在区域内以相互依赖的方式编码的多个像素。
格式 | 如何启用 |
---|---|
|
|
|
|
|
|
平面
VK_KHR_sampler_ycbcr_conversion 和 VK_EXT_ycbcr_2plane_444_formats 向 Vulkan 添加了多平面格式。可以使用 VK_IMAGE_ASPECT_PLANE_0_BIT
、VK_IMAGE_ASPECT_PLANE_1_BIT
和 VK_IMAGE_ASPECT_PLANE_2_BIT
分别访问平面。
打包
打包格式用于地址对齐的目的。例如,VK_FORMAT_A8B8G8R8_UNORM_PACK32
和 VK_FORMAT_R8G8B8A8_UNORM
可能看起来非常相似,但是当使用 规范的顶点输入提取部分中的公式时
attribAddress = bufferBindingAddress + vertexOffset + attribDesc.offset;
对于 VK_FORMAT_R8G8B8A8_UNORM
,attribAddress
必须是组件大小(8 位)的倍数,而 VK_FORMAT_A8B8G8R8_UNORM_PACK32
必须是打包大小(32 位)的倍数。
外部
目前仅支持 VK_ANDROID_external_memory_android_hardware_buffer
扩展。此扩展允许 Android 应用程序导入实现定义的外部格式,以便与 VkSamplerYcbcrConversion 一起使用。关于这些外部格式的许多限制在 规范文档中有所说明。