diff --git a/CMakeLists.txt b/CMakeLists.txt index 746bf1e..94f73b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -284,7 +284,8 @@ add_library(${PROJECT_NAME} SHARED wsi/swapchain_base.cpp wsi/synchronization.cpp wsi/wsi_factory.cpp - wsi/swapchain_image_creator.cpp) + wsi/swapchain_image_creator.cpp + wsi/swapchain_image_create_extensions/image_compression_control.cpp) if (VULKAN_WSI_LAYER_EXPERIMENTAL) target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/layer/present_timing_api.cpp) target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/wsi/extensions/present_timing.cpp) diff --git a/wsi/headless/swapchain.cpp b/wsi/headless/swapchain.cpp index 9f2d64f..cad029a 100644 --- a/wsi/headless/swapchain.cpp +++ b/wsi/headless/swapchain.cpp @@ -38,11 +38,12 @@ #include #include -#include #include "util/macros.hpp" #include "present_timing_handler.hpp" +#include + namespace wsi { namespace headless @@ -68,14 +69,8 @@ swapchain::~swapchain() VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info) { - auto compression_control = wsi_ext_image_compression_control::create(device, swapchain_create_info); - if (compression_control) - { - if (!add_swapchain_extension(m_allocator.make_unique(*compression_control))) - { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - } + UNUSED(device); + UNUSED(swapchain_create_info); if (m_device_data.is_present_id_enabled()) { @@ -198,24 +193,7 @@ VkResult swapchain::allocate_and_bind_swapchain_image(VkImageCreateInfo image_cr VkResult swapchain::create_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) { - m_image_create_info = image_create_info; - VkImageCompressionControlEXT image_compression_control = {}; - - if (m_device_data.is_swapchain_compression_control_enabled()) - { - auto *ext = get_swapchain_extension(); - /* For image compression control, additional requirements to be satisfied such as - * existence of VkImageCompressionControlEXT in swaphain_create_info for - * the ext to be added to the list. So we check whether we got a valid pointer - * and proceed if yes. */ - if (ext) - { - image_compression_control = ext->get_compression_control_properties(); - image_compression_control.pNext = m_image_create_info.pNext; - m_image_create_info.pNext = &image_compression_control; - } - } - return m_device_data.disp.CreateImage(m_device, &m_image_create_info, get_allocation_callbacks(), &image.image); + return m_device_data.disp.CreateImage(m_device, &image_create_info, get_allocation_callbacks(), &image.image); } void swapchain::present_image(const pending_present_request &pending_present) @@ -285,8 +263,18 @@ VkResult swapchain::get_required_image_creator_extensions( const VkSwapchainCreateInfoKHR &swapchain_create_info, util::vector> *extensions) { - UNUSED(swapchain_create_info); - UNUSED(extensions); + assert(extensions != nullptr); + + auto compression_control = swapchain_image_create_compression_control::create( + m_device_data.is_swapchain_compression_control_enabled(), swapchain_create_info); + if (compression_control) + { + if (!extensions->try_push_back( + m_allocator.make_unique(*compression_control))) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + } return VK_SUCCESS; } diff --git a/wsi/swapchain_image_create_extensions/image_compression_control.cpp b/wsi/swapchain_image_create_extensions/image_compression_control.cpp new file mode 100644 index 0000000..72c4157 --- /dev/null +++ b/wsi/swapchain_image_create_extensions/image_compression_control.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2025 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file image_compression_control.cpp + * + * @brief Contains the implementation for VK_EXT_image_compression_control extension. + */ +#include + +#include + +#include "image_compression_control.hpp" + +namespace wsi +{ +swapchain_image_create_compression_control::swapchain_image_create_compression_control( + const VkImageCompressionControlEXT &extension) + : m_compression_control{ VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT, nullptr, extension.flags, + extension.compressionControlPlaneCount, m_array_fixed_rate_flags } +{ + for (uint32_t i = 0; i < extension.compressionControlPlaneCount; i++) + { + m_compression_control.pFixedRateFlags[i] = extension.pFixedRateFlags[i]; + } +} + +swapchain_image_create_compression_control::swapchain_image_create_compression_control( + const swapchain_image_create_compression_control &extension) + : swapchain_image_create_compression_control(extension.m_compression_control) +{ +} + +VkImageCompressionControlEXT swapchain_image_create_compression_control::get_compression_control_properties() +{ + return m_compression_control; +} + +VkImageCompressionFlagsEXT swapchain_image_create_compression_control::get_bitmask_for_image_compression_flags() +{ + return m_compression_control.flags; +} + +std::optional swapchain_image_create_compression_control::create( + bool compression_enabled, const VkSwapchainCreateInfoKHR &swapchain_create_info) +{ + const auto *image_compression_control = util::find_extension( + VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT, swapchain_create_info.pNext); + + if (compression_enabled && image_compression_control != nullptr) + { + return swapchain_image_create_compression_control{ *image_compression_control }; + } + + return std::nullopt; +} + +VkResult swapchain_image_create_compression_control::extend_image_create_info(VkImageCreateInfo *image_create_info) +{ + assert(image_create_info != nullptr); + + m_compression_control.pNext = image_create_info->pNext; + image_create_info->pNext = &m_compression_control; + return VK_SUCCESS; +} + +}; diff --git a/wsi/swapchain_image_create_extensions/image_compression_control.hpp b/wsi/swapchain_image_create_extensions/image_compression_control.hpp new file mode 100644 index 0000000..3d8f6d3 --- /dev/null +++ b/wsi/swapchain_image_create_extensions/image_compression_control.hpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2025 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file image_compression_control.hpp + * + * @brief Contains the implementation for VK_EXT_image_compression_control extension. + * + */ + +#pragma once + +#include +#include + +#include +#include + +#include "swapchain_image_create_info_extension.hpp" + +namespace wsi +{ +using util::MAX_PLANES; + +/** + * @brief Image compresssion control extension class + * + * This class implements the image compression control features. + * Backends needing additional features will create its own local + * copy and inherit this class. + */ +class swapchain_image_create_compression_control : public swapchain_image_create_info_extension +{ +public: + swapchain_image_create_compression_control(const swapchain_image_create_compression_control &extension); + + swapchain_image_create_compression_control &operator=(const swapchain_image_create_compression_control &extension) + { + if (this == &extension) + { + return *this; + } + + auto compression_control = swapchain_image_create_compression_control(extension); + std::swap(m_compression_control, compression_control.m_compression_control); + for (uint32_t i = 0; i < compression_control.m_compression_control.compressionControlPlaneCount; i++) + { + m_compression_control.pFixedRateFlags[i] = compression_control.m_compression_control.pFixedRateFlags[i]; + } + + return *this; + } + + /** + * @brief Create swapchain_image_create_compression_control class if deemed necessary. + * + * @param device The Vulkan device + * @param swapchain_create_info Swapchain create info + * @return Valid swapchain_image_create_compression_control if requested by application, + * otherwise - an empty optional. + */ + static std::optional create( + bool compression_enabled, const VkSwapchainCreateInfoKHR &swapchain_create_info); + + /** + * @brief This API is used to get the compression control properties of an image. + * + * @return The image compression control properties. + */ + VkImageCompressionControlEXT get_compression_control_properties(); + + /** + * @brief This API is used to get the bitmask for image compression flags. + * + * @return The bitmask for image compression flags. + */ + VkImageCompressionFlagsEXT get_bitmask_for_image_compression_flags(); + + VkResult extend_image_create_info(VkImageCreateInfo *image_create_info) override; + +private: + /** + * @brief Constructor for the swapchain_image_create_compression_control class. + * + * @param extension Reference to VkImageCompressionControlEXT structure. + */ + swapchain_image_create_compression_control(const VkImageCompressionControlEXT &extension); + + /** + * @brief Array to hold the pFixedRateFlags. + */ + VkImageCompressionFixedRateFlagsEXT m_array_fixed_rate_flags[MAX_PLANES]; + + /** + * @brief Image compression control properties. + */ + VkImageCompressionControlEXT m_compression_control; +}; + +} /* namespace wsi */