mirror of
https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer.git
synced 2025-12-20 16:10:09 +01:00
Extend wsialloc_alloc with disjoint information
Extends wsialloc_alloc to return whether or not the allocation will be disjoint. Groups wsialloc_alloc's return values to a struct. Change-Id: I7542e37d8af16ce7989ab235c02305d562f3c667 Signed-off-by: Iason Paraskevopoulos <iason.paraskevopoulos@arm.com>
This commit is contained in:
parent
8a74233de2
commit
b02486ff87
4 changed files with 97 additions and 57 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2019, 2021-2022 Arm Limited.
|
* Copyright (c) 2017-2024 Arm Limited.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
@ -31,7 +31,12 @@
|
||||||
#define _WSIALLOC_H_
|
#define _WSIALLOC_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||||
#include <drm_fourcc.h>
|
#include <drm_fourcc.h>
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
@ -57,9 +62,10 @@ extern "C" {
|
||||||
* Version History:
|
* Version History:
|
||||||
* 1 - Initial wsialloc interface
|
* 1 - Initial wsialloc interface
|
||||||
* 2 - Added WSIALLOC_ALLOCATE_HIGHEST_FIXED_RATE_COMPRESSION
|
* 2 - Added WSIALLOC_ALLOCATE_HIGHEST_FIXED_RATE_COMPRESSION
|
||||||
|
* 3 - Grouped the return values of wsialloc_alloc to wsialloc_allocate_result and added another value for returning
|
||||||
|
* whether or not the allocation will be disjoint.
|
||||||
*/
|
*/
|
||||||
|
#define WSIALLOC_INTERFACE_VERSION 3
|
||||||
#define WSIALLOC_INTERFACE_VERSION 2
|
|
||||||
|
|
||||||
#define WSIALLOC_CONCAT(x, y) x##y
|
#define WSIALLOC_CONCAT(x, y) x##y
|
||||||
#define WSIALLOC_SYMBOL_VERSION(symbol, version) WSIALLOC_CONCAT(symbol, version)
|
#define WSIALLOC_SYMBOL_VERSION(symbol, version) WSIALLOC_CONCAT(symbol, version)
|
||||||
|
|
@ -159,63 +165,75 @@ typedef struct wsialloc_format
|
||||||
|
|
||||||
typedef struct wsialloc_allocate_info
|
typedef struct wsialloc_allocate_info
|
||||||
{
|
{
|
||||||
wsialloc_format *formats; /** List of formats to select from for the allocation */
|
wsialloc_format *formats; /** List of formats to select from for the allocation. */
|
||||||
unsigned format_count; /** Number of elements in formats array */
|
unsigned format_count; /** Number of elements in formats array. */
|
||||||
uint32_t width; /** The number of pixel columns required in the buffer. */
|
uint32_t width; /** The number of pixel columns required in the buffer. */
|
||||||
uint32_t height; /** The number of pixel rows required in the buffer. */
|
uint32_t height; /** The number of pixel rows required in the buffer. */
|
||||||
uint64_t flags; /** Set of @r wsialloc_allocate_flag allocation flags. */
|
uint64_t flags; /** Set of @r wsialloc_allocate_flag allocation flags. */
|
||||||
} wsialloc_allocate_info;
|
} wsialloc_allocate_info;
|
||||||
|
|
||||||
|
typedef struct wsialloc_allocate_result
|
||||||
|
{
|
||||||
|
wsialloc_format format; /** The selected format for allocation. */
|
||||||
|
/** Per plane distance between rows of blocks divided by the block height measured in bytes. */
|
||||||
|
int average_row_strides[WSIALLOC_MAX_PLANES];
|
||||||
|
/** Per plane offset into the file descriptor for the start of the plane. */
|
||||||
|
uint32_t offsets[WSIALLOC_MAX_PLANES];
|
||||||
|
int buffer_fds[WSIALLOC_MAX_PLANES]; /** Per plane file descriptor for the buffer. */
|
||||||
|
bool is_disjoint; /** Whether different fds will be used for each plane. */
|
||||||
|
} wsialloc_allocate_result;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allocate a buffer from the WSI Allocator
|
* @brief Allocate a buffer from the WSI Allocator
|
||||||
*
|
*
|
||||||
* Allocate a buffer of size @p info::width x @p info::height in a way that is suitable for the underlying
|
* Allocate a buffer of size @p info::width x @p info::height in a way that is suitable for the underlying
|
||||||
* window system and GPU.
|
* window system and GPU.
|
||||||
*
|
*
|
||||||
* The allocation is made using a format from the list specified in @p info::formats . On success, @p format is set with
|
* The allocation is made using a format from the list specified in @p info::formats . On success, @p result::format is set with
|
||||||
* the selected format that was used for the allocation.
|
* the selected format that was used for the allocation.
|
||||||
*
|
*
|
||||||
* Each plane is returned as a file descriptor. All other information returned about the buffer is also per-plane. It is
|
* Each plane is returned as a file descriptor. All other information returned about the buffer is also per-plane. It is
|
||||||
* assumed the caller already knows how many planes are implied by the @p format that was selected.
|
* assumed the caller already knows how many planes are implied by the @p result::format that was selected.
|
||||||
*
|
*
|
||||||
* Each row in the buffer may be larger than @p info::width to account for buffer alignment requirements in the
|
* Each row in the buffer may be larger than @p info::width to account for buffer alignment requirements in the
|
||||||
* underlying window system. @p strides must be examined to determine the number of bytes between subsequent rows
|
* underlying window system. @p result::average_row_strides must be examined to determine the number of bytes between
|
||||||
* in each of the buffer's planes. Only positive strides are allowed.
|
* subsequent rows in each of the buffer's planes. Only positive average_row_strides are allowed.
|
||||||
*
|
*
|
||||||
* The client may free the buffer's planes by invoking close() on some or all of the elements of @p buffer_fds
|
* The client may free the buffer's planes by invoking close() on some or all of the elements of @p result::buffer_fds
|
||||||
*
|
*
|
||||||
* The same file descriptor ('fd') may be written to different elements of @p buffer_fds more than once, for some or all
|
* The same file descriptor ('fd') may be written to different elements of @p result::buffer_fds more than once, for some or all
|
||||||
* of the planes. In this case:
|
* of the planes. In this case:
|
||||||
* - @p offsets @b must be used to determine where each plane starts in the file descriptor
|
* - @p result::offsets @b must be used to determine where each plane starts in the file descriptor
|
||||||
* - When the client frees the buffer, each unique fd in @p buffer_fds must only be closed once.
|
* - When the client frees the buffer, each unique fd in @p result::buffer_fds must only be closed once.
|
||||||
*
|
*
|
||||||
* Even if @p buffer_fds are all different or @p format is for a single plane, then the client must inspect @p offsets
|
* Even if @p result::buffer_fds are all different or @p result::format is for a single plane, then the client must inspect
|
||||||
* in case it contains non-zero values.
|
* @p result::offsets in case it contains non-zero values.
|
||||||
*
|
*
|
||||||
* @note The implementation might not export the file descriptors in @p buffer_fds in such a way that allows the client
|
* If @p result::buffer_fds are different then @p result::disjoint should be set to true.
|
||||||
|
*
|
||||||
|
* @note The implementation might not export the file descriptors in @p result::buffer_fds in such a way that allows the client
|
||||||
* to directly map them on the CPU as writable (PROT_WRITE).
|
* to directly map them on the CPU as writable (PROT_WRITE).
|
||||||
*
|
*
|
||||||
* The selected @p format modifier allows for a fourcc_mod_code() (as defined in drm_fourcc.h) to define
|
* The selected @p result::format modifier allows for a fourcc_mod_code() (as defined in drm_fourcc.h) to define
|
||||||
* a reordering or other modification of the data in the buffer's planes (e.g. compression,
|
* a reordering or other modification of the data in the buffer's planes (e.g. compression,
|
||||||
* change in number of planes, etc).
|
* change in number of planes, etc).
|
||||||
*
|
*
|
||||||
* @p strides is the per plane row byte stride of the @p format. For linear formats this is the number of bytes from the
|
* @p result::average_row_strides are per plane row average byte strides of the @p result::format. This is the number of bytes from the
|
||||||
* start of a row to the start of the next row. For block based formats it is the number of bytes from the start of one
|
* start of a row of blocks divided by the block height. It may also have format specific meaning for formats not in those
|
||||||
* row of blocks to the start of the next. It may also have format specific meaning for formats not in those categories.
|
* categories.
|
||||||
*
|
*
|
||||||
* @p strides and @p offsets may have modifier-specific meaning when a @p format with modifier is selected.
|
* @p result::average_row_strides and @p result::offsets may have modifier-specific
|
||||||
|
* meaning when a @p result::format with modifier is selected.
|
||||||
*
|
*
|
||||||
* @pre @p strides, @p buffer_fds, @p offsets are pointers to storage large enough to hold per-plane information
|
* @pre @p result::average_row_strides, @p result::buffer_fds, @p result::offsets
|
||||||
|
* are pointers to storage large enough to hold per-plane information.
|
||||||
* @pre @p info::width >=1 && @p info::height >= 1
|
* @pre @p info::width >=1 && @p info::height >= 1
|
||||||
* @pre @p allocator is a currently valid WSI Allocator from wsialloc_new()
|
* @pre @p allocator is a currently valid WSI Allocator from wsialloc_new()
|
||||||
* @post The allocated buffer will be zeroed.
|
* @post The allocated buffer will be zeroed.
|
||||||
*
|
*
|
||||||
* @param allocator The WSI Allocator to allocate from.
|
* @param allocator The WSI Allocator to allocate from.
|
||||||
* @param[in] info The requested allocation information.
|
* @param[in] info The requested allocation information.
|
||||||
* @param[out] format The selected format for allocation.
|
* @param[out] result The allocation's result.
|
||||||
* @param[out] strides Per-plane row byte stride of the buffer.
|
|
||||||
* @param[out] buffer_fds Per-plane file descriptors for the buffer.
|
|
||||||
* @param[out] offsets Per-plane offset into the file descriptor for the start of the plane.
|
|
||||||
|
|
||||||
* @retval WSIALLOC_ERROR_NONE on successful buffer allocation.
|
* @retval WSIALLOC_ERROR_NONE on successful buffer allocation.
|
||||||
* @retval WSIALLOC_ERROR_INVALID is returned for invalid parameters.
|
* @retval WSIALLOC_ERROR_INVALID is returned for invalid parameters.
|
||||||
|
|
@ -226,7 +244,7 @@ typedef struct wsialloc_allocate_info
|
||||||
*/
|
*/
|
||||||
|
|
||||||
wsialloc_error wsialloc_alloc(wsialloc_allocator *allocator, const wsialloc_allocate_info *info,
|
wsialloc_error wsialloc_alloc(wsialloc_allocator *allocator, const wsialloc_allocate_info *info,
|
||||||
wsialloc_format *format, int *strides, int *buffer_fds, uint32_t *offsets);
|
wsialloc_allocate_result *result);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2019, 2021-2022 Arm Limited.
|
* Copyright (c) 2017-2024 Arm Limited.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
@ -44,7 +44,7 @@
|
||||||
*
|
*
|
||||||
* This should only be increased when this implementation is updated to match newer versions of wsialloc.h.
|
* This should only be increased when this implementation is updated to match newer versions of wsialloc.h.
|
||||||
*/
|
*/
|
||||||
#define WSIALLOC_IMPLEMENTATION_VERSION 2
|
#define WSIALLOC_IMPLEMENTATION_VERSION 3
|
||||||
|
|
||||||
/* Ensure we are implementing the wsialloc version matching the wsialloc.h header we are using. */
|
/* Ensure we are implementing the wsialloc version matching the wsialloc.h header we are using. */
|
||||||
#if WSIALLOC_IMPLEMENTATION_VERSION != WSIALLOC_INTERFACE_VERSION
|
#if WSIALLOC_IMPLEMENTATION_VERSION != WSIALLOC_INTERFACE_VERSION
|
||||||
|
|
@ -81,7 +81,8 @@ static int find_alloc_heap_id(int fd)
|
||||||
|
|
||||||
struct ion_heap_data heaps[ION_NUM_HEAP_IDS];
|
struct ion_heap_data heaps[ION_NUM_HEAP_IDS];
|
||||||
struct ion_heap_query query = {
|
struct ion_heap_query query = {
|
||||||
.cnt = ION_NUM_HEAP_IDS, .heaps = (uint64_t)(uintptr_t)heaps,
|
.cnt = ION_NUM_HEAP_IDS,
|
||||||
|
.heaps = (uint64_t)(uintptr_t)heaps,
|
||||||
};
|
};
|
||||||
|
|
||||||
int ret = ioctl(fd, ION_IOC_HEAP_QUERY, &query);
|
int ret = ioctl(fd, ION_IOC_HEAP_QUERY, &query);
|
||||||
|
|
@ -109,7 +110,9 @@ static int allocate(int fd, size_t size, uint32_t heap_id)
|
||||||
assert(fd != -1);
|
assert(fd != -1);
|
||||||
|
|
||||||
struct ion_allocation_data alloc = {
|
struct ion_allocation_data alloc = {
|
||||||
.len = size, .heap_id_mask = 1u << heap_id, .flags = 0,
|
.len = size,
|
||||||
|
.heap_id_mask = 1u << heap_id,
|
||||||
|
.flags = 0,
|
||||||
};
|
};
|
||||||
int ret = ioctl(fd, ION_IOC_ALLOC, &alloc);
|
int ret = ioctl(fd, ION_IOC_ALLOC, &alloc);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
|
@ -281,13 +284,13 @@ static const fmt_spec *find_format(uint32_t fourcc)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool validate_parameters(const wsialloc_allocator *allocator, const wsialloc_allocate_info *info,
|
static bool validate_parameters(const wsialloc_allocator *allocator, const wsialloc_allocate_info *info,
|
||||||
const wsialloc_format *format, const int *strides, const uint32_t *offsets)
|
wsialloc_allocate_result *result)
|
||||||
{
|
{
|
||||||
if (allocator == NULL)
|
if (allocator == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (!strides || !offsets)
|
else if (!result)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -304,15 +307,13 @@ static bool validate_parameters(const wsialloc_allocator *allocator, const wsial
|
||||||
}
|
}
|
||||||
|
|
||||||
wsialloc_error wsialloc_alloc(wsialloc_allocator *allocator, const wsialloc_allocate_info *info,
|
wsialloc_error wsialloc_alloc(wsialloc_allocator *allocator, const wsialloc_allocate_info *info,
|
||||||
wsialloc_format *format, int *strides, int *buffer_fds, uint32_t *offsets)
|
wsialloc_allocate_result *result)
|
||||||
{
|
{
|
||||||
assert(allocator != NULL);
|
assert(allocator != NULL);
|
||||||
assert(info != NULL);
|
assert(info != NULL);
|
||||||
assert(format != NULL);
|
assert(result != NULL);
|
||||||
assert(strides != NULL);
|
|
||||||
assert(offsets != NULL);
|
|
||||||
|
|
||||||
if (!validate_parameters(allocator, info, format, strides, offsets))
|
if (!validate_parameters(allocator, info, result))
|
||||||
{
|
{
|
||||||
return WSIALLOC_ERROR_INVALID;
|
return WSIALLOC_ERROR_INVALID;
|
||||||
}
|
}
|
||||||
|
|
@ -355,13 +356,16 @@ wsialloc_error wsialloc_alloc(wsialloc_allocator *allocator, const wsialloc_allo
|
||||||
|
|
||||||
if (err == WSIALLOC_ERROR_NONE)
|
if (err == WSIALLOC_ERROR_NONE)
|
||||||
{
|
{
|
||||||
*format = selected_format_desc.format;
|
result->format = selected_format_desc.format;
|
||||||
*strides = local_strides[0];
|
result->average_row_strides[0] = local_strides[0];
|
||||||
*offsets = local_offsets[0];
|
result->offsets[0] = local_offsets[0];
|
||||||
if (!(info->flags & WSIALLOC_ALLOCATE_NO_MEMORY))
|
if (!(info->flags & WSIALLOC_ALLOCATE_NO_MEMORY))
|
||||||
{
|
{
|
||||||
*buffer_fds = local_fds[0];
|
result->buffer_fds[0] = local_fds[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result->is_disjoint = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022 Arm Limited.
|
* Copyright (c) 2022-2024 Arm Limited.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
@ -82,6 +82,11 @@ public:
|
||||||
m_buffer_fds = buffer_fds;
|
m_buffer_fds = buffer_fds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_buffer_fds(const int *buffer_fds)
|
||||||
|
{
|
||||||
|
std::copy(buffer_fds, buffer_fds + MAX_PLANES, m_buffer_fds.begin());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the per plane stride values.
|
* @brief Set the per plane stride values.
|
||||||
*/
|
*/
|
||||||
|
|
@ -90,6 +95,11 @@ public:
|
||||||
m_strides = strides;
|
m_strides = strides;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_strides(const int *strides)
|
||||||
|
{
|
||||||
|
std::copy(strides, strides + MAX_PLANES, m_strides.begin());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the per plane offset values.
|
* @brief Set the per plane offset values.
|
||||||
*/
|
*/
|
||||||
|
|
@ -98,6 +108,11 @@ public:
|
||||||
m_offsets = offsets;
|
m_offsets = offsets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_offsets(const uint32_t *offsets)
|
||||||
|
{
|
||||||
|
std::copy(offsets, offsets + MAX_PLANES, m_offsets.begin());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the number of planes the external format uses.
|
* @brief Get the number of planes the external format uses.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2019, 2021-2023 Arm Limited.
|
* Copyright (c) 2017-2019, 2021-2024 Arm Limited.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
@ -273,11 +273,13 @@ VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, wayl
|
||||||
image_create_info.extent.width, image_create_info.extent.height,
|
image_create_info.extent.width, image_create_info.extent.height,
|
||||||
allocation_flags };
|
allocation_flags };
|
||||||
|
|
||||||
std::array<int, MAX_PLANES> strides{};
|
wsialloc_allocate_result alloc_result = { 0 };
|
||||||
std::array<int, MAX_PLANES> buffer_fds{ -1, -1, -1, -1 };
|
/* Clear fds for error purposes */
|
||||||
std::array<uint32_t, MAX_PLANES> offsets{};
|
for (int i = 0; i < WSIALLOC_MAX_PLANES; ++i)
|
||||||
const auto res =
|
{
|
||||||
wsialloc_alloc(m_wsi_allocator, &alloc_info, allocated_format, strides.data(), buffer_fds.data(), offsets.data());
|
alloc_result.buffer_fds[i] = -1;
|
||||||
|
}
|
||||||
|
const auto res = wsialloc_alloc(m_wsi_allocator, &alloc_info, &alloc_result);
|
||||||
if (res != WSIALLOC_ERROR_NONE)
|
if (res != WSIALLOC_ERROR_NONE)
|
||||||
{
|
{
|
||||||
WSI_LOG_ERROR("Failed allocation of DMA Buffer. WSI error: %d", static_cast<int>(res));
|
WSI_LOG_ERROR("Failed allocation of DMA Buffer. WSI error: %d", static_cast<int>(res));
|
||||||
|
|
@ -287,10 +289,11 @@ VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, wayl
|
||||||
}
|
}
|
||||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
}
|
}
|
||||||
|
*allocated_format = alloc_result.format;
|
||||||
auto &external_memory = image_data->external_mem;
|
auto &external_memory = image_data->external_mem;
|
||||||
external_memory.set_strides(strides);
|
external_memory.set_strides(alloc_result.average_row_strides);
|
||||||
external_memory.set_buffer_fds(buffer_fds);
|
external_memory.set_buffer_fds(alloc_result.buffer_fds);
|
||||||
external_memory.set_offsets(offsets);
|
external_memory.set_offsets(alloc_result.offsets);
|
||||||
external_memory.set_memory_handle_type(VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
|
external_memory.set_memory_handle_type(VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue