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