mirror of
https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer.git
synced 2025-12-20 04:30:11 +01:00
Merge 'Introduce swapchain_image_creator' into 'main'
See merge request mesa/vulkan-wsi-layer!154
This commit is contained in:
commit
b2484fe518
25 changed files with 1206 additions and 224 deletions
|
|
@ -76,6 +76,7 @@ option(ENABLE_INSTRUMENTATION "Pass frame boundary events by using VK_EXT_frame_
|
|||
|
||||
if(BUILD_WSI_WAYLAND OR BUILD_WSI_DISPLAY)
|
||||
set(BUILD_DRM_UTILS true)
|
||||
set(BUILD_WSIALLOC_UTILS true)
|
||||
if(SELECT_EXTERNAL_ALLOCATOR STREQUAL "none")
|
||||
message(FATAL_ERROR "WSI only supported with an external allocator.")
|
||||
endif()
|
||||
|
|
@ -126,13 +127,26 @@ if(NOT SELECT_EXTERNAL_ALLOCATOR STREQUAL "none" AND EXTERNAL_WSIALLOC_LIBRARY S
|
|||
target_include_directories(wsialloc PRIVATE util/)
|
||||
endif()
|
||||
|
||||
if(BUILD_WSIALLOC_UTILS)
|
||||
add_library(wsi_utils STATIC wsi/wsi_alloc_utils.cpp)
|
||||
|
||||
target_include_directories(wsi_utils PRIVATE
|
||||
${PROJECT_SOURCE_DIR}
|
||||
${VULKAN_CXX_INCLUDE}
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
target_link_libraries(wsi_utils drm_utils)
|
||||
target_include_directories(wsi_utils PRIVATE util/wsialloc)
|
||||
target_compile_definitions(wsi_utils PRIVATE ${WSI_DEFINES})
|
||||
endif()
|
||||
|
||||
# Wayland WSI
|
||||
if(BUILD_WSI_WAYLAND)
|
||||
add_library(wayland_wsi STATIC
|
||||
wsi/wayland/surface_properties.cpp
|
||||
wsi/wayland/surface.cpp
|
||||
wsi/wayland/wl_helpers.cpp
|
||||
wsi/wayland/swapchain.cpp)
|
||||
wsi/wayland/swapchain.cpp
|
||||
wsi/swapchain_image_create_extensions/external_memory_extension.cpp)
|
||||
|
||||
if(VULKAN_WSI_LAYER_EXPERIMENTAL)
|
||||
target_sources(wayland_wsi PRIVATE wsi/wayland/present_id_wayland.cpp)
|
||||
|
|
@ -199,6 +213,7 @@ if(BUILD_WSI_WAYLAND)
|
|||
target_link_libraries(wayland_wsi wsialloc)
|
||||
endif()
|
||||
target_link_libraries(wayland_wsi drm_utils ${WAYLAND_CLIENT_LDFLAGS})
|
||||
target_link_libraries(wayland_wsi wsi_utils)
|
||||
list(APPEND LINK_WSI_LIBS wayland_wsi)
|
||||
if(ENABLE_WAYLAND_FIFO_PRESENTATION_THREAD)
|
||||
target_compile_definitions(wayland_wsi PRIVATE "-DWAYLAND_FIFO_PRESENTATION_THREAD_ENABLED=1")
|
||||
|
|
@ -239,7 +254,8 @@ if (BUILD_WSI_DISPLAY)
|
|||
wsi/display/drm_display.cpp
|
||||
wsi/display/surface_properties.cpp
|
||||
wsi/display/swapchain.cpp
|
||||
wsi/display/surface.cpp)
|
||||
wsi/display/surface.cpp
|
||||
wsi/swapchain_image_create_extensions/external_memory_extension.cpp)
|
||||
|
||||
if(VULKAN_WSI_LAYER_EXPERIMENTAL)
|
||||
target_sources(wsi_display PRIVATE wsi/display/present_wait_display.cpp)
|
||||
|
|
@ -260,6 +276,7 @@ if (BUILD_WSI_DISPLAY)
|
|||
target_compile_options(wsi_display INTERFACE "-DBUILD_WSI_DISPLAY=1")
|
||||
target_link_libraries(wsi_display ${LIBDRM_LDFLAGS} drm)
|
||||
target_link_libraries(wsi_display drm_utils)
|
||||
target_link_libraries(wsi_display wsi_utils)
|
||||
if(NOT EXTERNAL_WSIALLOC_LIBRARY STREQUAL "")
|
||||
target_link_libraries(wsi_display ${EXTERNAL_WSIALLOC_LIBRARY})
|
||||
else()
|
||||
|
|
@ -292,7 +309,9 @@ add_library(${PROJECT_NAME} SHARED
|
|||
wsi/surface_properties.cpp
|
||||
wsi/swapchain_base.cpp
|
||||
wsi/synchronization.cpp
|
||||
wsi/wsi_factory.cpp)
|
||||
wsi/wsi_factory.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)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 2021-2022, 2024 Arm Limited.
|
||||
* Copyright (c) 2019-2025 Arm Limited.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
|
|
@ -31,6 +31,15 @@ namespace util
|
|||
namespace drm
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Struct describing a DRM format with modifier.
|
||||
*/
|
||||
struct drm_format_pair
|
||||
{
|
||||
uint32_t fourcc;
|
||||
uint64_t modifier;
|
||||
};
|
||||
|
||||
uint32_t vk_to_drm_format(VkFormat vk_format);
|
||||
VkFormat drm_to_vk_format(uint32_t drm_format);
|
||||
VkFormat drm_to_vk_srgb_format(uint32_t drm_format);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Arm Limited.
|
||||
* Copyright (c) 2024-2025 Arm Limited.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
|
|
@ -44,7 +44,7 @@ namespace display
|
|||
const std::string default_dri_device_name{ "/dev/dri/card0" };
|
||||
|
||||
drm_display::drm_display(util::fd_owner drm_fd, int crtc_id, drm_connector_owner drm_connector,
|
||||
util::unique_ptr<util::vector<drm_format_pair>> supported_formats,
|
||||
util::unique_ptr<util::vector<util::drm::drm_format_pair>> supported_formats,
|
||||
util::unique_ptr<drm_display_mode> display_modes, size_t num_display_modes, uint32_t max_width,
|
||||
uint32_t max_height, bool supports_fb_modifiers)
|
||||
: m_drm_fd(std::move(drm_fd))
|
||||
|
|
@ -147,11 +147,12 @@ static bool find_primary_plane(const util::fd_owner &drm_fd, const drm_plane_res
|
|||
}
|
||||
|
||||
static bool fill_supported_formats(const drm_plane_owner &primary_plane,
|
||||
util::vector<drm_format_pair> &supported_formats)
|
||||
util::vector<util::drm::drm_format_pair> &supported_formats)
|
||||
{
|
||||
for (uint32_t i = 0; i < primary_plane->count_formats; i++)
|
||||
{
|
||||
if (!supported_formats.try_push_back(drm_format_pair{ primary_plane->formats[i], DRM_FORMAT_MOD_LINEAR }))
|
||||
if (!supported_formats.try_push_back(
|
||||
util::drm::drm_format_pair{ primary_plane->formats[i], DRM_FORMAT_MOD_LINEAR }))
|
||||
{
|
||||
WSI_LOG_ERROR("Out of host memory.");
|
||||
return false;
|
||||
|
|
@ -163,7 +164,7 @@ static bool fill_supported_formats(const drm_plane_owner &primary_plane,
|
|||
|
||||
static bool fill_supported_formats_with_modifiers(uint32_t primary_plane_index, const util::fd_owner &drm_fd,
|
||||
const drm_plane_resources_owner &plane_res,
|
||||
util::vector<drm_format_pair> &supported_formats)
|
||||
util::vector<util::drm::drm_format_pair> &supported_formats)
|
||||
{
|
||||
drm_object_properties_owner object_properties{ drmModeObjectGetProperties(
|
||||
drm_fd.get(), plane_res->planes[primary_plane_index], DRM_MODE_OBJECT_PLANE) };
|
||||
|
|
@ -191,7 +192,7 @@ static bool fill_supported_formats_with_modifiers(uint32_t primary_plane_index,
|
|||
|
||||
while (drmModeFormatModifierBlobIterNext(blob.get(), &iter))
|
||||
{
|
||||
if (!supported_formats.try_push_back(drm_format_pair{ iter.fmt, iter.mod }))
|
||||
if (!supported_formats.try_push_back(util::drm::drm_format_pair{ iter.fmt, iter.mod }))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -317,7 +318,7 @@ std::optional<drm_display> drm_display::make_display(const util::allocator &allo
|
|||
}
|
||||
#endif
|
||||
|
||||
auto supported_formats = allocator.make_unique<util::vector<drm_format_pair>>(allocator);
|
||||
auto supported_formats = allocator.make_unique<util::vector<util::drm::drm_format_pair>>(allocator);
|
||||
|
||||
if (supports_fb_modifiers)
|
||||
{
|
||||
|
|
@ -365,12 +366,12 @@ std::optional<drm_display> &drm_display::get_display()
|
|||
return display;
|
||||
}
|
||||
|
||||
const util::vector<drm_format_pair> *drm_display::get_supported_formats() const
|
||||
const util::vector<util::drm::drm_format_pair> *drm_display::get_supported_formats() const
|
||||
{
|
||||
return m_supported_formats.get();
|
||||
}
|
||||
|
||||
bool drm_display::is_format_supported(const drm_format_pair &format) const
|
||||
bool drm_display::is_format_supported(const util::drm::drm_format_pair &format) const
|
||||
{
|
||||
auto supported_format =
|
||||
std::find_if(m_supported_formats->begin(), m_supported_formats->end(), [format](const auto &supported_format) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Arm Limited.
|
||||
* Copyright (c) 2024-2025 Arm Limited.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
|
|
@ -256,7 +256,7 @@ public:
|
|||
*
|
||||
* @return Pointer to vector of supported formats.
|
||||
*/
|
||||
const util::vector<drm_format_pair> *get_supported_formats() const;
|
||||
const util::vector<util::drm::drm_format_pair> *get_supported_formats() const;
|
||||
|
||||
/**
|
||||
* @brief Query the display for support for adding framebuffers with format modifiers.
|
||||
|
|
@ -271,7 +271,7 @@ public:
|
|||
* @param format The format to query support for.
|
||||
* @return true if the format is supported by the display, otherwise false.
|
||||
*/
|
||||
bool is_format_supported(const drm_format_pair &format) const;
|
||||
bool is_format_supported(const util::drm::drm_format_pair &format) const;
|
||||
|
||||
/**
|
||||
* @brief Returns a CRTC compatible with this display's connector.
|
||||
|
|
@ -297,7 +297,7 @@ private:
|
|||
* @param allocator The allocator that the display will use.
|
||||
*/
|
||||
drm_display(util::fd_owner drm_fd, int crtc_id, drm_connector_owner drm_connector,
|
||||
util::unique_ptr<util::vector<drm_format_pair>> supported_formats,
|
||||
util::unique_ptr<util::vector<util::drm::drm_format_pair>> supported_formats,
|
||||
util::unique_ptr<drm_display_mode> display_modes, size_t num_display_modes, uint32_t max_width,
|
||||
uint32_t max_height, bool supports_fb_modifiers);
|
||||
|
||||
|
|
@ -319,7 +319,7 @@ private:
|
|||
/**
|
||||
* @brief Vector of supported formats for use with the display.
|
||||
*/
|
||||
util::unique_ptr<util::vector<drm_format_pair>> m_supported_formats;
|
||||
util::unique_ptr<util::vector<util::drm::drm_format_pair>> m_supported_formats;
|
||||
|
||||
/**
|
||||
* @brief Pointer to available display modes for the connected display.
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@
|
|||
#include "swapchain.hpp"
|
||||
#include "present_wait_display.hpp"
|
||||
|
||||
#include <wsi/swapchain_image_create_extensions/external_memory_extension.hpp>
|
||||
|
||||
namespace wsi
|
||||
{
|
||||
|
||||
|
|
@ -60,13 +62,6 @@ swapchain::~swapchain()
|
|||
{
|
||||
/* Call the base class teardown */
|
||||
teardown();
|
||||
|
||||
/* Free WSI allocator. */
|
||||
if (m_wsi_allocator != nullptr)
|
||||
{
|
||||
wsialloc_delete(m_wsi_allocator);
|
||||
}
|
||||
m_wsi_allocator = nullptr;
|
||||
}
|
||||
|
||||
static void page_flip_event(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
|
||||
|
|
@ -126,13 +121,19 @@ VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKH
|
|||
UNUSED(device);
|
||||
UNUSED(swapchain_create_info);
|
||||
UNUSED(use_presentation_thread);
|
||||
WSIALLOC_ASSERT_VERSION();
|
||||
if (wsialloc_new(&m_wsi_allocator) != WSIALLOC_ERROR_NONE)
|
||||
|
||||
auto wsi_allocator = swapchain_wsialloc_allocator::create();
|
||||
if (!wsi_allocator.has_value())
|
||||
{
|
||||
WSI_LOG_ERROR("Failed to create wsi allocator.");
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
m_wsi_allocator = m_allocator.make_unique<swapchain_wsialloc_allocator>(std::move(*wsi_allocator));
|
||||
if (m_wsi_allocator == nullptr)
|
||||
{
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -162,7 +163,7 @@ VkResult swapchain::get_surface_compatible_formats(const VkImageCreateInfo &info
|
|||
|
||||
for (const auto &prop : drm_format_props)
|
||||
{
|
||||
drm_format_pair drm_format{ util::drm::vk_to_drm_format(info.format), prop.drmFormatModifier };
|
||||
util::drm::drm_format_pair drm_format{ util::drm::vk_to_drm_format(info.format), prop.drmFormatModifier };
|
||||
|
||||
if (!display->is_format_supported(drm_format))
|
||||
{
|
||||
|
|
@ -267,13 +268,7 @@ VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, disp
|
|||
util::vector<wsialloc_format> &importable_formats,
|
||||
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;
|
||||
}
|
||||
|
||||
bool enable_fixed_rate = false;
|
||||
if (m_device_data.is_swapchain_compression_control_enabled())
|
||||
{
|
||||
auto *ext = get_swapchain_extension<wsi_ext_image_compression_control>();
|
||||
|
|
@ -285,36 +280,18 @@ VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, disp
|
|||
{
|
||||
if (ext->get_bitmask_for_image_compression_flags() & VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT)
|
||||
{
|
||||
allocation_flags |= WSIALLOC_ALLOCATE_HIGHEST_FIXED_RATE_COMPRESSION;
|
||||
enable_fixed_rate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wsialloc_allocate_info alloc_info = { importable_formats.data(), static_cast<unsigned>(importable_formats.size()),
|
||||
image_create_info.extent.width, image_create_info.extent.height,
|
||||
allocation_flags };
|
||||
wsialloc_allocate_result alloc_result = { .format = { .fourcc = 0, .modifier = 0, .flags = 0 },
|
||||
.average_row_strides = { 0 },
|
||||
.offsets = { 0 },
|
||||
.buffer_fds = { 0 },
|
||||
.is_disjoint = false };
|
||||
allocation_params params = { (image_create_info.flags & VK_IMAGE_CREATE_PROTECTED_BIT) != 0,
|
||||
image_create_info.extent, importable_formats, enable_fixed_rate, avoid_allocation };
|
||||
wsialloc_allocate_result alloc_result = { {}, { 0 }, { 0 }, { -1 }, false };
|
||||
TRY(m_wsi_allocator->allocate(params, &alloc_result));
|
||||
|
||||
/* 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;
|
||||
}
|
||||
const auto res = wsialloc_alloc(m_wsi_allocator, &alloc_info, &alloc_result);
|
||||
if (res != WSIALLOC_ERROR_NONE)
|
||||
{
|
||||
WSI_LOG_ERROR("Failed allocation of DMA Buffer. WSI error: %d", static_cast<int>(res));
|
||||
if (res == WSIALLOC_ERROR_NOT_SUPPORTED)
|
||||
{
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
}
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
*allocated_format = alloc_result.format;
|
||||
|
||||
auto &external_memory = image_data->external_mem;
|
||||
external_memory.set_strides(alloc_result.average_row_strides);
|
||||
external_memory.set_buffer_fds(alloc_result.buffer_fds);
|
||||
|
|
@ -345,26 +322,6 @@ VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, disp
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult fill_image_create_info(VkImageCreateInfo &image_create_info,
|
||||
util::vector<VkSubresourceLayout> &image_plane_layouts,
|
||||
VkImageDrmFormatModifierExplicitCreateInfoEXT &drm_mod_info,
|
||||
VkExternalMemoryImageCreateInfoKHR &external_info,
|
||||
display_image_data &image_data, uint64_t modifier)
|
||||
{
|
||||
TRY_LOG_CALL(image_data.external_mem.fill_image_plane_layouts(image_plane_layouts));
|
||||
|
||||
if (image_data.external_mem.is_disjoint())
|
||||
{
|
||||
image_create_info.flags |= VK_IMAGE_CREATE_DISJOINT_BIT;
|
||||
}
|
||||
|
||||
image_data.external_mem.fill_drm_mod_info(image_create_info.pNext, drm_mod_info, image_plane_layouts, modifier);
|
||||
image_data.external_mem.fill_external_info(external_info, &drm_mod_info);
|
||||
image_create_info.pNext = &external_info;
|
||||
image_create_info.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult swapchain::allocate_image(display_image_data *image_data)
|
||||
{
|
||||
util::vector<wsialloc_format> importable_formats(util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
||||
|
|
@ -383,8 +340,8 @@ VkResult swapchain::create_framebuffer(const VkImageCreateInfo &image_create_inf
|
|||
VkResult ret_code = VK_SUCCESS;
|
||||
std::array<uint32_t, util::MAX_PLANES> strides{ 0, 0, 0, 0 };
|
||||
std::array<uint64_t, util::MAX_PLANES> modifiers{ 0, 0, 0, 0 };
|
||||
const drm_format_pair allocated_format{ m_image_creation_parameters.m_allocated_format.fourcc,
|
||||
m_image_creation_parameters.m_allocated_format.modifier };
|
||||
const util::drm::drm_format_pair allocated_format{ m_image_creation_parameters.m_allocated_format.fourcc,
|
||||
m_image_creation_parameters.m_allocated_format.modifier };
|
||||
|
||||
auto &display = drm_display::get_display();
|
||||
if (!display.has_value())
|
||||
|
|
@ -474,7 +431,7 @@ VkResult swapchain::create_swapchain_image(VkImageCreateInfo image_create_info,
|
|||
}
|
||||
image.data = image_data;
|
||||
|
||||
if (m_image_create_info.format == VK_FORMAT_UNDEFINED)
|
||||
if (m_image_creation_parameters.m_allocated_format.fourcc == DRM_FORMAT_INVALID)
|
||||
{
|
||||
util::vector<wsialloc_format> importable_formats(
|
||||
util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
||||
|
|
@ -506,11 +463,6 @@ VkResult swapchain::create_swapchain_image(VkImageCreateInfo image_create_info,
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -683,6 +635,30 @@ void swapchain::destroy_image(swapchain_image &image)
|
|||
}
|
||||
}
|
||||
|
||||
VkResult swapchain::get_required_image_creator_extensions(
|
||||
const VkSwapchainCreateInfoKHR &swapchain_create_info,
|
||||
util::vector<util::unique_ptr<swapchain_image_create_info_extension>> *extensions)
|
||||
{
|
||||
auto compression_control = swapchain_image_create_compression_control::create(
|
||||
m_device_data.is_swapchain_compression_control_enabled(), swapchain_create_info);
|
||||
|
||||
auto &display = drm_display::get_display();
|
||||
if (!display.has_value())
|
||||
{
|
||||
WSI_LOG_ERROR("DRM display not available.");
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
if (!extensions->try_push_back(m_allocator.make_unique<swapchain_image_create_external_memory>(
|
||||
compression_control, m_wsi_allocator.get(), display->get_supported_formats(), m_device_data.physical_device,
|
||||
m_allocator)))
|
||||
{
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
} /* namespace display */
|
||||
|
||||
} /* namespace wsi*/
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
#include <util/wsialloc/wsialloc.h>
|
||||
#include <wsi/external_memory.hpp>
|
||||
|
||||
#include <wsi/wsi_alloc_utils.hpp>
|
||||
|
||||
namespace wsi
|
||||
{
|
||||
|
||||
|
|
@ -110,6 +112,17 @@ public:
|
|||
|
||||
void destroy_image(swapchain_image &image) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Get backend specific image create info extensions.
|
||||
*
|
||||
* @param swapchain_create_info Swapchain create info.
|
||||
* @param[out] extensions Backend specific swapchain image create info extensions.
|
||||
*/
|
||||
VkResult get_required_image_creator_extensions(
|
||||
const VkSwapchainCreateInfoKHR &swapchain_create_info,
|
||||
util::vector<util::unique_ptr<swapchain_image_create_info_extension>> *extensions) override;
|
||||
|
||||
private:
|
||||
VkResult allocate_image(display_image_data *image_data);
|
||||
|
||||
|
|
@ -133,7 +146,8 @@ private:
|
|||
*/
|
||||
VkResult add_required_extensions(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info) override;
|
||||
|
||||
wsialloc_allocator *m_wsi_allocator;
|
||||
util::unique_ptr<swapchain_wsialloc_allocator> m_wsi_allocator;
|
||||
|
||||
drm_display_mode *m_display_mode;
|
||||
image_creation_parameters m_image_creation_parameters;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -38,12 +38,13 @@
|
|||
|
||||
#include <wsi/extensions/present_id.hpp>
|
||||
#include <wsi/extensions/swapchain_maintenance.hpp>
|
||||
#include <wsi/extensions/image_compression_control.hpp>
|
||||
#include "util/macros.hpp"
|
||||
|
||||
#include "present_timing_handler.hpp"
|
||||
#include "present_wait_headless.hpp"
|
||||
|
||||
#include <wsi/swapchain_image_create_extensions/image_compression_control.hpp>
|
||||
|
||||
namespace wsi
|
||||
{
|
||||
namespace headless
|
||||
|
|
@ -69,14 +70,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<wsi_ext_image_compression_control>(*compression_control)))
|
||||
{
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
}
|
||||
UNUSED(device);
|
||||
UNUSED(swapchain_create_info);
|
||||
|
||||
if (m_device_data.is_present_id_enabled())
|
||||
{
|
||||
|
|
@ -210,24 +205,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<wsi_ext_image_compression_control>();
|
||||
/* 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)
|
||||
|
|
@ -294,5 +272,25 @@ VkResult swapchain::bind_swapchain_image(VkDevice &device, const VkBindImageMemo
|
|||
return device_data.disp.BindImageMemory(device, bind_image_mem_info->image, memory, 0);
|
||||
}
|
||||
|
||||
VkResult swapchain::get_required_image_creator_extensions(
|
||||
const VkSwapchainCreateInfoKHR &swapchain_create_info,
|
||||
util::vector<util::unique_ptr<swapchain_image_create_info_extension>> *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<swapchain_image_create_compression_control>(*compression_control)))
|
||||
{
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
} /* namespace headless */
|
||||
} /* namespace wsi */
|
||||
|
|
|
|||
|
|
@ -125,6 +125,16 @@ protected:
|
|||
VkResult bind_swapchain_image(VkDevice &device, const VkBindImageMemoryInfo *bind_image_mem_info,
|
||||
const VkBindImageMemorySwapchainInfoKHR *bind_sc_info) override;
|
||||
|
||||
/**
|
||||
* @brief Get backend specific image create info extensions.
|
||||
*
|
||||
* @param swapchain_create_info Swapchain create info.
|
||||
* @param[out] extensions Backend specific swapchain image create info extensions.
|
||||
*/
|
||||
VkResult get_required_image_creator_extensions(
|
||||
const VkSwapchainCreateInfoKHR &swapchain_create_info,
|
||||
util::vector<util::unique_ptr<swapchain_image_create_info_extension>> *extensions) override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Adds required extensions to the extension list of the swapchain
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021, 2024 Arm Limited.
|
||||
* Copyright (c) 2021-2025 Arm Limited.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
|
|
@ -36,15 +36,6 @@
|
|||
namespace wsi
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Struct describing a DRM format with modifier.
|
||||
*/
|
||||
struct drm_format_pair
|
||||
{
|
||||
uint32_t fourcc;
|
||||
uint64_t modifier;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A generic WSI representation of a VkSurface.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -225,6 +225,7 @@ swapchain_base::swapchain_base(layer::device_private_data &dev_data, const VkAll
|
|||
, m_error_state(VK_NOT_READY)
|
||||
, m_started_presenting(false)
|
||||
, m_extensions(m_allocator)
|
||||
, m_image_creator(m_allocator)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -269,23 +270,8 @@ VkResult swapchain_base::init(VkDevice device, const VkSwapchainCreateInfoKHR *s
|
|||
TRY_LOG_CALL(init_page_flip_thread());
|
||||
}
|
||||
|
||||
VkImageCreateInfo image_create_info = {};
|
||||
image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
image_create_info.pNext = nullptr;
|
||||
image_create_info.imageType = VK_IMAGE_TYPE_2D;
|
||||
image_create_info.format = swapchain_create_info->imageFormat;
|
||||
image_create_info.extent = { swapchain_create_info->imageExtent.width, swapchain_create_info->imageExtent.height,
|
||||
1 };
|
||||
image_create_info.mipLevels = 1;
|
||||
image_create_info.arrayLayers = swapchain_create_info->imageArrayLayers;
|
||||
image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
image_create_info.usage = swapchain_create_info->imageUsage;
|
||||
image_create_info.flags = 0;
|
||||
image_create_info.sharingMode = swapchain_create_info->imageSharingMode;
|
||||
image_create_info.queueFamilyIndexCount = swapchain_create_info->queueFamilyIndexCount;
|
||||
image_create_info.pQueueFamilyIndices = swapchain_create_info->pQueueFamilyIndices;
|
||||
image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
TRY_LOG_CALL(image_creator_init(*swapchain_create_info));
|
||||
m_image_create_info = m_image_creator.get_image_create_info();
|
||||
|
||||
VkResult result = m_free_image_semaphore.init(m_swapchain_images.size());
|
||||
if (result != VK_SUCCESS)
|
||||
|
|
@ -298,7 +284,7 @@ VkResult swapchain_base::init(VkDevice device, const VkSwapchainCreateInfoKHR *s
|
|||
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));
|
||||
TRY(create_swapchain_image(m_image_create_info, img));
|
||||
|
||||
if (image_deferred_allocation)
|
||||
{
|
||||
|
|
@ -306,7 +292,7 @@ VkResult swapchain_base::init(VkDevice device, const VkSwapchainCreateInfoKHR *s
|
|||
}
|
||||
else
|
||||
{
|
||||
TRY_LOG_CALL(allocate_and_bind_swapchain_image(image_create_info, img));
|
||||
TRY_LOG_CALL(allocate_and_bind_swapchain_image(m_image_create_info, img));
|
||||
}
|
||||
|
||||
VkSemaphoreCreateInfo semaphore_info = {};
|
||||
|
|
@ -778,4 +764,15 @@ bool swapchain_base::add_swapchain_extension(util::unique_ptr<wsi_ext> extension
|
|||
return m_extensions.add_extension(std::move(extension));
|
||||
}
|
||||
|
||||
VkResult swapchain_base::image_creator_init(const VkSwapchainCreateInfoKHR &swapchain_create_info)
|
||||
{
|
||||
m_image_creator.init(swapchain_create_info);
|
||||
|
||||
util::vector<util::unique_ptr<swapchain_image_create_info_extension>> extensions(m_allocator);
|
||||
TRY_LOG_CALL(get_required_image_creator_extensions(swapchain_create_info, &extensions));
|
||||
TRY_LOG_CALL(m_image_creator.add_extensions(extensions));
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
} /* namespace wsi */
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
|
||||
#include "extensions/frame_boundary.hpp"
|
||||
#include "extensions/wsi_extension.hpp"
|
||||
#include "swapchain_image_creator.hpp"
|
||||
#include "util/macros.hpp"
|
||||
|
||||
namespace wsi
|
||||
|
|
@ -479,12 +480,22 @@ protected:
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get backend specific image create info extensions.
|
||||
*
|
||||
* @param swapchain_create_info Swapchain create info.
|
||||
* @param[in,out] extensions Swapchain image create info extensions filled by the backend.
|
||||
*/
|
||||
virtual VkResult get_required_image_creator_extensions(
|
||||
const VkSwapchainCreateInfoKHR &swapchain_create_info,
|
||||
util::vector<util::unique_ptr<swapchain_image_create_info_extension>> *extensions) = 0;
|
||||
|
||||
/**
|
||||
* @brief Base swapchain teardown.
|
||||
*
|
||||
* Even though the inheritance gives us a nice way to defer display specific allocation
|
||||
* and presentation outside of the base class, it however robs the children classes - which
|
||||
* also happen to do some of their state setting - the oppurtunity to do the last clean up
|
||||
* also happen to do some of their state setting - the opportunity to do the last clean up
|
||||
* call, as the base class' destructor is called at the end. This method provides a way to do it.
|
||||
* The destructor is a virtual function and much of the swapchain teardown happens in this method
|
||||
* which gets called from the child's destructor.
|
||||
|
|
@ -709,6 +720,18 @@ private:
|
|||
* @brief Holds the swapchain extensions and related functionalities.
|
||||
*/
|
||||
wsi_ext_maintainer m_extensions;
|
||||
|
||||
/**
|
||||
* @brief Holds the VkImageCreateInfo and backend specific image create info extensions.
|
||||
*/
|
||||
swapchain_image_creator m_image_creator;
|
||||
|
||||
/**
|
||||
* @brief Initialize m_image_creator.
|
||||
*
|
||||
* @param swapchain_create_info Swapchain create info.
|
||||
*/
|
||||
VkResult image_creator_init(const VkSwapchainCreateInfoKHR &swapchain_create_info);
|
||||
};
|
||||
|
||||
} /* namespace wsi */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
* 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 external_memory_extension.cpp
|
||||
*/
|
||||
#include <cassert>
|
||||
|
||||
#include <util/helpers.hpp>
|
||||
#include <util/format_modifiers.hpp>
|
||||
|
||||
#include <layer/private_data.hpp>
|
||||
|
||||
#include "external_memory_extension.hpp"
|
||||
|
||||
namespace wsi
|
||||
{
|
||||
|
||||
VkResult swapchain_image_create_external_memory::extend_image_create_info(VkImageCreateInfo *image_create_info)
|
||||
{
|
||||
assert(image_create_info != nullptr);
|
||||
|
||||
util::vector<wsialloc_format> importable_formats(util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
||||
util::vector<uint64_t> exportable_modifiers(util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
||||
|
||||
/* Query supported modifers. */
|
||||
util::vector<VkDrmFormatModifierPropertiesEXT> drm_format_props(
|
||||
util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
||||
|
||||
TRY_LOG_CALL(
|
||||
get_surface_compatible_formats(*image_create_info, importable_formats, exportable_modifiers, drm_format_props));
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
bool enable_fixed_rate = false;
|
||||
if (m_compression)
|
||||
{
|
||||
if (m_compression->get_bitmask_for_image_compression_flags() & VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT)
|
||||
{
|
||||
enable_fixed_rate = true;
|
||||
}
|
||||
}
|
||||
|
||||
allocation_params params = { (image_create_info->flags & VK_IMAGE_CREATE_PROTECTED_BIT) != 0,
|
||||
image_create_info->extent, importable_formats, enable_fixed_rate, true };
|
||||
wsialloc_allocate_result alloc_result = { {}, { 0 }, { 0 }, { -1 }, false };
|
||||
assert(m_wsi_allocator);
|
||||
TRY(m_wsi_allocator->allocate(params, &alloc_result));
|
||||
|
||||
uint32_t prop_plane_count = 0;
|
||||
for (auto &prop : drm_format_props)
|
||||
{
|
||||
if (prop.drmFormatModifier == alloc_result.format.modifier)
|
||||
{
|
||||
prop_plane_count = prop.drmFormatModifierPlaneCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (alloc_result.is_disjoint)
|
||||
{
|
||||
image_create_info->flags |= VK_IMAGE_CREATE_DISJOINT_BIT;
|
||||
}
|
||||
|
||||
const uint32_t format_planes = util::drm::drm_fourcc_format_get_num_planes(alloc_result.format.fourcc);
|
||||
if (!m_plane_layouts.try_resize(format_planes))
|
||||
{
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
for (uint32_t plane = 0; plane < format_planes; ++plane)
|
||||
{
|
||||
assert(alloc_result.average_row_strides[plane] >= 0);
|
||||
m_plane_layouts[plane].offset = alloc_result.offsets[plane];
|
||||
m_plane_layouts[plane].rowPitch = static_cast<uint32_t>(alloc_result.average_row_strides[plane]);
|
||||
}
|
||||
|
||||
m_drm_mod_info.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT;
|
||||
m_drm_mod_info.pNext = image_create_info->pNext;
|
||||
m_drm_mod_info.drmFormatModifier = alloc_result.format.modifier;
|
||||
m_drm_mod_info.drmFormatModifierPlaneCount = prop_plane_count;
|
||||
m_drm_mod_info.pPlaneLayouts = m_plane_layouts.data();
|
||||
|
||||
m_external_info.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR;
|
||||
m_external_info.pNext = &m_drm_mod_info;
|
||||
m_external_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
|
||||
|
||||
image_create_info->pNext = &m_external_info;
|
||||
image_create_info->tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult swapchain_image_create_external_memory::get_surface_compatible_formats(
|
||||
const VkImageCreateInfo &info, util::vector<wsialloc_format> &importable_formats,
|
||||
util::vector<uint64_t> &exportable_modifers, util::vector<VkDrmFormatModifierPropertiesEXT> &drm_format_props)
|
||||
{
|
||||
TRY_LOG(util::get_drm_format_properties(m_physical_device, info.format, drm_format_props),
|
||||
"Failed to get format properties");
|
||||
|
||||
for (const auto &prop : drm_format_props)
|
||||
{
|
||||
bool is_supported = true;
|
||||
util::drm::drm_format_pair drm_format{ util::drm::vk_to_drm_format(info.format), prop.drmFormatModifier };
|
||||
|
||||
if (m_surface_formats != nullptr)
|
||||
{
|
||||
is_supported = false;
|
||||
for (const auto &format : *m_surface_formats)
|
||||
{
|
||||
if (format.fourcc == drm_format.fourcc && format.modifier == drm_format.modifier)
|
||||
{
|
||||
is_supported = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_supported)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
VkExternalImageFormatPropertiesKHR external_props = {};
|
||||
external_props.sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR;
|
||||
|
||||
VkImageFormatProperties2KHR format_props = {};
|
||||
format_props.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR;
|
||||
format_props.pNext = &external_props;
|
||||
|
||||
VkResult result = VK_SUCCESS;
|
||||
{
|
||||
VkPhysicalDeviceExternalImageFormatInfoKHR external_info = {};
|
||||
external_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR;
|
||||
external_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
|
||||
|
||||
VkPhysicalDeviceImageDrmFormatModifierInfoEXT drm_mod_info = {};
|
||||
drm_mod_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT;
|
||||
drm_mod_info.pNext = &external_info;
|
||||
drm_mod_info.drmFormatModifier = prop.drmFormatModifier;
|
||||
drm_mod_info.sharingMode = info.sharingMode;
|
||||
drm_mod_info.queueFamilyIndexCount = info.queueFamilyIndexCount;
|
||||
drm_mod_info.pQueueFamilyIndices = info.pQueueFamilyIndices;
|
||||
|
||||
VkPhysicalDeviceImageFormatInfo2KHR image_info = {};
|
||||
image_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR;
|
||||
image_info.pNext = &drm_mod_info;
|
||||
image_info.format = info.format;
|
||||
image_info.type = info.imageType;
|
||||
image_info.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
|
||||
image_info.usage = info.usage;
|
||||
image_info.flags = info.flags;
|
||||
|
||||
VkImageCompressionControlEXT compression_control = {};
|
||||
if (m_compression)
|
||||
{
|
||||
compression_control = m_compression->get_compression_control_properties();
|
||||
compression_control.pNext = image_info.pNext;
|
||||
image_info.pNext = &compression_control;
|
||||
}
|
||||
|
||||
auto &instance_data = layer::instance_private_data::get(m_physical_device);
|
||||
result = instance_data.disp.GetPhysicalDeviceImageFormatProperties2KHR(m_physical_device, &image_info,
|
||||
&format_props);
|
||||
}
|
||||
if (result != VK_SUCCESS)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (format_props.imageFormatProperties.maxExtent.width < info.extent.width ||
|
||||
format_props.imageFormatProperties.maxExtent.height < info.extent.height ||
|
||||
format_props.imageFormatProperties.maxExtent.depth < info.extent.depth)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (format_props.imageFormatProperties.maxMipLevels < info.mipLevels ||
|
||||
format_props.imageFormatProperties.maxArrayLayers < info.arrayLayers)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((format_props.imageFormatProperties.sampleCounts & info.samples) != info.samples)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (external_props.externalMemoryProperties.externalMemoryFeatures &
|
||||
VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR)
|
||||
{
|
||||
if (!exportable_modifers.try_push_back(drm_format.modifier))
|
||||
{
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if (external_props.externalMemoryProperties.externalMemoryFeatures &
|
||||
VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR)
|
||||
{
|
||||
uint64_t flags =
|
||||
(prop.drmFormatModifierTilingFeatures & VK_FORMAT_FEATURE_DISJOINT_BIT) ? 0 : WSIALLOC_FORMAT_NON_DISJOINT;
|
||||
wsialloc_format import_format{ drm_format.fourcc, drm_format.modifier, flags };
|
||||
if (!importable_formats.try_push_back(import_format))
|
||||
{
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* 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 external_memory_extension.hpp
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
#include <util/custom_allocator.hpp>
|
||||
#include <util/macros.hpp>
|
||||
#include "util/drm/drm_utils.hpp"
|
||||
|
||||
#include <wsi/wsi_alloc_utils.hpp>
|
||||
|
||||
#include "swapchain_image_create_info_extension.hpp"
|
||||
#include "image_compression_control.hpp"
|
||||
|
||||
namespace wsi
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*/
|
||||
class swapchain_image_create_external_memory : public swapchain_image_create_info_extension
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a swapchain_image_create_external_memory object.
|
||||
*
|
||||
* @param[in] compression Optional compression control parameters for the swapchain image.
|
||||
* @param[in] wsi_allocator wsialloc allocator pointer.
|
||||
* @param[in] surface_formats Supported surface formats from the presentation engine.
|
||||
* @param[in] physical_device Vulkan physical device handle.
|
||||
* @param[in] allocator User provided allocation callbacks.
|
||||
*/
|
||||
swapchain_image_create_external_memory(std::optional<swapchain_image_create_compression_control> compression,
|
||||
swapchain_wsialloc_allocator *wsi_allocator,
|
||||
const util::vector<util::drm::drm_format_pair> *surface_formats,
|
||||
VkPhysicalDevice physical_device, const util::allocator &allocator)
|
||||
: m_compression(compression)
|
||||
, m_wsi_allocator(wsi_allocator)
|
||||
, m_surface_formats(surface_formats)
|
||||
, m_physical_device(physical_device)
|
||||
, m_allocator(allocator)
|
||||
, m_plane_layouts(allocator)
|
||||
, m_drm_mod_info()
|
||||
, m_external_info()
|
||||
, m_allocated_format()
|
||||
{
|
||||
}
|
||||
|
||||
VkResult extend_image_create_info(VkImageCreateInfo *image_create_info) override;
|
||||
|
||||
/**
|
||||
* @brief Finds what formats are compatible with the requested swapchain image Vulkan Device and backend surface.
|
||||
*
|
||||
* @param info The Swapchain image creation info.
|
||||
* @param[out] importable_formats A list of formats that can be imported to the Vulkan Device.
|
||||
* @param[out] exportable_formats A list of formats that can be exported from the Vulkan Device.
|
||||
* @param[out] drm_format_props A list of all device supported VkDrmFormatModifierPropertiesEXT.
|
||||
*
|
||||
* @return VK_SUCCESS or VK_ERROR_OUT_OF_HOST_MEMORY
|
||||
*/
|
||||
VkResult get_surface_compatible_formats(const VkImageCreateInfo &info,
|
||||
util::vector<wsialloc_format> &importable_formats,
|
||||
util::vector<uint64_t> &exportable_modifers,
|
||||
util::vector<VkDrmFormatModifierPropertiesEXT> &drm_format_props);
|
||||
|
||||
private:
|
||||
std::optional<swapchain_image_create_compression_control> m_compression;
|
||||
swapchain_wsialloc_allocator *m_wsi_allocator;
|
||||
const util::vector<util::drm::drm_format_pair> *m_surface_formats;
|
||||
VkPhysicalDevice m_physical_device;
|
||||
const util::allocator &m_allocator;
|
||||
|
||||
util::vector<VkSubresourceLayout> m_plane_layouts;
|
||||
VkImageDrmFormatModifierExplicitCreateInfoEXT m_drm_mod_info;
|
||||
VkExternalMemoryImageCreateInfoKHR m_external_info;
|
||||
wsialloc_allocate_result m_allocated_format;
|
||||
};
|
||||
|
||||
} /* namespace wsi */
|
||||
|
|
@ -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 <cassert>
|
||||
|
||||
#include <util/helpers.hpp>
|
||||
|
||||
#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> swapchain_image_create_compression_control::create(
|
||||
bool compression_enabled, const VkSwapchainCreateInfoKHR &swapchain_create_info)
|
||||
{
|
||||
const auto *image_compression_control = util::find_extension<VkImageCompressionControlEXT>(
|
||||
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;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -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 <optional>
|
||||
#include <utility>
|
||||
|
||||
#include <util/custom_allocator.hpp>
|
||||
#include <util/macros.hpp>
|
||||
|
||||
#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<swapchain_image_create_compression_control> 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 */
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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 swapchain_image_create_info_extension.hpp
|
||||
*
|
||||
* @brief Base class for swapchain image create info extensions.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
namespace wsi
|
||||
{
|
||||
|
||||
class swapchain_image_create_info_extension
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Extend image_create_info pNext with extension specific data.
|
||||
*
|
||||
* A swapchain image create info extension will use this function to add its
|
||||
* extension specific data to pNext of image_create_info.
|
||||
*
|
||||
* @param[in, out] image_create_info VkImageCreateInfo for creating swapchain images
|
||||
*/
|
||||
virtual VkResult extend_image_create_info(VkImageCreateInfo *image_create_info) = 0;
|
||||
|
||||
virtual ~swapchain_image_create_info_extension() = default;
|
||||
};
|
||||
|
||||
} /* namespace wsi */
|
||||
72
wsi/swapchain_image_creator.cpp
Normal file
72
wsi/swapchain_image_creator.cpp
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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 swapchain_image_creator.cpp
|
||||
*/
|
||||
|
||||
#include "swapchain_image_creator.hpp"
|
||||
#include "swapchain_image_create_extensions/swapchain_image_create_info_extension.hpp"
|
||||
#include "util/helpers.hpp"
|
||||
|
||||
namespace wsi
|
||||
{
|
||||
|
||||
void swapchain_image_creator::init(const VkSwapchainCreateInfoKHR &swapchain_create_info)
|
||||
{
|
||||
m_image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
m_image_create_info.pNext = nullptr;
|
||||
m_image_create_info.imageType = VK_IMAGE_TYPE_2D;
|
||||
m_image_create_info.format = swapchain_create_info.imageFormat;
|
||||
m_image_create_info.extent = { swapchain_create_info.imageExtent.width, swapchain_create_info.imageExtent.height,
|
||||
1 };
|
||||
m_image_create_info.mipLevels = 1;
|
||||
m_image_create_info.arrayLayers = swapchain_create_info.imageArrayLayers;
|
||||
m_image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
m_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
m_image_create_info.usage = swapchain_create_info.imageUsage;
|
||||
m_image_create_info.flags = 0;
|
||||
m_image_create_info.sharingMode = swapchain_create_info.imageSharingMode;
|
||||
m_image_create_info.queueFamilyIndexCount = swapchain_create_info.queueFamilyIndexCount;
|
||||
m_image_create_info.pQueueFamilyIndices = swapchain_create_info.pQueueFamilyIndices;
|
||||
m_image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
}
|
||||
|
||||
VkResult swapchain_image_creator::add_extensions(
|
||||
util::vector<util::unique_ptr<swapchain_image_create_info_extension>> &extensions)
|
||||
{
|
||||
for (auto &extension : extensions)
|
||||
{
|
||||
TRY(extension->extend_image_create_info(&m_image_create_info));
|
||||
|
||||
if (!m_extensions.try_push_back(std::move(extension)))
|
||||
{
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
} /* namespace wsi */
|
||||
87
wsi/swapchain_image_creator.hpp
Normal file
87
wsi/swapchain_image_creator.hpp
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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 swapchain_image_creator.hpp
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <util/custom_allocator.hpp>
|
||||
#include <wsi/swapchain_image_create_extensions/swapchain_image_create_info_extension.hpp>
|
||||
|
||||
namespace wsi
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief This class is responsible for owning and extending a swapchain's image
|
||||
* creation info.
|
||||
*/
|
||||
class swapchain_image_creator
|
||||
{
|
||||
public:
|
||||
swapchain_image_creator(const util::allocator &allocator)
|
||||
: m_image_create_info()
|
||||
, m_extensions(allocator)
|
||||
{
|
||||
m_image_create_info.format = VK_FORMAT_UNDEFINED;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create image create info.
|
||||
*
|
||||
* @param swapchain_create_info Swapchain create info.
|
||||
*/
|
||||
void init(const VkSwapchainCreateInfoKHR &swapchain_create_info);
|
||||
|
||||
/**
|
||||
* @brief Extend create info with extension data.
|
||||
*
|
||||
* @param extensions Swapchain image create info extensions.
|
||||
*
|
||||
* @return VK_SUCCESS on success, an appropriate error code on failure.
|
||||
*
|
||||
* @note The extensions will be moved out of the vector and will become nullptr.
|
||||
*/
|
||||
VkResult add_extensions(util::vector<util::unique_ptr<swapchain_image_create_info_extension>> &extensions);
|
||||
|
||||
VkImageCreateInfo get_image_create_info() const
|
||||
{
|
||||
return m_image_create_info;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Image create info used for all swapchain images.
|
||||
*/
|
||||
VkImageCreateInfo m_image_create_info;
|
||||
|
||||
/**
|
||||
* @brief Swapchain image extensions needed for extending image create info.
|
||||
*/
|
||||
util::vector<util::unique_ptr<swapchain_image_create_info_extension>> m_extensions;
|
||||
};
|
||||
|
||||
} /* namespace wsi */
|
||||
|
|
@ -40,7 +40,7 @@ namespace wayland
|
|||
|
||||
struct formats_vector
|
||||
{
|
||||
util::vector<drm_format_pair> *formats{ nullptr };
|
||||
util::vector<util::drm::drm_format_pair> *formats{ nullptr };
|
||||
bool is_out_of_memory{ false };
|
||||
};
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ zwp_linux_dmabuf_v1_modifier_impl(void *data, struct zwp_linux_dmabuf_v1 *dma_bu
|
|||
UNUSED(dma_buf);
|
||||
auto *drm_supported_formats = reinterpret_cast<formats_vector *>(data);
|
||||
|
||||
drm_format_pair format = {};
|
||||
util::drm::drm_format_pair format = {};
|
||||
format.fourcc = drm_format;
|
||||
format.modifier = (static_cast<uint64_t>(modifier_hi) << 32) | modifier_low;
|
||||
|
||||
|
|
@ -101,7 +101,7 @@ wp_presentation_clock_id_impl(void *data, struct wp_presentation *wp_presentatio
|
|||
*/
|
||||
static VkResult get_supported_formats_and_modifiers(wl_display *display, wl_event_queue *queue,
|
||||
zwp_linux_dmabuf_v1 *dmabuf_interface,
|
||||
util::vector<drm_format_pair> &supported_formats)
|
||||
util::vector<util::drm::drm_format_pair> &supported_formats)
|
||||
{
|
||||
formats_vector drm_supported_formats;
|
||||
drm_supported_formats.formats = &supported_formats;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021, 2024-2025 Arm Limited.
|
||||
* Copyright (c) 2021-2025 Arm Limited.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
|
|
@ -39,6 +39,8 @@
|
|||
#include "wl_object_owner.hpp"
|
||||
#include "util/macros.hpp"
|
||||
|
||||
#include <util/drm/drm_utils.hpp>
|
||||
|
||||
namespace wsi
|
||||
{
|
||||
namespace wayland
|
||||
|
|
@ -128,7 +130,7 @@ public:
|
|||
*
|
||||
* The reference is valid throughout the lifetime of this surface.
|
||||
*/
|
||||
const util::vector<drm_format_pair> &get_formats() const
|
||||
const util::vector<util::drm::drm_format_pair> &get_formats() const
|
||||
{
|
||||
return supported_formats;
|
||||
}
|
||||
|
|
@ -182,7 +184,7 @@ private:
|
|||
/** The native Wayland surface */
|
||||
wl_surface *wayland_surface;
|
||||
/** A list of DRM formats supported by the Wayland compositor on this surface */
|
||||
util::vector<drm_format_pair> supported_formats;
|
||||
util::vector<util::drm::drm_format_pair> supported_formats;
|
||||
/** Surface properties specific to the Wayland surface. */
|
||||
surface_properties properties;
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ VkResult surface_properties::get_surface_capabilities(VkPhysicalDevice physical_
|
|||
|
||||
static VkResult surface_format_properties_add_modifier_support(VkPhysicalDevice phys_dev,
|
||||
surface_format_properties &format_props,
|
||||
const drm_format_pair &drm_format,
|
||||
const util::drm::drm_format_pair &drm_format,
|
||||
bool add_compression = false)
|
||||
{
|
||||
VkPhysicalDeviceExternalImageFormatInfoKHR external_info = {};
|
||||
|
|
@ -148,7 +148,7 @@ static VkResult surface_format_properties_add_modifier_support(VkPhysicalDevice
|
|||
}
|
||||
|
||||
static VkResult surface_format_properties_map_add(VkPhysicalDevice phys_dev, surface_format_properties_map &format_map,
|
||||
VkFormat format, const drm_format_pair &drm_format)
|
||||
VkFormat format, const util::drm::drm_format_pair &drm_format)
|
||||
{
|
||||
surface_format_properties format_props{ format };
|
||||
VkResult res = surface_format_properties_add_modifier_support(phys_dev, format_props, drm_format);
|
||||
|
|
@ -170,7 +170,7 @@ static VkResult surface_format_properties_map_add(VkPhysicalDevice phys_dev, sur
|
|||
}
|
||||
|
||||
static VkResult surface_format_properties_map_init(VkPhysicalDevice phys_dev, surface_format_properties_map &format_map,
|
||||
const util::vector<drm_format_pair> &drm_format_list)
|
||||
const util::vector<util::drm::drm_format_pair> &drm_format_list)
|
||||
{
|
||||
for (const auto &drm_format : drm_format_list)
|
||||
{
|
||||
|
|
@ -189,9 +189,9 @@ static VkResult surface_format_properties_map_init(VkPhysicalDevice phys_dev, su
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult surface_format_properties_map_add_compression(VkPhysicalDevice phys_dev,
|
||||
surface_format_properties_map &format_map,
|
||||
const util::vector<drm_format_pair> &drm_format_list)
|
||||
static VkResult surface_format_properties_map_add_compression(
|
||||
VkPhysicalDevice phys_dev, surface_format_properties_map &format_map,
|
||||
const util::vector<util::drm::drm_format_pair> &drm_format_list)
|
||||
{
|
||||
for (const auto &drm_format : drm_format_list)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@
|
|||
#include <wsi/extensions/swapchain_maintenance.hpp>
|
||||
#include <wsi/extensions/present_id.hpp>
|
||||
|
||||
#include <wsi/swapchain_image_create_extensions/external_memory_extension.hpp>
|
||||
|
||||
#include "present_timing_handler.hpp"
|
||||
#include "present_id_wayland.hpp"
|
||||
#include "present_wait_wayland.hpp"
|
||||
|
|
@ -67,18 +69,12 @@ swapchain::swapchain(layer::device_private_data &dev_data, const VkAllocationCal
|
|||
, m_wsi_allocator(nullptr)
|
||||
, m_image_creation_parameters({}, m_allocator, {}, {})
|
||||
{
|
||||
m_image_create_info.format = VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
swapchain::~swapchain()
|
||||
{
|
||||
teardown();
|
||||
|
||||
if (m_wsi_allocator != nullptr)
|
||||
{
|
||||
wsialloc_delete(m_wsi_allocator);
|
||||
}
|
||||
m_wsi_allocator = nullptr;
|
||||
if (m_buffer_queue != nullptr)
|
||||
{
|
||||
wl_event_queue_destroy(m_buffer_queue);
|
||||
|
|
@ -179,13 +175,18 @@ VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKH
|
|||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
WSIALLOC_ASSERT_VERSION();
|
||||
if (wsialloc_new(&m_wsi_allocator) != WSIALLOC_ERROR_NONE)
|
||||
auto wsi_allocator = swapchain_wsialloc_allocator::create();
|
||||
if (!wsi_allocator.has_value())
|
||||
{
|
||||
WSI_LOG_ERROR("Failed to create wsi allocator.");
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
m_wsi_allocator = m_allocator.make_unique<swapchain_wsialloc_allocator>(std::move(*wsi_allocator));
|
||||
if (m_wsi_allocator == nullptr)
|
||||
{
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
/*
|
||||
* When VK_PRESENT_MODE_MAILBOX_KHR has been chosen by the application we don't
|
||||
* initialize the page flip thread so the present_image function can be called
|
||||
|
|
@ -241,7 +242,7 @@ VkResult swapchain::get_surface_compatible_formats(const VkImageCreateInfo &info
|
|||
for (const auto &prop : drm_format_props)
|
||||
{
|
||||
bool is_supported = false;
|
||||
drm_format_pair drm_format{ util::drm::vk_to_drm_format(info.format), prop.drmFormatModifier };
|
||||
util::drm::drm_format_pair drm_format{ util::drm::vk_to_drm_format(info.format), prop.drmFormatModifier };
|
||||
|
||||
for (const auto &format : m_wsi_surface->get_formats())
|
||||
{
|
||||
|
|
@ -351,13 +352,7 @@ VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, wayl
|
|||
util::vector<wsialloc_format> &importable_formats,
|
||||
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;
|
||||
}
|
||||
|
||||
bool enable_fixed_rate = false;
|
||||
if (m_device_data.is_swapchain_compression_control_enabled())
|
||||
{
|
||||
auto *ext = get_swapchain_extension<wsi_ext_image_compression_control>();
|
||||
|
|
@ -369,33 +364,18 @@ VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, wayl
|
|||
{
|
||||
if (ext->get_bitmask_for_image_compression_flags() & VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT)
|
||||
{
|
||||
allocation_flags |= WSIALLOC_ALLOCATE_HIGHEST_FIXED_RATE_COMPRESSION;
|
||||
enable_fixed_rate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wsialloc_allocate_info alloc_info = { importable_formats.data(), static_cast<unsigned>(importable_formats.size()),
|
||||
image_create_info.extent.width, image_create_info.extent.height,
|
||||
allocation_flags };
|
||||
|
||||
allocation_params params = { (image_create_info.flags & VK_IMAGE_CREATE_PROTECTED_BIT) != 0,
|
||||
image_create_info.extent, importable_formats, enable_fixed_rate, avoid_allocation };
|
||||
wsialloc_allocate_result alloc_result = { {}, { 0 }, { 0 }, { -1 }, false };
|
||||
/* 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)
|
||||
{
|
||||
WSI_LOG_ERROR("Failed allocation of DMA Buffer. WSI error: %d", static_cast<int>(res));
|
||||
if (res == WSIALLOC_ERROR_NOT_SUPPORTED)
|
||||
{
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
}
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
TRY(m_wsi_allocator->allocate(params, &alloc_result));
|
||||
|
||||
*allocated_format = alloc_result.format;
|
||||
|
||||
auto &external_memory = image_data->external_mem;
|
||||
external_memory.set_strides(alloc_result.average_row_strides);
|
||||
external_memory.set_buffer_fds(alloc_result.buffer_fds);
|
||||
|
|
@ -426,26 +406,6 @@ VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, wayl
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult fill_image_create_info(VkImageCreateInfo &image_create_info,
|
||||
util::vector<VkSubresourceLayout> &image_plane_layouts,
|
||||
VkImageDrmFormatModifierExplicitCreateInfoEXT &drm_mod_info,
|
||||
VkExternalMemoryImageCreateInfoKHR &external_info,
|
||||
wayland_image_data &image_data, uint64_t modifier)
|
||||
{
|
||||
TRY_LOG_CALL(image_data.external_mem.fill_image_plane_layouts(image_plane_layouts));
|
||||
|
||||
if (image_data.external_mem.is_disjoint())
|
||||
{
|
||||
image_create_info.flags |= VK_IMAGE_CREATE_DISJOINT_BIT;
|
||||
}
|
||||
|
||||
image_data.external_mem.fill_drm_mod_info(image_create_info.pNext, drm_mod_info, image_plane_layouts, modifier);
|
||||
image_data.external_mem.fill_external_info(external_info, &drm_mod_info);
|
||||
image_create_info.pNext = &external_info;
|
||||
image_create_info.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult swapchain::allocate_image(wayland_image_data *image_data)
|
||||
{
|
||||
util::vector<wsialloc_format> importable_formats(util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
||||
|
|
@ -526,13 +486,13 @@ VkResult swapchain::create_swapchain_image(VkImageCreateInfo image_create_info,
|
|||
}
|
||||
image.data = image_data;
|
||||
|
||||
if (m_image_create_info.format == VK_FORMAT_UNDEFINED)
|
||||
if (m_image_creation_parameters.m_allocated_format.fourcc == DRM_FORMAT_INVALID)
|
||||
{
|
||||
util::vector<wsialloc_format> importable_formats(
|
||||
util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
||||
util::vector<uint64_t> exportable_modifiers(util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
||||
|
||||
/* Query supported modifers. */
|
||||
/* Query supported modifiers. */
|
||||
util::vector<VkDrmFormatModifierPropertiesEXT> drm_format_props(
|
||||
util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
||||
|
||||
|
|
@ -557,11 +517,6 @@ VkResult swapchain::create_swapchain_image(VkImageCreateInfo image_create_info,
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -758,5 +713,22 @@ VkResult swapchain::bind_swapchain_image(VkDevice &device, const VkBindImageMemo
|
|||
return image_data->external_mem.bind_swapchain_image_memory(bind_image_mem_info->image);
|
||||
}
|
||||
|
||||
VkResult swapchain::get_required_image_creator_extensions(
|
||||
const VkSwapchainCreateInfoKHR &swapchain_create_info,
|
||||
util::vector<util::unique_ptr<swapchain_image_create_info_extension>> *extensions)
|
||||
{
|
||||
auto compression_control = swapchain_image_create_compression_control::create(
|
||||
m_device_data.is_swapchain_compression_control_enabled(), swapchain_create_info);
|
||||
|
||||
if (!extensions->try_push_back(m_allocator.make_unique<swapchain_image_create_external_memory>(
|
||||
compression_control, m_wsi_allocator.get(), &m_wsi_surface->get_formats(), m_device_data.physical_device,
|
||||
m_allocator)))
|
||||
{
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace wayland
|
||||
} // namespace wsi
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ extern "C" {
|
|||
#include "util/custom_allocator.hpp"
|
||||
#include "wl_object_owner.hpp"
|
||||
|
||||
#include <wsi/wsi_alloc_utils.hpp>
|
||||
|
||||
#include <wsi/external_memory.hpp>
|
||||
|
||||
namespace wsi
|
||||
|
|
@ -181,6 +183,16 @@ protected:
|
|||
VkResult bind_swapchain_image(VkDevice &device, const VkBindImageMemoryInfo *bind_image_mem_info,
|
||||
const VkBindImageMemorySwapchainInfoKHR *bind_sc_info) override;
|
||||
|
||||
/**
|
||||
* @brief Get backend specific image create info extensions.
|
||||
*
|
||||
* @param swapchain_create_info Swapchain create info.
|
||||
* @param[out] extensions Backend specific swapchain image create info extensions.
|
||||
*/
|
||||
VkResult get_required_image_creator_extensions(
|
||||
const VkSwapchainCreateInfoKHR &swapchain_create_info,
|
||||
util::vector<util::unique_ptr<swapchain_image_create_info_extension>> *extensions) override;
|
||||
|
||||
private:
|
||||
VkResult create_wl_buffer(const VkImageCreateInfo &image_create_info, swapchain_image &image,
|
||||
wayland_image_data *image_data);
|
||||
|
|
@ -210,7 +222,7 @@ private:
|
|||
/**
|
||||
* @brief Handle to the WSI allocator.
|
||||
*/
|
||||
wsialloc_allocator *m_wsi_allocator;
|
||||
util::unique_ptr<swapchain_wsialloc_allocator> m_wsi_allocator;
|
||||
|
||||
/**
|
||||
* @brief Image creation parameters used for all swapchain images.
|
||||
|
|
|
|||
87
wsi/wsi_alloc_utils.cpp
Normal file
87
wsi/wsi_alloc_utils.cpp
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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 wsi_alloc_utils.hpp
|
||||
*/
|
||||
|
||||
#include "wsi_alloc_utils.hpp"
|
||||
#include "util/log.hpp"
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
namespace wsi
|
||||
{
|
||||
|
||||
std::optional<swapchain_wsialloc_allocator> swapchain_wsialloc_allocator::create()
|
||||
{
|
||||
wsialloc_allocator *allocator = nullptr;
|
||||
WSIALLOC_ASSERT_VERSION();
|
||||
if (wsialloc_new(&allocator) != WSIALLOC_ERROR_NONE)
|
||||
{
|
||||
WSI_LOG_ERROR("Failed to create wsi allocator.");
|
||||
return std::nullopt;
|
||||
}
|
||||
return swapchain_wsialloc_allocator(allocator);
|
||||
}
|
||||
|
||||
VkResult swapchain_wsialloc_allocator::allocate(const allocation_params &input, wsialloc_allocate_result *alloc_result)
|
||||
{
|
||||
assert(alloc_result != nullptr);
|
||||
|
||||
uint64_t allocation_flags = input.is_protected_memory ? WSIALLOC_ALLOCATE_PROTECTED : 0;
|
||||
if (input.avoid_allocation)
|
||||
{
|
||||
allocation_flags |= WSIALLOC_ALLOCATE_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (input.enable_fixed_rate)
|
||||
{
|
||||
allocation_flags |= WSIALLOC_ALLOCATE_HIGHEST_FIXED_RATE_COMPRESSION;
|
||||
}
|
||||
|
||||
wsialloc_allocate_info alloc_info = { input.importable_formats.data(),
|
||||
static_cast<unsigned>(input.importable_formats.size()), input.extent.width,
|
||||
input.extent.height, allocation_flags };
|
||||
|
||||
/* 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_allocator, &alloc_info, alloc_result);
|
||||
if (res != WSIALLOC_ERROR_NONE)
|
||||
{
|
||||
WSI_LOG_ERROR("Failed allocation of DMA Buffer. WSI error: %d", static_cast<int>(res));
|
||||
if (res == WSIALLOC_ERROR_NOT_SUPPORTED)
|
||||
{
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
}
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
} /* namespace wsi */
|
||||
107
wsi/wsi_alloc_utils.hpp
Normal file
107
wsi/wsi_alloc_utils.hpp
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* 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 wsi_alloc_utils.hpp
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include "util/wsialloc/wsialloc.h"
|
||||
#include <util/helpers.hpp>
|
||||
|
||||
#include "util/custom_allocator.hpp"
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
namespace wsi
|
||||
{
|
||||
|
||||
struct allocation_params
|
||||
{
|
||||
bool is_protected_memory;
|
||||
VkExtent3D extent;
|
||||
util::vector<wsialloc_format> &importable_formats;
|
||||
bool enable_fixed_rate;
|
||||
bool avoid_allocation;
|
||||
};
|
||||
|
||||
class swapchain_wsialloc_allocator
|
||||
{
|
||||
public:
|
||||
static std::optional<swapchain_wsialloc_allocator> create();
|
||||
|
||||
swapchain_wsialloc_allocator(swapchain_wsialloc_allocator &other) = delete;
|
||||
swapchain_wsialloc_allocator &operator=(swapchain_wsialloc_allocator &other) = delete;
|
||||
|
||||
swapchain_wsialloc_allocator(swapchain_wsialloc_allocator &&other)
|
||||
: m_allocator(other.m_allocator)
|
||||
{
|
||||
other.m_allocator = nullptr;
|
||||
}
|
||||
|
||||
swapchain_wsialloc_allocator &operator=(swapchain_wsialloc_allocator &&other)
|
||||
{
|
||||
if (this == &other)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (m_allocator != nullptr)
|
||||
{
|
||||
wsialloc_delete(m_allocator);
|
||||
m_allocator = nullptr;
|
||||
}
|
||||
std::swap(m_allocator, other.m_allocator);
|
||||
}
|
||||
|
||||
~swapchain_wsialloc_allocator()
|
||||
{
|
||||
if (m_allocator != nullptr)
|
||||
{
|
||||
wsialloc_delete(m_allocator);
|
||||
}
|
||||
}
|
||||
|
||||
wsialloc_allocator *get()
|
||||
{
|
||||
return m_allocator;
|
||||
}
|
||||
|
||||
VkResult allocate(const allocation_params &input, wsialloc_allocate_result *alloc_result);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Handle to the WSI allocator.
|
||||
*/
|
||||
wsialloc_allocator *m_allocator;
|
||||
|
||||
swapchain_wsialloc_allocator(wsialloc_allocator *allocator)
|
||||
: m_allocator(allocator)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace wsi */
|
||||
Loading…
Add table
Reference in a new issue