* [ICD Vulkan Entry Point Discovery](#icd-vulkan-entry-point-discovery)
* [ICD API Version](#icd-api-version)
* [ICD Unknown Physical Device Extensions](#icd-unknown-physical-device-extensions)
+ * [Physical Device Sorting](#physical-device-sorting)
* [ICD Dispatchable Object Creation](#icd-dispatchable-object-creation)
* [Handling KHR Surface Objects in WSI Extensions](#handling-khr-surface-objects-in-wsi-extensions)
* [Loader and ICD Interface Negotiation](#loader-and-icd-interface-negotiation)
* [Table of Debug Environment Variables](#table-of-debug-environment-variables)
* [Glossary of Terms](#glossary-of-terms)
-
+
## Overview
Vulkan is a layered architecture, made up of the following elements:
* `vkBeginCommandBuffer`
* `vkCreateEvent`
-You can query Vulkan Device functions using either `vkGetInstanceProcAddr` or
+You can query Vulkan Device functions using either `vkGetInstanceProcAddr` or
`vkGetDeviceProcAddr`. If you choose to use `vkGetInstanceProcAddr`, it will
have an additional level built into the call chain, which will reduce
performance slightly. However, the function pointer returned can be used for
Device call chains are created at `vkCreateDevice` and are generally simpler
because they deal with only a single device and the ICD can always be the
-*terminator* of the chain.
+*terminator* of the chain.
![Loader Device Call Chain](./images/loader_device_chain_loader.png)
* [WSI Extensions](#wsi-extensions)
* [Unknown Extensions](#unknown-extensions)
-
+
#### Interfacing with Vulkan Functions
There are several ways you can interface with Vulkan functions through the
loader.
The answer comes in how the call chain of Instance functions are implemented
versus the call chain of a Device functions. Remember, a [Vulkan Instance is a
-high-level construct used to provide Vulkan system-level
+high-level construct used to provide Vulkan system-level
information](#instance-related-objects).
Because of this, Instance functions need to be broadcast to
every available ICD on the system. The following diagram shows an approximate
- VK_KHR_swapchain
- VK_KHR_display
-In addition, each of the following OS targets for the loader support
+In addition, each of the following OS targets for the loader support
target-specific extensions:
| Windowing System | Extensions available |
* [Layer Library API Version 2](#layer-library-api-version-2)
* [Layer Library API Version 1](#layer-library-api-version-1)
* [Layer Library API Version 0](#layer-library-api-version-0)
-
-
+
+
#### Layer Discovery
As mentioned in the
#### Example Code for CreateDevice
```cpp
-VkResult
+VkResult
vkCreateDevice(
VkPhysicalDevice gpu,
const VkDeviceCreateInfo *pCreateInfo,
4. The loader will automatically collate all instance and device extensions in
a meta-layer's component layers, and report them as the meta-layer's properties
to the application when queried.
-
+
Restrictions to defining and using a meta-layer are:
1. A Meta-layer Manifest file **must** be a properly formatted that contains one
or more component layers.
be used.
4. All component layers **must be** at the same Vulkan API major and minor
version for the meta-layer to be used.
-
+
The ordering of a meta-layer's component layers in the instance or device
call-chain is simple:
* The first layer listed will be the layer closest to the application.
##### Associating Private Data with Vulkan Objects Within a Layer
A layer may want to associate its own private data with one or more Vulkan
-objects. Two common methods to do this are hash maps and object wrapping.
+objects. Two common methods to do this are hash maps and object wrapping.
###### Wrapping
* "library\_path"
* "api\_version"
-
+
### ICD Vulkan Entry Point Discovery
The Vulkan symbols exported by an ICD must not clash with the loader's exported
```
This function has very similar semantics to `vkGetInstanceProcAddr`.
-`vk_icdGetInstanceProcAddr` returns valid function pointers for all the
+`vk_icdGetInstanceProcAddr` returns valid function pointers for all the
global-level and instance-level Vulkan functions, and also for `vkGetDeviceProcAddr`.
Global-level functions are those which contain no dispatchable object as the
first parameter, such as `vkCreateInstance` and
-`vkEnumerateInstanceExtensionProperties`. The ICD must support querying
+`vkEnumerateInstanceExtensionProperties`. The ICD must support querying
global-level entry points by calling `vk_icdGetInstanceProcAddr` with a NULL
`VkInstance` parameter. Instance-level functions are those that have either
`VkInstance`, or `VkPhysicalDevice` as the first parameter dispatchable object.
All other Vulkan entry points must either:
* NOT be exported directly from the ICD library
* or NOT use the official Vulkan function names if they are exported
-
+
This requirement is for ICD libraries that include other
functionality (such as OpenGL) and thus could be loaded by the
application prior to when the Vulkan loader library is loaded by the
attempting to use the commands.
+### Physical Device Sorting
+
+When an application selects a GPU to use, it must enumerate physical devices or physical device groups.
+These API functions do not specify which order the physical devices or physical device groups will be presented in.
+On Windows, the loader will attempt to sort these objects so that the system preference will be listed first.
+This mechanism does not force an application to use any particular GPU — it merely changes the order in which they are presented.
+
+This mechanism requires that an ICD implement version 6 of the loader/ICD interface.
+Version 6 of this interface defines a new method that the ICD may provide on Windows:
+
+```c
+VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices);
+```
+
+This function takes an adapter LUID as input, and enumerates all Vulkan physical devices that are associated with that LUID.
+This works in the same way as other Vulkan enumerations — if `pPhysicalDevices` is `NULL`, then the count will be provided.
+Otherwise, the physical devices associated with the queried adapter will be provided.
+The function must provide multiple physical devices when the LUID referes to a linked adapter.
+This allows the loader to translate the adapter into Vulkan physical device groups.
+
+While the loader attempts to match the system's preference for GPU ordering, there are some limitations.
+Because this feature requires a new ICD interface, only physical devices from ICDs that support this function will be sorted.
+All unsorted physical devices will be listed at the end of the list, in an indeterminate order.
+Furthermore, only physical devices that correspond to an adapter may be sorted.
+This means that a software implementation would likely not be sorted.
+Finally, this API only applies to Windows systems and will only work on versions of Windows 10 that support GPU selection through the OS.
+Other platforms may be included in the future, but they will require separate platform-specific interfaces.
+
+
### ICD Dispatchable Object Creation
As previously covered, the loader requires dispatch tables to be accessible
pointer.
* **NOTE:** For any C\++ ICD's that implement VK objects directly as C\++
classes:
- * The C\++ compiler may put a vtable at offset zero if your class is
+ * The C\++ compiler may put a vtable at offset zero if your class is
non-POD due to the use of a virtual function.
* In this case use a regular C structure (see below).
3. The loader checks for a magic value (ICD\_LOADER\_MAGIC) in all the created
return newObj;
}
```
-
+
### Handling KHR Surface Objects in WSI Extensions
`vk_icdGetInstanceProcAddr` first, it supports at least version 1. Otherwise,
the loader only supports version 0.
+##### Loader Version 6 Interface Requirements
+
+Version 6 provides a mechanism to allow the loader to sort physical devices.
+The loader will only attempt to sort physical devices on an ICD if version 6 of the interface is supported.
+This version provides the `vk_icdEnumerateAdapterPhysicalDevices` function defined earlier in this document.
##### Loader Version 5 Interface Requirements
| VK_LAYER_PATH | Override the loader's standard Layer library search folders and use the provided delimited folders to search for layer Manifest files. | `export VK_LAYER_PATH=<path_a>:<path_b>`<br/><br/>`set VK_LAYER_PATH=<path_a>;<path_b>` |
| VK_LOADER_DISABLE_INST_EXT_FILTER | Disable the filtering out of instance extensions that the loader doesn't know about. This will allow applications to enable instance extensions exposed by ICDs but that the loader has no support for. **NOTE:** This may cause the loader or application to crash. | `export VK_LOADER_DISABLE_INST_EXT_FILTER=1`<br/><br/>`set VK_LOADER_DISABLE_INST_EXT_FILTER=1` |
| VK_LOADER_DEBUG | Enable loader debug messages. Options are:<br/>- error (only errors)<br/>- warn (warnings and errors)<br/>- info (info, warning, and errors)<br/> - debug (debug + all before) <br/> -all (report out all messages) | `export VK_LOADER_DEBUG=all`<br/><br/>`set VK_LOADER_DEBUG=warn` |
-
+
## Glossary of Terms
| Field Name | Field Value |