1 /* 2 * Copyright © 2021 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 #ifndef VK_INSTANCE_H 24 #define VK_INSTANCE_H 25 26 #include "vk_dispatch_table.h" 27 #include "vk_extensions.h" 28 #include "vk_object.h" 29 30 #include "c11/threads.h" 31 #include "util/list.h" 32 #include "util/u_debug.h" 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 struct vk_app_info { 39 /** VkApplicationInfo::pApplicationName */ 40 const char* app_name; 41 42 /** VkApplicationInfo::applicationVersion */ 43 uint32_t app_version; 44 45 /** VkApplicationInfo::pEngineName */ 46 const char* engine_name; 47 48 /** VkApplicationInfo::engineVersion */ 49 uint32_t engine_version; 50 51 /** VkApplicationInfo::apiVersion or `VK_API_VERSION_1_0` 52 * 53 * If the application does not provide a `pApplicationInfo` or the 54 * `apiVersion` field is 0, this is set to `VK_API_VERSION_1_0`. 55 */ 56 uint32_t api_version; 57 }; 58 59 struct _drmDevice; 60 struct vk_physical_device; 61 62 enum vk_trace_mode { 63 /** Radeon Memory Visualizer */ 64 VK_TRACE_MODE_RMV = 1 << 0, 65 66 /** Number of common trace modes. */ 67 VK_TRACE_MODE_COUNT = 1, 68 }; 69 70 /** Base struct for all `VkInstance` implementations 71 * 72 * This contains data structures necessary for detecting enabled extensions, 73 * handling entrypoint dispatch, and implementing `vkGetInstanceProcAddr()`. 74 * It also contains data copied from the `VkInstanceCreateInfo` such as the 75 * application information. 76 */ 77 struct vk_instance { 78 struct vk_object_base base; 79 80 /** Allocator used when creating this instance 81 * 82 * This is used as a fall-back for when a NULL pAllocator is passed into a 83 * device-level create function such as vkCreateImage(). 84 */ 85 VkAllocationCallbacks alloc; 86 87 /** VkInstanceCreateInfo::pApplicationInfo */ 88 struct vk_app_info app_info; 89 90 /** Table of all supported instance extensions 91 * 92 * This is the static const struct passed by the driver as the 93 * `supported_extensions` parameter to `vk_instance_init()`. 94 */ 95 const struct vk_instance_extension_table *supported_extensions; 96 97 /** Table of all enabled instance extensions 98 * 99 * This is generated automatically as part of `vk_instance_init()` from 100 * VkInstanceCreateInfo::ppEnabledExtensionNames. 101 */ 102 struct vk_instance_extension_table enabled_extensions; 103 104 /** Instance-level dispatch table */ 105 struct vk_instance_dispatch_table dispatch_table; 106 107 /* VK_EXT_debug_report debug callbacks */ 108 struct { 109 mtx_t callbacks_mutex; 110 struct list_head callbacks; 111 } debug_report; 112 113 /* VK_EXT_debug_utils */ 114 struct { 115 /* These callbacks are only used while creating or destroying an 116 * instance 117 */ 118 struct list_head instance_callbacks; 119 mtx_t callbacks_mutex; 120 /* Persistent callbacks */ 121 struct list_head callbacks; 122 } debug_utils; 123 124 /** List of all physical devices and callbacks 125 * 126 * This is used for automatic physical device creation, 127 * deletion and enumeration. 128 */ 129 struct { 130 struct list_head list; 131 bool enumerated; 132 133 /** Enumerate physical devices for this instance 134 * 135 * The driver can implement this callback for custom physical device 136 * enumeration. The returned value must be a valid return code of 137 * vkEnumeratePhysicalDevices. 138 * 139 * Note that the loader calls vkEnumeratePhysicalDevices of all 140 * installed ICDs and fails device enumeration when any of the calls 141 * fails. The driver should return VK_SUCCESS when it does not find any 142 * compatible device. 143 * 144 * If this callback is not set, try_create_for_drm will be used for 145 * enumeration. 146 */ 147 VkResult (*enumerate)(struct vk_instance *instance); 148 149 /** Try to create a physical device for a drm device 150 * 151 * The returned value must be a valid return code of 152 * vkEnumeratePhysicalDevices, or VK_ERROR_INCOMPATIBLE_DRIVER. When 153 * VK_ERROR_INCOMPATIBLE_DRIVER is returned, the error and the drm 154 * device are silently ignored. 155 */ 156 VkResult (*try_create_for_drm)(struct vk_instance *instance, 157 struct _drmDevice *device, 158 struct vk_physical_device **out); 159 160 /** Handle the destruction of a physical device 161 * 162 * This callback has to be implemented when using common physical device 163 * management. The device pointer and any resource allocated for the 164 * device should be freed here. 165 */ 166 void (*destroy)(struct vk_physical_device *pdevice); 167 168 mtx_t mutex; 169 } physical_devices; 170 171 /** Enabled tracing modes */ 172 uint64_t trace_mode; 173 174 uint32_t trace_frame; 175 char *trace_trigger_file; 176 }; 177 178 VK_DEFINE_HANDLE_CASTS(vk_instance, base, VkInstance, 179 VK_OBJECT_TYPE_INSTANCE); 180 181 /** Initialize a vk_instance 182 * 183 * Along with initializing the data structures in `vk_instance`, this function 184 * validates the Vulkan version number provided by the client and checks that 185 * every extension specified by 186 * `VkInstanceCreateInfo::ppEnabledExtensionNames` is actually supported by 187 * the implementation and returns `VK_ERROR_EXTENSION_NOT_PRESENT` if an 188 * unsupported extension is requested. 189 * 190 * @param[out] instance The instance to initialize 191 * @param[in] supported_extensions Table of all instance extensions supported 192 * by this instance 193 * @param[in] dispatch_table Instance-level dispatch table 194 * @param[in] pCreateInfo VkInstanceCreateInfo pointer passed to 195 * `vkCreateInstance()` 196 * @param[in] alloc Allocation callbacks used to create this 197 * instance; must not be `NULL` 198 */ 199 VkResult MUST_CHECK 200 vk_instance_init(struct vk_instance *instance, 201 const struct vk_instance_extension_table *supported_extensions, 202 const struct vk_instance_dispatch_table *dispatch_table, 203 const VkInstanceCreateInfo *pCreateInfo, 204 const VkAllocationCallbacks *alloc); 205 206 /** Tears down a vk_instance 207 * 208 * @param[out] instance The instance to tear down 209 */ 210 void 211 vk_instance_finish(struct vk_instance *instance); 212 213 /** Implementaiton of vkEnumerateInstanceExtensionProperties() */ 214 VkResult 215 vk_enumerate_instance_extension_properties( 216 const struct vk_instance_extension_table *supported_extensions, 217 uint32_t *pPropertyCount, 218 VkExtensionProperties *pProperties); 219 220 /** Implementaiton of vkGetInstanceProcAddr() */ 221 PFN_vkVoidFunction 222 vk_instance_get_proc_addr(const struct vk_instance *instance, 223 const struct vk_instance_entrypoint_table *entrypoints, 224 const char *name); 225 226 /** Unchecked version of vk_instance_get_proc_addr 227 * 228 * This is identical to `vk_instance_get_proc_addr()` except that it doesn't 229 * check whether extensions are enabled before returning function pointers. 230 * This is useful in window-system code where we may use extensions without 231 * the client explicitly enabling them. 232 */ 233 PFN_vkVoidFunction 234 vk_instance_get_proc_addr_unchecked(const struct vk_instance *instance, 235 const char *name); 236 237 /** Implementaiton of vk_icdGetPhysicalDeviceProcAddr() */ 238 PFN_vkVoidFunction 239 vk_instance_get_physical_device_proc_addr(const struct vk_instance *instance, 240 const char *name); 241 242 void 243 vk_instance_add_driver_trace_modes(struct vk_instance *instance, 244 const struct debug_control *modes); 245 246 #ifdef __cplusplus 247 } 248 #endif 249 250 #endif /* VK_INSTANCE_H */ 251