[![Khronos Vulkan][1]][2] [1]: https://vulkan.lunarg.com/img/Vulkan_100px_Dec16.png "https://www.khronos.org/vulkan/" [2]: https://www.khronos.org/vulkan/ # Driver interface to the Vulkan Loader [![Creative Commons][3]][4] [3]: https://i.creativecommons.org/l/by-nd/4.0/88x31.png "Creative Commons License" [4]: https://creativecommons.org/licenses/by-nd/4.0/ ## Table of Contents - [Overview](#overview) - [Driver Discovery](#driver-discovery) - [Overriding the Default Driver Discovery](#overriding-the-default-driver-discovery) - [Exception for Elevated Privileges](#exception-for-elevated-privileges) - [Examples](#examples) - [On Windows](#on-windows) - [On Linux](#on-linux) - [On macOS](#on-macos) - [Driver Manifest File Usage](#driver-manifest-file-usage) - [Driver Discovery on Windows](#driver-discovery-on-windows) - [Driver Discovery on Linux](#driver-discovery-on-linux) - [Example Linux Driver Search Path](#example-linux-driver-search-path) - [Driver Discovery on Fuchsia](#driver-discovery-on-fuchsia) - [Driver Discovery on macOS](#driver-discovery-on-macos) - [Example macOS Driver Search Path](#example-macos-driver-search-path) - [Additional Settings For Driver Debugging](#additional-settings-for-driver-debugging) - [Using Pre-Production ICDs or Software Drivers](#using-pre-production-icds-or-software-drivers) - [Driver Discovery on Android](#driver-discovery-on-android) - [Driver Manifest File Format](#driver-manifest-file-format) - [Driver Manifest File Versions](#driver-manifest-file-versions) - [Driver Manifest File Version 1.0.0](#driver-manifest-file-version-100) - [Driver Vulkan Entry Point Discovery](#driver-vulkan-entry-point-discovery) - [Driver API Version](#driver-api-version) - [Mixed Driver Instance Extension Support](#mixed-driver-instance-extension-support) - [Filtering Out Instance Extension Names](#filtering-out-instance-extension-names) - [Loader Instance Extension Emulation Support](#loader-instance-extension-emulation-support) - [Driver Unknown Physical Device Extensions](#driver-unknown-physical-device-extensions) - [Physical Device Sorting](#physical-device-sorting) - [Driver Dispatchable Object Creation](#driver-dispatchable-object-creation) - [Handling KHR Surface Objects in WSI Extensions](#handling-khr-surface-objects-in-wsi-extensions) - [Loader and Driver Interface Negotiation](#loader-and-driver-interface-negotiation) - [Windows, Linux and macOS Driver Negotiation](#windows-linux-and-macos-driver-negotiation) - [Version Negotiation Between Loader and Drivers](#version-negotiation-between-loader-and-drivers) - [Interfacing With Legacy Drivers or Loaders](#interfacing-with-legacy-drivers-or-loaders) - [Loader Version 6 Interface Requirements](#loader-version-6-interface-requirements) - [Loader Version 5 Interface Requirements](#loader-version-5-interface-requirements) - [Loader Version 4 Interface Requirements](#loader-version-4-interface-requirements) - [Loader Version 3 Interface Requirements](#loader-version-3-interface-requirements) - [Loader Version 2 Interface Requirements](#loader-version-2-interface-requirements) - [Loader Version 1 Interface Requirements](#loader-version-1-interface-requirements) - [Loader Version 0 Interface Requirements](#loader-version-0-interface-requirements) - [Additional Interface Notes:](#additional-interface-notes) - [Android Driver Negotiation](#android-driver-negotiation) - [Loader and Driver Policy](#loader-and-driver-policy) - [Number Format](#number-format) - [Android Differences](#android-differences) - [Requirements of Well-Behaved Drivers](#requirements-of-well-behaved-drivers) - [Requirements of a Well-Behaved Loader](#requirements-of-a-well-behaved-loader) ## Overview This is the Driver-centric view of working with the Vulkan loader. For the complete overview of all sections of the loader, please refer to the [LoaderInterfaceArchitecture.md](LoaderInterfaceArchitecture.md) file. **NOTE:** While many of the interfaces still use the "icd" sub-string to identify various behavior associated with drivers, this is purely historical and should not indicate that the implementing code do so through the traditional ICD interface. Granted, the majority of drivers to this date are ICD drivers targeting specific GPU hardware. ## Driver Discovery Vulkan allows multiple drivers each with one or more devices (represented by a Vulkan `VkPhysicalDevice` object) to be used collectively. The loader is responsible for discovering available Vulkan drivers on the system. Given a list of available drivers, the loader can enumerate all the physical devices available for an application and return this information to the application. The process in which the loader discovers the available drivers on a system is platform-dependent. Windows, Linux, Android, and macOS Driver Discovery details are listed below. ### Overriding the Default Driver Discovery There may be times that a developer wishes to force the loader to use a specific Driver. This could be for many reasons including using a beta driver, or forcing the loader to skip a problematic driver. In order to support this, the loader can be forced to look at specific drivers with either the `VK_DRIVER_FILES` or the older `VK_ICD_FILENAMES` environment variable. Both these environment variables behave the same, but `VK_ICD_FILENAMES` should be considered deprecated. The `VK_DRIVER_FILES` environment variable is a list of Driver Manifest files, containing the full path to the driver JSON Manifest file. This list is colon-separated on Linux and macOS, and semicolon-separated on Windows. Typically, `VK_DRIVER_FILES` will only contain a full pathname to one info file for a single driver. A separator (colon or semicolon) is only used if more than one driver is needed. ### Additional Driver Discovery There may be times that a developer wishes to force the loader to use a specific Driver in addition to the standard drivers (without replacing the standard search paths. The `VK_ADD_DRIVER_FILES` environment variable can be used to add a list of Driver Manifest files, containing the full path to the driver JSON Manifest file. This list is colon-separated on Linux and macOS, and semicolon-separated on Windows. It will be added prior to the standard driver search files. #### Exception for Elevated Privileges For security reasons, `VK_ICD_FILENAMES`, `VK_DRIVER_FILES` and `VK_ADD_DRIVER_FILES` are all ignored if running the Vulkan application with elevated privileges. Because of this, these environment variables can only be used for applications that do not use elevated privileges. For more information see [Elevated Privilege Caveats](LoaderInterfaceArchitecture.md#elevated-privilege-caveats) in the top-level [LoaderInterfaceArchitecture.md][LoaderInterfaceArchitecture.md] document. #### Examples In order to use the setting, simply set it to a properly delimited list of Driver Manifest files. In this case, please provide the global path to these files to reduce issues. For example: ##### On Windows ``` set VK_DRIVER_FILES=\windows\system32\nv-vk64.json ``` This is an example which is using the `VK_DRIVER_FILES` override on Windows to point to the Nvidia Vulkan Driver's Manifest file. ``` set VK_ADD_DRIVER_FILES=\windows\system32\nv-vk64.json ``` This is an example which is using the `VK_ADD_DRIVER_FILES` on Windows to point to the Nvidia Vulkan Driver's Manifest file which will be loaded first before all other drivers. ##### On Linux ``` export VK_DRIVER_FILES=/home/user/dev/mesa/share/vulkan/icd.d/intel_icd.x86_64.json ``` This is an example which is using the `VK_DRIVER_FILES` override on Linux to point to the Intel Mesa Driver's Manifest file. ``` export VK_ADD_DRIVER_FILES=/home/user/dev/mesa/share/vulkan/icd.d/intel_icd.x86_64.json ``` This is an example which is using the `VK_ADD_DRIVER_FILES` on Linux to point to the Intel Mesa Driver's Manifest file which will be loaded first before all other drivers. ##### On macOS ``` export VK_DRIVER_FILES=/home/user/MoltenVK/Package/Latest/MoltenVK/macOS/MoltenVK_icd.json ``` This is an example which is using the `VK_DRIVER_FILES` override on macOS to point to an installation and build of the MoltenVK GitHub repository that contains the MoltenVK driver. See the [Table of Debug Environment Variables](LoaderInterfaceArchitecture.md#table-of-debug-environment-variables) in the [LoaderInterfaceArchitecture.md document](LoaderInterfaceArchitecture.md) for more details ### Driver Manifest File Usage As with layers, on Windows, Linux and macOS systems, JSON-formatted manifest files are used to store driver information. In order to find system-installed drivers, the Vulkan loader will read the JSON files to identify the names and attributes of each driver. Notice that Driver Manifest files are much simpler than the corresponding layer Manifest files. See the [Current Driver Manifest File Format](#driver-manifest-file-format) section for more details. ### Driver Discovery on Windows In order to find available drivers (including installed ICDs), the loader scans through registry keys specific to Display Adapters and all Software Components associated with these adapters for the locations of JSON manifest files. These keys are located in device keys created during driver installation and contain configuration information for base settings, including OpenGL and Direct3D locations. The Device Adapter and Software Component key paths will be obtained by first enumerating DXGI adapters. Should that fail it will use the PnP Configuration Manager API. The `000X` key will be a numbered key, where each device is assigned a different number. ``` HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{Adapter GUID}\000X\VulkanDriverName HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{SoftwareComponent GUID}\000X\VulkanDriverName ``` In addition, on 64-bit systems there may be another set of registry values, listed below. These values record the locations of 32-bit layers on 64-bit operating systems, in the same way as the Windows-on-Windows functionality. ``` HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{Adapter GUID}\000X\VulkanDriverNameWow HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{SoftwareComponent GUID}\000X\VulkanDriverNameWow ``` If any of the above values exist and is of type `REG_SZ`, the loader will open the JSON manifest file specified by the key value. Each value must be a full absolute path to a JSON manifest file. The values may also be of type `REG_MULTI_SZ`, in which case the value will be interpreted as a list of paths to JSON manifest files. Additionally, the Vulkan loader will scan the values in the following Windows registry key: ``` HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\Drivers ``` For 32-bit applications on 64-bit Windows, the loader scan's the 32-bit registry location: ``` HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Khronos\Vulkan\Drivers ``` Every driver in these locations should be given as a DWORD, with value 0, where the name of the value is the full path to a JSON manifest file. The Vulkan loader will attempt to open each manifest file to obtain the information about a driver's shared library (".dll") file. For example, let us assume the registry contains the following data: ``` [HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\Drivers\] "C:\vendor a\vk_vendora.json"=dword:00000000 "C:\windows\system32\vendorb_vk.json"=dword:00000001 "C:\windows\system32\vendorc_icd.json"=dword:00000000 ``` In this case, the loader will step through each entry, and check the value. If the value is 0, then the loader will attempt to load the file. In this case, the loader will open the first and last listings, but not the middle. This is because the value of 1 for vendorb_vk.json disables the driver. The Vulkan loader will open each enabled manifest file found to obtain the name or pathname of a driver's shared library (".DLL") file. Drivers should use the registry locations from the PnP Configuration Manager wherever practical. Typically, this is most important for drivers, and the location clearly ties the driver to a given device. The `SOFTWARE\Khronos\Vulkan\Drivers` location is the older method for locating drivers, but is the primary location for software based drivers. See the [Driver Manifest File Format](#driver-manifest-file-format) section for more details. ### Driver Discovery on Linux On Linux, the Vulkan loader will scan for Driver Manifest files using environment variables or corresponding fallback values if the corresponding environment variable is not defined:
| Search Order | Directory/Environment Variable | Fallback | Additional Notes |
|---|---|---|---|
| 1 | $XDG_CONFIG_HOME | $HOME/.config | This path is ignored when running with elevated privileges such as
setuid, setgid, or filesystem capabilities. This is done because under these scenarios it is not safe to trust that the environment variables are non-malicious. See Elevated Privilege Caveats for more information. |
| 1 | $XDG_CONFIG_DIRS | /etc/xdg | |
| 2 | SYSCONFDIR | /etc | Compile-time option set to possible location of drivers installed from non-Linux-distribution-provided packages. |
| 3 | EXTRASYSCONFDIR | /etc | Compile-time option set to possible location of drivers installed from non-Linux-distribution-provided packages. Typically only set if SYSCONFDIR is set to something other than /etc |
| 4 | $XDG_DATA_HOME | $HOME/.local/share | This path is ignored when running with elevated privileges such as
setuid, setgid, or filesystem capabilities. This is done because under these scenarios it is not safe to trust that the environment variables are non-malicious. See Elevated Privilege Caveats for more information. |
| 5 | $XDG_DATA_DIRS | /usr/local/share/:/usr/share/ |
| Field Name | Field Value |
|---|---|
| "file_format_version" | The JSON format major.minor.patch version number of this file. Currently supported version is 1.0.0. |
| "ICD" | The identifier used to group all driver information together.
NOTE: Even though this is labelled ICD it is historical and just as accurate to use for other drivers. |
| "library_path" | The "library_path" specifies either a filename, a relative pathname, or
a full pathname to a driver shared library file. If "library_path" specifies a relative pathname, it is relative to the path of the JSON manifest file. If "library_path" specifies a filename, the library must live in the system's shared object search path. There are no rules about the name of the driver's shared library file other than it should end with the appropriate suffix (".DLL" on Windows, ".so" on Linux and ".dylib" on macOS). |
| "api_version" | The major.minor.patch version number of the Vulkan API that the shared
library files for the driver was built against. For example: 1.0.33. |
| Loader Supports I/f Version | Driver Supports I/f Version | Result |
|---|---|---|
| 4 or Earlier | Any Version | Driver must fail with VK_ERROR_INCOMPATIBLE_DRIVER
for all vkCreateInstance calls with apiVersion set to > Vulkan 1.0
because the loader is still at interface version <= 4. Otherwise, the driver should behave as normal. |
| 5 or Newer | 4 or Earlier | Loader must fail with VK_ERROR_INCOMPATIBLE_DRIVER if it
can't handle the apiVersion.
Driver may pass for all apiVersions, but since its interface is
<= 4, it is best if it assumes it needs to do the work of rejecting
anything > Vulkan 1.0 and fail with VK_ERROR_INCOMPATIBLE_DRIVER.
Otherwise, the driver should behave as normal. |
| 5 or Newer | 5 or Newer | Loader must fail with VK_ERROR_INCOMPATIBLE_DRIVER if it
can't handle the apiVersion, and drivers should fail with
VK_ERROR_INCOMPATIBLE_DRIVER only if they can not support
the specified apiVersion. Otherwise, the driver should behave as normal. |
| Requirement Number | Requirement Description | Result of Non-Compliance | Applicable to Android? | Enforceable by Loader? | Reference Section |
|---|---|---|---|---|---|
| LDP_DRIVER_1 | A driver must not cause other drivers to fail, crash, or otherwise misbehave. | The behavior is undefined and may result in crashes or corruption. | Yes | No | N/A |
| LDP_DRIVER_2 | A driver must not crash if it detects that there are no supported
Vulkan Physical Devices (VkPhysicalDevice) on the system when a
call to that driver is made using any Vulkan instance of physical device
API. This is because some devices can be hot-plugged. |
The behavior is undefined and may result in crashes or corruption. | Yes | No The loader has no direct knowledge of what devices (virtual or physical) may be supported by a given driver. |
N/A |
| LDP_DRIVER_3 | A driver must be able to negotiate a supported version of the loader/driver interface with the loader in accordance with the stated negotiation process. | The driver will not be loaded. | No | Yes | Interface Negotiation |
| LDP_DRIVER_4 | A driver must have a valid JSON manifest file for the loader to process that ends with the ".json" suffix. | The driver will not be loaded. | No | Yes | Manifest File Format |
| LDP_DRIVER_5 | A driver must pass conformance with the results submitted,
verified, and approved by Khronos before reporting a conformance version
through any mechanism provided by Vulkan (examples include inside the
VkPhysicalDeviceVulkan12Properties and the
VkPhysicalDeviceDriverProperties structs). Otherwise, when such a structure containing a conformance version is encountered, the driver must return a conformance version of 0.0.0.0 to indicate it hasn't been so verified and approved. |
Yes | No | The loader and/or the application may make assumptions about the capabilities of the driver resulting in undefined behavior possibly including crashes or corruption. | Vulkan CTS Documentation |
| LDP_DRIVER_6 | A driver supporting loader/driver interface version 1 or newer must
not directly export standard Vulkan entry-points.
Instead, it must export only the loader interface functions required by the interface versions it does support (for example vk_icdGetInstanceProcAddr). This is because the dynamic linking on some platforms has been problematic in the past and incorrectly links to exported functions from the wrong dynamic library at times. NOTE: This is actually true for all exports. When in doubt, don't export any items from a driver that could cause conflicts in other libraries. |
The behavior is undefined and may result in crashes or corruption. | Yes (except it always applies) | Yes | Interface Negotiation and Vulkan Entry-point Discovery |
| LDP_DRIVER_7 | If a driver desires to support Vulkan API 1.1 or newer, it must expose support of Vulkan loader/driver interface 5 or newer. | The driver will be used when it shouldn't be and will cause undefined behavior possibly including crashes or corruption. | No | Yes | Version 5 Interface Requirements |
| LDP_DRIVER_8 | If a driver wishes to handle its own VkSurfaceKHR object creation, it must implement loader/driver interface version 3 or newer and support querying all the relevant surface functions via vk_icdGetInstanceProcAddr. | The behavior is undefined and may result in crashes or corruption. | No | Yes | Handling KHR Surface Objects |
| LDP_DRIVER_9 | If a driver negotiation results in it using loader/driver interface
version 4 or earlier, the driver must verify that the Vulkan API
version passed into vkCreateInstance (through
VkInstanceCreateInfo’s VkApplicationInfo's
apiVersion) is supported.
If the requested Vulkan API version can not be supported by the driver,
it must return VK_ERROR_INCOMPATIBLE_DRIVER. This is not required if the interface version is 5 or newer because the responsibility for this check then falls on the loader. |
The behavior is undefined and may result in crashes or corruption. | No | No | Version 5 Interface Requirements |
| LDP_DRIVER_10 | If a driver negotiation results in it using loader/driver interface version 5 or newer, the driver must ignore the Vulkan API version passed into vkCreateInstance (through VkInstanceCreateInfo’s VkApplicationInfo's apiVersion). | The behavior is undefined and may result in crashes or corruption. | No | No | Version 5 Interface Requirements |
| LDP_DRIVER_11 | A driver must remove all Manifest files and references to those
files (i.e. Registry entries on Windows) when uninstalling.
Similarly, on updating the driver files, the old files must be all updated or removed. |
If an old file is left pointing to an incorrect library, it will result in undefined behavior which may include crashes or corruption. | No | No The loader has no idea what driver files are new, old, or incorrect. Any type of driver file verification would quickly become very complex since it would require the loader to maintain an internal database tracking badly behaving drivers based on the driver vendor, driver version, targeted platform(s), and possibly other criteria. |
N/A |
| LDP_DRIVER_12 | To work properly with the public Khronos Loader, a driver
must not expose platform interface extensions without first
publishing them with Khronos. Platforms under development may use modified versions of the Khronos Loader until the design because stable and/or public. |
The behavior is undefined and may result in crashes or corruption. | Yes (specifically for Android extensions) | No | N/A |
| Requirement Number | Requirement Description | Result of Non-Compliance | Applicable to Android? | Reference Section |
|---|---|---|---|---|
| LDP_LOADER_1 | A loader must return VK_ERROR_INCOMPATIBLE_DRIVER if it fails to find and load a valid Vulkan driver on the system. | The behavior is undefined and may result in crashes or corruption. | Yes | N/A |
| LDP_LOADER_2 | A loader must attempt to load any driver's Manifest file it
discovers and determines is formatted in accordance with this document.
The only exception is on platforms which determines driver location and functionality through some other mechanism. |
The behavior is undefined and may result in crashes or corruption. | Yes | Driver Discovery |
| LDP_LOADER_3 | A loader must support a mechanism to load driver in one or more
non-standard locations. This is to allow support for fully software drivers as well as evaluating in-development ICDs. The only exception to this rule is if the OS does not wish to support this due to security policies. |
It will be more difficult to use a Vulkan loader by certain tools and driver developers. | No | Pre-Production ICDs or SW |
| LDP_LOADER_4 | A loader must not load a Vulkan driver which defines an API version that is incompatible with itself. | The behavior is undefined and may result in crashes or corruption. | Yes | Driver Discovery |
| LDP_LOADER_5 | A loader must ignore any driver for which a compatible loader/driver interface version can not be negotiated. | The loader would load a driver improperly resulting in undefined behavior possibly including crashes or corruption. | No | Interface Negotiation |
| LDP_LOADER_6 | If a driver negotiation results in it using loader/driver interface
version 5 or newer, a loader must verify that the Vulkan API
version passed into vkCreateInstance (through
VkInstanceCreateInfo’s VkApplicationInfo's
apiVersion) is supported by at least one driver.
If the requested Vulkan API version can not be supported by any
driver, the loader must return
VK_ERROR_INCOMPATIBLE_DRIVER. This is not required if the interface version is 4 or earlier because the responsibility for this check then falls on the drivers. |
The behavior is undefined and may result in crashes or corruption. | No | Version 5 Interface Requirements |
| LDP_LOADER_7 | If there exist more than one driver on a system, and some of those
drivers support only Vulkan API version 1.0 while other drivers
support a newer Vulkan API version, then a loader must adjust
the apiVersion field of the VkInstanceCreateInfo’s
VkApplicationInfo to version 1.0 for all the drivers that are
only aware of Vulkan API version 1.0. Otherwise, the drivers that support Vulkan API version 1.0 will return VK_ERROR_INCOMPATIBLE_DRIVER during vkCreateInstance since 1.0 drivers were not aware of future versions. |
The behavior is undefined and may result in crashes or corruption. | No | Driver API Version |
| LDP_LOADER_8 | If more than one driver is present, and at least one driver does not support instance-level functionality that other drivers support; then a loader must support the instance-level functionality in some fashion for the non-supporting drivers. | The behavior is undefined and may result in crashes or corruption. | No | Loader Instance Extension Emulation Support |
| LDP_LOADER_9 | A loader must filter out instance extensions from the
VkInstanceCreateInfo structure's ppEnabledExtensionNames
field that the driver does not support during a call to the driver's
vkCreateInstance. This is because the application has no way of knowing which drivers support which extensions. This ties in directly with LDP_LOADER_8 above. |
The behavior is undefined and may result in crashes or corruption. | No | Filtering Out Instance Extension Names |
| LDP_LOADER_10 | A loader must support creating VkSurfaceKHR handles that may be shared by all underlying drivers. | The behavior is undefined and may result in crashes or corruption. | Yes | Handling KHR Surface Objects |
| LDP_LOADER_11 | If a driver exposes the appropriate VkSurfaceKHR
creation/handling entry-points, a loader must support creating
the driver-specific surface object handle and provide it, and not the
shared VkSurfaceKHR handle, back to that driver when requested.
Otherwise, a loader must provide the loader created VkSurfaceKHR handle. |
The behavior is undefined and may result in crashes or corruption. | No | Handling KHR Surface Objects |
| LDP_LOADER_12 | A loader must not call any vkEnumerate*ExtensionProperties entry-points in a driver if pLayerName is not NULL. | The behavior is undefined and may result in crashes or corruption. | Yes | Additional Interface Notes |
| LDP_LOADER_13 | A loader must not load from user-defined paths (including the
use of any of VK_ICD_FILENAMES, VK_DRIVER_FILES, or
VK_ADD_DRIVER_FILES environment variables) when running elevated
(Administrator/Super-user) applications. This is for security reasons. |
The behavior is undefined and may result in computer security lapses, crashes or corruption. | No | Exception for Administrator and Super-User mode |