Skip to content

Commit

Permalink
Add Image Compression Control Sample (#979)
Browse files Browse the repository at this point in the history
* Add Image Compression Control Sample

* rebase fixes

* review changes

* review changes

* review changes

* review changes

* review changes

* review changes
  • Loading branch information
JoseEmilio-ARM committed Mar 14, 2024
1 parent 875e20b commit 0d0cf9b
Show file tree
Hide file tree
Showing 36 changed files with 2,026 additions and 156 deletions.
1 change: 1 addition & 0 deletions antora/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
** xref:samples/performance/command_buffer_usage/README.adoc[Command buffer usage]
** xref:samples/performance/constant_data/README.adoc[Constant data]
** xref:samples/performance/descriptor_management/README.adoc[Descriptor management]
** xref:samples/performance/image_compression_control/README.adoc[Image compression control]
** xref:samples/performance/layout_transitions/README.adoc[Layout transitions]
** xref:samples/performance/msaa/README.adoc[MSAA]
** xref:samples/performance/multithreading_render_passes/README.adoc[Multithreading render passes]
Expand Down
356 changes: 354 additions & 2 deletions framework/common/strings.cpp

Large diffs are not rendered by default.

80 changes: 47 additions & 33 deletions framework/common/strings.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023, Arm Limited and Contributors
/* Copyright (c) 2018-2024, Arm Limited and Contributors
*
* SPDX-License-Identifier: Apache-2.0
*
Expand Down Expand Up @@ -103,112 +103,112 @@ std::string to_string(VkExtent2D format);
/**
* @brief Helper function to convert VkSampleCountFlagBits to a string
* @param flags Vulkan sample count flags to convert
* @return const std::string
* @return const std::string
*/
const std::string to_string(VkSampleCountFlagBits flags);

/**
* @brief Helper function to convert VkImageTiling to a string
* @brief Helper function to convert VkImageTiling to a string
* @param tiling Vulkan VkImageTiling to convert
* @return The string to return
* @return The string to return
*/
const std::string to_string(VkImageTiling tiling);

/**
* @brief Helper function to convert VkImageType to a string
* @brief Helper function to convert VkImageType to a string
* @param type Vulkan VkImageType to convert
* @return The string to return
* @return The string to return
*/
const std::string to_string(VkImageType type);

/**
* @brief Helper function to convert VkBlendFactor to a string
* @brief Helper function to convert VkBlendFactor to a string
* @param blend Vulkan VkBlendFactor to convert
* @return The string to return
* @return The string to return
*/
const std::string to_string(VkBlendFactor blend);

/**
* @brief Helper function to convert VkVertexInputRate to a string
* @brief Helper function to convert VkVertexInputRate to a string
* @param rate Vulkan VkVertexInputRate to convert
* @return The string to return
* @return The string to return
*/
const std::string to_string(VkVertexInputRate rate);

/**
* @brief Helper function to convert VkBool32 to a string
* @brief Helper function to convert VkBool32 to a string
* @param state Vulkan VkBool32 to convert
* @return The string to return
* @return The string to return
*/
const std::string to_string_vk_bool(VkBool32 state);

/**
* @brief Helper function to convert VkPrimitiveTopology to a string
* @brief Helper function to convert VkPrimitiveTopology to a string
* @param topology Vulkan VkPrimitiveTopology to convert
* @return The string to return
* @return The string to return
*/
const std::string to_string(VkPrimitiveTopology topology);

/**
* @brief Helper function to convert VkFrontFace to a string
* @brief Helper function to convert VkFrontFace to a string
* @param face Vulkan VkFrontFace to convert
* @return The string to return
* @return The string to return
*/
const std::string to_string(VkFrontFace face);

/**
* @brief Helper function to convert VkPolygonMode to a string
* @brief Helper function to convert VkPolygonMode to a string
* @param mode Vulkan VkPolygonMode to convert
* @return The string to return
* @return The string to return
*/
const std::string to_string(VkPolygonMode mode);

/**
* @brief Helper function to convert VkCompareOp to a string
* @brief Helper function to convert VkCompareOp to a string
* @param operation Vulkan VkCompareOp to convert
* @return The string to return
* @return The string to return
*/
const std::string to_string(VkCompareOp operation);

/**
* @brief Helper function to convert VkStencilOp to a string
* @brief Helper function to convert VkStencilOp to a string
* @param operation Vulkan VkStencilOp to convert
* @return The string to return
* @return The string to return
*/
const std::string to_string(VkStencilOp operation);

/**
* @brief Helper function to convert VkLogicOp to a string
* @brief Helper function to convert VkLogicOp to a string
* @param operation Vulkan VkLogicOp to convert
* @return The string to return
* @return The string to return
*/
const std::string to_string(VkLogicOp operation);

/**
* @brief Helper function to convert VkBlendOp to a string
* @brief Helper function to convert VkBlendOp to a string
* @param operation Vulkan VkBlendOp to convert
* @return The string to return
* @return The string to return
*/
const std::string to_string(VkBlendOp operation);

/**
* @brief Helper function to convert AlphaMode to a string
* @brief Helper function to convert AlphaMode to a string
* @param mode Vulkan AlphaMode to convert
* @return The string to return
* @return The string to return
*/
const std::string to_string(sg::AlphaMode mode);

/**
* @brief Helper function to convert bool to a string
* @brief Helper function to convert bool to a string
* @param flag Vulkan bool to convert (true/false)
* @return The string to return
* @return The string to return
*/
const std::string to_string(bool flag);

/**
* @brief Helper function to convert ShaderResourceType to a string
* @brief Helper function to convert ShaderResourceType to a string
* @param type Vulkan ShaderResourceType to convert
* @return The string to return
* @return The string to return
*/
const std::string to_string(ShaderResourceType type);

Expand All @@ -229,7 +229,7 @@ inline const std::string to_string(uint32_t bitmask, const std::map<T, const cha
{
if (append)
{
result << " / ";
result << " | ";
}
result << s.second;
append = true;
Expand Down Expand Up @@ -280,6 +280,20 @@ const std::string cull_mode_to_string(VkCullModeFlags bitmask);
*/
const std::string color_component_to_string(VkColorComponentFlags bitmask);

/**
* @brief Helper function to convert VkImageCompressionFlagsEXT to a string
* @param flags The flags to convert
* @return The converted string to return
*/
const std::string image_compression_flags_to_string(VkImageCompressionFlagsEXT flags);

/**
* @brief Helper function to convert VkImageCompressionFixedRateFlagsEXT to a string
* @param flags The flags to convert
* @return The converted string to return
*/
const std::string image_compression_fixed_rate_flags_to_string(VkImageCompressionFixedRateFlagsEXT flags);

/**
* @brief Helper function to split a single string into a vector of strings by a delimiter
* @param input The input string to be split
Expand Down
66 changes: 66 additions & 0 deletions framework/common/vk_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,72 @@ void image_layout_transition(VkCommandBuffer
image_memory_barriers.data());
}

std::vector<VkImageCompressionFixedRateFlagBitsEXT> fixed_rate_compression_flags_to_vector(VkImageCompressionFixedRateFlagsEXT flags)
{
const std::vector<VkImageCompressionFixedRateFlagBitsEXT> all_flags = {VK_IMAGE_COMPRESSION_FIXED_RATE_1BPC_BIT_EXT, VK_IMAGE_COMPRESSION_FIXED_RATE_2BPC_BIT_EXT,
VK_IMAGE_COMPRESSION_FIXED_RATE_3BPC_BIT_EXT, VK_IMAGE_COMPRESSION_FIXED_RATE_4BPC_BIT_EXT,
VK_IMAGE_COMPRESSION_FIXED_RATE_5BPC_BIT_EXT, VK_IMAGE_COMPRESSION_FIXED_RATE_6BPC_BIT_EXT,
VK_IMAGE_COMPRESSION_FIXED_RATE_7BPC_BIT_EXT, VK_IMAGE_COMPRESSION_FIXED_RATE_8BPC_BIT_EXT,
VK_IMAGE_COMPRESSION_FIXED_RATE_9BPC_BIT_EXT, VK_IMAGE_COMPRESSION_FIXED_RATE_10BPC_BIT_EXT,
VK_IMAGE_COMPRESSION_FIXED_RATE_11BPC_BIT_EXT, VK_IMAGE_COMPRESSION_FIXED_RATE_12BPC_BIT_EXT,
VK_IMAGE_COMPRESSION_FIXED_RATE_13BPC_BIT_EXT, VK_IMAGE_COMPRESSION_FIXED_RATE_14BPC_BIT_EXT,
VK_IMAGE_COMPRESSION_FIXED_RATE_15BPC_BIT_EXT, VK_IMAGE_COMPRESSION_FIXED_RATE_16BPC_BIT_EXT,
VK_IMAGE_COMPRESSION_FIXED_RATE_17BPC_BIT_EXT, VK_IMAGE_COMPRESSION_FIXED_RATE_18BPC_BIT_EXT,
VK_IMAGE_COMPRESSION_FIXED_RATE_19BPC_BIT_EXT, VK_IMAGE_COMPRESSION_FIXED_RATE_20BPC_BIT_EXT,
VK_IMAGE_COMPRESSION_FIXED_RATE_21BPC_BIT_EXT, VK_IMAGE_COMPRESSION_FIXED_RATE_22BPC_BIT_EXT,
VK_IMAGE_COMPRESSION_FIXED_RATE_23BPC_BIT_EXT, VK_IMAGE_COMPRESSION_FIXED_RATE_24BPC_BIT_EXT};

std::vector<VkImageCompressionFixedRateFlagBitsEXT> flags_vector;

for (size_t i = 0; i < all_flags.size(); i++)
{
if (all_flags[i] & flags)
{
flags_vector.push_back(all_flags[i]);
}
}

return flags_vector;
}

VkImageCompressionPropertiesEXT query_supported_fixed_rate_compression(VkPhysicalDevice gpu, const VkImageCreateInfo &create_info)
{
VkImageCompressionPropertiesEXT supported_compression_properties{VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT};

VkImageCompressionControlEXT compression_control{VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT};
compression_control.flags = VK_IMAGE_COMPRESSION_FIXED_RATE_DEFAULT_EXT;

VkPhysicalDeviceImageFormatInfo2 image_format_info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2};
image_format_info.format = create_info.format;
image_format_info.type = create_info.imageType;
image_format_info.tiling = create_info.tiling;
image_format_info.usage = create_info.usage;
image_format_info.pNext = &compression_control;

VkImageFormatProperties2 image_format_properties{VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2};
image_format_properties.pNext = &supported_compression_properties;

vkGetPhysicalDeviceImageFormatProperties2KHR(gpu, &image_format_info, &image_format_properties);

return supported_compression_properties;
}

VkImageCompressionPropertiesEXT query_applied_compression(VkDevice device, VkImage image)
{
VkImageSubresource2EXT image_subresource{VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2_KHR};
image_subresource.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
image_subresource.imageSubresource.mipLevel = 0;
image_subresource.imageSubresource.arrayLayer = 0;

VkImageCompressionPropertiesEXT compression_properties{VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT};
VkSubresourceLayout2EXT subresource_layout{VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2_KHR};
subresource_layout.pNext = &compression_properties;

vkGetImageSubresourceLayout2EXT(device, image, &image_subresource, &subresource_layout);

return compression_properties;
}

VkSurfaceFormatKHR select_surface_format(VkPhysicalDevice gpu, VkSurfaceKHR surface, std::vector<VkFormat> const &preferred_formats)
{
uint32_t surface_format_count;
Expand Down
9 changes: 9 additions & 0 deletions framework/common/vk_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,15 @@ void image_layout_transition(VkCommandBuffer
VkImageLayout old_layout,
VkImageLayout new_layout);

/**
* @brief Helper functions for compression controls
*/
std::vector<VkImageCompressionFixedRateFlagBitsEXT> fixed_rate_compression_flags_to_vector(VkImageCompressionFixedRateFlagsEXT flags);

VkImageCompressionPropertiesEXT query_supported_fixed_rate_compression(VkPhysicalDevice gpu, const VkImageCreateInfo &create_info);

VkImageCompressionPropertiesEXT query_applied_compression(VkDevice device, VkImage image);

/**
* @brief Load and store info for a render pass attachment.
*/
Expand Down
20 changes: 1 addition & 19 deletions framework/core/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,21 +75,6 @@ Device::Device(PhysicalDevice &gpu,
}

// Check extensions to enable Vma Dedicated Allocation
uint32_t device_extension_count;
VK_CHECK(vkEnumerateDeviceExtensionProperties(gpu.get_handle(), nullptr, &device_extension_count, nullptr));
device_extensions = std::vector<VkExtensionProperties>(device_extension_count);
VK_CHECK(vkEnumerateDeviceExtensionProperties(gpu.get_handle(), nullptr, &device_extension_count, device_extensions.data()));

// Display supported extensions
if (device_extensions.size() > 0)
{
LOGD("Device supports the following extensions:");
for (auto &extension : device_extensions)
{
LOGD(" \t{}", extension.extensionName);
}
}

bool can_get_memory_requirements = is_extension_supported("VK_KHR_get_memory_requirements2");
bool has_dedicated_allocation = is_extension_supported("VK_KHR_dedicated_allocation");

Expand Down Expand Up @@ -228,10 +213,7 @@ Device::~Device()

bool Device::is_extension_supported(const std::string &requested_extension) const
{
return std::find_if(device_extensions.begin(), device_extensions.end(),
[requested_extension](auto &device_extension) {
return std::strcmp(device_extension.extensionName, requested_extension.c_str()) == 0;
}) != device_extensions.end();
return gpu.is_extension_supported(requested_extension);
}

bool Device::is_enabled(const char *extension) const
Expand Down
2 changes: 0 additions & 2 deletions framework/core/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,6 @@ class Device : public core::VulkanResource<VkDevice>

std::unique_ptr<DebugUtils> debug_utils;

std::vector<VkExtensionProperties> device_extensions;

std::vector<const char *> enabled_extensions{};

std::vector<std::vector<Queue>> queues;
Expand Down
16 changes: 1 addition & 15 deletions framework/core/hpp_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,6 @@ HPPDevice::HPPDevice(vkb::core::HPPPhysicalDevice &gpu,
}

// Check extensions to enable Vma Dedicated Allocation
device_extensions = gpu.get_handle().enumerateDeviceExtensionProperties();

// Display supported extensions
if (device_extensions.size() > 0)
{
LOGD("HPPDevice supports the following extensions:");
for (auto &extension : device_extensions)
{
LOGD(" \t{}", extension.extensionName.data());
}
}

bool can_get_memory_requirements = is_extension_supported(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
bool has_dedicated_allocation = is_extension_supported(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);

Expand Down Expand Up @@ -204,9 +192,7 @@ HPPDevice::~HPPDevice()

bool HPPDevice::is_extension_supported(std::string const &requested_extension) const
{
return std::find_if(device_extensions.begin(),
device_extensions.end(),
[requested_extension](auto &device_extension) { return std::strcmp(device_extension.extensionName, requested_extension.c_str()) == 0; }) != device_extensions.end();
return gpu.is_extension_supported(requested_extension);
}

bool HPPDevice::is_enabled(std::string const &extension) const
Expand Down
2 changes: 0 additions & 2 deletions framework/core/hpp_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,6 @@ class HPPDevice : public vkb::core::HPPVulkanResource<vk::Device>

std::unique_ptr<vkb::core::HPPDebugUtils> debug_utils;

std::vector<vk::ExtensionProperties> device_extensions;

std::vector<const char *> enabled_extensions{};

std::vector<std::vector<vkb::core::HPPQueue>> queues;
Expand Down
19 changes: 19 additions & 0 deletions framework/core/hpp_physical_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ HPPPhysicalDevice::HPPPhysicalDevice(HPPInstance &instance, vk::PhysicalDevice p
LOGI("Found GPU: {}", properties.deviceName.data());

queue_family_properties = physical_device.getQueueFamilyProperties();

device_extensions = physical_device.enumerateDeviceExtensionProperties();

// Display supported extensions
if (device_extensions.size() > 0)
{
LOGD("HPPDevice supports the following extensions:");
for (auto &extension : device_extensions)
{
LOGD(" \t{}", extension.extensionName.data());
}
}
}

DriverVersion HPPPhysicalDevice::get_driver_version() const
Expand Down Expand Up @@ -69,6 +81,13 @@ void *HPPPhysicalDevice::get_extension_feature_chain() const
return last_requested_extension_feature;
}

bool HPPPhysicalDevice::is_extension_supported(const std::string &requested_extension) const
{
return std::find_if(device_extensions.begin(),
device_extensions.end(),
[requested_extension](auto &device_extension) { return std::strcmp(device_extension.extensionName, requested_extension.c_str()) == 0; }) != device_extensions.end();
}

const vk::PhysicalDeviceFeatures &HPPPhysicalDevice::get_features() const
{
return features;
Expand Down
Loading

0 comments on commit 0d0cf9b

Please sign in to comment.