1 /* 2 * 3 * Copyright (c) 2014-2022 The Khronos Group Inc. 4 * Copyright (c) 2014-2022 Valve Corporation 5 * Copyright (c) 2014-2022 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 "vulkan/vk_platform.h" 33 #include <vulkan/vulkan.h> 34 #include <vulkan/vk_layer.h> 35 #include <vulkan/vk_icd.h> 36 37 #include "vk_loader_platform.h" 38 #include "vk_loader_layer.h" 39 #include "vk_layer_dispatch_table.h" 40 #include "vk_loader_extensions.h" 41 42 #include "settings.h" 43 44 typedef enum VkStringErrorFlagBits { 45 VK_STRING_ERROR_NONE = 0x00000000, 46 VK_STRING_ERROR_LENGTH = 0x00000001, 47 VK_STRING_ERROR_BAD_DATA = 0x00000002, 48 VK_STRING_ERROR_NULL_PTR = 0x00000004, 49 } VkStringErrorFlagBits; 50 typedef VkFlags VkStringErrorFlags; 51 52 static const int MaxLoaderStringLength = 256; // 0xFF; 53 static const unsigned char UTF8_ONE_BYTE_CODE = 192; // 0xC0; 54 static const unsigned char UTF8_ONE_BYTE_MASK = 224; // 0xE0; 55 static const unsigned char UTF8_TWO_BYTE_CODE = 224; // 0xE0; 56 static const unsigned char UTF8_TWO_BYTE_MASK = 240; // 0xF0; 57 static const unsigned char UTF8_THREE_BYTE_CODE = 240; // 0xF0; 58 static const unsigned char UTF8_THREE_BYTE_MASK = 248; // 0xF8; 59 static const unsigned char UTF8_DATA_BYTE_CODE = 128; // 0x80; 60 static const unsigned char UTF8_DATA_BYTE_MASK = 192; // 0xC0; 61 62 // form of all dynamic lists/arrays 63 // only the list element should be changed 64 struct loader_generic_list { 65 size_t capacity; 66 uint32_t count; 67 void *list; 68 }; 69 70 struct loader_string_list { 71 uint32_t allocated_count; 72 uint32_t count; 73 char **list; 74 }; 75 76 struct loader_extension_list { 77 size_t capacity; 78 uint32_t count; 79 VkExtensionProperties *list; 80 }; 81 82 struct loader_dev_ext_props { 83 VkExtensionProperties props; 84 struct loader_string_list entrypoints; 85 }; 86 87 struct loader_device_extension_list { 88 size_t capacity; 89 uint32_t count; 90 struct loader_dev_ext_props *list; 91 }; 92 93 struct loader_used_object_status { 94 VkBool32 status; 95 VkAllocationCallbacks allocation_callbacks; 96 }; 97 98 struct loader_used_object_list { 99 size_t capacity; 100 uint32_t padding; // count variable isn't used 101 struct loader_used_object_status *list; 102 }; 103 104 struct loader_surface_allocation { 105 VkSurfaceKHR surface; 106 VkAllocationCallbacks allocation_callbacks; 107 }; 108 109 struct loader_surface_list { 110 size_t capacity; 111 uint32_t padding; // count variable isn't used 112 VkSurfaceKHR *list; 113 }; 114 115 struct loader_debug_utils_messenger_list { 116 size_t capacity; 117 uint32_t padding; // count variable isn't used 118 VkDebugUtilsMessengerEXT *list; 119 }; 120 121 struct loader_debug_report_callback_list { 122 size_t capacity; 123 uint32_t padding; // count variable isn't used 124 VkDebugReportCallbackEXT *list; 125 }; 126 127 struct loader_name_value { 128 char *name; 129 char *value; 130 }; 131 132 struct loader_layer_functions { 133 char *str_gipa; 134 char *str_gdpa; 135 char *str_negotiate_interface; 136 PFN_vkNegotiateLoaderLayerInterfaceVersion negotiate_layer_interface; 137 PFN_vkGetInstanceProcAddr get_instance_proc_addr; 138 PFN_vkGetDeviceProcAddr get_device_proc_addr; 139 PFN_GetPhysicalDeviceProcAddr get_physical_device_proc_addr; 140 }; 141 142 // This structure is used to store the json file version in a more manageable way. 143 typedef struct { 144 uint16_t major; 145 uint16_t minor; 146 uint16_t patch; 147 } loader_api_version; 148 149 // Enumeration used to clearly identify reason for library load failure. 150 enum loader_layer_library_status { 151 LOADER_LAYER_LIB_NOT_LOADED = 0, 152 153 LOADER_LAYER_LIB_SUCCESS_LOADED = 1, 154 155 LOADER_LAYER_LIB_ERROR_WRONG_BIT_TYPE = 20, 156 LOADER_LAYER_LIB_ERROR_FAILED_TO_LOAD = 21, 157 LOADER_LAYER_LIB_ERROR_OUT_OF_MEMORY = 22, 158 }; 159 160 enum layer_type_flags { 161 VK_LAYER_TYPE_FLAG_INSTANCE_LAYER = 0x1, // If not set, indicates Device layer 162 VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER = 0x2, // If not set, indicates Implicit layer 163 VK_LAYER_TYPE_FLAG_META_LAYER = 0x4, // If not set, indicates standard layer 164 }; 165 166 enum loader_layer_enabled_by_what { 167 ENABLED_BY_WHAT_UNSET, // default value indicates this field hasn't been filled in 168 ENABLED_BY_WHAT_LOADER_SETTINGS_FILE, 169 ENABLED_BY_WHAT_IMPLICIT_LAYER, 170 ENABLED_BY_WHAT_VK_INSTANCE_LAYERS, 171 ENABLED_BY_WHAT_VK_LOADER_LAYERS_ENABLE, 172 ENABLED_BY_WHAT_IN_APPLICATION_API, 173 ENABLED_BY_WHAT_META_LAYER, 174 }; 175 176 struct loader_layer_properties { 177 VkLayerProperties info; 178 enum layer_type_flags type_flags; 179 enum loader_settings_layer_control settings_control_value; 180 181 uint32_t interface_version; // PFN_vkNegotiateLoaderLayerInterfaceVersion 182 char *manifest_file_name; 183 char *lib_name; 184 enum loader_layer_library_status lib_status; 185 enum loader_layer_enabled_by_what enabled_by_what; 186 loader_platform_dl_handle lib_handle; 187 struct loader_layer_functions functions; 188 struct loader_extension_list instance_extension_list; 189 struct loader_device_extension_list device_extension_list; 190 struct loader_name_value disable_env_var; 191 struct loader_name_value enable_env_var; 192 struct loader_string_list component_layer_names; 193 struct { 194 char *enumerate_instance_extension_properties; 195 char *enumerate_instance_layer_properties; 196 char *enumerate_instance_version; 197 } pre_instance_functions; 198 struct loader_string_list override_paths; 199 bool is_override; 200 bool keep; 201 struct loader_string_list blacklist_layer_names; 202 struct loader_string_list app_key_paths; 203 }; 204 205 // Stores a list of loader_layer_properties 206 struct loader_layer_list { 207 size_t capacity; 208 uint32_t count; 209 struct loader_layer_properties *list; 210 }; 211 212 // Stores a list of pointers to loader_layer_properties 213 // Used for app_activated_layer_list and expanded_activated_layer_list 214 struct loader_pointer_layer_list { 215 size_t capacity; 216 uint32_t count; 217 struct loader_layer_properties **list; 218 }; 219 220 typedef VkResult(VKAPI_PTR *PFN_vkDevExt)(VkDevice device); 221 222 struct loader_dev_dispatch_table { 223 VkLayerDispatchTable core_dispatch; 224 PFN_vkDevExt ext_dispatch[MAX_NUM_UNKNOWN_EXTS]; 225 struct loader_device_terminator_dispatch extension_terminator_dispatch; 226 }; 227 228 // per CreateDevice structure 229 struct loader_device { 230 struct loader_dev_dispatch_table loader_dispatch; 231 VkDevice chain_device; // device object from the dispatch chain 232 VkDevice icd_device; // device object from the icd 233 struct loader_physical_device_term *phys_dev_term; 234 235 VkAllocationCallbacks alloc_callbacks; 236 237 // List of activated device extensions that layers support (but not necessarily the driver which have functions that require 238 // trampolines to work correctly. EX - vkDebugMarkerSetObjectNameEXT can name wrapped handles like instance, physical device, 239 // or surface 240 struct { 241 bool ext_debug_marker_enabled; 242 bool ext_debug_utils_enabled; 243 } layer_extensions; 244 245 // List of activated device extensions that have terminators implemented in the loader 246 struct { 247 bool khr_swapchain_enabled; 248 bool khr_display_swapchain_enabled; 249 bool khr_device_group_enabled; 250 bool ext_debug_marker_enabled; 251 bool ext_debug_utils_enabled; 252 bool ext_full_screen_exclusive_enabled; 253 bool version_1_1_enabled; 254 bool version_1_2_enabled; 255 bool version_1_3_enabled; 256 } driver_extensions; 257 258 struct loader_device *next; 259 260 // Makes vkGetDeviceProcAddr check if core functions are supported by the current app_api_version. 261 // Only set to true if VK_KHR_maintenance5 is enabled. 262 bool should_ignore_device_commands_from_newer_version; 263 }; 264 265 // Per ICD information 266 267 // Per ICD structure 268 struct loader_icd_term { 269 // pointers to find other structs 270 const struct loader_scanned_icd *scanned_icd; 271 const struct loader_instance *this_instance; 272 struct loader_device *logical_device_list; 273 VkInstance instance; // instance object from the icd 274 struct loader_icd_term_dispatch dispatch; 275 276 struct loader_icd_term *next; 277 278 PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS]; 279 bool supports_get_dev_prop_2; 280 bool supports_ext_surface_maintenance_1; 281 282 uint32_t physical_device_count; 283 284 struct loader_surface_list surface_list; 285 struct loader_debug_utils_messenger_list debug_utils_messenger_list; 286 struct loader_debug_report_callback_list debug_report_callback_list; 287 }; 288 289 // Per ICD library structure 290 struct loader_icd_tramp_list { 291 size_t capacity; 292 uint32_t count; 293 struct loader_scanned_icd *scanned_list; 294 }; 295 296 struct loader_instance_dispatch_table { 297 VkLayerInstanceDispatchTable layer_inst_disp; // must be first entry in structure 298 299 // Physical device functions unknown to the loader 300 PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS]; 301 }; 302 303 // Unique magic number identifier for the loader. 304 #define LOADER_MAGIC_NUMBER 0x10ADED010110ADEDUL 305 306 // Per instance structure 307 struct loader_instance { 308 struct loader_instance_dispatch_table *disp; // must be first entry in structure 309 uint64_t magic; // Should be LOADER_MAGIC_NUMBER 310 311 // Store all the terminators for instance functions in case a layer queries one *after* vkCreateInstance 312 VkLayerInstanceDispatchTable terminator_dispatch; 313 314 // Vulkan API version the app is intending to use. 315 loader_api_version app_api_version; 316 317 // We need to manually track physical devices over time. If the user 318 // re-queries the information, we don't want to delete old data or 319 // create new data unless necessary. 320 uint32_t total_gpu_count; 321 uint32_t phys_dev_count_term; 322 struct loader_physical_device_term **phys_devs_term; 323 uint32_t phys_dev_count_tramp; 324 struct loader_physical_device_tramp **phys_devs_tramp; 325 326 // We also need to manually track physical device groups, but we don't need 327 // loader specific structures since we have that content in the physical 328 // device stored internal to the public structures. 329 uint32_t phys_dev_group_count_term; 330 struct VkPhysicalDeviceGroupProperties **phys_dev_groups_term; 331 332 struct loader_instance *next; 333 334 uint32_t icd_terms_count; 335 struct loader_icd_term *icd_terms; 336 struct loader_icd_tramp_list icd_tramp_list; 337 338 // Must store the strings inside loader_instance directly - since the asm code will offset into 339 // loader_instance to get the function name 340 uint32_t dev_ext_disp_function_count; 341 char *dev_ext_disp_functions[MAX_NUM_UNKNOWN_EXTS]; 342 uint32_t phys_dev_ext_disp_function_count; 343 char *phys_dev_ext_disp_functions[MAX_NUM_UNKNOWN_EXTS]; 344 345 struct loader_msg_callback_map_entry *icd_msg_callback_map; 346 347 struct loader_string_list enabled_layer_names; 348 349 struct loader_layer_list instance_layer_list; 350 bool override_layer_present; 351 352 // List of activated layers. 353 // app_ is the version based on exactly what the application asked for. 354 // This is what must be returned to the application on Enumerate calls. 355 // expanded_ is the version based on expanding meta-layers into their 356 // individual component layers. This is what is used internally. 357 struct loader_pointer_layer_list app_activated_layer_list; 358 struct loader_pointer_layer_list expanded_activated_layer_list; 359 360 VkInstance instance; // layers/ICD instance returned to trampoline 361 362 struct loader_extension_list ext_list; // icds and loaders extensions 363 struct loader_instance_extension_enables enabled_known_extensions; 364 365 // Indicates which indices in the array are in-use and which are free to be reused 366 struct loader_used_object_list surfaces_list; 367 struct loader_used_object_list debug_utils_messengers_list; 368 struct loader_used_object_list debug_report_callbacks_list; 369 370 // Stores debug callbacks - used in the log. 371 VkLayerDbgFunctionNode *current_dbg_function_head; // Current head 372 VkLayerDbgFunctionNode *instance_only_dbg_function_head; // Only used for instance create/destroy 373 374 VkAllocationCallbacks alloc_callbacks; 375 376 // Set to true after vkCreateInstance has returned - necessary for loader_gpa_instance_terminator() 377 bool instance_finished_creation; 378 379 loader_settings settings; 380 381 bool portability_enumeration_enabled; 382 bool portability_enumeration_flag_bit_set; 383 bool portability_enumeration_extension_enabled; 384 385 bool wsi_surface_enabled; 386 #if defined(VK_USE_PLATFORM_WIN32_KHR) 387 bool wsi_win32_surface_enabled; 388 #endif 389 #if defined(VK_USE_PLATFORM_WAYLAND_KHR) 390 bool wsi_wayland_surface_enabled; 391 #endif 392 #if defined(VK_USE_PLATFORM_XCB_KHR) 393 bool wsi_xcb_surface_enabled; 394 #endif 395 #if defined(VK_USE_PLATFORM_XLIB_KHR) 396 bool wsi_xlib_surface_enabled; 397 #endif 398 #if defined(VK_USE_PLATFORM_DIRECTFB_EXT) 399 bool wsi_directfb_surface_enabled; 400 #endif 401 #if defined(VK_USE_PLATFORM_ANDROID_KHR) 402 bool wsi_android_surface_enabled; 403 #endif 404 #if defined(VK_USE_PLATFORM_OHOS) 405 bool wsi_ohos_surface_enabled; 406 #endif 407 #if defined(VK_USE_PLATFORM_MACOS_MVK) 408 bool wsi_macos_surface_enabled; 409 #endif 410 #if defined(VK_USE_PLATFORM_IOS_MVK) 411 bool wsi_ios_surface_enabled; 412 #endif 413 #if defined(VK_USE_PLATFORM_GGP) 414 bool wsi_ggp_surface_enabled; 415 #endif 416 bool wsi_headless_surface_enabled; 417 #if defined(VK_USE_PLATFORM_METAL_EXT) 418 bool wsi_metal_surface_enabled; 419 #endif 420 #if defined(VK_USE_PLATFORM_FUCHSIA) 421 bool wsi_imagepipe_surface_enabled; 422 #endif 423 #if defined(VK_USE_PLATFORM_SCREEN_QNX) 424 bool wsi_screen_surface_enabled; 425 #endif 426 #if defined(VK_USE_PLATFORM_VI_NN) 427 bool wsi_vi_surface_enabled; 428 #endif 429 bool wsi_display_enabled; 430 bool wsi_display_props2_enabled; 431 bool create_terminator_invalid_extension; 432 bool supports_get_dev_prop_2; 433 }; 434 435 // VkPhysicalDevice requires special treatment by loader. Firstly, terminator 436 // code must be able to get the struct loader_icd_term to call into the proper 437 // driver (multiple ICD/gpu case). This can be accomplished by wrapping the 438 // created VkPhysicalDevice in loader terminate_EnumeratePhysicalDevices(). 439 // Secondly, the loader must be able to handle wrapped by layer VkPhysicalDevice 440 // in trampoline code. This implies, that the loader trampoline code must also 441 // wrap the VkPhysicalDevice object in trampoline code. Thus, loader has to 442 // wrap the VkPhysicalDevice created object twice. In trampoline code it can't 443 // rely on the terminator object wrapping since a layer may also wrap. Since 444 // trampoline code wraps the VkPhysicalDevice this means all loader trampoline 445 // code that passes a VkPhysicalDevice should unwrap it. 446 447 // Unique identifier for physical devices 448 #define PHYS_TRAMP_MAGIC_NUMBER 0x10ADED020210ADEDUL 449 450 // Per enumerated PhysicalDevice structure, used to wrap in trampoline code and 451 // also same structure used to wrap in terminator code 452 struct loader_physical_device_tramp { 453 struct loader_instance_dispatch_table *disp; // must be first entry in structure 454 struct loader_instance *this_instance; 455 uint64_t magic; // Should be PHYS_TRAMP_MAGIC_NUMBER 456 VkPhysicalDevice phys_dev; // object from layers/loader terminator 457 }; 458 459 // Per enumerated PhysicalDevice structure, used to wrap in terminator code 460 struct loader_physical_device_term { 461 struct loader_instance_dispatch_table *disp; // must be first entry in structure 462 struct loader_icd_term *this_icd_term; 463 VkPhysicalDevice phys_dev; // object from ICD 464 }; 465 466 #if defined(LOADER_ENABLE_LINUX_SORT) 467 // Structure for storing the relevant device information for selecting a device. 468 // NOTE: Needs to be defined here so we can store this content in the term structure 469 // for quicker sorting. 470 struct LinuxSortedDeviceInfo { 471 // Associated Vulkan Physical Device 472 VkPhysicalDevice physical_device; 473 bool default_device; 474 475 // Loader specific items about the driver providing support for this physical device 476 struct loader_icd_term *icd_term; 477 478 // Some generic device properties 479 VkPhysicalDeviceType device_type; 480 char device_name[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE]; 481 uint32_t vendor_id; 482 uint32_t device_id; 483 484 // PCI information on this device 485 bool has_pci_bus_info; 486 uint32_t pci_domain; 487 uint32_t pci_bus; 488 uint32_t pci_device; 489 uint32_t pci_function; 490 }; 491 #endif // LOADER_ENABLE_LINUX_SORT 492 493 // Per enumerated PhysicalDeviceGroup structure, used to wrap in terminator code 494 struct loader_physical_device_group_term { 495 struct loader_icd_term *this_icd_term; 496 VkPhysicalDeviceGroupProperties group_props; 497 #if defined(LOADER_ENABLE_LINUX_SORT) 498 struct LinuxSortedDeviceInfo internal_device_info[VK_MAX_DEVICE_GROUP_SIZE]; 499 #endif // LOADER_ENABLE_LINUX_SORT 500 }; 501 502 struct loader_struct { 503 struct loader_instance *instances; 504 }; 505 506 struct loader_scanned_icd { 507 char *lib_name; 508 loader_platform_dl_handle handle; 509 uint32_t api_version; 510 uint32_t interface_version; 511 PFN_vkGetInstanceProcAddr GetInstanceProcAddr; 512 PFN_GetPhysicalDeviceProcAddr GetPhysicalDeviceProcAddr; 513 PFN_vkCreateInstance CreateInstance; 514 PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties; 515 #if defined(VK_USE_PLATFORM_WIN32_KHR) 516 PFN_vk_icdEnumerateAdapterPhysicalDevices EnumerateAdapterPhysicalDevices; 517 #endif 518 }; 519 520 enum loader_data_files_type { 521 LOADER_DATA_FILE_MANIFEST_DRIVER = 0, 522 LOADER_DATA_FILE_MANIFEST_EXPLICIT_LAYER, 523 LOADER_DATA_FILE_MANIFEST_IMPLICIT_LAYER, 524 LOADER_DATA_FILE_NUM_TYPES // Not a real field, used for possible loop terminator 525 }; 526 527 struct loader_icd_physical_devices { 528 uint32_t device_count; 529 VkPhysicalDevice *physical_devices; 530 struct loader_icd_term *icd_term; 531 #if defined(WIN32) 532 LUID windows_adapter_luid; 533 #endif 534 }; 535 536 struct loader_msg_callback_map_entry { 537 VkDebugReportCallbackEXT icd_obj; 538 VkDebugReportCallbackEXT loader_obj; 539 }; 540 541 typedef enum loader_filter_string_type { 542 FILTER_STRING_FULLNAME = 0, 543 FILTER_STRING_SUBSTRING, 544 FILTER_STRING_PREFIX, 545 FILTER_STRING_SUFFIX, 546 FILTER_STRING_SPECIAL, 547 } loader_filter_string_type; 548 549 struct loader_envvar_filter_value { 550 char value[VK_MAX_EXTENSION_NAME_SIZE]; 551 size_t length; 552 loader_filter_string_type type; 553 }; 554 555 #define MAX_ADDITIONAL_FILTERS 16 556 struct loader_envvar_filter { 557 uint32_t count; 558 struct loader_envvar_filter_value filters[MAX_ADDITIONAL_FILTERS]; 559 }; 560 struct loader_envvar_disable_layers_filter { 561 struct loader_envvar_filter additional_filters; 562 bool disable_all; 563 bool disable_all_implicit; 564 bool disable_all_explicit; 565 }; 566 567 struct loader_envvar_all_filters { 568 struct loader_envvar_filter enable_filter; 569 struct loader_envvar_disable_layers_filter disable_filter; 570 struct loader_envvar_filter allow_filter; 571 }; 572