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