Something went wrong. Try again.
The open source OpenXR runtime
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197// Copyright 2022-2024, Collabora, Ltd.// Copyright 2025-2026, NVIDIA CORPORATION.// SPDX-License-Identifier: BSL-1.0/*! * @file * @brief Basic Vulkan compositor tests. * @author Rylie Pavlik <rylie.pavlik@collabora.com> * @author Korcan Hussein <korcan.hussein@collabora.com> */
#include "mock/mock_compositor.h"#include "client/comp_vk_client.h"#include "xrt/xrt_results.h"#include <vulkan/vulkan_core.h>
#undef Always#undef None#undef Success
#include "catch_amalgamated.hpp"#include "util/comp_vulkan.h"#include "util/u_logging.h"#include "util/u_extension_list.h"#include "vk/vk_helpers.h"#include "xrt/xrt_compositor.h"#include <xrt/xrt_deleters.hpp>
#include <memory>#include <iostream>
using unique_native_compositor = std::unique_ptr<xrt_compositor_native, xrt::deleters::ptr_ptr_deleter<xrt_compositor_native, &xrt_comp_native_destroy>>;
// clang-format off#define COMP_INSTANCE_EXTENSIONS_COMMON \ VK_EXT_DEBUG_REPORT_EXTENSION_NAME, \ VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, \ VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, \ VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, \ VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, \ VK_KHR_SURFACE_EXTENSION_NAME// clang-format on
static const char *instance_extensions_common[] = { COMP_INSTANCE_EXTENSIONS_COMMON,};static const char *required_device_extensions[] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, // VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, // VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME, // VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, // VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME, // VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, //
// Platform version of "external_memory"#if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_FD) VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
#elif defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_AHARDWAREBUFFER) VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_KHR_MAINTENANCE_1_EXTENSION_NAME, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME,
#elif defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_WIN32_HANDLE) VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME,
#else#error "Need port!"#endif
// Platform version of "external_fence" and "external_semaphore"#if defined(XRT_GRAPHICS_SYNC_HANDLE_IS_FD) // Optional
#elif defined(XRT_GRAPHICS_SYNC_HANDLE_IS_WIN32_HANDLE) VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME,
#else#error "Need port!"#endif};
using unique_string_list = std::unique_ptr<u_extension_list, xrt::deleters::ptr_ptr_deleter<u_extension_list, &u_extension_list_destroy>>;
static voidxrt_comp_vk_destroy(struct xrt_compositor **ptr_xc){ if (!ptr_xc) { return; } xrt_compositor *xc = *ptr_xc; xrt_comp_destroy(&xc);}
using unique_compositor_vk = std::unique_ptr<struct xrt_compositor, xrt::deleters::ptr_ptr_deleter<struct xrt_compositor, &xrt_comp_vk_destroy>>;
TEST_CASE("client_compositor", "[.][needgpu]"){ xrt_compositor_native *xcn = mock_create_native_compositor(); struct mock_compositor *mc = mock_compositor(&(xcn->base));
// every backend needs at least the common extensions unique_string_list required_instance_ext_list{ u_extension_list_create_from_array(instance_extensions_common, ARRAY_SIZE(instance_extensions_common))};
unique_string_list optional_instance_ext_list{u_extension_list_create()};
unique_string_list required_device_extension_list{ u_extension_list_create_from_array(required_device_extensions, ARRAY_SIZE(required_device_extensions))};
unique_string_list optional_device_extension_list{u_extension_list_create()};
comp_vulkan_arguments args{ VK_MAKE_VERSION(1, 0, 0), vkGetInstanceProcAddr, required_instance_ext_list.get(), optional_instance_ext_list.get(), required_device_extension_list.get(), optional_device_extension_list.get(), U_LOGGING_TRACE, false /* only_compute_queue */, true /*timeline_semaphore*/, -1, false, xrt_uuid_t{}, -1, }; vk_bundle vk_bundle_storage{}; vk_bundle *vk = &vk_bundle_storage; comp_vulkan_results results{}; REQUIRE(comp_vulkan_init_bundle(vk, &args, &results)); struct xrt_compositor *xcvk = xrt_gfx_vk_provider_create( // xcn, // vk->instance, // vkGetInstanceProcAddr, // vk->physical_device, // vk->device,#if defined(XRT_GRAPHICS_SYNC_HANDLE_IS_FD) // vk->external.fence_sync_fd, // vk->external.binary_semaphore_sync_fd, // vk->external.timeline_semaphore_sync_fd, //#elif defined(XRT_GRAPHICS_SYNC_HANDLE_IS_WIN32_HANDLE) vk->external.fence_win32_handle, // vk->external.binary_semaphore_win32_handle, // vk->external.timeline_semaphore_win32_handle, //#else#error "Need port for fence sync handles checkers"#endif vk->has_KHR_image_format_list, // image_format_list_enabled false, // debug_utils_enabled false, // renderdoc_enabled vk->main_queue->family_index, // vk->main_queue->index); struct xrt_compositor *xc = xcvk;
SECTION("CreateSwapchain calls native create") { bool nativeCreateCalled = false; mc->userdata = &nativeCreateCalled; mc->compositor_hooks.create_swapchain = [](struct mock_compositor *mc, struct mock_compositor_swapchain *mcsc, const struct xrt_swapchain_create_info *info, struct xrt_swapchain **out_xsc) { *static_cast<bool *>(mc->userdata) = true; return XRT_SUCCESS; }; xrt_swapchain_create_info xsci{}; xsci.format = VK_FORMAT_B8G8R8A8_SRGB; xsci.bits = (xrt_swapchain_usage_bits)(XRT_SWAPCHAIN_USAGE_COLOR | XRT_SWAPCHAIN_USAGE_SAMPLED); xsci.sample_count = 1; xsci.width = 800; xsci.height = 600; xsci.face_count = 1; xsci.array_size = 1; xsci.mip_count = 1;
struct xrt_swapchain *xsc = nullptr; // This will fail because the mock compositor doesn't actually create images for Vulkan to import, but // it will get far enough to trigger our hook and update the flag. xrt_comp_create_swapchain(xc, &xsci, &xsc); CHECK(nativeCreateCalled); xrt_swapchain_reference(&xsc, nullptr); }
xrt_comp_destroy(&xc);
vk_deinit_mutex(vk);
xrt_comp_native_destroy(&xcn);}