1<!-- markdownlint-disable MD041 --> 2[![Khronos Vulkan][1]][2] 3 4[1]: https://vulkan.lunarg.com/img/Vulkan_100px_Dec16.png "https://www.khronos.org/vulkan/" 5[2]: https://www.khronos.org/vulkan/ 6 7# Driver interface to the Vulkan Loader 8[![Creative Commons][3]][4] 9 10<!-- Copyright © 2015-2021 LunarG, Inc. --> 11 12[3]: https://i.creativecommons.org/l/by-nd/4.0/88x31.png "Creative Commons License" 13[4]: https://creativecommons.org/licenses/by-nd/4.0/ 14 15 16## Table of Contents 17 18- [Overview](#overview) 19- [Driver Discovery](#driver-discovery) 20 - [Overriding the Default Driver Discovery](#overriding-the-default-driver-discovery) 21 - [Additional Driver Discovery](#additional-driver-discovery) 22 - [Exception for Elevated Privileges](#exception-for-elevated-privileges) 23 - [Examples](#examples) 24 - [On Windows](#on-windows) 25 - [On Linux](#on-linux) 26 - [On macOS](#on-macos) 27 - [Driver Manifest File Usage](#driver-manifest-file-usage) 28 - [Driver Discovery on Windows](#driver-discovery-on-windows) 29 - [Driver Discovery on Linux](#driver-discovery-on-linux) 30 - [Example Linux Driver Search Path](#example-linux-driver-search-path) 31 - [Driver Discovery on Fuchsia](#driver-discovery-on-fuchsia) 32 - [Driver Discovery on macOS](#driver-discovery-on-macos) 33 - [Example macOS Driver Search Path](#example-macos-driver-search-path) 34 - [Additional Settings For Driver Debugging](#additional-settings-for-driver-debugging) 35 - [Using Pre-Production ICDs or Software Drivers](#using-pre-production-icds-or-software-drivers) 36 - [Driver Discovery on Android](#driver-discovery-on-android) 37- [Driver Manifest File Format](#driver-manifest-file-format) 38 - [Driver Manifest File Versions](#driver-manifest-file-versions) 39 - [Driver Manifest File Version 1.0.0](#driver-manifest-file-version-100) 40 - [Driver Manifest File Version 1.0.1](#driver-manifest-file-version-101) 41- [Driver Vulkan Entry Point Discovery](#driver-vulkan-entry-point-discovery) 42- [Driver API Version](#driver-api-version) 43- [Mixed Driver Instance Extension Support](#mixed-driver-instance-extension-support) 44 - [Filtering Out Instance Extension Names](#filtering-out-instance-extension-names) 45 - [Loader Instance Extension Emulation Support](#loader-instance-extension-emulation-support) 46- [Driver Unknown Physical Device Extensions](#driver-unknown-physical-device-extensions) 47 - [Reason for adding `vk_icdGetPhysicalDeviceProcAddr`](#reason-for-adding-vk_icdgetphysicaldeviceprocaddr) 48- [Physical Device Sorting](#physical-device-sorting) 49- [Driver Dispatchable Object Creation](#driver-dispatchable-object-creation) 50- [Handling KHR Surface Objects in WSI Extensions](#handling-khr-surface-objects-in-wsi-extensions) 51- [Loader and Driver Interface Negotiation](#loader-and-driver-interface-negotiation) 52 - [Windows, Linux and macOS Driver Negotiation](#windows-linux-and-macos-driver-negotiation) 53 - [Version Negotiation Between Loader and Drivers](#version-negotiation-between-loader-and-drivers) 54 - [Interfacing With Legacy Drivers or Loaders](#interfacing-with-legacy-drivers-or-loaders) 55 - [Loader Version 6 Interface Requirements](#loader-version-6-interface-requirements) 56 - [Loader Version 5 Interface Requirements](#loader-version-5-interface-requirements) 57 - [Loader Version 4 Interface Requirements](#loader-version-4-interface-requirements) 58 - [Loader Version 3 Interface Requirements](#loader-version-3-interface-requirements) 59 - [Loader Version 2 Interface Requirements](#loader-version-2-interface-requirements) 60 - [Loader Version 1 Interface Requirements](#loader-version-1-interface-requirements) 61 - [Loader Version 0 Interface Requirements](#loader-version-0-interface-requirements) 62 - [Additional Interface Notes:](#additional-interface-notes) 63 - [Android Driver Negotiation](#android-driver-negotiation) 64- [Loader implementation of VK_KHR_portability_enumeration](#loader-implementation-of-vk_khr_portability_enumeration) 65- [Loader and Driver Policy](#loader-and-driver-policy) 66 - [Number Format](#number-format) 67 - [Android Differences](#android-differences) 68 - [Requirements of Well-Behaved Drivers](#requirements-of-well-behaved-drivers) 69 - [Removed Driver Policies](#removed-driver-policies) 70 - [Requirements of a Well-Behaved Loader](#requirements-of-a-well-behaved-loader) 71 72 73## Overview 74 75This is the Driver-centric view of working with the Vulkan loader. 76For the complete overview of all sections of the loader, please refer to the 77[LoaderInterfaceArchitecture.md](LoaderInterfaceArchitecture.md) file. 78 79**NOTE:** While many of the interfaces still use the "icd" sub-string to 80identify various behavior associated with drivers, this is purely 81historical and should not indicate that the implementing code do so through 82the traditional ICD interface. 83Granted, the majority of drivers to this date are ICD drivers 84targeting specific GPU hardware. 85 86## Driver Discovery 87 88Vulkan allows multiple drivers each with one or more devices 89(represented by a Vulkan `VkPhysicalDevice` object) to be used collectively. 90The loader is responsible for discovering available Vulkan drivers on 91the system. 92Given a list of available drivers, the loader can enumerate all the 93physical devices available for an application and return this information to the 94application. 95The process in which the loader discovers the available drivers on a 96system is platform-dependent. 97Windows, Linux, Android, and macOS Driver Discovery details are listed 98below. 99 100### Overriding the Default Driver Discovery 101 102There may be times that a developer wishes to force the loader to use a specific 103Driver. 104This could be for many reasons including using a beta driver, or forcing the 105loader to skip a problematic driver. 106In order to support this, the loader can be forced to look at specific 107drivers with either the `VK_DRIVER_FILES` or the older `VK_ICD_FILENAMES` 108environment variable. 109Both these environment variables behave the same, but `VK_ICD_FILENAMES` 110should be considered deprecated. 111If both `VK_DRIVER_FILES` and `VK_ICD_FILENAMES` environment variables are 112present, then the newer `VK_DRIVER_FILES` will be used, and the values in 113`VK_ICD_FILENAMES` will be ignored. 114 115The `VK_DRIVER_FILES` environment variable is a list of Driver Manifest 116files, containing the full path to the driver JSON Manifest file. 117This list is colon-separated on Linux and macOS, and semicolon-separated on 118Windows. 119Typically, `VK_DRIVER_FILES` will only contain a full pathname to one info 120file for a single driver. 121A separator (colon or semicolon) is only used if more than one driver is needed. 122 123### Additional Driver Discovery 124 125There may be times that a developer wishes to force the loader to use a specific 126Driver in addition to the standard drivers (without replacing the standard 127search paths. 128The `VK_ADD_DRIVER_FILES` environment variable can be used to add a list of 129Driver Manifest files, containing the full path to the driver JSON Manifest file. 130This list is colon-separated on Linux and macOS, and semicolon-separated on 131Windows. 132It will be added prior to the standard driver search files. 133If `VK_DRIVER_FILES` or `VK_ICD_FILENAMES` is present, then 134`VK_ADD_DRIVER_FILES` will not be used by the loader and any values will be 135ignored. 136 137#### Exception for Elevated Privileges 138 139For security reasons, `VK_ICD_FILENAMES`, `VK_DRIVER_FILES` and 140`VK_ADD_DRIVER_FILES` are all ignored if running the Vulkan application with 141elevated privileges. 142Because of this, these environment variables can only be used for applications 143that do not use elevated privileges. 144 145For more information see 146[Elevated Privilege Caveats](LoaderInterfaceArchitecture.md#elevated-privilege-caveats) 147in the top-level 148[LoaderInterfaceArchitecture.md](LoaderInterfaceArchitecture.md) document. 149 150#### Examples 151 152In order to use the setting, simply set it to a properly delimited list of 153Driver Manifest files. 154In this case, please provide the global path to these files to reduce issues. 155 156For example: 157 158##### On Windows 159 160``` 161set VK_DRIVER_FILES=\windows\system32\nv-vk64.json 162``` 163 164This is an example which is using the `VK_DRIVER_FILES` override on Windows to 165point to the Nvidia Vulkan Driver's Manifest file. 166 167``` 168set VK_ADD_DRIVER_FILES=\windows\system32\nv-vk64.json 169``` 170 171This is an example which is using the `VK_ADD_DRIVER_FILES` on Windows to 172point to the Nvidia Vulkan Driver's Manifest file which will be loaded first 173before all other drivers. 174 175##### On Linux 176 177``` 178export VK_DRIVER_FILES=/home/user/dev/mesa/share/vulkan/icd.d/intel_icd.x86_64.json 179``` 180 181This is an example which is using the `VK_DRIVER_FILES` override on Linux to 182point to the Intel Mesa Driver's Manifest file. 183 184``` 185export VK_ADD_DRIVER_FILES=/home/user/dev/mesa/share/vulkan/icd.d/intel_icd.x86_64.json 186``` 187 188This is an example which is using the `VK_ADD_DRIVER_FILES` on Linux to 189point to the Intel Mesa Driver's Manifest file which will be loaded first 190before all other drivers. 191 192##### On macOS 193 194``` 195export VK_DRIVER_FILES=/home/user/MoltenVK/Package/Latest/MoltenVK/macOS/MoltenVK_icd.json 196``` 197 198This is an example which is using the `VK_DRIVER_FILES` override on macOS to 199point to an installation and build of the MoltenVK GitHub repository that 200contains the MoltenVK driver. 201 202See the 203[Table of Debug Environment Variables](LoaderInterfaceArchitecture.md#table-of-debug-environment-variables) 204in the [LoaderInterfaceArchitecture.md document](LoaderInterfaceArchitecture.md) 205for more details 206 207 208### Driver Manifest File Usage 209 210As with layers, on Windows, Linux and macOS systems, JSON-formatted manifest 211files are used to store driver information. 212In order to find system-installed drivers, the Vulkan loader will read the JSON 213files to identify the names and attributes of each driver. 214Notice that Driver Manifest files are much simpler than the corresponding 215layer Manifest files. 216 217See the 218[Current Driver Manifest File Format](#driver-manifest-file-format) 219section for more details. 220 221 222### Driver Discovery on Windows 223 224In order to find available drivers (including installed ICDs), the 225loader scans through registry keys specific to Display Adapters and all Software 226Components associated with these adapters for the locations of JSON manifest 227files. 228These keys are located in device keys created during driver installation and 229contain configuration information for base settings, including OpenGL and 230Direct3D locations. 231 232The Device Adapter and Software Component key paths will be obtained by first 233enumerating DXGI adapters. 234Should that fail it will use the PnP Configuration Manager API. 235The `000X` key will be a numbered key, where each device is assigned a different 236number. 237 238``` 239HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{Adapter GUID}\000X\VulkanDriverName 240HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{SoftwareComponent GUID}\000X\VulkanDriverName 241``` 242 243In addition, on 64-bit systems there may be another set of registry values, 244listed below. 245These values record the locations of 32-bit layers on 64-bit operating systems, 246in the same way as the Windows-on-Windows functionality. 247 248``` 249HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{Adapter GUID}\000X\VulkanDriverNameWow 250HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{SoftwareComponent GUID}\000X\VulkanDriverNameWow 251``` 252 253If any of the above values exist and is of type `REG_SZ`, the loader will open 254the JSON manifest file specified by the key value. 255Each value must be a full absolute path to a JSON manifest file. 256The values may also be of type `REG_MULTI_SZ`, in which case the value will be 257interpreted as a list of paths to JSON manifest files. 258 259Additionally, the Vulkan loader will scan the values in the following Windows 260registry key: 261 262``` 263HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\Drivers 264``` 265 266For 32-bit applications on 64-bit Windows, the loader scan's the 32-bit 267registry location: 268 269``` 270HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Khronos\Vulkan\Drivers 271``` 272 273Every driver in these locations should be given as a DWORD, with value 0, where 274the name of the value is the full path to a JSON manifest file. 275The Vulkan loader will attempt to open each manifest file to obtain the 276information about a driver's shared library (".dll") file. 277 278For example, let us assume the registry contains the following data: 279 280``` 281[HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\Drivers\] 282 283"C:\vendor a\vk_vendor_a.json"=dword:00000000 284"C:\windows\system32\vendor_b_vk.json"=dword:00000001 285"C:\windows\system32\vendor_c_icd.json"=dword:00000000 286``` 287 288In this case, the loader will step through each entry, and check the value. 289If the value is 0, then the loader will attempt to load the file. 290In this case, the loader will open the first and last listings, but not the 291middle. 292This is because the value of 1 for vendor_b_vk.json disables the driver. 293 294Additionally, the Vulkan loader will scan the system for well-known Windows 295AppX/MSIX packages. If a package is found, the loader will scan the root directory 296of this installed package for JSON manifest files. At this time, the only package 297that is known is Microsoft's 298[OpenCL™ and OpenGL® Compatibility Pack](https://apps.microsoft.com/store/detail/9NQPSL29BFFF?hl=en-us&gl=US). 299 300The Vulkan loader will open each enabled manifest file found to obtain the name 301or pathname of a driver's shared library (".DLL") file. 302 303Drivers should use the registry locations from the PnP Configuration 304Manager wherever practical. 305Typically, this is most important for drivers, and the location clearly 306ties the driver to a given device. 307The `SOFTWARE\Khronos\Vulkan\Drivers` location is the older method for locating 308drivers, but is the primary location for software based drivers. 309 310See the 311[Driver Manifest File Format](#driver-manifest-file-format) 312section for more details. 313 314 315### Driver Discovery on Linux 316 317On Linux, the Vulkan loader will scan for Driver Manifest files using 318environment variables or corresponding fallback values if the corresponding 319environment variable is not defined: 320 321<table style="width:100%"> 322 <tr> 323 <th>Search Order</th> 324 <th>Directory/Environment Variable</th> 325 <th>Fallback</th> 326 <th>Additional Notes</th> 327 </tr> 328 <tr> 329 <td>1</td> 330 <td>$XDG_CONFIG_HOME</td> 331 <td>$HOME/.config</td> 332 <td><b>This path is ignored when running with elevated privileges such as 333 setuid, setgid, or filesystem capabilities</b>.<br/> 334 This is done because under these scenarios it is not safe to trust 335 that the environment variables are non-malicious.<br/> 336 See <a href="LoaderInterfaceArchitecture.md#elevated-privilege-caveats"> 337 Elevated Privilege Caveats</a> for more information. 338 </td> 339 </tr> 340 <tr> 341 <td>1</td> 342 <td>$XDG_CONFIG_DIRS</td> 343 <td>/etc/xdg</td> 344 <td></td> 345 </tr> 346 <tr> 347 <td>2</td> 348 <td>SYSCONFDIR</td> 349 <td>/etc</td> 350 <td>Compile-time option set to possible location of drivers 351 installed from non-Linux-distribution-provided packages. 352 </td> 353 </tr> 354 <tr> 355 <td>3</td> 356 <td>EXTRASYSCONFDIR</td> 357 <td>/etc</td> 358 <td>Compile-time option set to possible location of drivers 359 installed from non-Linux-distribution-provided packages. 360 Typically only set if SYSCONFDIR is set to something other than /etc 361 </td> 362 </tr> 363 <tr> 364 <td>4</td> 365 <td>$XDG_DATA_HOME</td> 366 <td>$HOME/.local/share</td> 367 <td><b>This path is ignored when running with elevated privileges such as 368 setuid, setgid, or filesystem capabilities</b>.<br/> 369 This is done because under these scenarios it is not safe to trust 370 that the environment variables are non-malicious.<br/> 371 See <a href="LoaderInterfaceArchitecture.md#elevated-privilege-caveats"> 372 Elevated Privilege Caveats</a> for more information. 373 </td> 374 </tr> 375 <tr> 376 <td>5</td> 377 <td>$XDG_DATA_DIRS</td> 378 <td>/usr/local/share/:/usr/share/</td> 379 <td></td> 380 </tr> 381</table> 382 383The directory lists are concatenated together using the standard platform path 384separator (:). 385The loader then selects each path, and applies the "/vulkan/icd.d" suffix onto 386each and looks in that specific folder for manifest files. 387 388The Vulkan loader will open each manifest file found to obtain the name or 389pathname of a driver's shared library (".dylib") file. 390 391**NOTE** While the order of folders searched for manifest files is well 392defined, the order contents are read by the loader in each directory is 393[random due to the behavior of readdir](https://www.ibm.com/support/pages/order-directory-contents-returned-calls-readdir). 394 395See the 396[Driver Manifest File Format](#driver-manifest-file-format) 397section for more details. 398 399It is also important to note that while `VK_DRIVER_FILES` will point the loader 400to finding the manifest files, it does not guarantee the library files mentioned 401by the manifest will immediately be found. 402Often, the Driver Manifest file will point to the library file using a 403relative or absolute path. 404When a relative or absolute path is used, the loader can typically find the 405library file without querying the operating system. 406However, if a library is listed only by name, the loader may not find it, 407unless the driver is installed placing the library in an operating system 408searchable default location. 409If problems occur finding a library file associated with a driver, try updating 410the `LD_LIBRARY_PATH` environment variable to point at the location of the 411corresponding `.so` file. 412 413 414#### Example Linux Driver Search Path 415 416For a fictional user "me" the Driver Manifest search path might look 417like the following: 418 419``` 420 /home/me/.config/vulkan/icd.d 421 /etc/xdg/vulkan/icd.d 422 /usr/local/etc/vulkan/icd.d 423 /etc/vulkan/icd.d 424 /home/me/.local/share/vulkan/icd.d 425 /usr/local/share/vulkan/icd.d 426 /usr/share/vulkan/icd.d 427``` 428 429 430### Driver Discovery on Fuchsia 431 432On Fuchsia, the Vulkan loader will scan for manifest files using environment 433variables or corresponding fallback values if the corresponding environment 434variable is not defined in the same way as 435[Linux](#linux-driver-discovery). 436The **only** difference is that Fuchsia does not allow fallback values for 437*$XDG_DATA_DIRS* or *$XDG_HOME_DIRS*. 438 439 440### Driver Discovery on macOS 441 442On macOS, the Vulkan loader will scan for Driver Manifest files using 443the application resource folder as well as environment variables or 444corresponding fallback values if the corresponding environment variable is not 445defined. 446The order is similar to the search path on Linux with the exception that 447the application's bundle resources are searched first: 448`(bundle)/Contents/Resources/`. 449 450#### Example macOS Driver Search Path 451 452For a fictional user "Me" the Driver Manifest search path might look 453like the following: 454 455``` 456 <bundle>/Contents/Resources/vulkan/icd.d 457 /Users/Me/.config/vulkan/icd.d 458 /etc/xdg/vulkan/icd.d 459 /usr/local/etc/vulkan/icd.d 460 /etc/vulkan/icd.d 461 /Users/Me/.local/share/vulkan/icd.d 462 /usr/local/share/vulkan/icd.d 463 /usr/share/vulkan/icd.d 464``` 465 466 467#### Additional Settings For Driver Debugging 468 469Sometimes, the driver may encounter issues when loading. 470A useful option may be to enable the `LD_BIND_NOW` environment variable 471to debug the issue. 472This forces every dynamic library's symbols to be fully resolved on load. 473If there is a problem with a driver missing symbols on the current system, this 474will expose it and cause the Vulkan loader to fail on loading the driver. 475It is recommended that `LD_BIND_NOW` along with `VK_LOADER_DEBUG=error,warn` 476to expose any issues. 477 478 479### Using Pre-Production ICDs or Software Drivers 480 481Both software and pre-production ICDs can use an alternative mechanism to 482detect their drivers. 483Independent Hardware Vendor (IHV) may not want to fully install a pre-production 484ICD and so it can't be found in the standard location. 485For example, a pre-production ICD may simply be a shared library in the 486developer's build tree. 487In this case, there should be a way to allow developers to point to such an 488ICD without modifying the system-installed ICD(s) on their system. 489 490This need is met with the use of the `VK_DRIVER_FILES` environment variable, 491which will override the mechanism used for finding system-installed 492drivers. 493 494In other words, only the drivers listed in `VK_DRIVER_FILES` will be 495used. 496 497See 498[Overriding the Default Driver Discovery](#overriding-the-default-driver-discovery) 499for more information on this. 500 501 502### Driver Discovery on Android 503 504The Android loader lives in the system library folder. 505The location cannot be changed. 506The loader will load the driver via `hw_get_module` with the ID of "vulkan". 507**Due to security policies in Android, none of this can be modified under** 508**normal use.** 509 510 511## Driver Manifest File Format 512 513The following section discusses the details of the Driver Manifest JSON file format. 514The JSON file itself does not have any requirements for naming. 515The only requirement is that the extension suffix of the file is ".json". 516 517Here is an example driver JSON Manifest file: 518 519```json 520{ 521 "file_format_version": "1.0.1", 522 "ICD": { 523 "library_path": "path to driver library", 524 "api_version": "1.2.205", 525 "library_arch" : "64", 526 "is_portability_driver": false 527 } 528} 529``` 530 531<table style="width:100%"> 532 <tr> 533 <th>Field Name</th> 534 <th>Field Value</th> 535 </tr> 536 <tr> 537 <td>"file_format_version"</td> 538 <td>The JSON format major.minor.patch version number of this file.<br/> 539 Supported versions are: 1.0.0 and 1.0.1.</td> 540 </tr> 541 <tr> 542 <td>"ICD"</td> 543 <td>The identifier used to group all driver information together. 544 <br/> 545 <b>NOTE:</b> Even though this is labelled <i>ICD</i> it is historical 546 and just as accurate to use for other drivers.</td> 547 </tr> 548 <tr> 549 <td>"library_path"</td> 550 <td>The "library_path" specifies either a filename, a relative pathname, or 551 a full pathname to a driver shared library file. <br /> 552 If "library_path" specifies a relative pathname, it is relative to the 553 path of the JSON manifest file. <br /> 554 If "library_path" specifies a filename, the library must live in the 555 system's shared object search path. <br /> 556 There are no rules about the name of the driver's shared library file 557 other than it should end with the appropriate suffix (".DLL" on 558 Windows, ".so" on Linux and ".dylib" on macOS).</td> 559 </tr> 560 <tr> 561 <td>"library_arch"</td> 562 <td>Optional field which specifies the architecture of the binary associated 563 with "library_path". <br /> 564 Allows the loader to quickly determine if the architecture of the driver 565 matches that of the running application. <br /> 566 The only valid values are "32" and "64".</td> 567 </tr> 568 <tr> 569 <td>"api_version" </td> 570 <td>The major.minor.patch version number of the maximum Vulkan API supported 571 by the driver. 572 However, just because the driver supports the specific Vulkan API version, 573 it does not guarantee that the hardware on a user's system can support 574 that version. 575 Information on what the underlying physical device can support must be 576 queried by the user using the <i>vkGetPhysicalDeviceProperties</i> API call. 577 <br/> 578 For example: 1.0.33.</td> 579 </tr> 580 <tr> 581 <td>"is_portability_driver" </td> 582 <td>Defines whether the driver contains any VkPhysicalDevices which implement 583 the VK_KHR_portability_subset extension.<br/> 584 </td> 585 </tr> 586</table> 587 588**NOTE:** If the same driver shared library supports multiple, incompatible 589versions of text manifest file format versions, it must have separate JSON files 590for each (all of which may point to the same shared library). 591 592### Driver Manifest File Versions 593 594The current highest supported Layer Manifest file format supported is 1.0.1. 595Information about each version is detailed in the following sub-sections: 596 597#### Driver Manifest File Version 1.0.0 598 599The initial version of the Driver Manifest file specified the basic 600format and fields of a layer JSON file. 601The fields supported in version 1.0.0 of the file format include: 602 * "file\_format\_version" 603 * "ICD" 604 * "library\_path" 605 * "api\_version" 606 607#### Driver Manifest File Version 1.0.1 608 609Added the `is_portability_driver` boolean field for drivers to self report that 610they contain VkPhysicalDevices which support the VK_KHR_portability_subset 611extension. This is an optional field. Omitting the field has the same effect as 612setting the field to `false`. 613 614Added the "library\_arch" field to the driver manifest to allow the loader to 615quickly determine if the driver matches the architecture of the current running 616application. This field is optional. 617 618## Driver Vulkan Entry Point Discovery 619 620The Vulkan symbols exported by a driver must not clash with the loader's 621exported Vulkan symbols. 622Because of this, all drivers must export the following function that is 623used for discovery of driver Vulkan entry-points. 624This entry-point is not a part of the Vulkan API itself, only a private 625interface between the loader and drivers for version 1 and higher 626interfaces. 627 628```cpp 629VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL 630 vk_icdGetInstanceProcAddr( 631 VkInstance instance, 632 const char* pName); 633``` 634 635This function has very similar semantics to `vkGetInstanceProcAddr`. 636`vk_icdGetInstanceProcAddr` returns valid function pointers for all the 637global-level and instance-level Vulkan functions, and also for 638`vkGetDeviceProcAddr`. 639Global-level functions are those which contain no dispatchable object as the 640first parameter, such as `vkCreateInstance` and 641`vkEnumerateInstanceExtensionProperties`. 642The driver must support querying global-level entry points by calling 643`vk_icdGetInstanceProcAddr` with a NULL `VkInstance` parameter. 644Instance-level functions are those that have either `VkInstance`, or 645`VkPhysicalDevice` as the first parameter dispatchable object. 646Both core entry points and any instance extension entry points the 647driver supports should be available via `vk_icdGetInstanceProcAddr`. 648Future Vulkan instance extensions may define and use new instance-level 649dispatchable objects other than `VkInstance` and `VkPhysicalDevice`, in which 650case extension entry points using these newly defined dispatchable objects must 651be queryable via `vk_icdGetInstanceProcAddr`. 652 653All other Vulkan entry points must either: 654 * NOT be exported directly from the driver library 655 * or NOT use the official Vulkan function names if they are exported 656 657This requirement is for driver libraries that include other functionality (such 658as OpenGL) and thus could be loaded by the application prior to when the Vulkan 659loader library is loaded by the application. 660 661Beware of interposing by dynamic OS library loaders if the official Vulkan 662names are used. 663On Linux, if official names are used, the driver library must be linked with 664`-Bsymbolic`. 665 666 667## Driver API Version 668 669When an application calls `vkCreateInstance`, it can optionally include a 670`VkApplicationInfo` struct, which includes an `apiVersion` field. 671A Vulkan 1.0 driver was required to return `VK_ERROR_INCOMPATIBLE_DRIVER` if it 672did not support the API version that the user passed. 673Beginning with Vulkan 1.1, drivers are not allowed to return this error 674for any value of `apiVersion`. 675This creates a problem when working with multiple drivers, where one is 676a 1.0 driver and another is newer. 677 678A loader that is newer than 1.0 will always give the version it supports when 679the application calls `vkEnumerateInstanceVersion`, regardless of the API 680version supported by the drivers on the system. 681This means that when the application calls `vkCreateInstance`, the loader will 682be forced to pass a copy of the `VkApplicationInfo` struct where `apiVersion` is 6831.0 to any 1.0 drivers in order to prevent an error. 684To determine if this must be done, the loader will perform the following steps: 685 6861. Check the driver's JSON manifest file for the "api_version" field. 6872. If the JSON version is greater than or equal to 1.1, Load the driver's 688dynamic library 6893. Call the driver's `vkGetInstanceProcAddr` command to get a pointer to 690`vkEnumerateInstanceVersion` 6914. If the pointer to `vkEnumerateInstanceVersion` is not `NULL`, it will be 692called to get the driver's supported API version 693 694The driver will be treated as a 1.0 driver if any of the following conditions 695are met: 696 697- The JSON manifest's "api_version" field is less that version 1.1 698- The function pointer to `vkEnumerateInstanceVersion` is `NULL` 699- The version returned by `vkEnumerateInstanceVersion` is less than 1.1 700- `vkEnumerateInstanceVersion` returns anything other than `VK_SUCCESS` 701 702If the driver only supports Vulkan 1.0, the loader will ensure that any 703`VkApplicationInfo` struct that is passed to the driver will have an 704`apiVersion` field set to Vulkan 1.0. 705Otherwise, the loader will pass the struct to the driver without any 706changes. 707 708 709## Mixed Driver Instance Extension Support 710 711On a system with more than one driver, a special case can arise. 712Some drivers may expose an instance extension that the loader is already 713aware of. 714Other drivers on that same system may not support the same instance 715extension. 716 717In that scenario, the loader has some additional responsibilities: 718 719 720### Filtering Out Instance Extension Names 721 722During a call to `vkCreateInstance`, the list of requested instance extensions 723is passed down to each driver. 724Since the driver may not support one or more of these instance extensions, the 725loader will filter out any instance extensions that are not supported by the 726driver. 727This is done per driver since different drivers may support different instance 728extensions. 729 730 731### Loader Instance Extension Emulation Support 732 733In the same scenario, the loader must emulate the instance extension 734entry-points, to the best of its ability, for each driver that does not support 735an instance extension directly. 736This must work correctly when combined with calling into the other 737drivers which do support the extension natively. 738In this fashion, the application will be unaware of what drivers are 739missing support for this extension. 740 741 742## Driver Unknown Physical Device Extensions 743 744Drivers that implement entrypoints which take a `VkPhysicalDevice` as the first 745parameter *should* support `vk_icdGetPhysicalDeviceProcAddr`. This function 746is added to the Driver Interface Version 4 and allows the loader to distinguish 747between entrypoints which take `VkDevice` and `VkPhysicalDevice` as the first 748parameter. This allows the loader to properly support entrypoints that are 749unknown to it gracefully. 750 751```cpp 752PFN_vkVoidFunction 753 vk_icdGetPhysicalDeviceProcAddr( 754 VkInstance instance, 755 const char* pName); 756``` 757 758This function behaves similar to `vkGetInstanceProcAddr` and 759`vkGetDeviceProcAddr` except it should only return values for physical device 760extension entry points. 761In this way, it compares "pName" to every physical device function supported in 762the driver. 763 764Implementations of the function should have the following behavior: 765* If `pName` is the name of a Vulkan API entrypoint that takes a `VkPhysicalDevice` 766 as its primary dispatch handle, and the driver supports the entrypoint, then 767 the driver **must** return the valid function pointer to the driver's 768 implementation of that entrypoint. 769* If `pName` is the name of a Vulkan API entrypoint that takes something other than 770 a `VkPhysicalDevice` as its primary dispatch handle, then the driver **must** 771 return `NULL`. 772* If the driver is unaware of any entrypoint with the name `pName`, it **must** 773 return `NULL`. 774 775If a driver intends to support functions that take VkPhysicalDevice as the 776dispatchable parameter, then the driver should support 777`vk_icdGetPhysicalDeviceProcAddr`. This is because if these functions aren't 778known to the loader, such as those from unreleased extensions or because 779the loader is an older build thus doesn't know about them _yet_, the loader 780won't be able to distinguish whether this is a device or physical device 781function. 782 783If a driver does implement this support, it must export the function from the 784driver library using the name `vk_icdGetPhysicalDeviceProcAddr` so that the 785symbol can be located through the platform's dynamic linking utilities. 786 787The behavior of the loader's `vkGetInstanceProcAddr` with support for the 788`vk_icdGetPhysicalDeviceProcAddr` function is as follows: 789 1. Check if core function: 790 - If it is, return the function pointer 791 2. Check if known instance or device extension function: 792 - If it is, return the function pointer 793 3. Call the layer/driver `GetPhysicalDeviceProcAddr` 794 - If it returns `non-NULL`, return a trampoline to a generic physical device 795function, and set up a generic terminator which will pass it to the proper 796driver. 797 4. Call down using `GetInstanceProcAddr` 798 - If it returns non-NULL, treat it as an unknown logical device command. 799This means setting up a generic trampoline function that takes in a `VkDevice` 800as the first parameter and adjusting the dispatch table to call the 801driver/layer's function after getting the dispatch table from the 802`VkDevice`. 803Then, return the pointer to the corresponding trampoline function. 804 5. Return `NULL` 805 806The result is that if the command gets promoted to Vulkan core later, it will no 807longer be set up using `vk_icdGetPhysicalDeviceProcAddr`. 808Additionally, if the loader adds direct support for the extension, it will no 809longer get to step 3, because step 2 will return a valid function pointer. 810However, the driver should continue to support the command query via 811`vk_icdGetPhysicalDeviceProcAddr`, until at least a Vulkan version bump, because 812an older loader may still be attempting to use the commands. 813 814### Reason for adding `vk_icdGetPhysicalDeviceProcAddr` 815 816Originally, when the loader's `vkGetInstanceProcAddr` was called, it would 817result in the following behavior: 818 1. The loader would check if it was a core function: 819 - If so, it would return the function pointer 820 2. The loader would check if it was a known extension function: 821 - If so, it would return the function pointer 822 3. If the loader knew nothing about it, it would call down using 823`GetInstanceProcAddr` 824 - If it returned `non-NULL`, treat it as an unknown logical device command. 825 - This meant setting up a generic trampoline function that takes in a 826VkDevice as the first parameter and adjusting the dispatch table to call the 827driver/layer's function after getting the dispatch table from the 828`VkDevice`. 829 4. If all the above failed, the loader would return `NULL` to the application. 830 831This caused problems when a driver attempted to expose new physical device 832extensions the loader knew nothing about, but an application was aware of. 833Because the loader knew nothing about it, the loader would get to step 3 in the 834above process and would treat the function as an unknown logical device command. 835The problem is, this would create a generic `VkDevice` trampoline function 836which, on the first call, would attempt to dereference the VkPhysicalDevice as a 837`VkDevice`. 838This would lead to a crash or corruption. 839 840## Physical Device Sorting 841 842When an application selects a GPU to use, it must enumerate physical devices or 843physical device groups. 844These API functions do not specify which order the physical devices or physical 845device groups will be presented in. 846On Windows, the loader will attempt to sort these objects so that the system 847preference will be listed first. 848This mechanism does not force an application to use any particular GPU — 849it merely changes the order in which they are presented. 850 851This mechanism requires that a driver provide version 6 of the loader/driver 852interface. 853Version 6 of this interface defines a new exported function that the driver may 854provide on Windows: 855 856```c 857VKAPI_ATTR VkResult VKAPI_CALL 858 vk_icdEnumerateAdapterPhysicalDevices( 859 VkInstance instance, 860 LUID adapterLUID, 861 uint32_t* pPhysicalDeviceCount, 862 VkPhysicalDevice* pPhysicalDevices); 863``` 864 865This function takes an adapter LUID as input, and enumerates all Vulkan physical 866devices that are associated with that LUID. 867This works in the same way as other Vulkan enumerations — if 868`pPhysicalDevices` is `NULL`, then the count will be provided. 869Otherwise, the physical devices associated with the queried adapter will be 870provided. 871The function must provide multiple physical devices when the LUID refers to a 872linked adapter. 873This allows the loader to translate the adapter into Vulkan physical device 874groups. 875 876While the loader attempts to match the system's preference for GPU ordering, 877there are some limitations. 878Because this feature requires a new driver interface, only physical devices from 879drivers that support this function will be sorted. 880All unsorted physical devices will be listed at the end of the list, in an 881indeterminate order. 882Furthermore, only physical devices that correspond to an adapter may be sorted. 883This means that a software driver would likely not be sorted. 884Finally, this API only applies to Windows systems and will only work on versions 885of Windows 10 that support GPU selection through the OS. 886Other platforms may be included in the future, but they will require separate 887platform-specific interfaces. 888 889 890## Driver Dispatchable Object Creation 891 892As previously covered, the loader requires dispatch tables to be accessible 893within Vulkan dispatchable objects, such as: `VkInstance`, `VkPhysicalDevice`, 894`VkDevice`, `VkQueue`, and `VkCommandBuffer`. 895The specific requirements on all dispatchable objects created by drivers 896are as follows: 897 898- All dispatchable objects created by a driver can be cast to void \*\* 899- The loader will replace the first entry with a pointer to the dispatch table 900which is owned by the loader. 901This implies three things for drivers: 902 1. The driver must return a pointer for the opaque dispatchable object handle 903 2. This pointer points to a regular C structure with the first entry being a 904 pointer. 905 * **NOTE:** For any C\++ drivers that implement VK objects directly 906as C\++ classes: 907 * The C\++ compiler may put a vtable at offset zero if the class is 908non-POD due to the use of a virtual function. 909 * In this case use a regular C structure (see below). 910 3. The loader checks for a magic value (ICD\_LOADER\_MAGIC) in all the created 911 dispatchable objects, as follows (see `include/vulkan/vk_icd.h`): 912 913```cpp 914#include "vk_icd.h" 915 916union _VK_LOADER_DATA { 917 uintptr loadermagic; 918 void * loaderData; 919} VK_LOADER_DATA; 920 921vkObj 922 alloc_icd_obj() 923{ 924 vkObj *newObj = alloc_obj(); 925 ... 926 // Initialize pointer to loader's dispatch table with ICD_LOADER_MAGIC 927 928 set_loader_magic_value(newObj); 929 ... 930 return newObj; 931} 932``` 933 934 935## Handling KHR Surface Objects in WSI Extensions 936 937Normally, drivers handle object creation and destruction for various Vulkan 938objects. 939The WSI surface extensions for Linux, Windows, macOS, and QNX 940("VK\_KHR\_win32\_surface", "VK\_KHR\_xcb\_surface", "VK\_KHR\_xlib\_surface", 941"VK\_KHR\_wayland\_surface", "VK\_MVK\_macos\_surface", 942"VK\_QNX\_screen\_surface" and "VK\_KHR\_surface") are handled differently. 943For these extensions, the `VkSurfaceKHR` object creation and destruction may be 944handled by either the loader or a driver. 945 946If the loader handles the management of the `VkSurfaceKHR` objects: 947 1. The loader will handle the calls to `vkCreateXXXSurfaceKHR` and 948`vkDestroySurfaceKHR` 949 functions without involving the drivers. 950 * Where XXX stands for the Windowing System name: 951 * Wayland 952 * XCB 953 * Xlib 954 * Windows 955 * Android 956 * MacOS (`vkCreateMacOSSurfaceMVK`) 957 * QNX (`vkCreateScreenSurfaceQNX`) 958 2. The loader creates a `VkIcdSurfaceXXX` object for the corresponding 959`vkCreateXXXSurfaceKHR` call. 960 * The `VkIcdSurfaceXXX` structures are defined in `include/vulkan/vk_icd.h`. 961 3. Drivers can cast any `VkSurfaceKHR` object to a pointer to the 962appropriate `VkIcdSurfaceXXX` structure. 963 4. The first field of all the `VkIcdSurfaceXXX` structures is a 964`VkIcdSurfaceBase` enumerant that indicates whether the 965 surface object is Win32, XCB, Xlib, Wayland, or Screen. 966 967The driver may choose to handle `VkSurfaceKHR` object creation instead. 968If a driver desires to handle creating and destroying it must do the following: 969 1. Support version 3 or newer of the loader/driver interface. 970 2. Export and handle all functions that take in a `VkSurfaceKHR` object, 971including: 972 * `vkCreateXXXSurfaceKHR` 973 * `vkGetPhysicalDeviceSurfaceSupportKHR` 974 * `vkGetPhysicalDeviceSurfaceCapabilitiesKHR` 975 * `vkGetPhysicalDeviceSurfaceFormatsKHR` 976 * `vkGetPhysicalDeviceSurfacePresentModesKHR` 977 * `vkCreateSwapchainKHR` 978 * `vkDestroySurfaceKHR` 979 980Because the `VkSurfaceKHR` object is an instance-level object, one object can be 981associated with multiple drivers. 982Therefore, when the loader receives the `vkCreateXXXSurfaceKHR` call, it still 983creates an internal `VkSurfaceIcdXXX` object. 984This object acts as a container for each driver's version of the 985`VkSurfaceKHR` object. 986If a driver does not support the creation of its own `VkSurfaceKHR` object, the 987loader's container stores a NULL for that driver. 988On the other hand, if the driver does support `VkSurfaceKHR` creation, the 989loader will make the appropriate `vkCreateXXXSurfaceKHR` call to the 990driver, and store the returned pointer in its container object. 991The loader then returns the `VkSurfaceIcdXXX` as a `VkSurfaceKHR` object back up 992the call chain. 993Finally, when the loader receives the `vkDestroySurfaceKHR` call, it 994subsequently calls `vkDestroySurfaceKHR` for each driver whose internal 995`VkSurfaceKHR` object is not NULL. 996Then the loader destroys the container object before returning. 997 998 999## Loader and Driver Interface Negotiation 1000 1001Generally, for functions issued by an application, the loader can be viewed as a 1002pass through. 1003That is, the loader generally doesn't modify the functions or their parameters, 1004but simply calls the driver's entry point for that function. 1005There are specific additional interface requirements a driver needs to comply 1006with that are not part of any requirements from the Vulkan specification. 1007These additional requirements are versioned to allow flexibility in the future. 1008 1009 1010### Windows, Linux and macOS Driver Negotiation 1011 1012 1013#### Version Negotiation Between Loader and Drivers 1014 1015All drivers (supporting interface version 2 or higher) must export the 1016following function that is used for determination of the interface version that 1017will be used. 1018This entry point is not a part of the Vulkan API itself, only a private 1019interface between the loader and drivers. 1020 1021```cpp 1022VKAPI_ATTR VkResult VKAPI_CALL 1023 vk_icdNegotiateLoaderICDInterfaceVersion( 1024 uint32_t* pSupportedVersion); 1025``` 1026 1027This function allows the loader and driver to agree on an interface version to 1028use. 1029The "pSupportedVersion" parameter is both an input and output parameter. 1030"pSupportedVersion" is filled in by the loader with the desired latest interface 1031version supported by the loader (typically the latest). 1032The driver receives this and returns back the version it desires in the same 1033field. 1034Because it is setting up the interface version between the loader and 1035driver, this should be the first call made by a loader to the driver (even prior 1036to any calls to `vk_icdGetInstanceProcAddr`). 1037 1038If the driver receiving the call no longer supports the interface version 1039provided by the loader (due to deprecation), then it should report a 1040`VK_ERROR_INCOMPATIBLE_DRIVER` error. 1041Otherwise it sets the value pointed by "pSupportedVersion" to the latest 1042interface version supported by both the driver and the loader and returns 1043`VK_SUCCESS`. 1044 1045The driver should report `VK_SUCCESS` in case the loader-provided interface 1046version is newer than that supported by the driver, as it's the loader's 1047responsibility to determine whether it can support the older interface version 1048supported by the driver. 1049The driver should also report `VK_SUCCESS` in the case its interface version is 1050greater than the loader's, but return the loader's version. 1051Thus, upon return of `VK_SUCCESS` the "pSupportedVersion" will contain the 1052desired interface version to be used by the driver. 1053 1054If the loader receives an interface version from the driver that the loader no 1055longer supports (due to deprecation), or it receives a 1056`VK_ERROR_INCOMPATIBLE_DRIVER` error instead of `VK_SUCCESS`, then the loader 1057will treat the driver as incompatible and will not load it for use. 1058In this case, the application will not see the driver's `vkPhysicalDevice` 1059during enumeration. 1060 1061#### Interfacing With Legacy Drivers or Loaders 1062 1063If a loader sees that a driver does not export the 1064`vk_icdNegotiateLoaderICDInterfaceVersion` function, then the loader assumes the 1065corresponding driver only supports either interface version 0 or 1. 1066 1067From the other side of the interface, if a driver sees a call to 1068`vk_icdGetInstanceProcAddr` before a call to 1069`vk_icdNegotiateLoaderICDInterfaceVersion`, then it knows that loader making the 1070calls is a legacy loader supporting version 0 or 1. 1071If the loader calls `vk_icdGetInstanceProcAddr` first, it supports at least 1072version 1. 1073Otherwise, the loader only supports version 0. 1074 1075#### Loader Version 6 Interface Requirements 1076 1077Version 6 provides a mechanism to allow the loader to sort physical devices. 1078The loader will only attempt to sort physical devices on a driver if version 6 1079of the interface is supported. 1080This version provides the `vk_icdEnumerateAdapterPhysicalDevices` function 1081defined earlier in this document. 1082 1083#### Loader Version 5 Interface Requirements 1084 1085Version 5 of the loader/driver interface has no changes to the actual interface. 1086If the loader requests interface version 5 or greater, it is simply 1087an indication to drivers that the loader is now evaluating whether the API 1088Version info passed into vkCreateInstance is a valid version for the loader. 1089If it is not, the loader will catch this during vkCreateInstance and fail with a 1090`VK_ERROR_INCOMPATIBLE_DRIVER` error. 1091 1092On the other hand, if version 5 or newer is not requested by the loader, then it 1093indicates to the driver that the loader is ignorant of the API version being 1094requested. 1095Because of this, it falls on the driver to validate that the API Version is not 1096greater than major = 1 and minor = 0. 1097If it is, then the driver should automatically fail with a 1098`VK_ERROR_INCOMPATIBLE_DRIVER` error since the loader is a 1.0 loader, and is 1099unaware of the version. 1100 1101Here is a table of the expected behaviors: 1102 1103<table style="width:100%"> 1104 <tr> 1105 <th>Loader Supports I/f Version</th> 1106 <th>Driver Supports I/f Version</th> 1107 <th>Result</th> 1108 </tr> 1109 <tr> 1110 <td>4 or Earlier</td> 1111 <td>Any Version</td> 1112 <td>Driver <b>must fail</b> with <b>VK_ERROR_INCOMPATIBLE_DRIVER</b> 1113 for all vkCreateInstance calls with apiVersion set to > Vulkan 1.0 1114 because the loader is still at interface version <= 4.<br/> 1115 Otherwise, the driver should behave as normal. 1116 </td> 1117 </tr> 1118 <tr> 1119 <td>5 or Newer</td> 1120 <td>4 or Earlier</td> 1121 <td>Loader <b>must fail</b> with <b>VK_ERROR_INCOMPATIBLE_DRIVER</b> if it 1122 can't handle the apiVersion. 1123 Driver may pass for all apiVersions, but since its interface is 1124 <= 4, it is best if it assumes it needs to do the work of rejecting 1125 anything > Vulkan 1.0 and fail with <b>VK_ERROR_INCOMPATIBLE_DRIVER</b>. 1126 <br/> 1127 Otherwise, the driver should behave as normal. 1128 </td> 1129 </tr> 1130 <tr> 1131 <td>5 or Newer</td> 1132 <td>5 or Newer</td> 1133 <td>Loader <b>must fail</b> with <b>VK_ERROR_INCOMPATIBLE_DRIVER</b> if it 1134 can't handle the apiVersion, and drivers should fail with 1135 <b>VK_ERROR_INCOMPATIBLE_DRIVER</b> <i>only if</i> they can not support 1136 the specified apiVersion. <br/> 1137 Otherwise, the driver should behave as normal. 1138 </td> 1139 </tr> 1140</table> 1141 1142#### Loader Version 4 Interface Requirements 1143 1144The major change to version 4 of the loader/driver interface is the 1145support of 1146[Unknown Physical Device Extensions](#driver-unknown-physical-device-extensions) 1147using the `vk_icdGetPhysicalDeviceProcAddr` function. 1148This function is purely optional. 1149However, if a driver supports a physical device extension, it must provide a 1150`vk_icdGetPhysicalDeviceProcAddr` function. 1151Otherwise, the loader will continue to treat any unknown functions as VkDevice 1152functions and cause invalid behavior. 1153 1154 1155#### Loader Version 3 Interface Requirements 1156 1157The primary change that occurred in version 3 of the loader/driver interface was 1158to allow a driver to handle creation/destruction of their own KHR_surfaces. 1159Up until this point, the loader created a surface object that was used by all 1160drivers. 1161However, some drivers may want to provide their own surface handles. 1162If a driver chooses to enable this support, it must export support for version 3 1163of the loader/driver interface, as well as any Vulkan function that uses a 1164KHR_surface handle, such as: 1165- `vkCreateXXXSurfaceKHR` (where XXX is the platform-specific identifier [i.e. 1166`vkCreateWin32SurfaceKHR` for Windows]) 1167- `vkDestroySurfaceKHR` 1168- `vkCreateSwapchainKHR` 1169- `vkGetPhysicalDeviceSurfaceSupportKHR` 1170- `vkGetPhysicalDeviceSurfaceCapabilitiesKHR` 1171- `vkGetPhysicalDeviceSurfaceFormatsKHR` 1172- `vkGetPhysicalDeviceSurfacePresentModesKHR` 1173 1174A driver can still choose to not take advantage of this functionality 1175by simply not exposing the above `vkCreateXXXSurfaceKHR` and 1176`vkDestroySurfaceKHR` functions. 1177 1178 1179#### Loader Version 2 Interface Requirements 1180 1181Version 2 interface is the first to implement the new 1182`vk_icdNegotiateLoaderICDInterfaceVersion` functionality, see 1183[Version Negotiation Between Loader and Drivers](#version-negotiation-between-loader-and-drivers) for more details 1184on that function. 1185 1186Additional, version 2 was the first to define that Vulkan dispatchable objects 1187created by drivers must now be created in accordance to the 1188[Driver Dispatchable Object Creation](#driver-dispatchable-object-creation) 1189section. 1190 1191 1192#### Loader Version 1 Interface Requirements 1193 1194Version 1 of the interface added the driver-specific entry-point 1195`vk_icdGetInstanceProcAddr`. 1196Since this is before the creation of the 1197`vk_icdNegotiateLoaderICDInterfaceVersion` entry-point, the loader has no 1198negotiation process for determine what interface version the driver 1199supports. 1200Because of this, the loader detects support for version 1 of the interface 1201by the absence of the negotiate function, but the presence of the 1202`vk_icdGetInstanceProcAddr`. 1203No other entry-points need to be exported by the driver as the loader will query 1204the appropriate function pointers using that. 1205 1206 1207#### Loader Version 0 Interface Requirements 1208 1209Version 0 interface does not support either `vk_icdGetInstanceProcAddr` or 1210`vk_icdNegotiateLoaderICDInterfaceVersion`. 1211Because of this, the loader will assume the driver supports only version 0 of 1212the interface unless one of those functions exists. 1213 1214Additionally, for version 0, the driver must expose at least the following core 1215Vulkan entry-points so the loader may build up the interface to the driver: 1216 1217- The function `vkGetInstanceProcAddr` **must be exported** in the driver 1218library and returns valid function pointers for all the Vulkan API entry points. 1219- `vkCreateInstance` **must be exported** by the driver library. 1220- `vkEnumerateInstanceExtensionProperties` **must be exported** by the driver 1221library. 1222 1223 1224#### Additional Interface Notes: 1225 1226- The loader will filter out extensions requested in `vkCreateInstance` and 1227`vkCreateDevice` before calling into the driver; filtering will be of extensions 1228advertised by entities (e.g. layers) different from the driver in question. 1229- The loader will not call the driver for `vkEnumerate*LayerProperties` 1230as layer properties are obtained from the layer libraries and layer JSON files. 1231- If a driver library author wants to implement a layer, it can do so by having 1232the appropriate layer JSON manifest file refer to the driver library file. 1233- The loader will not call the driver for `vkEnumerate*ExtensionProperties` if 1234"pLayerName" is not equal to `NULL`. 1235- Drivers creating new dispatchable objects via device extensions need 1236to initialize the created dispatchable object. 1237The loader has generic *trampoline* code for unknown device extensions. 1238This generic *trampoline* code doesn't initialize the dispatch table within the 1239newly created object. 1240See the 1241[Driver Dispatchable Object Creation](#driver-dispatchable-object-creation) 1242section for more information on how to initialize created dispatchable objects 1243for extensions non known by the loader. 1244 1245 1246### Android Driver Negotiation 1247 1248The Android loader uses the same protocol for initializing the dispatch table as 1249described above. 1250The only difference is that the Android loader queries layer and extension 1251information directly from the respective libraries and does not use the JSON 1252manifest files used by the Windows, Linux and macOS loaders. 1253 1254 1255## Loader implementation of VK_KHR_portability_enumeration 1256 1257The loader implements the `VK_KHR_portability_enumeration` instance extension, 1258which filters out any drivers that report support for the portability subset 1259device extension. Unless the application explicitly requests enumeration of 1260portability devices by setting the VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR 1261bit in the VkInstanceCreateInfo::flags, the loader does not load any drivers 1262that declare themselves to be portability drivers. 1263 1264Drivers declare whether they are portability drivers or not in the Driver Manifest 1265Json file, with the `is_portability_driver` boolean field. 1266[More information here](#driver-manifest-file-version-101) 1267 1268The initial support for this extension only reported errors when an application 1269did not enable the portability enumeration feature. It did not filter out 1270portability drivers. This was done to give a grace period for applications to 1271update their instance creation logic without outright breaking the application. 1272 1273## Loader and Driver Policy 1274 1275This section is intended to define proper behavior expected between the loader 1276and drivers. 1277Much of this section is additive to the Vulkan spec, and necessary for 1278maintaining consistency across platforms. 1279In fact, much of the language can be found throughout this document, but is 1280summarized here for convenience. 1281Additionally, there should be a way to identify bad or non-conformant behavior 1282in a driver and remedy it as soon as possible. 1283Therefore, a policy numbering system is provided to clearly identify each 1284policy statement in a unique way. 1285 1286Finally, based on the goal of making the loader efficient and performant, 1287some of these policy statements defining proper driver behavior may not 1288be testable (and therefore aren't enforceable by the loader). 1289However, that should not detract from the requirement in order to provide the 1290best experience to end-users and developers. 1291 1292 1293### Number Format 1294 1295Loader/Driver policy items start with the prefix `LDP_` (short for 1296Loader/Driver Policy) which is followed by an identifier based on what 1297component the policy is targeted against. 1298In this case there are only two possible components: 1299 - Drivers: which will have the string `DRIVER_` as part of the policy number. 1300 - The Loader: which will have the string `LOADER_` as part of the policy 1301 number. 1302 1303 1304### Android Differences 1305 1306As stated before, the Android Loader is actually separate from the Khronos 1307Loader. 1308Because of this and other platform requirements, not all of these policy 1309statements apply to Android. 1310Each table also has a column titled "Applicable to Android?" 1311which indicates which policy statements apply to drivers that are focused 1312only on Android support. 1313Further information on the Android loader can be found in the 1314<a href="https://source.android.com/devices/graphics/implement-vulkan"> 1315Android Vulkan documentation</a>. 1316 1317 1318### Requirements of Well-Behaved Drivers 1319 1320<table style="width:100%"> 1321 <tr> 1322 <th>Requirement Number</th> 1323 <th>Requirement Description</th> 1324 <th>Result of Non-Compliance</th> 1325 <th>Applicable to Android?</th> 1326 <th>Enforceable by Loader?</th> 1327 <th>Reference Section</th> 1328 </tr> 1329 <tr> 1330 <td><small><b>LDP_DRIVER_1</b></small></td> 1331 <td>A driver <b>must not</b> cause other drivers to fail, crash, or 1332 otherwise misbehave. 1333 </td> 1334 <td>The behavior is undefined and may result in crashes or corruption.</td> 1335 <td>Yes</td> 1336 <td>No</td> 1337 <td><small>N/A</small></td> 1338 </tr> 1339 <tr> 1340 <td><small><b>LDP_DRIVER_2</b></small></td> 1341 <td>A driver <b>must not</b> crash if it detects that there are no supported 1342 Vulkan Physical Devices (<i>VkPhysicalDevice</i>) on the system when a 1343 call to that driver is made using any Vulkan instance of physical device 1344 API.<br/> 1345 This is because some devices can be hot-plugged. 1346 </td> 1347 <td>The behavior is undefined and may result in crashes or corruption.</td> 1348 <td>Yes</td> 1349 <td>No<br/> 1350 The loader has no direct knowledge of what devices (virtual or physical) 1351 may be supported by a given driver.</td> 1352 <td><small>N/A</small> 1353 </td> 1354 </tr> 1355 <tr> 1356 <td><small><b>LDP_DRIVER_3</b></small></td> 1357 <td>A driver <b>must</b> be able to negotiate a supported version of the 1358 loader/driver interface with the loader in accordance with the stated 1359 negotiation process. 1360 </td> 1361 <td>The driver will not be loaded.</td> 1362 <td>No</td> 1363 <td>Yes</td> 1364 <td><small> 1365 <a href="#loader-and-driver-interface-negotiation"> 1366 Interface Negotiation</a></small> 1367 </td> 1368 </tr> 1369 <tr> 1370 <td><small><b>LDP_DRIVER_4</b></small></td> 1371 <td>A driver <b>must</b> have a valid JSON manifest file for the loader to 1372 process that ends with the ".json" suffix. 1373 </td> 1374 <td>The driver will not be loaded.</td> 1375 <td>No</td> 1376 <td>Yes</td> 1377 <td><small> 1378 <a href="#driver-manifest-file-format">Manifest File Format</a> 1379 </small> 1380 </td> 1381 </tr> 1382 <tr> 1383 <td><small><b>LDP_DRIVER_5</b></small></td> 1384 <td>A driver <b>must</b> pass conformance with the results submitted, 1385 verified, and approved by Khronos before reporting a conformance version 1386 through any mechanism provided by Vulkan (examples include inside the 1387 <i>VkPhysicalDeviceVulkan12Properties</i> and the 1388 <i>VkPhysicalDeviceDriverProperties</i> structs).<br/> 1389 Otherwise, when such a structure containing a conformance version is 1390 encountered, the driver <b>must</b> return a conformance version 1391 of 0.0.0.0 to indicate it hasn't been so verified and approved. 1392 </td> 1393 <td>Yes</td> 1394 <td>No</td> 1395 <td>The loader and/or the application may make assumptions about the 1396 capabilities of the driver resulting in undefined behavior 1397 possibly including crashes or corruption. 1398 </td> 1399 <td><small> 1400 <a href="https://github.com/KhronosGroup/VK-GL-CTS/blob/master/external/openglcts/README.md"> 1401 Vulkan CTS Documentation</a> 1402 </small> 1403 </td> 1404 </tr> 1405 <tr> 1406 <td><small><b>LDP_DRIVER_6</b></small></td> 1407 <td>Removed - See <a href="#removed-driver-policies">Removed Driver Policies</a> 1408 </td> 1409 <td>-</td> 1410 <td>-</td> 1411 <td>-</td> 1412 <td>-</td> 1413 </tr> 1414 <tr> 1415 <td><small><b>LDP_DRIVER_7</b></small></td> 1416 <td>If a driver desires to support Vulkan API 1.1 or newer, it <b>must</b> 1417 expose support of Vulkan loader/driver interface 5 or newer. 1418 </td> 1419 <td>The driver will be used when it shouldn't be and will cause 1420 undefined behavior possibly including crashes or corruption. 1421 </td> 1422 <td>No</td> 1423 <td>Yes</td> 1424 <td><small> 1425 <a href="#loader-version-5-interface-requirements"> 1426 Version 5 Interface Requirements</a></small> 1427 </td> 1428 </tr> 1429 <tr> 1430 <td><small><b>LDP_DRIVER_8</b></small></td> 1431 <td>If a driver wishes to handle its own <i>VkSurfaceKHR</i> object 1432 creation, it <b>must</b> implement loader/driver interface version 3 or 1433 newer and support querying all the relevant surface functions via 1434 <i>vk_icdGetInstanceProcAddr</i>. 1435 </td> 1436 <td>The behavior is undefined and may result in crashes or corruption.</td> 1437 <td>No</td> 1438 <td>Yes</td> 1439 <td><small> 1440 <a href="#handling-khr-surface-objects-in-wsi-extensions"> 1441 Handling KHR Surface Objects</a></small> 1442 </td> 1443 </tr> 1444 <tr> 1445 <td><small><b>LDP_DRIVER_9</b></small></td> 1446 <td>If a driver negotiation results in it using loader/driver interface 1447 version 4 or earlier, the driver <b>must</b> verify that the Vulkan API 1448 version passed into <i>vkCreateInstance</i> (through 1449 <i>VkInstanceCreateInfo</i>’s <i>VkApplicationInfo</i>'s 1450 <i>apiVersion</i>) is supported. 1451 If the requested Vulkan API version can not be supported by the driver, 1452 it <b>must</b> return <b>VK_ERROR_INCOMPATIBLE_DRIVER</b>. <br/> 1453 This is not required if the interface version is 5 or newer because the 1454 responsibility for this check then falls on the loader. 1455 </td> 1456 <td>The behavior is undefined and may result in crashes or corruption.</td> 1457 <td>No</td> 1458 <td>No</td> 1459 <td><small> 1460 <a href="#loader-version-5-interface-requirements"> 1461 Version 5 Interface Requirements</a></small> 1462 </td> 1463 </tr> 1464 <tr> 1465 <td><small><b>LDP_DRIVER_10</b></small></td> 1466 <td>If a driver negotiation results in it using loader/driver interface 1467 version 5 or newer, the driver <b>must</b> ignore the Vulkan API version 1468 passed into <i>vkCreateInstance</i> (through 1469 <i>VkInstanceCreateInfo</i>’s <i>VkApplicationInfo</i>'s 1470 <i>apiVersion</i>). 1471 </td> 1472 <td>The behavior is undefined and may result in crashes or corruption.</td> 1473 <td>No</td> 1474 <td>No</td> 1475 <td><small> 1476 <a href="#loader-version-5-interface-requirements"> 1477 Version 5 Interface Requirements</a></small> 1478 </td> 1479 </tr> 1480 <tr> 1481 <td><small><b>LDP_DRIVER_11</b></small></td> 1482 <td>A driver <b>must</b> remove all Manifest files and references to those 1483 files (i.e. Registry entries on Windows) when uninstalling. 1484 <br/> 1485 Similarly, on updating the driver files, the old files <b>must</b> be 1486 all updated or removed. 1487 </td> 1488 <td>If an old file is left pointing to an incorrect library, it will 1489 result in undefined behavior which may include crashes or corruption. 1490 </td> 1491 <td>No</td> 1492 <td>No<br/> 1493 The loader has no idea what driver files are new, old, or incorrect. 1494 Any type of driver file verification would quickly become very complex 1495 since it would require the loader to maintain an internal database 1496 tracking badly behaving drivers based on the driver vendor, driver 1497 version, targeted platform(s), and possibly other criteria. 1498 </td> 1499 <td><small>N/A</small></td> 1500 </tr> 1501 <tr> 1502 <td><small><b>LDP_DRIVER_12</b></small></td> 1503 <td>To work properly with the public Khronos Loader, a driver 1504 <b>must not</b> expose platform interface extensions without first 1505 publishing them with Khronos.<br/> 1506 Platforms under development may use modified versions of the Khronos 1507 Loader until the design because stable and/or public. 1508 </td> 1509 <td>The behavior is undefined and may result in crashes or corruption.</td> 1510 <td>Yes (specifically for Android extensions)</td> 1511 <td>No</td> 1512 <td><small>N/A</small></td> 1513 </tr> 1514</table> 1515 1516#### Removed Driver Policies 1517 1518These policies were in the loader source at some point but later removed. They are documented here for reference. 1519 1520<table> 1521 <tr> 1522 <th>Requirement Number</th> 1523 <th>Requirement Description</th> 1524 <th>Removal Reason</th> 1525 </tr> 1526 <tr> 1527 <td><small><b>LDP_DRIVER_6</b></small></td> 1528 <td>A driver supporting loader/driver interface version 1 or newer <b>must 1529 not</b> directly export standard Vulkan entry-points. 1530 <br/> 1531 Instead, it <b>must</b> export only the loader interface functions 1532 required by the interface versions it does support (for example 1533 <i>vk_icdGetInstanceProcAddr</i>). <br/> 1534 This is because the dynamic linking on some platforms has been 1535 problematic in the past and incorrectly links to exported functions from 1536 the wrong dynamic library at times. <br/> 1537 <b>NOTE:</b> This is actually true for all exports. 1538 When in doubt, don't export any items from a driver that could cause 1539 conflicts in other libraries.<br/> 1540 </td> 1541 <td> 1542 This policy has been removed due to there being valid circumstances for 1543 drivers to export core entrypoints. 1544 Additionally, it was not found that dynamic linking would cause many 1545 issues in practice. 1546 </td> 1547 </tr> 1548</table> 1549 1550### Requirements of a Well-Behaved Loader 1551 1552<table style="width:100%"> 1553 <tr> 1554 <th>Requirement Number</th> 1555 <th>Requirement Description</th> 1556 <th>Result of Non-Compliance</th> 1557 <th>Applicable to Android?</th> 1558 <th>Reference Section</th> 1559 </tr> 1560 <tr> 1561 <td><small><b>LDP_LOADER_1</b></small></td> 1562 <td>A loader <b>must</b> return <b>VK_ERROR_INCOMPATIBLE_DRIVER</b> if it 1563 fails to find and load a valid Vulkan driver on the system. 1564 </td> 1565 <td>The behavior is undefined and may result in crashes or corruption.</td> 1566 <td>Yes</td> 1567 <td><small>N/A</small></td> 1568 </tr> 1569 <tr> 1570 <td><small><b>LDP_LOADER_2</b></small></td> 1571 <td>A loader <b>must</b> attempt to load any driver's Manifest file it 1572 discovers and determines is formatted in accordance with this document. 1573 <br/> 1574 The <b>only</b> exception is on platforms which determines driver 1575 location and functionality through some other mechanism. 1576 </td> 1577 <td>The behavior is undefined and may result in crashes or corruption.</td> 1578 <td>Yes</td> 1579 <td><small> 1580 <a href="#driver-discovery">Driver Discovery</a></small> 1581 </td> 1582 </tr> 1583 <tr> 1584 <td><small><b>LDP_LOADER_3</b></small></td> 1585 <td>A loader <b>must</b> support a mechanism to load driver in one or more 1586 non-standard locations.<br/> 1587 This is to allow support for fully software drivers as well as 1588 evaluating in-development ICDs. <br/> 1589 The <b>only</b> exception to this rule is if the OS does not wish to 1590 support this due to security policies. 1591 </td> 1592 <td>It will be more difficult to use a Vulkan loader by certain 1593 tools and driver developers.</td> 1594 <td>No</td> 1595 <td><small> 1596 <a href="#using-pre-production-icds-or-software-drivers"> 1597 Pre-Production ICDs or SW</a></small> 1598 </td> 1599 </tr> 1600 <tr> 1601 <td><small><b>LDP_LOADER_4</b></small></td> 1602 <td>A loader <b>must not</b> load a Vulkan driver which defines an API 1603 version that is incompatible with itself. 1604 </td> 1605 <td>The behavior is undefined and may result in crashes or corruption.</td> 1606 <td>Yes</td> 1607 <td><small> 1608 <a href="#driver-discovery">Driver Discovery</a></small> 1609 </td> 1610 </tr> 1611 <tr> 1612 <td><small><b>LDP_LOADER_5</b></small></td> 1613 <td>A loader <b>must</b> ignore any driver for which a compatible 1614 loader/driver interface version can not be negotiated. 1615 </td> 1616 <td>The loader would load a driver improperly resulting in undefined 1617 behavior possibly including crashes or corruption. 1618 </td> 1619 <td>No</td> 1620 <td><small> 1621 <a href="#loader-and-driver-interface-negotiation"> 1622 Interface Negotiation</a></small> 1623 </td> 1624 </tr> 1625 <tr> 1626 <td><small><b>LDP_LOADER_6</b></small></td> 1627 <td>If a driver negotiation results in it using loader/driver interface 1628 version 5 or newer, a loader <b>must</b> verify that the Vulkan API 1629 version passed into <i>vkCreateInstance</i> (through 1630 <i>VkInstanceCreateInfo</i>’s <i>VkApplicationInfo</i>'s 1631 <i>apiVersion</i>) is supported by at least one driver. 1632 If the requested Vulkan API version can not be supported by any 1633 driver, the loader <b>must</b> return 1634 <b>VK_ERROR_INCOMPATIBLE_DRIVER</b>.<br/> 1635 This is not required if the interface version is 4 or earlier because 1636 the responsibility for this check then falls on the drivers. 1637 </td> 1638 <td>The behavior is undefined and may result in crashes or corruption.</td> 1639 <td>No</td> 1640 <td><small> 1641 <a href="#loader-version-5-interface-requirements"> 1642 Version 5 Interface Requirements</a></small> 1643 </td> 1644 </tr> 1645 <tr> 1646 <td><small><b>LDP_LOADER_7</b></small></td> 1647 <td>If there exist more than one driver on a system, and some of those 1648 drivers support <i>only</i> Vulkan API version 1.0 while other drivers 1649 support a newer Vulkan API version, then a loader <b>must</b> adjust 1650 the <i>apiVersion</i> field of the <i>VkInstanceCreateInfo</i>’s 1651 <i>VkApplicationInfo</i> to version 1.0 for all the drivers that are 1652 only aware of Vulkan API version 1.0.<br/> 1653 Otherwise, the drivers that support Vulkan API version 1.0 will 1654 return <b>VK_ERROR_INCOMPATIBLE_DRIVER</b> during 1655 <i>vkCreateInstance</i> since 1.0 drivers were not aware of future 1656 versions. 1657 </td> 1658 <td>The behavior is undefined and may result in crashes or corruption.</td> 1659 <td>No</td> 1660 <td><small> 1661 <a href="#driver-api-version">Driver API Version</a> 1662 </small> 1663 </td> 1664 </tr> 1665 <tr> 1666 <td><small><b>LDP_LOADER_8</b></small></td> 1667 <td>If more than one driver is present, and at least one driver <i>does not 1668 support</i> instance-level functionality that other drivers support; 1669 then a loader <b>must</b> support the instance-level functionality in 1670 some fashion for the non-supporting drivers. 1671 </td> 1672 <td>The behavior is undefined and may result in crashes or corruption.</td> 1673 <td>No</td> 1674 <td><small> 1675 <a href="#loader-instance-extension-emulation-support"> 1676 Loader Instance Extension Emulation Support</a></small> 1677 </td> 1678 </tr> 1679 <tr> 1680 <td><small><b>LDP_LOADER_9</b></small></td> 1681 <td>A loader <b>must</b> filter out instance extensions from the 1682 <i>VkInstanceCreateInfo</i> structure's <i>ppEnabledExtensionNames</i> 1683 field that the driver does not support during a call to the driver's 1684 <i>vkCreateInstance</i>.<br/> 1685 This is because the application has no way of knowing which 1686 drivers support which extensions.<br/> 1687 This ties in directly with <i>LDP_LOADER_8</i> above. 1688 </td> 1689 <td>The behavior is undefined and may result in crashes or corruption.</td> 1690 <td>No</td> 1691 <td><small> 1692 <a href="#filtering-out-instance-extension-names"> 1693 Filtering Out Instance Extension Names</a></small> 1694 </td> 1695 </tr> 1696 <tr> 1697 <td><small><b>LDP_LOADER_10</b></small></td> 1698 <td>A loader <b>must</b> support creating <i>VkSurfaceKHR</i> handles 1699 that <b>may</b> be shared by all underlying drivers. 1700 </td> 1701 <td>The behavior is undefined and may result in crashes or corruption.</td> 1702 <td>Yes</td> 1703 <td><small> 1704 <a href="#handling-khr-surface-objects-in-wsi-extensions"> 1705 Handling KHR Surface Objects</a></small> 1706 </td> 1707 </tr> 1708 <tr> 1709 <td><small><b>LDP_LOADER_11</b></small></td> 1710 <td>If a driver exposes the appropriate <i>VkSurfaceKHR</i> 1711 creation/handling entry-points, a loader <b>must</b> support creating 1712 the driver-specific surface object handle and provide it, and not the 1713 shared <i>VkSurfaceKHR</i> handle, back to that driver when requested. 1714 <br/> 1715 Otherwise, a loader <b>must</b> provide the loader created 1716 <i>VkSurfaceKHR</i> handle. 1717 </td> 1718 <td>The behavior is undefined and may result in crashes or corruption.</td> 1719 <td>No</td> 1720 <td><small> 1721 <a href="#handling-khr-surface-objects-in-wsi-extensions"> 1722 Handling KHR Surface Objects</a></small> 1723 </td> 1724 </tr> 1725 <tr> 1726 <td><small><b>LDP_LOADER_12</b></small></td> 1727 <td>A loader <b>must not</b> call any <i>vkEnumerate*ExtensionProperties</i> 1728 entry-points in a driver if <i>pLayerName</i> is not <b>NULL</b>. 1729 </td> 1730 <td>The behavior is undefined and may result in crashes or corruption.</td> 1731 <td>Yes</td> 1732 <td><small> 1733 <a href="#additional-interface-notes"> 1734 Additional Interface Notes</a></small> 1735 </td> 1736 </tr> 1737 <tr> 1738 <td><small><b>LDP_LOADER_13</b></small></td> 1739 <td>A loader <b>must</b> not load from user-defined paths (including the 1740 use of any of <i>VK_ICD_FILENAMES</i>, <i>VK_DRIVER_FILES</i>, or 1741 <i>VK_ADD_DRIVER_FILES</i> environment variables) when running elevated 1742 (Administrator/Super-user) applications.<br/> 1743 <b>This is for security reasons.</b> 1744 </td> 1745 <td>The behavior is undefined and may result in computer security lapses, 1746 crashes or corruption. 1747 </td> 1748 <td>No</td> 1749 <td><small> 1750 <a href="#exception-for-administrator-and-super-user-mode"> 1751 Exception for Administrator and Super-User mode 1752 </a></small> 1753 </td> 1754 </tr> 1755</table> 1756 1757<br/> 1758 1759[Return to the top-level LoaderInterfaceArchitecture.md file.](LoaderInterfaceArchitecture.md) 1760