forked from suyu/suyu
vulkan/wrapper: Sort physical devices
Sort discrete GPUs over the rest, Nvidia over AMD, AMD over Intel, Intel over the rest. This gives us a somewhat consistent order when Optimus is removed (renderdoc does this when it's attached). This can break the configuration of users with an Intel GPU that manually remove Optimus on yuzu. That said, it's a very unlikely to happen.
This commit is contained in:
parent
5305806071
commit
c81bf06d03
1 changed files with 20 additions and 1 deletions
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
@ -16,6 +17,23 @@ namespace Vulkan::vk {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
void SortPhysicalDevices(std::vector<VkPhysicalDevice>& devices, const InstanceDispatch& dld) {
|
||||||
|
std::stable_sort(devices.begin(), devices.end(), [&](auto lhs, auto rhs) {
|
||||||
|
// This will call Vulkan more than needed, but these calls are cheap.
|
||||||
|
const auto lhs_properties = vk::PhysicalDevice(lhs, dld).GetProperties();
|
||||||
|
const auto rhs_properties = vk::PhysicalDevice(rhs, dld).GetProperties();
|
||||||
|
|
||||||
|
// Prefer discrete GPUs, Nvidia over AMD, AMD over Intel, Intel over the rest.
|
||||||
|
const bool preferred =
|
||||||
|
(lhs_properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
|
||||||
|
rhs_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) ||
|
||||||
|
(lhs_properties.vendorID == 0x10DE && rhs_properties.vendorID != 0x10DE) ||
|
||||||
|
(lhs_properties.vendorID == 0x1002 && rhs_properties.vendorID != 0x1002) ||
|
||||||
|
(lhs_properties.vendorID == 0x8086 && rhs_properties.vendorID != 0x8086);
|
||||||
|
return !preferred;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool Proc(T& result, const InstanceDispatch& dld, const char* proc_name,
|
bool Proc(T& result, const InstanceDispatch& dld, const char* proc_name,
|
||||||
VkInstance instance = nullptr) noexcept {
|
VkInstance instance = nullptr) noexcept {
|
||||||
|
@ -383,7 +401,8 @@ std::optional<std::vector<VkPhysicalDevice>> Instance::EnumeratePhysicalDevices(
|
||||||
if (dld->vkEnumeratePhysicalDevices(handle, &num, physical_devices.data()) != VK_SUCCESS) {
|
if (dld->vkEnumeratePhysicalDevices(handle, &num, physical_devices.data()) != VK_SUCCESS) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
return physical_devices;
|
SortPhysicalDevices(physical_devices, *dld);
|
||||||
|
return std::make_optional(std::move(physical_devices));
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugCallback Instance::TryCreateDebugCallback(
|
DebugCallback Instance::TryCreateDebugCallback(
|
||||||
|
|
Loading…
Reference in a new issue