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/vk_sdk_platform.h" 34 #include <vulkan/vulkan.h> 35 #include <vulkan/vk_layer.h> 36 #include <vulkan/vk_icd.h> 37 38 #include "vk_loader_platform.h" 39 #include "vk_loader_layer.h" 40 #include "vk_layer_dispatch_table.h" 41 #include "vk_loader_extensions.h" 42 43 typedef enum VkStringErrorFlagBits { 44 VK_STRING_ERROR_NONE = 0x00000000, 45 VK_STRING_ERROR_LENGTH = 0x00000001, 46 VK_STRING_ERROR_BAD_DATA = 0x00000002, 47 VK_STRING_ERROR_NULL_PTR = 0x00000004, 48 } VkStringErrorFlagBits; 49 typedef VkFlags VkStringErrorFlags; 50 51 static const int MaxLoaderStringLength = 256; // 0xFF; 52 static const unsigned char UTF8_ONE_BYTE_CODE = 192; // 0xC0; 53 static const unsigned char UTF8_ONE_BYTE_MASK = 224; // 0xE0; 54 static const unsigned char UTF8_TWO_BYTE_CODE = 224; // 0xE0; 55 static const unsigned char UTF8_TWO_BYTE_MASK = 240; // 0xF0; 56 static const unsigned char UTF8_THREE_BYTE_CODE = 240; // 0xF0; 57 static const unsigned char UTF8_THREE_BYTE_MASK = 248; // 0xF8; 58 static const unsigned char UTF8_DATA_BYTE_CODE = 128; // 0x80; 59 static const unsigned char UTF8_DATA_BYTE_MASK = 192; // 0xC0; 60 61 // form of all dynamic lists/arrays 62 // only the list element should be changed 63 struct loader_generic_list { 64 size_t capacity; 65 uint32_t count; 66 void *list; 67 }; 68 69 struct loader_extension_list { 70 size_t capacity; 71 uint32_t count; 72 VkExtensionProperties *list; 73 }; 74 75 struct loader_dev_ext_props { 76 VkExtensionProperties props; 77 uint32_t entrypoint_count; 78 char **entrypoints; 79 }; 80 81 struct loader_device_extension_list { 82 size_t capacity; 83 uint32_t count; 84 struct loader_dev_ext_props *list; 85 }; 86 87 struct loader_name_value { 88 char name[MAX_STRING_SIZE]; 89 char value[MAX_STRING_SIZE]; 90 }; 91 92 struct loader_layer_functions { 93 char str_gipa[MAX_STRING_SIZE]; 94 char str_gdpa[MAX_STRING_SIZE]; 95 char str_negotiate_interface[MAX_STRING_SIZE]; 96 PFN_vkNegotiateLoaderLayerInterfaceVersion negotiate_layer_interface; 97 PFN_vkGetInstanceProcAddr get_instance_proc_addr; 98 PFN_vkGetDeviceProcAddr get_device_proc_addr; 99 PFN_GetPhysicalDeviceProcAddr get_physical_device_proc_addr; 100 }; 101 102 struct loader_override_expiration { 103 uint16_t year; 104 uint8_t month; 105 uint8_t day; 106 uint8_t hour; 107 uint8_t minute; 108 }; 109 110 // This structure is used to store the json file version in a more manageable way. 111 typedef struct { 112 uint16_t major; 113 uint16_t minor; 114 uint16_t patch; 115 } loader_api_version; 116 117 // Enumeration used to clearly identify reason for library load failure. 118 enum loader_layer_library_status { 119 LOADER_LAYER_LIB_NOT_LOADED = 0, 120 121 LOADER_LAYER_LIB_SUCCESS_LOADED = 1, 122 123 LOADER_LAYER_LIB_ERROR_WRONG_BIT_TYPE = 20, 124 LOADER_LAYER_LIB_ERROR_FAILED_TO_LOAD = 21, 125 }; 126 127 enum layer_type_flags { 128 VK_LAYER_TYPE_FLAG_INSTANCE_LAYER = 0x1, // If not set, indicates Device layer 129 VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER = 0x2, // If not set, indicates Implicit layer 130 VK_LAYER_TYPE_FLAG_META_LAYER = 0x4, // If not set, indicates standard layer 131 }; 132 133 struct loader_layer_properties { 134 VkLayerProperties info; 135 enum layer_type_flags type_flags; 136 uint32_t interface_version; // PFN_vkNegotiateLoaderLayerInterfaceVersion 137 char manifest_file_name[MAX_STRING_SIZE]; 138 char lib_name[MAX_STRING_SIZE]; 139 enum loader_layer_library_status lib_status; 140 loader_platform_dl_handle lib_handle; 141 struct loader_layer_functions functions; 142 struct loader_extension_list instance_extension_list; 143 struct loader_device_extension_list device_extension_list; 144 struct loader_name_value disable_env_var; 145 struct loader_name_value enable_env_var; 146 uint32_t num_component_layers; 147 char (*component_layer_names)[MAX_STRING_SIZE]; 148 struct { 149 char enumerate_instance_extension_properties[MAX_STRING_SIZE]; 150 char enumerate_instance_layer_properties[MAX_STRING_SIZE]; 151 char enumerate_instance_version[MAX_STRING_SIZE]; 152 } pre_instance_functions; 153 uint32_t num_override_paths; 154 char (*override_paths)[MAX_STRING_SIZE]; 155 bool is_override; 156 bool has_expiration; 157 struct loader_override_expiration expiration; 158 bool keep; 159 uint32_t num_blacklist_layers; 160 char (*blacklist_layer_names)[MAX_STRING_SIZE]; 161 uint32_t num_app_key_paths; 162 char (*app_key_paths)[MAX_STRING_SIZE]; 163 }; 164 165 struct loader_layer_list { 166 size_t capacity; 167 uint32_t count; 168 struct loader_layer_properties *list; 169 }; 170 171 typedef VkResult(VKAPI_PTR *PFN_vkDevExt)(VkDevice device); 172 173 struct loader_dev_dispatch_table { 174 VkLayerDispatchTable core_dispatch; 175 PFN_vkDevExt ext_dispatch[MAX_NUM_UNKNOWN_EXTS]; 176 }; 177 178 // per CreateDevice structure 179 struct loader_device { 180 struct loader_dev_dispatch_table loader_dispatch; 181 VkDevice chain_device; // device object from the dispatch chain 182 VkDevice icd_device; // device object from the icd 183 struct loader_physical_device_term *phys_dev_term; 184 185 // List of activated layers. 186 // app_ is the version based on exactly what the application asked for. 187 // This is what must be returned to the application on Enumerate calls. 188 // expanded_ is the version based on expanding meta-layers into their 189 // individual component layers. This is what is used internally. 190 struct loader_layer_list app_activated_layer_list; 191 struct loader_layer_list expanded_activated_layer_list; 192 193 VkAllocationCallbacks alloc_callbacks; 194 195 // List of activated device extensions that have terminators implemented in the loader 196 struct { 197 bool khr_swapchain_enabled; 198 bool khr_display_swapchain_enabled; 199 bool khr_device_group_enabled; 200 bool ext_debug_marker_enabled; 201 bool ext_debug_utils_enabled; 202 bool ext_full_screen_exclusive_enabled; 203 } extensions; 204 205 struct loader_device *next; 206 }; 207 208 // Per ICD information 209 210 // Per ICD structure 211 struct loader_icd_term { 212 // pointers to find other structs 213 const struct loader_scanned_icd *scanned_icd; 214 const struct loader_instance *this_instance; 215 struct loader_device *logical_device_list; 216 VkInstance instance; // instance object from the icd 217 struct loader_icd_term_dispatch dispatch; 218 219 struct loader_icd_term *next; 220 221 PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS]; 222 bool supports_get_dev_prop_2; 223 }; 224 225 // Per ICD library structure 226 struct loader_icd_tramp_list { 227 size_t capacity; 228 uint32_t count; 229 struct loader_scanned_icd *scanned_list; 230 }; 231 232 struct loader_instance_dispatch_table { 233 VkLayerInstanceDispatchTable layer_inst_disp; // must be first entry in structure 234 235 // Physical device functions unknown to the loader 236 PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS]; 237 }; 238 239 // Unique magic number identifier for the loader. 240 #define LOADER_MAGIC_NUMBER 0x10ADED010110ADEDUL 241 242 // Per instance structure 243 struct loader_instance { 244 struct loader_instance_dispatch_table *disp; // must be first entry in structure 245 uint64_t magic; // Should be LOADER_MAGIC_NUMBER 246 247 // Vulkan API version the app is intending to use. 248 loader_api_version app_api_version; 249 250 // We need to manually track physical devices over time. If the user 251 // re-queries the information, we don't want to delete old data or 252 // create new data unless necessary. 253 uint32_t total_gpu_count; 254 uint32_t phys_dev_count_term; 255 struct loader_physical_device_term **phys_devs_term; 256 uint32_t phys_dev_count_tramp; 257 struct loader_physical_device_tramp **phys_devs_tramp; 258 259 // We also need to manually track physical device groups, but we don't need 260 // loader specific structures since we have that content in the physical 261 // device stored internal to the public structures. 262 uint32_t phys_dev_group_count_term; 263 struct VkPhysicalDeviceGroupProperties **phys_dev_groups_term; 264 265 struct loader_instance *next; 266 267 uint32_t total_icd_count; 268 struct loader_icd_term *icd_terms; 269 struct loader_icd_tramp_list icd_tramp_list; 270 271 uint32_t dev_ext_disp_function_count; 272 char *dev_ext_disp_functions[MAX_NUM_UNKNOWN_EXTS]; 273 uint32_t phys_dev_ext_disp_function_count; 274 char *phys_dev_ext_disp_functions[MAX_NUM_UNKNOWN_EXTS]; 275 276 struct loader_msg_callback_map_entry *icd_msg_callback_map; 277 278 struct loader_layer_list instance_layer_list; 279 bool override_layer_present; 280 281 // List of activated layers. 282 // app_ is the version based on exactly what the application asked for. 283 // This is what must be returned to the application on Enumerate calls. 284 // expanded_ is the version based on expanding meta-layers into their 285 // individual component layers. This is what is used internally. 286 struct loader_layer_list app_activated_layer_list; 287 struct loader_layer_list expanded_activated_layer_list; 288 289 VkInstance instance; // layers/ICD instance returned to trampoline 290 291 struct loader_extension_list ext_list; // icds and loaders extensions 292 struct loader_instance_extension_enables enabled_known_extensions; 293 294 // Stores debug callbacks - used in the log 295 VkLayerDbgFunctionNode *DbgFunctionHead; 296 297 // Stores the debug callbacks set during instance creation 298 // These are kept separate because they aren't to be used outside of instance creation and destruction 299 // So they are swapped out at the end of instance creation and swapped in at instance destruction 300 VkLayerDbgFunctionNode *InstanceCreationDeletionDebugFunctionHead; 301 302 VkAllocationCallbacks alloc_callbacks; 303 304 bool portability_enumeration_enabled; 305 306 bool wsi_surface_enabled; 307 #ifdef VK_USE_PLATFORM_WIN32_KHR 308 bool wsi_win32_surface_enabled; 309 #endif 310 #ifdef VK_USE_PLATFORM_WAYLAND_KHR 311 bool wsi_wayland_surface_enabled; 312 #endif 313 #ifdef VK_USE_PLATFORM_XCB_KHR 314 bool wsi_xcb_surface_enabled; 315 #endif 316 #ifdef VK_USE_PLATFORM_XLIB_KHR 317 bool wsi_xlib_surface_enabled; 318 #endif 319 #ifdef VK_USE_PLATFORM_DIRECTFB_EXT 320 bool wsi_directfb_surface_enabled; 321 #endif 322 #ifdef VK_USE_PLATFORM_ANDROID_KHR 323 bool wsi_android_surface_enabled; 324 #endif 325 #ifdef VK_USE_PLATFORM_OHOS 326 bool wsi_ohos_surface_enabled; 327 #endif 328 #ifdef VK_USE_PLATFORM_MACOS_MVK 329 bool wsi_macos_surface_enabled; 330 #endif 331 #ifdef VK_USE_PLATFORM_IOS_MVK 332 bool wsi_ios_surface_enabled; 333 #endif 334 #ifdef VK_USE_PLATFORM_GGP 335 bool wsi_ggp_surface_enabled; 336 #endif 337 bool wsi_headless_surface_enabled; 338 #if defined(VK_USE_PLATFORM_METAL_EXT) 339 bool wsi_metal_surface_enabled; 340 #endif 341 #ifdef VK_USE_PLATFORM_FUCHSIA 342 bool wsi_imagepipe_surface_enabled; 343 #endif 344 #ifdef VK_USE_PLATFORM_SCREEN_QNX 345 bool wsi_screen_surface_enabled; 346 #endif 347 #ifdef VK_USE_PLATFORM_VI_NN 348 bool wsi_vi_surface_enabled; 349 #endif 350 bool wsi_display_enabled; 351 bool wsi_display_props2_enabled; 352 bool create_terminator_invalid_extension; 353 bool supports_get_dev_prop_2; 354 }; 355 356 // VkPhysicalDevice requires special treatment by loader. Firstly, terminator 357 // code must be able to get the struct loader_icd_term to call into the proper 358 // driver (multiple ICD/gpu case). This can be accomplished by wrapping the 359 // created VkPhysicalDevice in loader terminate_EnumeratePhysicalDevices(). 360 // Secondly, the loader must be able to handle wrapped by layer VkPhysicalDevice 361 // in trampoline code. This implies, that the loader trampoline code must also 362 // wrap the VkPhysicalDevice object in trampoline code. Thus, loader has to 363 // wrap the VkPhysicalDevice created object twice. In trampoline code it can't 364 // rely on the terminator object wrapping since a layer may also wrap. Since 365 // trampoline code wraps the VkPhysicalDevice this means all loader trampoline 366 // code that passes a VkPhysicalDevice should unwrap it. 367 368 // Unique identifier for physical devices 369 #define PHYS_TRAMP_MAGIC_NUMBER 0x10ADED020210ADEDUL 370 371 // Per enumerated PhysicalDevice structure, used to wrap in trampoline code and 372 // also same structure used to wrap in terminator code 373 struct loader_physical_device_tramp { 374 struct loader_instance_dispatch_table *disp; // must be first entry in structure 375 struct loader_instance *this_instance; 376 uint64_t magic; // Should be PHYS_TRAMP_MAGIC_NUMBER 377 VkPhysicalDevice phys_dev; // object from layers/loader terminator 378 }; 379 380 // Per enumerated PhysicalDevice structure, used to wrap in terminator code 381 struct loader_physical_device_term { 382 struct loader_instance_dispatch_table *disp; // must be first entry in structure 383 struct loader_icd_term *this_icd_term; 384 uint8_t icd_index; 385 VkPhysicalDevice phys_dev; // object from ICD 386 }; 387 388 #ifdef LOADER_ENABLE_LINUX_SORT 389 // Structure for storing the relevent device information for selecting a device. 390 // NOTE: Needs to be defined here so we can store this content in the term structrue 391 // for quicker sorting. 392 struct LinuxSortedDeviceInfo { 393 // Associated Vulkan Physical Device 394 VkPhysicalDevice physical_device; 395 bool default_device; 396 397 // Loader specific items about the driver providing support for this physical device 398 uint32_t icd_index; 399 struct loader_icd_term *icd_term; 400 401 // Some generic device properties 402 VkPhysicalDeviceType device_type; 403 char device_name[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE]; 404 uint32_t vendor_id; 405 uint32_t device_id; 406 407 // PCI information on this device 408 bool has_pci_bus_info; 409 uint32_t pci_domain; 410 uint32_t pci_bus; 411 uint32_t pci_device; 412 uint32_t pci_function; 413 }; 414 #endif // LOADER_ENABLE_LINUX_SORT 415 416 // Per enumerated PhysicalDeviceGroup structure, used to wrap in terminator code 417 struct loader_physical_device_group_term { 418 struct loader_icd_term *this_icd_term; 419 uint8_t icd_index; 420 VkPhysicalDeviceGroupProperties group_props; 421 #ifdef LOADER_ENABLE_LINUX_SORT 422 struct LinuxSortedDeviceInfo internal_device_info[VK_MAX_DEVICE_GROUP_SIZE]; 423 #endif // LOADER_ENABLE_LINUX_SORT 424 }; 425 426 struct loader_struct { 427 struct loader_instance *instances; 428 }; 429 430 struct loader_scanned_icd { 431 char *lib_name; 432 loader_platform_dl_handle handle; 433 uint32_t api_version; 434 uint32_t interface_version; 435 PFN_vkGetInstanceProcAddr GetInstanceProcAddr; 436 PFN_GetPhysicalDeviceProcAddr GetPhysicalDeviceProcAddr; 437 PFN_vkCreateInstance CreateInstance; 438 PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties; 439 #if defined(VK_USE_PLATFORM_WIN32_KHR) 440 PFN_vk_icdEnumerateAdapterPhysicalDevices EnumerateAdapterPhysicalDevices; 441 #endif 442 }; 443 444 enum loader_data_files_type { 445 LOADER_DATA_FILE_MANIFEST_DRIVER = 0, 446 LOADER_DATA_FILE_MANIFEST_EXPLICIT_LAYER, 447 LOADER_DATA_FILE_MANIFEST_IMPLICIT_LAYER, 448 LOADER_DATA_FILE_NUM_TYPES // Not a real field, used for possible loop terminator 449 }; 450 451 struct loader_data_files { 452 uint32_t count; 453 uint32_t alloc_count; 454 char **filename_list; 455 }; 456 457 struct loader_phys_dev_per_icd { 458 uint32_t device_count; 459 VkPhysicalDevice *physical_devices; 460 uint32_t icd_index; 461 struct loader_icd_term *icd_term; 462 }; 463 464 struct loader_msg_callback_map_entry { 465 VkDebugReportCallbackEXT icd_obj; 466 VkDebugReportCallbackEXT loader_obj; 467 }; 468