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