1 /* 2 * 3 * Copyright (c) 2014-2021 The Khronos Group Inc. 4 * Copyright (c) 2014-2021 Valve Corporation 5 * Copyright (c) 2014-2021 LunarG, Inc. 6 * Copyright (C) 2015 Google Inc. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 * Author: Jon Ashburn <jon@lunarg.com> 21 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com> 22 * Author: Chia-I Wu <olvaffe@gmail.com> 23 * Author: Chia-I Wu <olv@lunarg.com> 24 * Author: Mark Lobodzinski <mark@LunarG.com> 25 * Author: Lenny Komow <lenny@lunarg.com> 26 * Author: Charles Giessen <charles@lunarg.com> 27 * 28 */ 29 30 #pragma once 31 32 #include "vk_loader_platform.h" 33 34 enum layer_type_flags { 35 VK_LAYER_TYPE_FLAG_INSTANCE_LAYER = 0x1, // If not set, indicates Device layer 36 VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER = 0x2, // If not set, indicates Implicit layer 37 VK_LAYER_TYPE_FLAG_META_LAYER = 0x4, // If not set, indicates standard layer 38 }; 39 40 typedef enum VkStringErrorFlagBits { 41 VK_STRING_ERROR_NONE = 0x00000000, 42 VK_STRING_ERROR_LENGTH = 0x00000001, 43 VK_STRING_ERROR_BAD_DATA = 0x00000002, 44 VK_STRING_ERROR_NULL_PTR = 0x00000004, 45 } VkStringErrorFlagBits; 46 typedef VkFlags VkStringErrorFlags; 47 48 static const int MaxLoaderStringLength = 256; 49 static const char UTF8_ONE_BYTE_CODE = 0xC0; 50 static const char UTF8_ONE_BYTE_MASK = 0xE0; 51 static const char UTF8_TWO_BYTE_CODE = 0xE0; 52 static const char UTF8_TWO_BYTE_MASK = 0xF0; 53 static const char UTF8_THREE_BYTE_CODE = 0xF0; 54 static const char UTF8_THREE_BYTE_MASK = 0xF8; 55 static const char UTF8_DATA_BYTE_CODE = 0x80; 56 static const char UTF8_DATA_BYTE_MASK = 0xC0; 57 58 // form of all dynamic lists/arrays 59 // only the list element should be changed 60 struct loader_generic_list { 61 size_t capacity; 62 uint32_t count; 63 void *list; 64 }; 65 66 struct loader_extension_list { 67 size_t capacity; 68 uint32_t count; 69 VkExtensionProperties *list; 70 }; 71 72 struct loader_dev_ext_props { 73 VkExtensionProperties props; 74 uint32_t entrypoint_count; 75 char **entrypoints; 76 }; 77 78 struct loader_device_extension_list { 79 size_t capacity; 80 uint32_t count; 81 struct loader_dev_ext_props *list; 82 }; 83 84 struct loader_name_value { 85 char name[MAX_STRING_SIZE]; 86 char value[MAX_STRING_SIZE]; 87 }; 88 89 struct loader_layer_functions { 90 char str_gipa[MAX_STRING_SIZE]; 91 char str_gdpa[MAX_STRING_SIZE]; 92 char str_negotiate_interface[MAX_STRING_SIZE]; 93 PFN_vkNegotiateLoaderLayerInterfaceVersion negotiate_layer_interface; 94 PFN_vkGetInstanceProcAddr get_instance_proc_addr; 95 PFN_vkGetDeviceProcAddr get_device_proc_addr; 96 PFN_GetPhysicalDeviceProcAddr get_physical_device_proc_addr; 97 }; 98 99 struct loader_override_expiration { 100 uint16_t year; 101 uint8_t month; 102 uint8_t day; 103 uint8_t hour; 104 uint8_t minute; 105 }; 106 107 struct loader_layer_properties { 108 VkLayerProperties info; 109 enum layer_type_flags type_flags; 110 uint32_t interface_version; // PFN_vkNegotiateLoaderLayerInterfaceVersion 111 char manifest_file_name[MAX_STRING_SIZE]; 112 char lib_name[MAX_STRING_SIZE]; 113 loader_platform_dl_handle lib_handle; 114 struct loader_layer_functions functions; 115 struct loader_extension_list instance_extension_list; 116 struct loader_device_extension_list device_extension_list; 117 struct loader_name_value disable_env_var; 118 struct loader_name_value enable_env_var; 119 uint32_t num_component_layers; 120 char (*component_layer_names)[MAX_STRING_SIZE]; 121 struct { 122 char enumerate_instance_extension_properties[MAX_STRING_SIZE]; 123 char enumerate_instance_layer_properties[MAX_STRING_SIZE]; 124 char enumerate_instance_version[MAX_STRING_SIZE]; 125 } pre_instance_functions; 126 uint32_t num_override_paths; 127 char (*override_paths)[MAX_STRING_SIZE]; 128 bool is_override; 129 bool has_expiration; 130 struct loader_override_expiration expiration; 131 bool keep; 132 uint32_t num_blacklist_layers; 133 char (*blacklist_layer_names)[MAX_STRING_SIZE]; 134 uint32_t num_app_key_paths; 135 char (*app_key_paths)[MAX_STRING_SIZE]; 136 }; 137 138 struct loader_layer_list { 139 size_t capacity; 140 uint32_t count; 141 struct loader_layer_properties *list; 142 }; 143 144 struct loader_dispatch_hash_list { 145 size_t capacity; 146 uint32_t count; 147 uint32_t *index; // index into the dev_ext dispatch table 148 }; 149 150 // loader_dispatch_hash_entry and loader_dev_ext_dispatch_table.dev_ext have 151 // one to one correspondence; one loader_dispatch_hash_entry for one dev_ext 152 // dispatch entry. 153 // Also have a one to one correspondence with functions in dev_ext_trampoline.c 154 struct loader_dispatch_hash_entry { 155 char *func_name; 156 struct loader_dispatch_hash_list list; // to handle hashing collisions 157 }; 158 159 typedef VkResult(VKAPI_PTR *PFN_vkDevExt)(VkDevice device); 160 struct loader_dev_ext_dispatch_table { 161 PFN_vkDevExt dev_ext[MAX_NUM_UNKNOWN_EXTS]; 162 }; 163 164 struct loader_dev_dispatch_table { 165 VkLayerDispatchTable core_dispatch; 166 struct loader_dev_ext_dispatch_table ext_dispatch; 167 }; 168 169 // per CreateDevice structure 170 struct loader_device { 171 struct loader_dev_dispatch_table loader_dispatch; 172 VkDevice chain_device; // device object from the dispatch chain 173 VkDevice icd_device; // device object from the icd 174 struct loader_physical_device_term *phys_dev_term; 175 176 // List of activated layers. 177 // app_ is the version based on exactly what the application asked for. 178 // This is what must be returned to the application on Enumerate calls. 179 // expanded_ is the version based on expanding meta-layers into their 180 // individual component layers. This is what is used internally. 181 struct loader_layer_list app_activated_layer_list; 182 struct loader_layer_list expanded_activated_layer_list; 183 184 VkAllocationCallbacks alloc_callbacks; 185 186 // List of activated device extensions that have terminators implemented in the loader 187 struct { 188 bool khr_swapchain_enabled; 189 bool khr_display_swapchain_enabled; 190 bool khr_device_group_enabled; 191 bool ext_debug_marker_enabled; 192 bool ext_debug_utils_enabled; 193 bool ext_full_screen_exclusive_enabled; 194 } extensions; 195 196 struct loader_device *next; 197 }; 198 199 // Per ICD information 200 201 // Per ICD structure 202 struct loader_icd_term { 203 // pointers to find other structs 204 const struct loader_scanned_icd *scanned_icd; 205 const struct loader_instance *this_instance; 206 struct loader_device *logical_device_list; 207 VkInstance instance; // instance object from the icd 208 struct loader_icd_term_dispatch dispatch; 209 210 struct loader_icd_term *next; 211 212 PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS]; 213 }; 214 215 // Per ICD library structure 216 struct loader_icd_tramp_list { 217 size_t capacity; 218 uint32_t count; 219 struct loader_scanned_icd *scanned_list; 220 }; 221 222 struct loader_instance_dispatch_table { 223 VkLayerInstanceDispatchTable layer_inst_disp; // must be first entry in structure 224 225 // Physical device functions unknown to the loader 226 PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS]; 227 }; 228 229 // Unique magic number identifier for the loader. 230 #define LOADER_MAGIC_NUMBER 0x10ADED010110ADEDUL 231 232 // Per instance structure 233 struct loader_instance { 234 struct loader_instance_dispatch_table *disp; // must be first entry in structure 235 uint64_t magic; // Should be LOADER_MAGIC_NUMBER 236 237 // Vulkan API version the app is intending to use. 238 uint16_t app_api_major_version; 239 uint16_t app_api_minor_version; 240 241 // We need to manually track physical devices over time. If the user 242 // re-queries the information, we don't want to delete old data or 243 // create new data unless necessary. 244 uint32_t total_gpu_count; 245 uint32_t phys_dev_count_term; 246 struct loader_physical_device_term **phys_devs_term; 247 uint32_t phys_dev_count_tramp; 248 struct loader_physical_device_tramp **phys_devs_tramp; 249 250 // We also need to manually track physical device groups, but we don't need 251 // loader specific structures since we have that content in the physical 252 // device stored internal to the public structures. 253 uint32_t phys_dev_group_count_term; 254 struct VkPhysicalDeviceGroupProperties **phys_dev_groups_term; 255 uint32_t phys_dev_group_count_tramp; 256 struct VkPhysicalDeviceGroupProperties **phys_dev_groups_tramp; 257 258 struct loader_instance *next; 259 260 uint32_t total_icd_count; 261 struct loader_icd_term *icd_terms; 262 struct loader_icd_tramp_list icd_tramp_list; 263 264 struct loader_dispatch_hash_entry dev_ext_disp_hash[MAX_NUM_UNKNOWN_EXTS]; 265 struct loader_dispatch_hash_entry phys_dev_ext_disp_hash[MAX_NUM_UNKNOWN_EXTS]; 266 267 struct loader_msg_callback_map_entry *icd_msg_callback_map; 268 269 struct loader_layer_list instance_layer_list; 270 bool override_layer_present; 271 272 // List of activated layers. 273 // app_ is the version based on exactly what the application asked for. 274 // This is what must be returned to the application on Enumerate calls. 275 // expanded_ is the version based on expanding meta-layers into their 276 // individual component layers. This is what is used internally. 277 struct loader_layer_list app_activated_layer_list; 278 struct loader_layer_list expanded_activated_layer_list; 279 280 VkInstance instance; // layers/ICD instance returned to trampoline 281 282 struct loader_extension_list ext_list; // icds and loaders extensions 283 union loader_instance_extension_enables enabled_known_extensions; 284 285 VkLayerDbgFunctionNode *DbgFunctionHead; 286 uint32_t num_tmp_report_callbacks; 287 VkDebugReportCallbackCreateInfoEXT *tmp_report_create_infos; 288 VkDebugReportCallbackEXT *tmp_report_callbacks; 289 uint32_t num_tmp_messengers; 290 VkDebugUtilsMessengerCreateInfoEXT *tmp_messenger_create_infos; 291 VkDebugUtilsMessengerEXT *tmp_messengers; 292 293 VkAllocationCallbacks alloc_callbacks; 294 295 bool wsi_surface_enabled; 296 #ifdef VK_USE_PLATFORM_WIN32_KHR 297 bool wsi_win32_surface_enabled; 298 #endif 299 #ifdef VK_USE_PLATFORM_WAYLAND_KHR 300 bool wsi_wayland_surface_enabled; 301 #endif 302 #ifdef VK_USE_PLATFORM_XCB_KHR 303 bool wsi_xcb_surface_enabled; 304 #endif 305 #ifdef VK_USE_PLATFORM_XLIB_KHR 306 bool wsi_xlib_surface_enabled; 307 #endif 308 #ifdef VK_USE_PLATFORM_DIRECTFB_EXT 309 bool wsi_directfb_surface_enabled; 310 #endif 311 #ifdef VK_USE_PLATFORM_ANDROID_KHR 312 bool wsi_android_surface_enabled; 313 #endif 314 #ifdef VK_USE_PLATFORM_MACOS_MVK 315 bool wsi_macos_surface_enabled; 316 #endif 317 #ifdef VK_USE_PLATFORM_IOS_MVK 318 bool wsi_ios_surface_enabled; 319 #endif 320 #ifdef VK_USE_PLATFORM_GGP 321 bool wsi_ggp_surface_enabled; 322 #endif 323 bool wsi_headless_surface_enabled; 324 #if defined(VK_USE_PLATFORM_METAL_EXT) 325 bool wsi_metal_surface_enabled; 326 #endif 327 #ifdef VK_USE_PLATFORM_FUCHSIA 328 bool wsi_imagepipe_surface_enabled; 329 #endif 330 #ifdef VK_USE_PLATFORM_SCREEN_QNX 331 bool wsi_screen_surface_enabled; 332 #endif 333 bool wsi_display_enabled; 334 bool wsi_display_props2_enabled; 335 bool create_terminator_invalid_extension; 336 }; 337 338 // VkPhysicalDevice requires special treatment by loader. Firstly, terminator 339 // code must be able to get the struct loader_icd_term to call into the proper 340 // driver (multiple ICD/gpu case). This can be accomplished by wrapping the 341 // created VkPhysicalDevice in loader terminate_EnumeratePhysicalDevices(). 342 // Secondly, the loader must be able to handle wrapped by layer VkPhysicalDevice 343 // in trampoline code. This implies, that the loader trampoline code must also 344 // wrap the VkPhysicalDevice object in trampoline code. Thus, loader has to 345 // wrap the VkPhysicalDevice created object twice. In trampoline code it can't 346 // rely on the terminator object wrapping since a layer may also wrap. Since 347 // trampoline code wraps the VkPhysicalDevice this means all loader trampoline 348 // code that passes a VkPhysicalDevice should unwrap it. 349 350 // Unique identifier for physical devices 351 #define PHYS_TRAMP_MAGIC_NUMBER 0x10ADED020210ADEDUL 352 353 // Per enumerated PhysicalDevice structure, used to wrap in trampoline code and 354 // also same structure used to wrap in terminator code 355 struct loader_physical_device_tramp { 356 struct loader_instance_dispatch_table *disp; // must be first entry in structure 357 struct loader_instance *this_instance; 358 uint64_t magic; // Should be PHYS_TRAMP_MAGIC_NUMBER 359 VkPhysicalDevice phys_dev; // object from layers/loader terminator 360 }; 361 362 // Per enumerated PhysicalDevice structure, used to wrap in terminator code 363 struct loader_physical_device_term { 364 struct loader_instance_dispatch_table *disp; // must be first entry in structure 365 struct loader_icd_term *this_icd_term; 366 uint8_t icd_index; 367 VkPhysicalDevice phys_dev; // object from ICD 368 }; 369 370 struct loader_struct { 371 struct loader_instance *instances; 372 }; 373 374 struct loader_scanned_icd { 375 char *lib_name; 376 loader_platform_dl_handle handle; 377 uint32_t api_version; 378 uint32_t interface_version; 379 PFN_vkGetInstanceProcAddr GetInstanceProcAddr; 380 PFN_GetPhysicalDeviceProcAddr GetPhysicalDeviceProcAddr; 381 PFN_vkCreateInstance CreateInstance; 382 PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties; 383 #if defined(VK_USE_PLATFORM_WIN32_KHR) 384 PFN_vk_icdEnumerateAdapterPhysicalDevices EnumerateAdapterPhysicalDevices; 385 #endif 386 }; 387 388 struct loader_phys_dev_per_icd { 389 uint32_t count; 390 VkPhysicalDevice *phys_devs; 391 struct loader_icd_term *this_icd_term; 392 }; 393 394 enum loader_data_files_type { 395 LOADER_DATA_FILE_MANIFEST_ICD = 0, 396 LOADER_DATA_FILE_MANIFEST_LAYER, 397 LOADER_DATA_FILE_NUM_TYPES // Not a real field, used for possible loop terminator 398 }; 399 400 struct loader_data_files { 401 uint32_t count; 402 uint32_t alloc_count; 403 char **filename_list; 404 }; 405 406 struct LoaderSortedPhysicalDevice { 407 uint32_t device_count; 408 VkPhysicalDevice *physical_devices; 409 uint32_t icd_index; 410 struct loader_icd_term *icd_term; 411 }; 412 413 struct loader_msg_callback_map_entry { 414 VkDebugReportCallbackEXT icd_obj; 415 VkDebugReportCallbackEXT loader_obj; 416 };