Skip to content

Commit

Permalink
Consistent loader device ordering
Browse files Browse the repository at this point in the history
The loader ICD ordering could be random on Linux based on using readdir
to find ICD manifest files.  This can result in random behaviors as
applications that select only the first device can switch which device is
used.  To resolve this, we now sort based on device type and then
internally to the types based on PCI bus information.

This also introduces a VK_LOADER_DEFAULT_DEVICE environment variable
that can be used to force a specific PCI device.  This environment variable
is actually a duplicate of the MESA_VK_DEVICE_SELECT variable, which is
also looked for if the loader environment variable is not found.

Note, that at least one ICD must support it for the extension to be used at all.
So we only do the sorting if one ICD supports it.

Fixes part of #657
  • Loading branch information
MarkY-LunarG committed Jan 12, 2022
1 parent 1fb5697 commit cbe28ac
Show file tree
Hide file tree
Showing 12 changed files with 1,191 additions and 74 deletions.
6 changes: 6 additions & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,12 @@ if (!is_android) {
}
libs = [ "Cfgmgr32.lib" ]
}
if (is_linux) {
sources += [
"loader/loader_linux.c",
"loader/loader_linux.h",
]
}
if (is_mac) {
frameworks = [ "CoreFoundation.framework" ]
}
Expand Down
34 changes: 34 additions & 0 deletions docs/LoaderApplicationInterface.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
* [Instance and Device Extensions](#instance-and-device-extensions)
* [WSI Extensions](#wsi-extensions)
* [Unknown Extensions](#unknown-extensions)
* [Physical Device Ordering](#physical-device-ordering)

## Overview

Expand Down Expand Up @@ -888,5 +889,38 @@ variable to a non-zero number.
This will effectively disable the loader's filtering of instance extension
names.

## Physical Device Ordering

Prior to the 1.2.204 loader, physical devices on Linux could be returned in an
inconsistent order.
To remedy this, the Vulkan loader will now sort devices once they have been
received from the drivers (before returning the information to any enabled
layers) in the following fashion:
* Sort based on device type (Discrete, Integrated, Virtual, all others)
* Sort internal to the types based on PCI information (Domain, Bus, Device, and
Function).

This allows for a consistent physical device order from run to run on the same
system, unless the actual underlying hardware changes.

A new environment variable is defined to give users the ability to force a
specific device, `VK_LOADER_DEVICE_SELECT`.
This environment variable should be set to the desired devices hex value for
Vendor Id and Device Id (as returned from `vkGetPhysicalDeviceProperties` in
the `VkPhysicalDeviceProperties` structure).
It should look like the following:

```
set VK_LOADER_DEVICE_SELECT=0x10de:0x1f91
```

This will force on the device with a vendor ID of "0x10de" and a device ID
of "0x1f91".
If that device is not found, this is simply ignored.

All device selection work done in the loader can be disabled by setting the
environment variable `VK_LOADER_DISABLE_SELECT` to a non-zero value.
This is intended for debug purposes to narrow down any issues with the loader
device selection mechanism, but can be used by others.

[Return to the top-level LoaderInterfaceArchitecture.md file.](LoaderInterfaceArchitecture.md)
21 changes: 21 additions & 0 deletions docs/LoaderInterfaceArchitecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,27 @@ discovery.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;path_a&gt;;&lt;path_b&gt;</small>
</td>
</tr>
<tr>
<td><small><i>VK_LOADER_DEVICE_SELECT</i></small></td>
<td><b>Linux Only</b><br/>
Allows the user to force a particular device to be prioritized above all
other devices in the return order of <i>vkGetPhysicalDevices<i> and
<i>vkGetPhysicalDeviceGroups<i> functions.<br/>
The value should be "<hex vendor id>:<hex device id>".<br/>
<b>NOTE:</b> This not remove devices.
</td>
<td><small>set VK_LOADER_DEVICE_SELECT=0x10de:0x1f91</small>
</td>
</tr>
<tr>
<td><small><i>VK_LOADER_DISABLE_SELECT</i></small></td>
<td><b>Linux Only</b><br/>
Allows the user to disable the consistent sorting algorithm run in the
loader before returning the set of physical devices to layers.<br/>
</td>
<td><small>set VK_LOADER_DISABLE_SELECT=1</small>
</td>
</tr>
<tr>
<td><small><i>VK_LOADER_DISABLE_INST_EXT_FILTER</i></small></td>
<td>Disable the filtering out of instance extensions that the loader doesn't
Expand Down
3 changes: 3 additions & 0 deletions loader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ set(NORMAL_LOADER_SRCS

if(WIN32)
set(NORMAL_LOADER_SRCS ${NORMAL_LOADER_SRCS} loader_windows.c)
else(UNIX AND NOT APPLE) # i.e.: Linux
set(NORMAL_LOADER_SRCS ${NORMAL_LOADER_SRCS} loader_linux.c)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS LOADER_ENABLE_LINUX_SORT)
endif()

set(OPT_LOADER_SRCS dev_ext_trampoline.c phys_dev_ext.c)
Expand Down
Loading

0 comments on commit cbe28ac

Please sign in to comment.