The open source OpenXR runtime
1// Copyright 2019-2022, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Vulkan code for tests.
6 *
7 * @author Jakob Bornecrantz <jakob@collabora.com>
8 * @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
9 * @author Rylie Pavlik <rylie.pavlik@collabora.com>
10 */
11#pragma once
12
13#include <xrt/xrt_config_have.h>
14#include <xrt/xrt_deleters.hpp>
15
16#ifdef XRT_HAVE_VULKAN
17#include <xrt/xrt_config_vulkan.h>
18#include <xrt/xrt_vulkan_includes.h>
19#include <vk/vk_helpers.h>
20#include <util/comp_vulkan.h>
21#include <util/u_string_list.hpp>
22
23
24static const char *instance_extensions_common[] = {
25 VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, //
26 VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, //
27 VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, //
28 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, //
29};
30
31static const char *required_device_extensions[] = {
32 VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, //
33 VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME, //
34 VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, //
35 VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME, //
36 VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, //
37
38// Platform version of "external_memory"
39#if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_FD)
40 VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
41
42#elif defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_AHARDWAREBUFFER)
43 VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME,
44 VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME,
45 VK_KHR_MAINTENANCE_1_EXTENSION_NAME,
46 VK_KHR_BIND_MEMORY_2_EXTENSION_NAME,
47 VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME,
48
49#elif defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_WIN32_HANDLE)
50 VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME,
51
52#else
53#error "Need port!"
54#endif
55
56// Platform version of "external_fence" and "external_semaphore"
57#if defined(XRT_GRAPHICS_SYNC_HANDLE_IS_FD) // Optional
58
59#elif defined(XRT_GRAPHICS_SYNC_HANDLE_IS_WIN32_HANDLE)
60 VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, //
61 VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME, //
62
63#else
64#error "Need port!"
65#endif
66};
67
68static const char *optional_device_extensions[] = {
69#ifdef VK_KHR_timeline_semaphore
70 VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME,
71#endif
72};
73using unique_string_list =
74 std::unique_ptr<u_string_list, xrt::deleters::ptr_ptr_deleter<u_string_list, &u_string_list_destroy>>;
75
76struct VkBundleDestroyer
77{
78 void
79 operator()(struct vk_bundle *vk) const
80 {
81 if (!vk) {
82 return;
83 }
84 if (vk->device != VK_NULL_HANDLE) {
85 vk->vkDestroyDevice(vk->device, NULL);
86 vk->device = VK_NULL_HANDLE;
87 }
88 if (vk->instance != VK_NULL_HANDLE) {
89 vk->vkDestroyInstance(vk->instance, NULL);
90 vk->instance = VK_NULL_HANDLE;
91 }
92 delete vk;
93 }
94};
95
96static void
97vk_bundle_destroy(struct vk_bundle *vk)
98{
99 if (!vk) {
100 return;
101 }
102 if (vk->device != VK_NULL_HANDLE) {
103 vk->vkDestroyDevice(vk->device, NULL);
104 vk->device = VK_NULL_HANDLE;
105 }
106 if (vk->instance != VK_NULL_HANDLE) {
107 vk->vkDestroyInstance(vk->instance, NULL);
108 vk->instance = VK_NULL_HANDLE;
109 }
110 vk_deinit_mutex(vk);
111 delete vk;
112}
113// using unique_vk_bundle = std::unique_ptr<struct vk_bundle, VkBundleDestroyer>;
114using unique_vk_bundle =
115 std::unique_ptr<struct vk_bundle, xrt::deleters::ptr_deleter<struct vk_bundle, &vk_bundle_destroy>>;
116
117static inline bool
118vktest_init_bundle(struct vk_bundle *vk)
119{
120 // every backend needs at least the common extensions
121 unique_string_list required_instance_ext_list{
122 u_string_list_create_from_array(instance_extensions_common, ARRAY_SIZE(instance_extensions_common))};
123
124 unique_string_list optional_instance_ext_list{u_string_list_create()};
125
126 unique_string_list required_device_extension_list{
127 u_string_list_create_from_array(required_device_extensions, ARRAY_SIZE(required_device_extensions))};
128
129 unique_string_list optional_device_extension_list{
130 u_string_list_create_from_array(optional_device_extensions, ARRAY_SIZE(optional_device_extensions))};
131
132 U_ZERO(vk);
133 comp_vulkan_arguments args{VK_MAKE_VERSION(1, 0, 0),
134 vkGetInstanceProcAddr,
135 required_instance_ext_list.get(),
136 optional_instance_ext_list.get(),
137 required_device_extension_list.get(),
138 optional_device_extension_list.get(),
139 U_LOGGING_TRACE,
140 false /* only_compute_queue */,
141 true /*timeline_semaphore*/,
142 -1,
143 -1};
144 comp_vulkan_results results{};
145 bool success = comp_vulkan_init_bundle(vk, &args, &results);
146
147 // success = success && VK_SUCCESS == vk_init_mutex(vk);
148 return success;
149}
150
151#else
152
153struct vk_bundle
154{
155};
156
157using unique_vk_bundle = std::unique_ptr<struct vk_bundle>;
158
159#endif
160
161static unique_vk_bundle
162makeVkBundle()
163{
164 unique_vk_bundle ret{new vk_bundle};
165 return ret;
166}