From daf356cc1f2edda3682f29b41084a604e4d42cbf Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 4 Mar 2026 13:39:27 +0000 Subject: [PATCH] ipc: Break out swapchain functions into own handler function Part-of: --- src/xrt/ipc/CMakeLists.txt | 1 + src/xrt/ipc/server/ipc_server_handler.c | 229 --------------- .../ipc/server/ipc_server_handler_swapchain.c | 261 ++++++++++++++++++ 3 files changed, 262 insertions(+), 229 deletions(-) create mode 100644 src/xrt/ipc/server/ipc_server_handler_swapchain.c diff --git a/src/xrt/ipc/CMakeLists.txt b/src/xrt/ipc/CMakeLists.txt index 99ca65504..ab6f93426 100644 --- a/src/xrt/ipc/CMakeLists.txt +++ b/src/xrt/ipc/CMakeLists.txt @@ -134,6 +134,7 @@ add_library( ${CMAKE_CURRENT_BINARY_DIR}/ipc_server_generated.h server/ipc_server.h server/ipc_server_handler.c + server/ipc_server_handler_swapchain.c server/ipc_server_per_client_thread.c server/ipc_server_process.c server/ipc_server_objects.c diff --git a/src/xrt/ipc/server/ipc_server_handler.c b/src/xrt/ipc/server/ipc_server_handler.c index 2fb0147fb..c3426de1c 100644 --- a/src/xrt/ipc/server/ipc_server_handler.c +++ b/src/xrt/ipc/server/ipc_server_handler.c @@ -48,41 +48,6 @@ } while (0) -static xrt_result_t -validate_swapchain_state(volatile struct ipc_client_state *ics, uint32_t *out_index) -{ - // Our handle is just the index for now. - uint32_t index = 0; - for (; index < IPC_MAX_CLIENT_SWAPCHAINS; index++) { - if (!ics->swapchain_data[index].active) { - break; - } - } - - if (index >= IPC_MAX_CLIENT_SWAPCHAINS) { - IPC_ERROR(ics->server, "Too many swapchains!"); - return XRT_ERROR_IPC_FAILURE; - } - - *out_index = index; - - return XRT_SUCCESS; -} - -static void -set_swapchain_info(volatile struct ipc_client_state *ics, - uint32_t index, - const struct xrt_swapchain_create_info *info, - struct xrt_swapchain *xsc) -{ - ics->xscs[index] = xsc; - ics->swapchain_data[index].active = true; - ics->swapchain_data[index].width = info->width; - ics->swapchain_data[index].height = info->height; - ics->swapchain_data[index].format = info->format; - ics->swapchain_data[index].image_count = xsc->image_count; -} - static xrt_result_t validate_reference_space_type(volatile struct ipc_client_state *ics, enum xrt_reference_space_type type) { @@ -1772,200 +1737,6 @@ ipc_handle_system_set_client_io_blocks(volatile struct ipc_client_state *_ics, return ipc_server_set_client_io_blocks(s, client_id, blocks); } -xrt_result_t -ipc_handle_swapchain_get_properties(volatile struct ipc_client_state *ics, - const struct xrt_swapchain_create_info *info, - struct xrt_swapchain_create_properties *xsccp) -{ - IPC_TRACE_MARKER(); - - if (ics->xc == NULL) { - return XRT_ERROR_IPC_SESSION_NOT_CREATED; - } - - return xrt_comp_get_swapchain_create_properties(ics->xc, info, xsccp); -} - -xrt_result_t -ipc_handle_swapchain_create(volatile struct ipc_client_state *ics, - const struct xrt_swapchain_create_info *info, - uint32_t *out_id, - uint32_t *out_image_count, - uint64_t *out_size, - bool *out_use_dedicated_allocation, - uint32_t max_handle_capacity, - xrt_graphics_buffer_handle_t *out_handles, - uint32_t *out_handle_count) -{ - IPC_TRACE_MARKER(); - - xrt_result_t xret = XRT_SUCCESS; - uint32_t index = 0; - - xret = validate_swapchain_state(ics, &index); - if (xret != XRT_SUCCESS) { - return xret; - } - - // Create the swapchain - struct xrt_swapchain *xsc = NULL; // Has to be NULL. - xret = xrt_comp_create_swapchain(ics->xc, info, &xsc); - if (xret != XRT_SUCCESS) { - if (xret == XRT_ERROR_SWAPCHAIN_FLAG_VALID_BUT_UNSUPPORTED) { - IPC_WARN(ics->server, - "xrt_comp_create_swapchain: Attempted to create valid, but unsupported swapchain"); - } else { - IPC_ERROR(ics->server, "Error xrt_comp_create_swapchain failed!"); - } - return xret; - } - - // It's now safe to increment the number of swapchains. - ics->swapchain_count++; - - IPC_TRACE(ics->server, "Created swapchain %d.", index); - - set_swapchain_info(ics, index, info, xsc); - - // return our result to the caller. - struct xrt_swapchain_native *xscn = (struct xrt_swapchain_native *)xsc; - - // Limit checking - assert(xsc->image_count <= XRT_MAX_SWAPCHAIN_IMAGES); - assert(xsc->image_count <= max_handle_capacity); - - for (size_t i = 1; i < xsc->image_count; i++) { - assert(xscn->images[0].size == xscn->images[i].size); - assert(xscn->images[0].use_dedicated_allocation == xscn->images[i].use_dedicated_allocation); - } - - // Assuming all images allocated in the same swapchain have the same allocation requirements. - *out_size = xscn->images[0].size; - *out_use_dedicated_allocation = xscn->images[0].use_dedicated_allocation; - *out_id = index; - *out_image_count = xsc->image_count; - - // Setup the fds. - *out_handle_count = xsc->image_count; - for (size_t i = 0; i < xsc->image_count; i++) { - out_handles[i] = xscn->images[i].handle; - } - - return XRT_SUCCESS; -} - -xrt_result_t -ipc_handle_swapchain_import(volatile struct ipc_client_state *ics, - const struct xrt_swapchain_create_info *info, - const struct ipc_arg_swapchain_from_native *args, - uint32_t *out_id, - const xrt_graphics_buffer_handle_t *handles, - uint32_t handle_count) -{ - IPC_TRACE_MARKER(); - - xrt_result_t xret = XRT_SUCCESS; - uint32_t index = 0; - - xret = validate_swapchain_state(ics, &index); - if (xret != XRT_SUCCESS) { - return xret; - } - - struct xrt_image_native xins[XRT_MAX_SWAPCHAIN_IMAGES] = XRT_STRUCT_INIT; - for (uint32_t i = 0; i < handle_count; i++) { - xins[i].handle = handles[i]; - xins[i].size = args->sizes[i]; -#if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_WIN32_HANDLE) - // DXGI handles need to be dealt with differently, they are identified - // by having their lower bit set to 1 during transfer - if ((size_t)xins[i].handle & 1) { - xins[i].handle = (HANDLE)((size_t)xins[i].handle - 1); - xins[i].is_dxgi_handle = true; - } -#endif - } - - // create the swapchain - struct xrt_swapchain *xsc = NULL; - xret = xrt_comp_import_swapchain(ics->xc, info, xins, handle_count, &xsc); - if (xret != XRT_SUCCESS) { - return xret; - } - - // It's now safe to increment the number of swapchains. - ics->swapchain_count++; - - IPC_TRACE(ics->server, "Created swapchain %d.", index); - - set_swapchain_info(ics, index, info, xsc); - *out_id = index; - - return XRT_SUCCESS; -} - -xrt_result_t -ipc_handle_swapchain_wait_image(volatile struct ipc_client_state *ics, uint32_t id, int64_t timeout_ns, uint32_t index) -{ - if (ics->xc == NULL) { - return XRT_ERROR_IPC_SESSION_NOT_CREATED; - } - - //! @todo Look up the index. - uint32_t sc_index = id; - struct xrt_swapchain *xsc = ics->xscs[sc_index]; - - return xrt_swapchain_wait_image(xsc, timeout_ns, index); -} - -xrt_result_t -ipc_handle_swapchain_acquire_image(volatile struct ipc_client_state *ics, uint32_t id, uint32_t *out_index) -{ - if (ics->xc == NULL) { - return XRT_ERROR_IPC_SESSION_NOT_CREATED; - } - - //! @todo Look up the index. - uint32_t sc_index = id; - struct xrt_swapchain *xsc = ics->xscs[sc_index]; - - xrt_swapchain_acquire_image(xsc, out_index); - - return XRT_SUCCESS; -} - -xrt_result_t -ipc_handle_swapchain_release_image(volatile struct ipc_client_state *ics, uint32_t id, uint32_t index) -{ - if (ics->xc == NULL) { - return XRT_ERROR_IPC_SESSION_NOT_CREATED; - } - - //! @todo Look up the index. - uint32_t sc_index = id; - struct xrt_swapchain *xsc = ics->xscs[sc_index]; - - xrt_swapchain_release_image(xsc, index); - - return XRT_SUCCESS; -} - -xrt_result_t -ipc_handle_swapchain_destroy(volatile struct ipc_client_state *ics, uint32_t id) -{ - if (ics->xc == NULL) { - return XRT_ERROR_IPC_SESSION_NOT_CREATED; - } - - ics->swapchain_count--; - - // Drop our reference, does NULL checking. Cast away volatile. - xrt_swapchain_reference((struct xrt_swapchain **)&ics->xscs[id], NULL); - ics->swapchain_data[id].active = false; - - return XRT_SUCCESS; -} - /* * diff --git a/src/xrt/ipc/server/ipc_server_handler_swapchain.c b/src/xrt/ipc/server/ipc_server_handler_swapchain.c new file mode 100644 index 000000000..d0df9e253 --- /dev/null +++ b/src/xrt/ipc/server/ipc_server_handler_swapchain.c @@ -0,0 +1,261 @@ +// Copyright 2020-2024, Collabora, Ltd. +// Copyright 2025-2026, NVIDIA CORPORATION. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Swapchain handling functions called from generated dispatch function. + * @author Pete Black + * @author Jakob Bornecrantz + * @author Korcan Hussein + * @ingroup ipc_server + */ + +#include "util/u_misc.h" +#include "util/u_trace_marker.h" + +#include "server/ipc_server.h" +#include "ipc_server_generated.h" +#include "xrt/xrt_results.h" + + +/* + * + * Helper functions. + * + */ + +static xrt_result_t +validate_swapchain_state(volatile struct ipc_client_state *ics, uint32_t *out_index) +{ + // Our handle is just the index for now. + uint32_t index = 0; + for (; index < IPC_MAX_CLIENT_SWAPCHAINS; index++) { + if (!ics->swapchain_data[index].active) { + break; + } + } + + if (index >= IPC_MAX_CLIENT_SWAPCHAINS) { + IPC_ERROR(ics->server, "Too many swapchains!"); + return XRT_ERROR_IPC_FAILURE; + } + + *out_index = index; + + return XRT_SUCCESS; +} + +static void +set_swapchain_info(volatile struct ipc_client_state *ics, + uint32_t index, + const struct xrt_swapchain_create_info *info, + struct xrt_swapchain *xsc) +{ + ics->xscs[index] = xsc; + ics->swapchain_data[index].active = true; + ics->swapchain_data[index].width = info->width; + ics->swapchain_data[index].height = info->height; + ics->swapchain_data[index].format = info->format; + ics->swapchain_data[index].image_count = xsc->image_count; +} + + +/* + * + * Handle functions. + * + */ + +xrt_result_t +ipc_handle_swapchain_get_properties(volatile struct ipc_client_state *ics, + const struct xrt_swapchain_create_info *info, + struct xrt_swapchain_create_properties *xsccp) +{ + IPC_TRACE_MARKER(); + + if (ics->xc == NULL) { + return XRT_ERROR_IPC_SESSION_NOT_CREATED; + } + + return xrt_comp_get_swapchain_create_properties(ics->xc, info, xsccp); +} + +xrt_result_t +ipc_handle_swapchain_create(volatile struct ipc_client_state *ics, + const struct xrt_swapchain_create_info *info, + uint32_t *out_id, + uint32_t *out_image_count, + uint64_t *out_size, + bool *out_use_dedicated_allocation, + uint32_t max_handle_capacity, + xrt_graphics_buffer_handle_t *out_handles, + uint32_t *out_handle_count) +{ + IPC_TRACE_MARKER(); + + xrt_result_t xret = XRT_SUCCESS; + uint32_t index = 0; + + xret = validate_swapchain_state(ics, &index); + if (xret != XRT_SUCCESS) { + return xret; + } + + // Create the swapchain + struct xrt_swapchain *xsc = NULL; // Has to be NULL. + xret = xrt_comp_create_swapchain(ics->xc, info, &xsc); + if (xret != XRT_SUCCESS) { + if (xret == XRT_ERROR_SWAPCHAIN_FLAG_VALID_BUT_UNSUPPORTED) { + IPC_WARN(ics->server, + "xrt_comp_create_swapchain: Attempted to create valid, but unsupported swapchain"); + } else { + IPC_ERROR(ics->server, "Error xrt_comp_create_swapchain failed!"); + } + return xret; + } + + // It's now safe to increment the number of swapchains. + ics->swapchain_count++; + + IPC_TRACE(ics->server, "Created swapchain %d.", index); + + set_swapchain_info(ics, index, info, xsc); + + // return our result to the caller. + struct xrt_swapchain_native *xscn = (struct xrt_swapchain_native *)xsc; + + // Limit checking + assert(xsc->image_count <= XRT_MAX_SWAPCHAIN_IMAGES); + assert(xsc->image_count <= max_handle_capacity); + + for (size_t i = 1; i < xsc->image_count; i++) { + assert(xscn->images[0].size == xscn->images[i].size); + assert(xscn->images[0].use_dedicated_allocation == xscn->images[i].use_dedicated_allocation); + } + + // Assuming all images allocated in the same swapchain have the same allocation requirements. + *out_size = xscn->images[0].size; + *out_use_dedicated_allocation = xscn->images[0].use_dedicated_allocation; + *out_id = index; + *out_image_count = xsc->image_count; + + // Setup the fds. + *out_handle_count = xsc->image_count; + for (size_t i = 0; i < xsc->image_count; i++) { + out_handles[i] = xscn->images[i].handle; + } + + return XRT_SUCCESS; +} + +xrt_result_t +ipc_handle_swapchain_import(volatile struct ipc_client_state *ics, + const struct xrt_swapchain_create_info *info, + const struct ipc_arg_swapchain_from_native *args, + uint32_t *out_id, + const xrt_graphics_buffer_handle_t *handles, + uint32_t handle_count) +{ + IPC_TRACE_MARKER(); + + xrt_result_t xret = XRT_SUCCESS; + uint32_t index = 0; + + xret = validate_swapchain_state(ics, &index); + if (xret != XRT_SUCCESS) { + return xret; + } + + struct xrt_image_native xins[XRT_MAX_SWAPCHAIN_IMAGES] = XRT_STRUCT_INIT; + for (uint32_t i = 0; i < handle_count; i++) { + xins[i].handle = handles[i]; + xins[i].size = args->sizes[i]; +#if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_WIN32_HANDLE) + // DXGI handles need to be dealt with differently, they are identified + // by having their lower bit set to 1 during transfer + if ((size_t)xins[i].handle & 1) { + xins[i].handle = (HANDLE)((size_t)xins[i].handle - 1); + xins[i].is_dxgi_handle = true; + } +#endif + } + + // create the swapchain + struct xrt_swapchain *xsc = NULL; + xret = xrt_comp_import_swapchain(ics->xc, info, xins, handle_count, &xsc); + if (xret != XRT_SUCCESS) { + return xret; + } + + // It's now safe to increment the number of swapchains. + ics->swapchain_count++; + + IPC_TRACE(ics->server, "Created swapchain %d.", index); + + set_swapchain_info(ics, index, info, xsc); + *out_id = index; + + return XRT_SUCCESS; +} + +xrt_result_t +ipc_handle_swapchain_wait_image(volatile struct ipc_client_state *ics, uint32_t id, int64_t timeout_ns, uint32_t index) +{ + if (ics->xc == NULL) { + return XRT_ERROR_IPC_SESSION_NOT_CREATED; + } + + //! @todo Look up the index. + uint32_t sc_index = id; + struct xrt_swapchain *xsc = ics->xscs[sc_index]; + + return xrt_swapchain_wait_image(xsc, timeout_ns, index); +} + +xrt_result_t +ipc_handle_swapchain_acquire_image(volatile struct ipc_client_state *ics, uint32_t id, uint32_t *out_index) +{ + if (ics->xc == NULL) { + return XRT_ERROR_IPC_SESSION_NOT_CREATED; + } + + //! @todo Look up the index. + uint32_t sc_index = id; + struct xrt_swapchain *xsc = ics->xscs[sc_index]; + + xrt_swapchain_acquire_image(xsc, out_index); + + return XRT_SUCCESS; +} + +xrt_result_t +ipc_handle_swapchain_release_image(volatile struct ipc_client_state *ics, uint32_t id, uint32_t index) +{ + if (ics->xc == NULL) { + return XRT_ERROR_IPC_SESSION_NOT_CREATED; + } + + //! @todo Look up the index. + uint32_t sc_index = id; + struct xrt_swapchain *xsc = ics->xscs[sc_index]; + + xrt_swapchain_release_image(xsc, index); + + return XRT_SUCCESS; +} + +xrt_result_t +ipc_handle_swapchain_destroy(volatile struct ipc_client_state *ics, uint32_t id) +{ + if (ics->xc == NULL) { + return XRT_ERROR_IPC_SESSION_NOT_CREATED; + } + + ics->swapchain_count--; + + // Drop our reference, does NULL checking. Cast away volatile. + xrt_swapchain_reference((struct xrt_swapchain **)&ics->xscs[id], NULL); + ics->swapchain_data[id].active = false; + + return XRT_SUCCESS; +} -- 2.51.2