The open source OpenXR runtime
at main 6.9 kB view raw
1// Copyright 2022-2024, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Basic Vulkan compositor tests. 6 * @author Rylie Pavlik <rylie.pavlik@collabora.com> 7 * @author Korcan Hussein <korcan.hussein@collabora.com> 8 */ 9 10 11#include "mock/mock_compositor.h" 12#include "client/comp_vk_client.h" 13#include "xrt/xrt_results.h" 14#include <vulkan/vulkan_core.h> 15 16#undef Always 17#undef None 18#undef Success 19 20#include "catch_amalgamated.hpp" 21#include "util/comp_vulkan.h" 22#include "util/u_logging.h" 23#include "util/u_string_list.h" 24#include "vk/vk_helpers.h" 25#include "xrt/xrt_compositor.h" 26#include <xrt/xrt_deleters.hpp> 27 28#include <memory> 29#include <iostream> 30 31using unique_native_compositor = 32 std::unique_ptr<xrt_compositor_native, 33 xrt::deleters::ptr_ptr_deleter<xrt_compositor_native, &xrt_comp_native_destroy>>; 34 35// clang-format off 36#define COMP_INSTANCE_EXTENSIONS_COMMON \ 37 VK_EXT_DEBUG_REPORT_EXTENSION_NAME, \ 38 VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, \ 39 VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, \ 40 VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, \ 41 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, \ 42 VK_KHR_SURFACE_EXTENSION_NAME 43// clang-format on 44 45static const char *instance_extensions_common[] = { 46 COMP_INSTANCE_EXTENSIONS_COMMON, 47}; 48static const char *required_device_extensions[] = { 49 VK_KHR_SWAPCHAIN_EXTENSION_NAME, // 50 VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, // 51 VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME, // 52 VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, // 53 VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME, // 54 VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, // 55 56// Platform version of "external_memory" 57#if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_FD) 58 VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, 59 60#elif defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_AHARDWAREBUFFER) 61 VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME, 62 VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, 63 VK_KHR_MAINTENANCE_1_EXTENSION_NAME, 64 VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, 65 VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME, 66 67#elif defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_WIN32_HANDLE) 68 VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, 69 70#else 71#error "Need port!" 72#endif 73 74// Platform version of "external_fence" and "external_semaphore" 75#if defined(XRT_GRAPHICS_SYNC_HANDLE_IS_FD) // Optional 76 77#elif defined(XRT_GRAPHICS_SYNC_HANDLE_IS_WIN32_HANDLE) 78 VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, 79 VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME, 80 81#else 82#error "Need port!" 83#endif 84}; 85 86 87using unique_string_list = 88 std::unique_ptr<u_string_list, xrt::deleters::ptr_ptr_deleter<u_string_list, &u_string_list_destroy>>; 89 90static void 91xrt_comp_vk_destroy(struct xrt_compositor_vk **ptr_xcvk) 92{ 93 if (!ptr_xcvk) { 94 return; 95 } 96 xrt_compositor *xc = &(*ptr_xcvk)->base; 97 xrt_comp_destroy(&xc); 98} 99 100using unique_compositor_vk = 101 std::unique_ptr<struct xrt_compositor_vk, 102 xrt::deleters::ptr_ptr_deleter<struct xrt_compositor_vk, &xrt_comp_vk_destroy>>; 103 104TEST_CASE("client_compositor", "[.][needgpu]") 105{ 106 xrt_compositor_native *xcn = mock_create_native_compositor(); 107 struct mock_compositor *mc = mock_compositor(&(xcn->base)); 108 109 // every backend needs at least the common extensions 110 unique_string_list required_instance_ext_list{ 111 u_string_list_create_from_array(instance_extensions_common, ARRAY_SIZE(instance_extensions_common))}; 112 113 unique_string_list optional_instance_ext_list{u_string_list_create()}; 114 115 unique_string_list required_device_extension_list{ 116 u_string_list_create_from_array(required_device_extensions, ARRAY_SIZE(required_device_extensions))}; 117 118 unique_string_list optional_device_extension_list{u_string_list_create()}; 119 120 comp_vulkan_arguments args{VK_MAKE_VERSION(1, 0, 0), 121 vkGetInstanceProcAddr, 122 required_instance_ext_list.get(), 123 optional_instance_ext_list.get(), 124 required_device_extension_list.get(), 125 optional_device_extension_list.get(), 126 U_LOGGING_TRACE, 127 false /* only_compute_queue */, 128 true /*timeline_semaphore*/, 129 -1, 130 -1}; 131 vk_bundle vk_bundle_storage{}; 132 vk_bundle *vk = &vk_bundle_storage; 133 comp_vulkan_results results{}; 134 REQUIRE(comp_vulkan_init_bundle(vk, &args, &results)); 135 struct xrt_compositor_vk *xcvk = xrt_gfx_vk_provider_create( // 136 xcn, // 137 vk->instance, // 138 vkGetInstanceProcAddr, // 139 vk->physical_device, // 140 vk->device, 141#if defined(XRT_GRAPHICS_SYNC_HANDLE_IS_FD) // 142 vk->external.fence_sync_fd, // 143 vk->external.binary_semaphore_sync_fd, // 144 vk->external.timeline_semaphore_sync_fd, // 145#elif defined(XRT_GRAPHICS_SYNC_HANDLE_IS_WIN32_HANDLE) 146 vk->external.fence_win32_handle, // 147 vk->external.binary_semaphore_win32_handle, // 148 vk->external.timeline_semaphore_win32_handle, // 149#else 150#error "Need port for fence sync handles checkers" 151#endif 152 vk->has_KHR_image_format_list, // image_format_list_enabled 153 false, // debug_utils_enabled 154 false, // renderdoc_enabled 155 vk->main_queue->family_index, // 156 vk->main_queue->index); 157 struct xrt_compositor *xc = &xcvk->base; 158 159 SECTION("CreateSwapchain calls native create") 160 { 161 bool nativeCreateCalled = false; 162 mc->userdata = &nativeCreateCalled; 163 mc->compositor_hooks.create_swapchain = 164 [](struct mock_compositor *mc, struct mock_compositor_swapchain *mcsc, 165 const struct xrt_swapchain_create_info *info, struct xrt_swapchain **out_xsc) { 166 *static_cast<bool *>(mc->userdata) = true; 167 return XRT_SUCCESS; 168 }; 169 xrt_swapchain_create_info xsci{}; 170 xsci.format = VK_FORMAT_B8G8R8A8_SRGB; 171 xsci.bits = (xrt_swapchain_usage_bits)(XRT_SWAPCHAIN_USAGE_COLOR | XRT_SWAPCHAIN_USAGE_SAMPLED); 172 xsci.sample_count = 1; 173 xsci.width = 800; 174 xsci.height = 600; 175 xsci.face_count = 1; 176 xsci.array_size = 1; 177 xsci.mip_count = 1; 178 179 struct xrt_swapchain *xsc = nullptr; 180 // This will fail because the mock compositor doesn't actually create images for Vulkan to import, but 181 // it will get far enough to trigger our hook and update the flag. 182 xrt_comp_create_swapchain(xc, &xsci, &xsc); 183 CHECK(nativeCreateCalled); 184 xrt_swapchain_reference(&xsc, nullptr); 185 } 186 187 xrt_comp_destroy(&xc); 188 189 vk_deinit_mutex(vk); 190 191 xrt_comp_native_destroy(&xcn); 192}