To create a VkImage, you need a VkImageCreateInfo structure defining the image’s properties. Before creating the image, you can use these properties to query if the image supports fixed-rate compression on your platform. For instance, the structure may look like this:
VkImageCreateInfo image_create_info{VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
image_create_info.format = VK_FORMAT_R8G8B8_UNORM;
image_create_info.imageType = VK_IMAGE_TYPE_2D;
image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
image_create_info.extent = {8, 8, 1};
image_create_info.mipLevels = 1;
image_create_info.arrayLayers = 1;
image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
To query for fixed-rate compression support, use this information to fill in a VkImageFormatProperties2 structure:
VkPhysicalDeviceImageFormatInfo2 image_format_info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2};
image_format_info.format = image_create_info.format;
image_format_info.type = image_create_info.imageType;
image_format_info.tiling = image_create_info.tiling;
image_format_info.usage = image_create_info.usage;
Additionally, add a
VkImageCompressionControlEXT
to its pNext
chain:
VkImageCompressionControlEXT compression_control{VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT};
compression_control.flags = VK_IMAGE_COMPRESSION_FIXED_RATE_DEFAULT_EXT;
image_format_info.pNext = &compression_control;
You may then prepare a VkImageFormatProperties2
structure, with a
VkImageCompressionPropertiesEXT
in its pNext
chain:
VkImageCompressionPropertiesEXT supported_compression_properties{VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT};
VkImageFormatProperties2 image_format_properties{VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2};
image_format_properties.pNext = &supported_compression_properties;
Finally, put these two together in a call to vkGetPhysicalDeviceImageFormatProperties2KHR
:
vkGetPhysicalDeviceImageFormatProperties2KHR(get_device().get_gpu().get_handle(), &image_format_info, &image_format_properties);
You can then inspect the values written to VkImageCompressionPropertiesEXT
to determine if the image supports fixed-rate compression.
For instance, you may use the print function helper provided below to inspect the logs when running your sample:
LOGI("Image supports {}", compression_to_string(supported_compression_properties.imageCompressionFlags));
LOGI("Image supports {}", fixed_rate_flags_to_string(supported_compression_properties.imageCompressionFixedRateFlags));
The logcat output may look like this:
I/VulkanSamples: [info] Image supports VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT
I/VulkanSamples: [info] Image supports VK_IMAGE_COMPRESSION_FIXED_RATE_2BPC_BIT_EXT | VK_IMAGE_COMPRESSION_FIXED_RATE_4BPC_BIT_EXT | VK_IMAGE_COMPRESSION_FIXED_RATE_5BPC_BIT_EXT
Print helper functions for reference:
const std::string compression_to_string(VkImageCompressionFlagsEXT flag)
{
switch (flag)
{
case VK_IMAGE_COMPRESSION_DEFAULT_EXT:
return "VK_IMAGE_COMPRESSION_DEFAULT_EXT";
case VK_IMAGE_COMPRESSION_FIXED_RATE_DEFAULT_EXT:
return "VK_IMAGE_COMPRESSION_FIXED_RATE_DEFAULT_EXT";
case VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT:
return "VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT";
case VK_IMAGE_COMPRESSION_DISABLED_EXT:
return "VK_IMAGE_COMPRESSION_DISABLED_EXT";
default:
{
return "";
}
}
}
const std::string fixed_rate_flags_to_string(uint32_t flags)
{
if (0 == flags)
{
return "VK_IMAGE_COMPRESSION_FIXED_RATE_NONE_EXT";
}
const std::map<VkImageCompressionFixedRateFlagsEXT, const char *> string_map =
{{VK_IMAGE_COMPRESSION_FIXED_RATE_1BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_1BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_2BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_2BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_3BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_3BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_4BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_4BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_5BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_5BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_6BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_6BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_7BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_7BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_8BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_8BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_9BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_9BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_10BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_10BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_11BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_11BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_12BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_12BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_13BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_13BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_14BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_14BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_15BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_15BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_16BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_16BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_17BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_17BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_18BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_18BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_19BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_19BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_20BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_20BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_21BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_21BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_22BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_22BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_23BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_23BPC_BIT_EXT"},
{VK_IMAGE_COMPRESSION_FIXED_RATE_24BPC_BIT_EXT, "VK_IMAGE_COMPRESSION_FIXED_RATE_24BPC_BIT_EXT"}};
std::stringstream result;
bool append = false;
for (const auto &s : string_map)
{
if (flags & s.first)
{
if (append)
{
result << " | ";
}
result << s.second;
append = true;
}
}
return result.str();
}
You may find that the output of the code looks like:
I/VulkanSamples: [info] Image supports VK_IMAGE_COMPRESSION_DISABLED_EXT
I/VulkanSamples: [info] Image supports VK_IMAGE_COMPRESSION_FIXED_RATE_NONE_EXT
This means that the image does not support any sort of compression.
Possible reasons are discussed in
Arm GPU Best Practices Developer Guide
.
Depending on the device, image properties like image_create_info.format
and image_create_info.usage
(e.g., storage images) may be incompatible with fixed-rate compression.
Try using different values for these in case you find a suitable combination for your application that supports fixed-rate compression. Otherwise, for better performance, try to find one that at least supports AFBC if possible, following the guidance found in the AFBC guide , so that the output ideally looks like this:
I/VulkanSamples: [info] IMAGE SUPPORTS VK_IMAGE_COMPRESSION_DEFAULT_EXT
I/VulkanSamples: [info] IMAGE SUPPORTS VK_IMAGE_COMPRESSION_FIXED_RATE_NONE_EXT