From cbf6c9765c91a0c39fd92aa734f177c6605fab86 Mon Sep 17 00:00:00 2001 From: Iason Paraskevopoulos Date: Thu, 25 Apr 2024 15:07:47 +0100 Subject: [PATCH] Separate image creation from create_and_bind_swapchain Change-Id: Ifbc6a5fb57c962006550838667944b03654ce0e4 Signed-off-by: Iason Paraskevopoulos Signed-off-by: Fufu Fang --- wsi/external_memory.cpp | 4 +- wsi/headless/swapchain.cpp | 44 ++++++++--------- wsi/headless/swapchain.hpp | 16 +++++-- wsi/swapchain_base.cpp | 9 ++-- wsi/swapchain_base.hpp | 16 +++++-- wsi/wayland/swapchain.cpp | 96 +++++++++++++++++++++----------------- wsi/wayland/swapchain.hpp | 19 ++++++-- 7 files changed, 123 insertions(+), 81 deletions(-) diff --git a/wsi/external_memory.cpp b/wsi/external_memory.cpp index ad1a606..f186036 100644 --- a/wsi/external_memory.cpp +++ b/wsi/external_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Arm Limited. + * Copyright (c) 2022-2024 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -68,7 +68,7 @@ uint32_t external_memory::get_num_planes() { for (uint32_t plane = 0; plane < MAX_PLANES; plane++) { - if (m_buffer_fds[plane] == -1) + if (m_strides[plane] == -1) { break; } diff --git a/wsi/headless/swapchain.cpp b/wsi/headless/swapchain.cpp index 508c243..fd3d82d 100644 --- a/wsi/headless/swapchain.cpp +++ b/wsi/headless/swapchain.cpp @@ -76,32 +76,11 @@ VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKH return VK_SUCCESS; } -VkResult swapchain::create_and_bind_swapchain_image(VkImageCreateInfo image_create, wsi::swapchain_image &image) +VkResult swapchain::allocate_and_bind_swapchain_image(VkImageCreateInfo image_create, swapchain_image &image) { VkResult res = VK_SUCCESS; const std::lock_guard lock(m_image_status_mutex); - m_image_create_info = image_create; -#if WSI_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN - if (m_device_data.is_swapchain_compression_control_enabled()) - { - /* Initialize compression control */ - m_image_compression_control.sType = VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT; - m_image_compression_control.compressionControlPlaneCount = - m_image_compression_control_params.compression_control_plane_count; - m_image_compression_control.flags = m_image_compression_control_params.flags; - m_image_compression_control.pFixedRateFlags = m_image_compression_control_params.fixed_rate_flags.data(); - m_image_compression_control.pNext = m_image_create_info.pNext; - - m_image_create_info.pNext = &m_image_compression_control; - } -#endif - res = m_device_data.disp.CreateImage(m_device, &m_image_create_info, get_allocation_callbacks(), &image.image); - if (res != VK_SUCCESS) - { - return res; - } - VkMemoryRequirements memory_requirements = {}; m_device_data.disp.GetImageMemoryRequirements(m_device, image.image, &memory_requirements); @@ -161,6 +140,27 @@ VkResult swapchain::create_and_bind_swapchain_image(VkImageCreateInfo image_crea return res; } +VkResult swapchain::create_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) +{ + m_image_create_info = image_create_info; +#if WSI_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN + if (m_device_data.is_swapchain_compression_control_enabled()) + { + /* Initialize compression control */ + m_image_compression_control.sType = VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT; + m_image_compression_control.compressionControlPlaneCount = + m_image_compression_control_params.compression_control_plane_count; + m_image_compression_control.flags = m_image_compression_control_params.flags; + m_image_compression_control.pFixedRateFlags = m_image_compression_control_params.fixed_rate_flags.data(); + m_image_compression_control.pNext = m_image_create_info.pNext; + + m_image_create_info.pNext = &m_image_compression_control; + } +#endif + + return m_device_data.disp.CreateImage(m_device, &m_image_create_info, get_allocation_callbacks(), &image.image); +} + void swapchain::present_image(uint32_t pending_index) { unpresent_image(pending_index); diff --git a/wsi/headless/swapchain.hpp b/wsi/headless/swapchain.hpp index b247924..64e1b51 100644 --- a/wsi/headless/swapchain.hpp +++ b/wsi/headless/swapchain.hpp @@ -60,16 +60,26 @@ protected: bool &use_presentation_thread) override; /** - * @brief Creates and binds a new swapchain image. + * @brief Allocates and binds a new swapchain image. + * + * @param image_create_info Data to be used to create the image. + * @param image Handle to the image. + * + * @return Returns VK_SUCCESS on success, otherwise an appropriate error code. + */ + VkResult allocate_and_bind_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) override; + + /** + * @brief Creates a new swapchain image. * * @param image_create_info Data to be used to create the image. * @param image Handle to the image. * * @return If image creation is successful returns VK_SUCCESS, otherwise * will return VK_ERROR_OUT_OF_DEVICE_MEMORY or VK_ERROR_INITIALIZATION_FAILED - * depending on the error that occured. + * depending on the error that occurred. */ - VkResult create_and_bind_swapchain_image(VkImageCreateInfo image_create_info, wsi::swapchain_image &image) override; + VkResult create_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) override; /** * @brief Method to perform a present - just calls unpresent_image on headless diff --git a/wsi/swapchain_base.cpp b/wsi/swapchain_base.cpp index d4c2d14..57181cd 100644 --- a/wsi/swapchain_base.cpp +++ b/wsi/swapchain_base.cpp @@ -322,17 +322,18 @@ VkResult swapchain_base::init(VkDevice device, const VkSwapchainCreateInfoKHR *s } const bool image_deferred_allocation = - image_create_info.flags & VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT; + swapchain_create_info->flags & VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT; for (auto &img : m_swapchain_images) { + TRY(create_swapchain_image(image_create_info, img)); + if (image_deferred_allocation) { - m_image_create_info = image_create_info; img.status = swapchain_image::UNALLOCATED; } else { - TRY_LOG_CALL(create_and_bind_swapchain_image(image_create_info, img)); + TRY_LOG_CALL(allocate_and_bind_swapchain_image(image_create_info, img)); } VkSemaphoreCreateInfo semaphore_info = {}; @@ -465,7 +466,7 @@ VkResult swapchain_base::acquire_next_image(uint64_t timeout, VkSemaphore semaph { if (m_swapchain_images[i].status == swapchain_image::UNALLOCATED) { - auto res = create_and_bind_swapchain_image(m_image_create_info, m_swapchain_images[i]); + auto res = allocate_and_bind_swapchain_image(m_image_create_info, m_swapchain_images[i]); if (res != VK_SUCCESS) { WSI_LOG_ERROR("Failed to allocate swapchain image."); diff --git a/wsi/swapchain_base.hpp b/wsi/swapchain_base.hpp index 01ca4fd..75fa25a 100644 --- a/wsi/swapchain_base.hpp +++ b/wsi/swapchain_base.hpp @@ -414,16 +414,26 @@ protected: void teardown(); /** - * @brief Creates and binds a new swapchain image. + * @brief Allocates and binds a new swapchain image. + * + * @param image_create_info Data to be used to create the image. + * @param image Handle to the image. + * + * @return Returns VK_SUCCESS on success, otherwise an appropriate error code. + */ + virtual VkResult allocate_and_bind_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) = 0; + + /** + * @brief Creates a new swapchain image. * * @param image_create_info Data to be used to create the image. * @param image Handle to the image. * * @return If image creation is successful returns VK_SUCCESS, otherwise * will return VK_ERROR_OUT_OF_DEVICE_MEMORY or VK_ERROR_INITIALIZATION_FAILED - * depending on the error that occured. + * depending on the error that occurred. */ - virtual VkResult create_and_bind_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) = 0; + virtual VkResult create_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) = 0; /** * @brief Method to present and image diff --git a/wsi/wayland/swapchain.cpp b/wsi/wayland/swapchain.cpp index 371fbea..830a792 100644 --- a/wsi/wayland/swapchain.cpp +++ b/wsi/wayland/swapchain.cpp @@ -257,10 +257,14 @@ VkResult swapchain::get_surface_compatible_formats(const VkImageCreateInfo &info VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, wayland_image_data *image_data, util::vector &importable_formats, - wsialloc_format *allocated_format) + wsialloc_format *allocated_format, bool avoid_allocation) { bool is_protected_memory = (image_create_info.flags & VK_IMAGE_CREATE_PROTECTED_BIT) != 0; uint64_t allocation_flags = is_protected_memory ? WSIALLOC_ALLOCATE_PROTECTED : 0; + if (avoid_allocation) + { + allocation_flags |= WSIALLOC_ALLOCATE_NO_MEMORY; + } #if WSI_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN if (m_image_compression_control_params.flags & VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT) @@ -274,10 +278,11 @@ VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, wayl allocation_flags }; wsialloc_allocate_result alloc_result = { 0 }; - /* Clear fds for error purposes */ + /* Clear buffer_fds and average_row_strides for error purposes */ for (int i = 0; i < WSIALLOC_MAX_PLANES; ++i) { alloc_result.buffer_fds[i] = -1; + alloc_result.average_row_strides[i] = -1; } const auto res = wsialloc_alloc(m_wsi_allocator, &alloc_info, &alloc_result); if (res != WSIALLOC_ERROR_NONE) @@ -318,43 +323,16 @@ static VkResult fill_image_create_info(VkImageCreateInfo &image_create_info, return VK_SUCCESS; } -VkResult swapchain::allocate_image(VkImageCreateInfo &image_create_info, wayland_image_data *image_data, VkImage *image) +VkResult swapchain::allocate_image(VkImageCreateInfo &image_create_info, wayland_image_data *image_data) { util::vector importable_formats(util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)); auto &m_allocated_format = m_image_creation_parameters.m_allocated_format; - if (m_image_create_info.format != VK_FORMAT_UNDEFINED) + if (!importable_formats.try_push_back(m_allocated_format)) { - if (!importable_formats.try_push_back(m_allocated_format)) - { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - TRY_LOG_CALL(allocate_wsialloc(m_image_create_info, image_data, importable_formats, &m_allocated_format)); + return VK_ERROR_OUT_OF_HOST_MEMORY; } - else - { - util::vector exportable_modifiers(util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)); - TRY_LOG_CALL(get_surface_compatible_formats(image_create_info, importable_formats, exportable_modifiers)); + TRY_LOG_CALL(allocate_wsialloc(m_image_create_info, image_data, importable_formats, &m_allocated_format, false)); - /* TODO: Handle exportable images which use ICD allocated memory in preference to an external allocator. */ - if (importable_formats.empty()) - { - WSI_LOG_ERROR("Export/Import not supported."); - return VK_ERROR_INITIALIZATION_FAILED; - } - - wsialloc_format allocated_format = { 0 }; - TRY_LOG_CALL(allocate_wsialloc(image_create_info, image_data, importable_formats, &allocated_format)); - - TRY_LOG_CALL(fill_image_create_info( - image_create_info, m_image_creation_parameters.m_image_layout, m_image_creation_parameters.m_drm_mod_info, - m_image_creation_parameters.m_external_info, *image_data, allocated_format.modifier)); - - m_image_create_info = image_create_info; - m_allocated_format = allocated_format; - } - - TRY_LOG(m_device_data.disp.CreateImage(m_device, &m_image_create_info, get_allocation_callbacks(), image), - "Image creation failed"); return VK_SUCCESS; } @@ -389,20 +367,14 @@ VkResult swapchain::create_wl_buffer(const VkImageCreateInfo &image_create_info, return VK_SUCCESS; } -VkResult swapchain::create_and_bind_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) +VkResult swapchain::allocate_and_bind_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) { - /* Create image_data */ - auto image_data = m_allocator.create(1, m_device, m_allocator); - if (image_data == nullptr) - { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - std::unique_lock image_status_lock(m_image_status_mutex); - image.data = image_data; image.status = swapchain_image::FREE; - TRY_LOG(allocate_image(image_create_info, image_data, &image.image), "Failed to allocate image"); + assert(image.data != nullptr); + auto image_data = static_cast(image.data); + TRY_LOG(allocate_image(image_create_info, image_data), "Failed to allocate image"); image_status_lock.unlock(); TRY_LOG(create_wl_buffer(image_create_info, image, image_data), "Failed to create wl_buffer"); @@ -421,6 +393,44 @@ VkResult swapchain::create_and_bind_swapchain_image(VkImageCreateInfo image_crea return VK_SUCCESS; } +VkResult swapchain::create_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) +{ + /* Create image_data */ + auto image_data = m_allocator.create(1, m_device, m_allocator); + if (image_data == nullptr) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + image.data = image_data; + + if (m_image_create_info.format == VK_FORMAT_UNDEFINED) + { + util::vector importable_formats( + util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)); + util::vector exportable_modifiers(util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)); + TRY_LOG_CALL(get_surface_compatible_formats(image_create_info, importable_formats, exportable_modifiers)); + + /* TODO: Handle exportable images which use ICD allocated memory in preference to an external allocator. */ + if (importable_formats.empty()) + { + WSI_LOG_ERROR("Export/Import not supported."); + return VK_ERROR_INITIALIZATION_FAILED; + } + + wsialloc_format allocated_format = { 0 }; + TRY_LOG_CALL(allocate_wsialloc(image_create_info, image_data, importable_formats, &allocated_format, true)); + + TRY_LOG_CALL(fill_image_create_info( + image_create_info, m_image_creation_parameters.m_image_layout, m_image_creation_parameters.m_drm_mod_info, + m_image_creation_parameters.m_external_info, *image_data, allocated_format.modifier)); + + m_image_create_info = image_create_info; + m_image_creation_parameters.m_allocated_format = allocated_format; + } + + return m_device_data.disp.CreateImage(m_device, &m_image_create_info, get_allocation_callbacks(), &image.image); +} + void swapchain::present_image(uint32_t pendingIndex) { int res; diff --git a/wsi/wayland/swapchain.hpp b/wsi/wayland/swapchain.hpp index d9fcc8b..f09da05 100644 --- a/wsi/wayland/swapchain.hpp +++ b/wsi/wayland/swapchain.hpp @@ -94,7 +94,17 @@ protected: bool &use_presentation_thread) override; /** - * @brief Creates and binds a new swapchain image. + * @brief Allocates and binds a new swapchain image. + * + * @param image_create_info Data to be used to create the image. + * @param image Handle to the image. + * + * @return Returns VK_SUCCESS on success, otherwise an appropriate error code. + */ + VkResult allocate_and_bind_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) override; + + /** + * @brief Creates a new swapchain image. * * @param image_create_info Data to be used to create the image. * @param image Handle to the image. @@ -103,7 +113,7 @@ protected: * will return VK_ERROR_OUT_OF_DEVICE_MEMORY or VK_ERROR_INITIALIZATION_FAILED * depending on the error that occurred. */ - VkResult create_and_bind_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) override; + VkResult create_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) override; /** * @brief Method to present an image @@ -158,9 +168,10 @@ protected: private: VkResult create_wl_buffer(const VkImageCreateInfo &image_create_info, swapchain_image &image, wayland_image_data *image_data); - VkResult allocate_image(VkImageCreateInfo &image_create_info, wayland_image_data *image_data, VkImage *image); + VkResult allocate_image(VkImageCreateInfo &image_create_info, wayland_image_data *image_data); VkResult allocate_wsialloc(VkImageCreateInfo &image_create_info, wayland_image_data *image_data, - util::vector &importable_formats, wsialloc_format *allocated_format); + util::vector &importable_formats, wsialloc_format *allocated_format, + bool avoid_allocation); struct wl_display *m_display; struct wl_surface *m_surface;