// Copyright 2021-2022 The Khronos Group, Inc. // SPDX-License-Identifier: CC-BY-4.0 ifndef::chapters[:chapters:] [[formats]] = Formats 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 link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#formats[Vulkan Spec format chapter] and the link:https://www.khronos.org/registry/DataFormat/specs/1.3/dataformat.1.3.html[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`, xref:{chapters}vertex_input_data_processing.adoc#input-attribute-format[vertex input attribute], link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#spirvenv-image-formats[mapping SPIR-V image formats], creating link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkAccelerationStructureGeometryTrianglesDataKHR.html[triangle geometry in a bottom-level acceleration structure], etc. [[feature-support]] == Feature Support It is important to understand that "format support" is not a single binary value per format, but rather each format has a set of link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkFormatFeatureFlagBits.html[VkFormatFeatureFlagBits] that each describes with features are supported for a format. The supported formats may vary across implementations, but a link:https://www.khronos.org/registry/vulkan/specs/1.3/html/vkspec.html#features-required-format-support[minimum set of format features are guaranteed]. An application can link:https://www.khronos.org/registry/vulkan/specs/1.3/html/vkspec.html#formats-properties[query] for the supported format properties. [NOTE] ==== Both link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_KHR_get_physical_device_properties2.html[VK_KHR_get_physical_device_properties2] and link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_KHR_format_feature_flags2.html[VK_KHR_format_feature_flags2] expose another way to query for format features. ==== === Format Feature Query Example 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. [source,cpp] ---- // 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 } ---- [source,cpp] ---- // 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 } ---- [source,cpp] ---- // Using VK_KHR_format_feature_flags2 VkFormatProperties3KHR formatProperties3; formatProperties2.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR; formatProperties2.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 } ---- == Variations of Formats Formats come in many variations, most can be grouped by the https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#_identification_of_formats[name of the format]. When dealing with images, the link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkImageAspectFlagBits.html[VkImageAspectFlagBits] values are used to represent which part of the data is being accessed for operations such as clears and copies. === Color Format with a `R`, `G`, `B` or `A` component and accessed with the `VK_IMAGE_ASPECT_COLOR_BIT` === Depth and Stencil Formats with a `D` or `S` component. These formats are link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#formats-depth-stencil[considered opaque] and have special rules when it comes to link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VkBufferImageCopy[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] ==== link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_KHR_separate_depth_stencil_layouts.html[VK_KHR_separate_depth_stencil_layouts] and link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_EXT_separate_stencil_usage.html[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 xref:{chapters}depth.adoc#depth-formats[depth chapter]. === Compressed link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#compressed_image_formats[Compressed image formats] representation of multiple pixels encoded interdependently within a region. .Vulkan Compressed Image Formats [options="header"] |=== |Format|How to enable |link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#appendix-compressedtex-bc[BC (Block-Compressed)] |`VkPhysicalDeviceFeatures::textureCompressionBC` |link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#appendix-compressedtex-etc2[ETC2 and EAC] |`VkPhysicalDeviceFeatures::textureCompressionETC2` |link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#appendix-compressedtex-astc[ASTC LDR] |`VkPhysicalDeviceFeatures::textureCompressionASTC_LDR` |link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#appendix-compressedtex-astc[ASTC HDR] |link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_EXT_texture_compression_astc_hdr.html[VK_EXT_texture_compression_astc_hdr] |link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#appendix-compressedtex-pvrtc[PVRTC] | link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_IMG_format_pvrtc.html[VK_IMG_format_pvrtc] |=== === Planar link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_KHR_sampler_ycbcr_conversion.html[VK_KHR_sampler_ycbcr_conversion] and link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_EXT_ycbcr_2plane_444_formats.html[VK_EXT_ycbcr_2plane_444_formats] add xref:{chapters}VK_KHR_sampler_ycbcr_conversion.adoc#multi-planar-formats[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 link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#formats-packed[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 link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#fxvertex-input-extraction[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). === External 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 xref:{chapters}VK_KHR_sampler_ycbcr_conversion.adoc[VkSamplerYcbcrConversion]. There are many restrictions what are allowed with these external formats which are link:https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#memory-external-android-hardware-buffer-external-formats[documented in the spec].