Vulkan formats are used to describe how memory is laid out. This chapter aims to give a high-level overview of the variations of formats in Vulkan and some logistical information for how to use them. All details are already well specified in both the Vulkan Spec format chapter and the Khronos Data Format Specification.
The most common use case for a VkFormat
is when creating a VkImage
. Because the VkFormat
s are well defined, they are also used when describing the memory layout for things such as a VkBufferView
, vertex input attribute, mapping SPIR-V image formats, creating triangle geometry in a bottom-level acceleration structure, etc.
It is important to understand that "format support" is not a single binary value per format, but rather each format has a set of VkFormatFeatureFlagBits that each describes which features are supported for a format.
The supported formats may vary across implementations, but a minimum set of format features are guaranteed. An application can query for the supported format properties.
Note
|
Both VK_KHR_get_physical_device_properties2 and VK_KHR_format_feature_flags2 expose another way to query for format features. |
In this example, the code will check if the VK_FORMAT_R8_UNORM
format supports being sampled from a VkImage
created with VK_IMAGE_TILING_LINEAR
for VkImageCreateInfo::tiling
. To do this, the code will query the linearTilingFeatures
flags for VK_FORMAT_R8_UNORM
to see if the VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
is supported by the implementation.
// 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
}
Formats come in many variations, most can be grouped by the name of the format. When dealing with images, the VkImageAspectFlagBits values are used to represent which part of the data is being accessed for operations such as clears and copies.
Formats with a D
or S
component. These formats are considered opaque and have special rules when it comes to copy to and from depth/stencil images.
Some formats have both a depth and stencil component and can be accessed separately with VK_IMAGE_ASPECT_DEPTH_BIT
and VK_IMAGE_ASPECT_STENCIL_BIT
.
Note
|
VK_KHR_separate_depth_stencil_layouts and VK_EXT_separate_stencil_usage, which are both promoted to Vulkan 1.2, can be used to have finer control between the depth and stencil components. |
More information about depth format can also be found in the depth chapter.
Compressed image formats representation of multiple pixels encoded interdependently within a region.
Format | How to enable |
---|---|
|
|
|
|
|
|
VK_KHR_sampler_ycbcr_conversion and VK_EXT_ycbcr_2plane_444_formats add multi-planar formats to Vulkan. The planes can be accessed separately with VK_IMAGE_ASPECT_PLANE_0_BIT
, VK_IMAGE_ASPECT_PLANE_1_BIT
, and VK_IMAGE_ASPECT_PLANE_2_BIT
.
Packed formats are for the purposes of address alignment. As an example, VK_FORMAT_A8B8G8R8_UNORM_PACK32
and VK_FORMAT_R8G8B8A8_UNORM
might seem very similar, but when using the formula from the Vertex Input Extraction section of the spec
attribAddress = bufferBindingAddress + vertexOffset + attribDesc.offset;
For VK_FORMAT_R8G8B8A8_UNORM
the attribAddress
has to be a multiple of the component size (8 bits) while VK_FORMAT_A8B8G8R8_UNORM_PACK32
has to be a multiple of the packed size (32 bits).
Currently only supported with the VK_ANDROID_external_memory_android_hardware_buffer
extension. This extension allows Android applications to import implementation-defined external formats to be used with a VkSamplerYcbcrConversion. There are many restrictions what are allowed with these external formats which are documented in the spec.