mirror of
https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer.git
synced 2025-12-20 06:50:08 +01:00
Add external memory extension
Adds a swapchain create info extension for creating an image using external memory. This removes the need for modifying the image_create_info in the display and wayland backends. There is still code duplication left in these backends though, because swapchain allocation needs to know the selected format. This will be removed when the swapchain images will be created from the swapchain image creator. Moves the definition of drm_format_pair to drm_utils. Removes two step initialization from swapchain_wsi_allocator. Change-Id: I0c937a59cc62e7e3134f0af4728fdda3739237bd Signed-off-by: Iason Paraskevopoulos <iason.paraskevopoulos@arm.com>
This commit is contained in:
parent
b326e4b21f
commit
ca3820a0ba
16 changed files with 463 additions and 118 deletions
|
|
@ -145,7 +145,8 @@ if(BUILD_WSI_WAYLAND)
|
||||||
wsi/wayland/surface_properties.cpp
|
wsi/wayland/surface_properties.cpp
|
||||||
wsi/wayland/surface.cpp
|
wsi/wayland/surface.cpp
|
||||||
wsi/wayland/wl_helpers.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)
|
if(VULKAN_WSI_LAYER_EXPERIMENTAL)
|
||||||
target_sources(wayland_wsi PRIVATE wsi/wayland/present_timing_handler.cpp)
|
target_sources(wayland_wsi PRIVATE wsi/wayland/present_timing_handler.cpp)
|
||||||
|
|
@ -249,7 +250,8 @@ if (BUILD_WSI_DISPLAY)
|
||||||
wsi/display/drm_display.cpp
|
wsi/display/drm_display.cpp
|
||||||
wsi/display/surface_properties.cpp
|
wsi/display/surface_properties.cpp
|
||||||
wsi/display/swapchain.cpp
|
wsi/display/swapchain.cpp
|
||||||
wsi/display/surface.cpp)
|
wsi/display/surface.cpp
|
||||||
|
wsi/swapchain_image_create_extensions/external_memory_extension.cpp)
|
||||||
|
|
||||||
pkg_check_modules(LIBDRM REQUIRED libdrm)
|
pkg_check_modules(LIBDRM REQUIRED libdrm)
|
||||||
message(STATUS "Using libdrm include directories: ${LIBDRM_INCLUDE_DIRS}")
|
message(STATUS "Using libdrm include directories: ${LIBDRM_INCLUDE_DIRS}")
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, 2021-2022, 2024 Arm Limited.
|
* Copyright (c) 2019-2025 Arm Limited.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
@ -31,6 +31,15 @@ namespace util
|
||||||
namespace drm
|
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);
|
uint32_t vk_to_drm_format(VkFormat vk_format);
|
||||||
VkFormat drm_to_vk_format(uint32_t drm_format);
|
VkFormat drm_to_vk_format(uint32_t drm_format);
|
||||||
VkFormat drm_to_vk_srgb_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
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
@ -44,7 +44,7 @@ namespace display
|
||||||
const std::string default_dri_device_name{ "/dev/dri/card0" };
|
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,
|
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,
|
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)
|
uint32_t max_height, bool supports_fb_modifiers)
|
||||||
: m_drm_fd(std::move(drm_fd))
|
: 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,
|
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++)
|
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.");
|
WSI_LOG_ERROR("Out of host memory.");
|
||||||
return false;
|
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,
|
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,
|
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_object_properties_owner object_properties{ drmModeObjectGetProperties(
|
||||||
drm_fd.get(), plane_res->planes[primary_plane_index], DRM_MODE_OBJECT_PLANE) };
|
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))
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -317,7 +318,7 @@ std::optional<drm_display> drm_display::make_display(const util::allocator &allo
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
if (supports_fb_modifiers)
|
||||||
{
|
{
|
||||||
|
|
@ -365,12 +366,12 @@ std::optional<drm_display> &drm_display::get_display()
|
||||||
return 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();
|
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 =
|
auto supported_format =
|
||||||
std::find_if(m_supported_formats->begin(), m_supported_formats->end(), [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
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
@ -256,7 +256,7 @@ public:
|
||||||
*
|
*
|
||||||
* @return Pointer to vector of supported formats.
|
* @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.
|
* @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.
|
* @param format The format to query support for.
|
||||||
* @return true if the format is supported by the display, otherwise false.
|
* @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.
|
* @brief Returns a CRTC compatible with this display's connector.
|
||||||
|
|
@ -297,7 +297,7 @@ private:
|
||||||
* @param allocator The allocator that the display will use.
|
* @param allocator The allocator that the display will use.
|
||||||
*/
|
*/
|
||||||
drm_display(util::fd_owner drm_fd, int crtc_id, drm_connector_owner drm_connector,
|
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,
|
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);
|
uint32_t max_height, bool supports_fb_modifiers);
|
||||||
|
|
||||||
|
|
@ -319,7 +319,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* @brief Vector of supported formats for use with the display.
|
* @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.
|
* @brief Pointer to available display modes for the connected display.
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,8 @@
|
||||||
|
|
||||||
#include "swapchain.hpp"
|
#include "swapchain.hpp"
|
||||||
|
|
||||||
|
#include <wsi/swapchain_image_create_extensions/external_memory_extension.hpp>
|
||||||
|
|
||||||
namespace wsi
|
namespace wsi
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -48,7 +50,7 @@ namespace display
|
||||||
swapchain::swapchain(layer::device_private_data &dev_data, const VkAllocationCallbacks *pAllocator,
|
swapchain::swapchain(layer::device_private_data &dev_data, const VkAllocationCallbacks *pAllocator,
|
||||||
surface &wsi_surface)
|
surface &wsi_surface)
|
||||||
: wsi::swapchain_base(dev_data, pAllocator)
|
: wsi::swapchain_base(dev_data, pAllocator)
|
||||||
, m_wsi_allocator()
|
, m_wsi_allocator(nullptr)
|
||||||
, m_display_mode(wsi_surface.get_display_mode())
|
, m_display_mode(wsi_surface.get_display_mode())
|
||||||
, m_image_creation_parameters({}, m_allocator, {}, {})
|
, m_image_creation_parameters({}, m_allocator, {}, {})
|
||||||
{
|
{
|
||||||
|
|
@ -108,7 +110,17 @@ VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKH
|
||||||
UNUSED(swapchain_create_info);
|
UNUSED(swapchain_create_info);
|
||||||
UNUSED(use_presentation_thread);
|
UNUSED(use_presentation_thread);
|
||||||
|
|
||||||
TRY(m_wsi_allocator.init());
|
auto wsi_allocator = swapchain_wsialloc_allocator::create();
|
||||||
|
if (!wsi_allocator.has_value())
|
||||||
|
{
|
||||||
|
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;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -139,7 +151,7 @@ VkResult swapchain::get_surface_compatible_formats(const VkImageCreateInfo &info
|
||||||
|
|
||||||
for (const auto &prop : drm_format_props)
|
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))
|
if (!display->is_format_supported(drm_format))
|
||||||
{
|
{
|
||||||
|
|
@ -264,7 +276,7 @@ VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, disp
|
||||||
allocation_params params = { (image_create_info.flags & VK_IMAGE_CREATE_PROTECTED_BIT) != 0,
|
allocation_params params = { (image_create_info.flags & VK_IMAGE_CREATE_PROTECTED_BIT) != 0,
|
||||||
image_create_info.extent, importable_formats, enable_fixed_rate, avoid_allocation };
|
image_create_info.extent, importable_formats, enable_fixed_rate, avoid_allocation };
|
||||||
wsialloc_allocate_result alloc_result = { {}, { 0 }, { 0 }, { -1 }, false };
|
wsialloc_allocate_result alloc_result = { {}, { 0 }, { 0 }, { -1 }, false };
|
||||||
TRY(m_wsi_allocator.allocate(params, &alloc_result));
|
TRY(m_wsi_allocator->allocate(params, &alloc_result));
|
||||||
|
|
||||||
*allocated_format = alloc_result.format;
|
*allocated_format = alloc_result.format;
|
||||||
|
|
||||||
|
|
@ -298,26 +310,6 @@ VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, disp
|
||||||
return VK_SUCCESS;
|
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)
|
VkResult swapchain::allocate_image(display_image_data *image_data)
|
||||||
{
|
{
|
||||||
util::vector<wsialloc_format> importable_formats(util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
util::vector<wsialloc_format> importable_formats(util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
||||||
|
|
@ -336,8 +328,8 @@ VkResult swapchain::create_framebuffer(const VkImageCreateInfo &image_create_inf
|
||||||
VkResult ret_code = VK_SUCCESS;
|
VkResult ret_code = VK_SUCCESS;
|
||||||
std::array<uint32_t, util::MAX_PLANES> strides{ 0, 0, 0, 0 };
|
std::array<uint32_t, util::MAX_PLANES> strides{ 0, 0, 0, 0 };
|
||||||
std::array<uint64_t, util::MAX_PLANES> modifiers{ 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,
|
const util::drm::drm_format_pair allocated_format{ m_image_creation_parameters.m_allocated_format.fourcc,
|
||||||
m_image_creation_parameters.m_allocated_format.modifier };
|
m_image_creation_parameters.m_allocated_format.modifier };
|
||||||
|
|
||||||
auto &display = drm_display::get_display();
|
auto &display = drm_display::get_display();
|
||||||
if (!display.has_value())
|
if (!display.has_value())
|
||||||
|
|
@ -427,7 +419,7 @@ VkResult swapchain::create_swapchain_image(VkImageCreateInfo image_create_info,
|
||||||
}
|
}
|
||||||
image.data = image_data;
|
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::vector<wsialloc_format> importable_formats(
|
||||||
util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
||||||
|
|
@ -459,11 +451,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;
|
m_image_creation_parameters.m_allocated_format = allocated_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -640,8 +627,22 @@ VkResult swapchain::get_required_image_creator_extensions(
|
||||||
const VkSwapchainCreateInfoKHR &swapchain_create_info,
|
const VkSwapchainCreateInfoKHR &swapchain_create_info,
|
||||||
util::vector<util::unique_ptr<swapchain_image_create_info_extension>> *extensions)
|
util::vector<util::unique_ptr<swapchain_image_create_info_extension>> *extensions)
|
||||||
{
|
{
|
||||||
UNUSED(swapchain_create_info);
|
auto compression_control = swapchain_image_create_compression_control::create(
|
||||||
UNUSED(extensions);
|
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;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ private:
|
||||||
*/
|
*/
|
||||||
VkResult add_required_extensions(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info) override;
|
VkResult add_required_extensions(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info) override;
|
||||||
|
|
||||||
swapchain_wsialloc_allocator m_wsi_allocator;
|
util::unique_ptr<swapchain_wsialloc_allocator> m_wsi_allocator;
|
||||||
|
|
||||||
drm_display_mode *m_display_mode;
|
drm_display_mode *m_display_mode;
|
||||||
image_creation_parameters m_image_creation_parameters;
|
image_creation_parameters m_image_creation_parameters;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, 2024 Arm Limited.
|
* Copyright (c) 2021-2025 Arm Limited.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
@ -36,15 +36,6 @@
|
||||||
namespace wsi
|
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.
|
* @brief A generic WSI representation of a VkSurface.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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,89 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
using util::MAX_PLANES;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
class swapchain_image_create_external_memory : public swapchain_image_create_info_extension
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
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;
|
||||||
|
|
||||||
|
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 */
|
||||||
|
|
@ -40,7 +40,7 @@ namespace wayland
|
||||||
|
|
||||||
struct formats_vector
|
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 };
|
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);
|
UNUSED(dma_buf);
|
||||||
auto *drm_supported_formats = reinterpret_cast<formats_vector *>(data);
|
auto *drm_supported_formats = reinterpret_cast<formats_vector *>(data);
|
||||||
|
|
||||||
drm_format_pair format = {};
|
util::drm::drm_format_pair format = {};
|
||||||
format.fourcc = drm_format;
|
format.fourcc = drm_format;
|
||||||
format.modifier = (static_cast<uint64_t>(modifier_hi) << 32) | modifier_low;
|
format.modifier = (static_cast<uint64_t>(modifier_hi) << 32) | modifier_low;
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ zwp_linux_dmabuf_v1_modifier_impl(void *data, struct zwp_linux_dmabuf_v1 *dma_bu
|
||||||
*/
|
*/
|
||||||
static VkResult get_supported_formats_and_modifiers(wl_display *display, wl_event_queue *queue,
|
static VkResult get_supported_formats_and_modifiers(wl_display *display, wl_event_queue *queue,
|
||||||
zwp_linux_dmabuf_v1 *dmabuf_interface,
|
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;
|
formats_vector drm_supported_formats;
|
||||||
drm_supported_formats.formats = &supported_formats;
|
drm_supported_formats.formats = &supported_formats;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, 2024 Arm Limited.
|
* Copyright (c) 2021-2025 Arm Limited.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
@ -38,6 +38,8 @@
|
||||||
#include "wl_object_owner.hpp"
|
#include "wl_object_owner.hpp"
|
||||||
#include "util/macros.hpp"
|
#include "util/macros.hpp"
|
||||||
|
|
||||||
|
#include <util/drm/drm_utils.hpp>
|
||||||
|
|
||||||
namespace wsi
|
namespace wsi
|
||||||
{
|
{
|
||||||
namespace wayland
|
namespace wayland
|
||||||
|
|
@ -116,7 +118,7 @@ public:
|
||||||
*
|
*
|
||||||
* The reference is valid throughout the lifetime of this surface.
|
* 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;
|
return supported_formats;
|
||||||
}
|
}
|
||||||
|
|
@ -162,7 +164,7 @@ private:
|
||||||
/** The native Wayland surface */
|
/** The native Wayland surface */
|
||||||
wl_surface *wayland_surface;
|
wl_surface *wayland_surface;
|
||||||
/** A list of DRM formats supported by the Wayland compositor on this 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 specific to the Wayland surface. */
|
||||||
surface_properties properties;
|
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,
|
static VkResult surface_format_properties_add_modifier_support(VkPhysicalDevice phys_dev,
|
||||||
surface_format_properties &format_props,
|
surface_format_properties &format_props,
|
||||||
const drm_format_pair &drm_format,
|
const util::drm::drm_format_pair &drm_format,
|
||||||
bool add_compression = false)
|
bool add_compression = false)
|
||||||
{
|
{
|
||||||
VkPhysicalDeviceExternalImageFormatInfoKHR external_info = {};
|
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,
|
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 };
|
surface_format_properties format_props{ format };
|
||||||
VkResult res = surface_format_properties_add_modifier_support(phys_dev, format_props, drm_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,
|
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)
|
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;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkResult surface_format_properties_map_add_compression(VkPhysicalDevice phys_dev,
|
static VkResult surface_format_properties_map_add_compression(
|
||||||
surface_format_properties_map &format_map,
|
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)
|
for (const auto &drm_format : drm_format_list)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -63,10 +63,9 @@ swapchain::swapchain(layer::device_private_data &dev_data, const VkAllocationCal
|
||||||
, m_surface(wsi_surface.get_wl_surface())
|
, m_surface(wsi_surface.get_wl_surface())
|
||||||
, m_wsi_surface(&wsi_surface)
|
, m_wsi_surface(&wsi_surface)
|
||||||
, m_buffer_queue(nullptr)
|
, m_buffer_queue(nullptr)
|
||||||
, m_wsi_allocator()
|
, m_wsi_allocator(nullptr)
|
||||||
, m_image_creation_parameters({}, m_allocator, {}, {})
|
, m_image_creation_parameters({}, m_allocator, {}, {})
|
||||||
{
|
{
|
||||||
m_image_create_info.format = VK_FORMAT_UNDEFINED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
swapchain::~swapchain()
|
swapchain::~swapchain()
|
||||||
|
|
@ -147,7 +146,17 @@ VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKH
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRY(m_wsi_allocator.init());
|
auto wsi_allocator = swapchain_wsialloc_allocator::create();
|
||||||
|
if (!wsi_allocator.has_value())
|
||||||
|
{
|
||||||
|
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
|
* When VK_PRESENT_MODE_MAILBOX_KHR has been chosen by the application we don't
|
||||||
|
|
@ -196,7 +205,7 @@ VkResult swapchain::get_surface_compatible_formats(const VkImageCreateInfo &info
|
||||||
for (const auto &prop : drm_format_props)
|
for (const auto &prop : drm_format_props)
|
||||||
{
|
{
|
||||||
bool is_supported = false;
|
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())
|
for (const auto &format : m_wsi_surface->get_formats())
|
||||||
{
|
{
|
||||||
|
|
@ -326,7 +335,7 @@ VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, wayl
|
||||||
allocation_params params = { (image_create_info.flags & VK_IMAGE_CREATE_PROTECTED_BIT) != 0,
|
allocation_params params = { (image_create_info.flags & VK_IMAGE_CREATE_PROTECTED_BIT) != 0,
|
||||||
image_create_info.extent, importable_formats, enable_fixed_rate, avoid_allocation };
|
image_create_info.extent, importable_formats, enable_fixed_rate, avoid_allocation };
|
||||||
wsialloc_allocate_result alloc_result = { {}, { 0 }, { 0 }, { -1 }, false };
|
wsialloc_allocate_result alloc_result = { {}, { 0 }, { 0 }, { -1 }, false };
|
||||||
TRY(m_wsi_allocator.allocate(params, &alloc_result));
|
TRY(m_wsi_allocator->allocate(params, &alloc_result));
|
||||||
|
|
||||||
*allocated_format = alloc_result.format;
|
*allocated_format = alloc_result.format;
|
||||||
|
|
||||||
|
|
@ -360,26 +369,6 @@ VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, wayl
|
||||||
return VK_SUCCESS;
|
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)
|
VkResult swapchain::allocate_image(wayland_image_data *image_data)
|
||||||
{
|
{
|
||||||
util::vector<wsialloc_format> importable_formats(util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
util::vector<wsialloc_format> importable_formats(util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
||||||
|
|
@ -460,13 +449,13 @@ VkResult swapchain::create_swapchain_image(VkImageCreateInfo image_create_info,
|
||||||
}
|
}
|
||||||
image.data = image_data;
|
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::vector<wsialloc_format> importable_formats(
|
||||||
util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
||||||
util::vector<uint64_t> exportable_modifiers(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::vector<VkDrmFormatModifierPropertiesEXT> drm_format_props(
|
||||||
util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
||||||
|
|
||||||
|
|
@ -491,11 +480,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;
|
m_image_creation_parameters.m_allocated_format = allocated_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -667,8 +651,15 @@ VkResult swapchain::get_required_image_creator_extensions(
|
||||||
const VkSwapchainCreateInfoKHR &swapchain_create_info,
|
const VkSwapchainCreateInfoKHR &swapchain_create_info,
|
||||||
util::vector<util::unique_ptr<swapchain_image_create_info_extension>> *extensions)
|
util::vector<util::unique_ptr<swapchain_image_create_info_extension>> *extensions)
|
||||||
{
|
{
|
||||||
UNUSED(swapchain_create_info);
|
auto compression_control = swapchain_image_create_compression_control::create(
|
||||||
UNUSED(extensions);
|
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;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -222,7 +222,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* @brief Handle to the WSI allocator.
|
* @brief Handle to the WSI allocator.
|
||||||
*/
|
*/
|
||||||
swapchain_wsialloc_allocator m_wsi_allocator;
|
util::unique_ptr<swapchain_wsialloc_allocator> m_wsi_allocator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Image creation parameters used for all swapchain images.
|
* @brief Image creation parameters used for all swapchain images.
|
||||||
|
|
|
||||||
|
|
@ -33,15 +33,16 @@
|
||||||
namespace wsi
|
namespace wsi
|
||||||
{
|
{
|
||||||
|
|
||||||
VkResult swapchain_wsialloc_allocator::init()
|
std::optional<swapchain_wsialloc_allocator> swapchain_wsialloc_allocator::create()
|
||||||
{
|
{
|
||||||
|
wsialloc_allocator *allocator = nullptr;
|
||||||
WSIALLOC_ASSERT_VERSION();
|
WSIALLOC_ASSERT_VERSION();
|
||||||
if (wsialloc_new(&m_allocator) != WSIALLOC_ERROR_NONE)
|
if (wsialloc_new(&allocator) != WSIALLOC_ERROR_NONE)
|
||||||
{
|
{
|
||||||
WSI_LOG_ERROR("Failed to create wsi allocator.");
|
WSI_LOG_ERROR("Failed to create wsi allocator.");
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
return VK_SUCCESS;
|
return swapchain_wsialloc_allocator(allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult swapchain_wsialloc_allocator::allocate(const allocation_params &input, wsialloc_allocate_result *alloc_result)
|
VkResult swapchain_wsialloc_allocator::allocate(const allocation_params &input, wsialloc_allocate_result *alloc_result)
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include "util/wsialloc/wsialloc.h"
|
#include "util/wsialloc/wsialloc.h"
|
||||||
|
#include <util/helpers.hpp>
|
||||||
|
|
||||||
#include "util/custom_allocator.hpp"
|
#include "util/custom_allocator.hpp"
|
||||||
|
|
||||||
|
|
@ -50,13 +51,31 @@ struct allocation_params
|
||||||
class swapchain_wsialloc_allocator
|
class swapchain_wsialloc_allocator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
swapchain_wsialloc_allocator(wsialloc_allocator *allocator)
|
static std::optional<swapchain_wsialloc_allocator> create();
|
||||||
: m_allocator(allocator)
|
|
||||||
|
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()
|
swapchain_wsialloc_allocator &operator=(swapchain_wsialloc_allocator &&other)
|
||||||
: m_allocator(nullptr){};
|
{
|
||||||
|
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()
|
~swapchain_wsialloc_allocator()
|
||||||
{
|
{
|
||||||
|
|
@ -71,7 +90,6 @@ public:
|
||||||
return m_allocator;
|
return m_allocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult init();
|
|
||||||
VkResult allocate(const allocation_params &input, wsialloc_allocate_result *alloc_result);
|
VkResult allocate(const allocation_params &input, wsialloc_allocate_result *alloc_result);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -79,6 +97,11 @@ private:
|
||||||
* @brief Handle to the WSI allocator.
|
* @brief Handle to the WSI allocator.
|
||||||
*/
|
*/
|
||||||
wsialloc_allocator *m_allocator;
|
wsialloc_allocator *m_allocator;
|
||||||
|
|
||||||
|
swapchain_wsialloc_allocator(wsialloc_allocator *allocator)
|
||||||
|
: m_allocator(allocator)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace wsi */
|
} /* namespace wsi */
|
||||||
Loading…
Add table
Reference in a new issue