mirror of
https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer.git
synced 2025-12-24 11:10:08 +01:00
Fix the number of planes calculation
Previously, the number of planes was incorrectly calculated. The number of planes for non-linear images was the format planes from wsialloc instead of the memory planes expected by the implementation. Additionally, the VK_IMAGE_CREATE_DISJOINT_BIT was based on the format planes during image creation, instead of using the allocation planes from wsialloc. This commit corrects these issues by ensuring the plane count and disjoint bit is set based on the appropriate memory planes. Signed-off-by: Angeliki Agathi Tsintzira <angelikiagathi.tsintzira@arm.com> Change-Id: I47ca4a0c710cdf21d94705c57f08de4f04b3a761
This commit is contained in:
parent
7f428885e1
commit
1fa0ac21f3
6 changed files with 144 additions and 52 deletions
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 2021 Arm Limited.
|
||||
* Copyright (c) 2019, 2021, 2024 Arm Limited.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
|
|
@ -77,5 +77,47 @@ VkFormat drm_to_vk_srgb_format(uint32_t drm_format)
|
|||
return VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
/* Returns the number of planes represented by a fourcc format. */
|
||||
uint32_t drm_fourcc_format_get_num_planes(uint32_t format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case DRM_FORMAT_RGB332:
|
||||
case DRM_FORMAT_BGR233:
|
||||
case DRM_FORMAT_XRGB4444:
|
||||
case DRM_FORMAT_XBGR4444:
|
||||
case DRM_FORMAT_RGBX4444:
|
||||
case DRM_FORMAT_BGRX4444:
|
||||
case DRM_FORMAT_ARGB4444:
|
||||
case DRM_FORMAT_ABGR4444:
|
||||
case DRM_FORMAT_RGBA4444:
|
||||
case DRM_FORMAT_BGRA4444:
|
||||
case DRM_FORMAT_XRGB1555:
|
||||
case DRM_FORMAT_XBGR1555:
|
||||
case DRM_FORMAT_RGBX5551:
|
||||
case DRM_FORMAT_BGRX5551:
|
||||
case DRM_FORMAT_ARGB1555:
|
||||
case DRM_FORMAT_ABGR1555:
|
||||
case DRM_FORMAT_RGBA5551:
|
||||
case DRM_FORMAT_BGRA5551:
|
||||
case DRM_FORMAT_RGB565:
|
||||
case DRM_FORMAT_BGR565:
|
||||
case DRM_FORMAT_RGB888:
|
||||
case DRM_FORMAT_BGR888:
|
||||
case DRM_FORMAT_XRGB8888:
|
||||
case DRM_FORMAT_XBGR8888:
|
||||
case DRM_FORMAT_RGBX8888:
|
||||
case DRM_FORMAT_BGRX8888:
|
||||
case DRM_FORMAT_ARGB8888:
|
||||
case DRM_FORMAT_ABGR8888:
|
||||
case DRM_FORMAT_RGBA8888:
|
||||
case DRM_FORMAT_BGRA8888:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace drm
|
||||
} // namespace util
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 2021-2022 Arm Limited.
|
||||
* Copyright (c) 2019, 2021-2022, 2024 Arm Limited.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
|
|
@ -34,6 +34,7 @@ namespace drm
|
|||
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);
|
||||
uint32_t drm_fourcc_format_get_num_planes(uint32_t format);
|
||||
|
||||
} // namespace drm
|
||||
} // namespace util
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "util/log.hpp"
|
||||
#include "util/helpers.hpp"
|
||||
#include "util/drm/drm_utils.hpp"
|
||||
|
||||
namespace wsi
|
||||
{
|
||||
|
|
@ -64,43 +65,26 @@ external_memory::~external_memory()
|
|||
|
||||
uint32_t external_memory::get_num_planes()
|
||||
{
|
||||
if (m_num_planes == 0)
|
||||
{
|
||||
for (uint32_t plane = 0; plane < MAX_PLANES; plane++)
|
||||
{
|
||||
if (m_strides[plane] == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
m_num_planes++;
|
||||
}
|
||||
}
|
||||
return m_num_planes;
|
||||
}
|
||||
|
||||
uint32_t external_memory::get_num_memories()
|
||||
{
|
||||
return m_num_memories;
|
||||
}
|
||||
|
||||
bool external_memory::is_disjoint()
|
||||
{
|
||||
uint32_t planes = get_num_planes();
|
||||
if (planes > 1)
|
||||
{
|
||||
for (uint32_t plane = 1; plane < planes; ++plane)
|
||||
{
|
||||
if (m_buffer_fds[plane] != m_buffer_fds[0])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return m_num_memories != 1;
|
||||
}
|
||||
|
||||
VkResult external_memory::get_fd_mem_type_index(uint32_t index, uint32_t *mem_idx)
|
||||
VkResult external_memory::get_fd_mem_type_index(int fd, uint32_t *mem_idx)
|
||||
{
|
||||
auto &device_data = layer::device_private_data::get(m_device);
|
||||
VkMemoryFdPropertiesKHR mem_props = {};
|
||||
mem_props.sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR;
|
||||
|
||||
TRY_LOG(device_data.disp.GetMemoryFdPropertiesKHR(m_device, m_handle_type, m_buffer_fds[index], &mem_props),
|
||||
TRY_LOG(device_data.disp.GetMemoryFdPropertiesKHR(m_device, m_handle_type, fd, &mem_props),
|
||||
"Error querying file descriptor properties");
|
||||
|
||||
for (*mem_idx = 0; *mem_idx < VK_MAX_MEMORY_TYPES; (*mem_idx)++)
|
||||
|
|
@ -120,25 +104,27 @@ VkResult external_memory::import_plane_memories()
|
|||
{
|
||||
if (is_disjoint())
|
||||
{
|
||||
uint32_t memory_plane = 0;
|
||||
for (uint32_t plane = 0; plane < get_num_planes(); plane++)
|
||||
{
|
||||
auto it = std::find(std::begin(m_buffer_fds), std::end(m_buffer_fds), m_buffer_fds[plane]);
|
||||
if (std::distance(std::begin(m_buffer_fds), it) == plane)
|
||||
{
|
||||
TRY_LOG_CALL(import_plane_memory(plane));
|
||||
TRY_LOG_CALL(import_plane_memory(m_buffer_fds[plane], &m_memories[memory_plane]));
|
||||
memory_plane++;
|
||||
}
|
||||
}
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
return import_plane_memory(0);
|
||||
return import_plane_memory(m_buffer_fds[0], &m_memories[0]);
|
||||
}
|
||||
|
||||
VkResult external_memory::import_plane_memory(uint32_t index)
|
||||
VkResult external_memory::import_plane_memory(int fd, VkDeviceMemory *memory)
|
||||
{
|
||||
uint32_t mem_index = 0;
|
||||
TRY_LOG_CALL(get_fd_mem_type_index(index, &mem_index));
|
||||
TRY_LOG_CALL(get_fd_mem_type_index(fd, &mem_index));
|
||||
|
||||
const off_t fd_size = lseek(m_buffer_fds[index], 0, SEEK_END);
|
||||
const off_t fd_size = lseek(fd, 0, SEEK_END);
|
||||
if (fd_size < 0)
|
||||
{
|
||||
WSI_LOG_ERROR("Failed to get fd size.");
|
||||
|
|
@ -148,7 +134,7 @@ VkResult external_memory::import_plane_memory(uint32_t index)
|
|||
VkImportMemoryFdInfoKHR import_mem_info = {};
|
||||
import_mem_info.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR;
|
||||
import_mem_info.handleType = m_handle_type;
|
||||
import_mem_info.fd = m_buffer_fds[index];
|
||||
import_mem_info.fd = fd;
|
||||
|
||||
VkMemoryAllocateInfo alloc_info = {};
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
|
|
@ -157,9 +143,8 @@ VkResult external_memory::import_plane_memory(uint32_t index)
|
|||
alloc_info.memoryTypeIndex = mem_index;
|
||||
|
||||
auto &device_data = layer::device_private_data::get(m_device);
|
||||
TRY_LOG(
|
||||
device_data.disp.AllocateMemory(m_device, &alloc_info, m_allocator.get_original_callbacks(), &m_memories[index]),
|
||||
"Failed to import device memory");
|
||||
TRY_LOG(device_data.disp.AllocateMemory(m_device, &alloc_info, m_allocator.get_original_callbacks(), memory),
|
||||
"Failed to import device memory");
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
@ -170,20 +155,19 @@ VkResult external_memory::bind_swapchain_image_memory(const VkImage &image)
|
|||
if (is_disjoint())
|
||||
{
|
||||
util::vector<VkBindImageMemoryInfo> bind_img_mem_infos(m_allocator);
|
||||
if (!bind_img_mem_infos.try_resize(get_num_planes()))
|
||||
if (!bind_img_mem_infos.try_resize(get_num_memories()))
|
||||
{
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
util::vector<VkBindImagePlaneMemoryInfo> bind_plane_mem_infos(m_allocator);
|
||||
if (!bind_plane_mem_infos.try_resize(get_num_planes()))
|
||||
if (!bind_plane_mem_infos.try_resize(get_num_memories()))
|
||||
{
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
for (uint32_t plane = 0; plane < get_num_planes(); plane++)
|
||||
for (uint32_t plane = 0; plane < get_num_memories(); plane++)
|
||||
{
|
||||
|
||||
bind_plane_mem_infos[plane].planeAspect = util::PLANE_FLAG_BITS[plane];
|
||||
bind_plane_mem_infos[plane].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO;
|
||||
bind_plane_mem_infos[plane].pNext = nullptr;
|
||||
|
|
@ -230,7 +214,7 @@ void external_memory::fill_drm_mod_info(const void *pNext, VkImageDrmFormatModif
|
|||
drm_mod_info.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT;
|
||||
drm_mod_info.pNext = pNext;
|
||||
drm_mod_info.drmFormatModifier = modifier;
|
||||
drm_mod_info.drmFormatModifierPlaneCount = get_num_planes();
|
||||
drm_mod_info.drmFormatModifierPlaneCount = get_num_memories();
|
||||
drm_mod_info.pPlaneLayouts = plane_layouts.data();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,8 +119,13 @@ public:
|
|||
uint32_t get_num_planes(void);
|
||||
|
||||
/**
|
||||
* @brief Returns whether the external memory uses a multi-planar format where each plane is separately bound to
|
||||
* memory.
|
||||
* @brief Get the number of memory planes the format uses.
|
||||
*/
|
||||
uint32_t get_num_memories(void);
|
||||
|
||||
/**
|
||||
* @brief Returns whether the external memory uses a multi-planar format where each plane is
|
||||
* separately bound to memory or not.
|
||||
*/
|
||||
bool is_disjoint(void);
|
||||
|
||||
|
|
@ -132,6 +137,31 @@ public:
|
|||
m_handle_type = handle_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the number of memory planes.
|
||||
*/
|
||||
void set_num_memories(uint32_t num_memory_planes)
|
||||
{
|
||||
m_num_memories = num_memory_planes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the number of format planes and set the number of memory planes
|
||||
* if is_disjoint is false.
|
||||
*
|
||||
* @param is_disjoint If memory planes are disjoined.
|
||||
* @param planes_count The number of format planes.
|
||||
*/
|
||||
void set_format_info(const bool is_disjoint, uint32_t planes_count)
|
||||
{
|
||||
m_num_planes = planes_count;
|
||||
|
||||
if (!is_disjoint)
|
||||
{
|
||||
m_num_memories = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Binds the external memory to a swapchain image.
|
||||
*
|
||||
|
|
@ -183,11 +213,11 @@ public:
|
|||
void fill_external_info(VkExternalMemoryImageCreateInfoKHR &external_info, void *pNext);
|
||||
|
||||
private:
|
||||
VkResult get_fd_mem_type_index(uint32_t index, uint32_t *mem_idx);
|
||||
VkResult get_fd_mem_type_index(int fd, uint32_t *mem_idx);
|
||||
|
||||
VkResult import_plane_memories(void);
|
||||
|
||||
VkResult import_plane_memory(uint32_t index);
|
||||
VkResult import_plane_memory(int fd, VkDeviceMemory *memory);
|
||||
|
||||
std::array<int, MAX_PLANES> m_buffer_fds{ -1, -1, -1, -1 };
|
||||
std::array<int, MAX_PLANES> m_strides{ 0, 0, 0, 0 };
|
||||
|
|
@ -195,6 +225,7 @@ private:
|
|||
std::array<VkDeviceMemory, MAX_PLANES> m_memories = { VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE,
|
||||
VK_NULL_HANDLE };
|
||||
uint32_t m_num_planes{ 0 };
|
||||
uint32_t m_num_memories{ 0 };
|
||||
VkExternalMemoryHandleTypeFlagBits m_handle_type{ VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT };
|
||||
const VkDevice &m_device;
|
||||
const util::allocator &m_allocator;
|
||||
|
|
|
|||
|
|
@ -136,12 +136,9 @@ static struct wl_buffer_listener buffer_listener = { buffer_release };
|
|||
|
||||
VkResult swapchain::get_surface_compatible_formats(const VkImageCreateInfo &info,
|
||||
util::vector<wsialloc_format> &importable_formats,
|
||||
util::vector<uint64_t> &exportable_modifers)
|
||||
util::vector<uint64_t> &exportable_modifers,
|
||||
util::vector<VkDrmFormatModifierPropertiesEXT> &drm_format_props)
|
||||
{
|
||||
/* Query supported modifers. */
|
||||
util::vector<VkDrmFormatModifierPropertiesEXT> drm_format_props(
|
||||
util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
|
||||
|
||||
TRY_LOG(util::get_drm_format_properties(m_device_data.physical_device, info.format, drm_format_props),
|
||||
"Failed to get format properties");
|
||||
|
||||
|
|
@ -299,6 +296,28 @@ VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, wayl
|
|||
external_memory.set_strides(alloc_result.average_row_strides);
|
||||
external_memory.set_buffer_fds(alloc_result.buffer_fds);
|
||||
external_memory.set_offsets(alloc_result.offsets);
|
||||
|
||||
uint32_t num_planes = util::drm::drm_fourcc_format_get_num_planes(alloc_result.format.fourcc);
|
||||
|
||||
if (!avoid_allocation)
|
||||
{
|
||||
uint32_t num_memory_planes = 0;
|
||||
|
||||
for (uint32_t i = 0; i < num_planes; ++i)
|
||||
{
|
||||
auto it = std::find(std::begin(alloc_result.buffer_fds) + i + 1, std::end(alloc_result.buffer_fds),
|
||||
alloc_result.buffer_fds[i]);
|
||||
if (it == std::end(alloc_result.buffer_fds))
|
||||
{
|
||||
num_memory_planes++;
|
||||
}
|
||||
}
|
||||
|
||||
assert(alloc_result.is_disjoint == (num_memory_planes > 1));
|
||||
external_memory.set_num_memories(num_memory_planes);
|
||||
}
|
||||
|
||||
external_memory.set_format_info(alloc_result.is_disjoint, num_planes);
|
||||
external_memory.set_memory_handle_type(VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
@ -408,7 +427,13 @@ VkResult swapchain::create_swapchain_image(VkImageCreateInfo image_create_info,
|
|||
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));
|
||||
TRY_LOG_CALL(get_surface_compatible_formats(image_create_info, importable_formats, exportable_modifiers));
|
||||
|
||||
/* 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())
|
||||
|
|
@ -420,6 +445,14 @@ VkResult swapchain::create_swapchain_image(VkImageCreateInfo image_create_info,
|
|||
wsialloc_format allocated_format = { 0 };
|
||||
TRY_LOG_CALL(allocate_wsialloc(image_create_info, image_data, importable_formats, &allocated_format, true));
|
||||
|
||||
for (auto &prop : drm_format_props)
|
||||
{
|
||||
if (prop.drmFormatModifier == allocated_format.modifier)
|
||||
{
|
||||
image_data->external_mem.set_num_memories(prop.drmFormatModifierPlaneCount);
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
|
|
|
|||
|
|
@ -203,7 +203,8 @@ private:
|
|||
*/
|
||||
VkResult get_surface_compatible_formats(const VkImageCreateInfo &info,
|
||||
util::vector<wsialloc_format> &importable_formats,
|
||||
util::vector<uint64_t> &exportable_modifers);
|
||||
util::vector<uint64_t> &exportable_modifers,
|
||||
util::vector<VkDrmFormatModifierPropertiesEXT> &drm_format_props);
|
||||
};
|
||||
} // namespace wayland
|
||||
} // namespace wsi
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue