docs: Update loader doc with device sorting info
authorLenny Komow <lenny@lunarg.com>
Mon, 6 Apr 2020 14:07:37 +0000 (08:07 -0600)
committerLenny Komow <lenny@lunarg.com>
Fri, 14 Aug 2020 20:38:39 +0000 (14:38 -0600)
loader/LoaderAndLayerInterface.md

index 1533f0a..6fa5a24 100644 (file)
     * [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:
@@ -191,7 +192,7 @@ first parameter.  Some Vulkan Device functions are:
  * `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
@@ -268,7 +269,7 @@ the loader has to be aware of any instance-level extensions which work on a
 
 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)
 
@@ -298,7 +299,7 @@ including:
     * [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.
@@ -369,7 +370,7 @@ dispatch table so that all your Instance functions are queried using
 
 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
@@ -692,7 +693,7 @@ extension support:
 - 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 |
@@ -798,9 +799,9 @@ In this section we'll discuss how the loader interacts with layers, including:
     * [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
@@ -1432,7 +1433,7 @@ VkResult vkCreateInstance(
 #### Example Code for CreateDevice
 
 ```cpp
-VkResult 
+VkResult
 vkCreateDevice(
         VkPhysicalDevice gpu,
         const VkDeviceCreateInfo *pCreateInfo,
@@ -1492,7 +1493,7 @@ the meta-layer.
  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.
@@ -1500,7 +1501,7 @@ 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.
@@ -1609,7 +1610,7 @@ This means that implicit layers can use pre-instance intercepts to modify data t
 ##### 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
@@ -2313,7 +2314,7 @@ fields of a layer JSON file.  The fields of the 1.0.0 file format include:
  * "library\_path"
  * "api\_version"
 
+
 ###  ICD Vulkan Entry Point Discovery
 
 The Vulkan symbols exported by an ICD must not clash with the loader's exported
@@ -2330,11 +2331,11 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(
 ```
 
 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.
@@ -2348,7 +2349,7 @@ using these newly defined dispatchable objects must be queryable via
 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
@@ -2474,6 +2475,35 @@ until at least a Vulkan version bump, because an older loader may still be
 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 &mdash; 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 &mdash; 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
@@ -2489,7 +2519,7 @@ dispatchable objects created by ICDs are as follows:
    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
@@ -2514,7 +2544,7 @@ vkObj alloc_icd_obj()
     return newObj;
 }
 ```
+
 
 ### Handling KHR Surface Objects in WSI Extensions
 
@@ -2642,6 +2672,11 @@ is a legacy loader supporting version 0 or 1.  If the loader calls
 `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
 
@@ -2766,7 +2801,7 @@ of discovery.
 | 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 |