• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &copy; 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 &mdash;
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 &mdash; 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