diff options
| -rw-r--r-- | src/video_core/renderer_vulkan/wrapper.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/src/video_core/renderer_vulkan/wrapper.cpp b/src/video_core/renderer_vulkan/wrapper.cpp index 9b94dfff1..cffa243e9 100644 --- a/src/video_core/renderer_vulkan/wrapper.cpp +++ b/src/video_core/renderer_vulkan/wrapper.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | ||
| 5 | #include <exception> | 6 | #include <exception> |
| 6 | #include <memory> | 7 | #include <memory> |
| 7 | #include <optional> | 8 | #include <optional> |
| @@ -16,6 +17,23 @@ namespace Vulkan::vk { | |||
| 16 | 17 | ||
| 17 | namespace { | 18 | namespace { |
| 18 | 19 | ||
| 20 | void SortPhysicalDevices(std::vector<VkPhysicalDevice>& devices, const InstanceDispatch& dld) { | ||
| 21 | std::stable_sort(devices.begin(), devices.end(), [&](auto lhs, auto rhs) { | ||
| 22 | // This will call Vulkan more than needed, but these calls are cheap. | ||
| 23 | const auto lhs_properties = vk::PhysicalDevice(lhs, dld).GetProperties(); | ||
| 24 | const auto rhs_properties = vk::PhysicalDevice(rhs, dld).GetProperties(); | ||
| 25 | |||
| 26 | // Prefer discrete GPUs, Nvidia over AMD, AMD over Intel, Intel over the rest. | ||
| 27 | const bool preferred = | ||
| 28 | (lhs_properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && | ||
| 29 | rhs_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) || | ||
| 30 | (lhs_properties.vendorID == 0x10DE && rhs_properties.vendorID != 0x10DE) || | ||
| 31 | (lhs_properties.vendorID == 0x1002 && rhs_properties.vendorID != 0x1002) || | ||
| 32 | (lhs_properties.vendorID == 0x8086 && rhs_properties.vendorID != 0x8086); | ||
| 33 | return !preferred; | ||
| 34 | }); | ||
| 35 | } | ||
| 36 | |||
| 19 | template <typename T> | 37 | template <typename T> |
| 20 | bool Proc(T& result, const InstanceDispatch& dld, const char* proc_name, | 38 | bool Proc(T& result, const InstanceDispatch& dld, const char* proc_name, |
| 21 | VkInstance instance = nullptr) noexcept { | 39 | VkInstance instance = nullptr) noexcept { |
| @@ -383,7 +401,8 @@ std::optional<std::vector<VkPhysicalDevice>> Instance::EnumeratePhysicalDevices( | |||
| 383 | if (dld->vkEnumeratePhysicalDevices(handle, &num, physical_devices.data()) != VK_SUCCESS) { | 401 | if (dld->vkEnumeratePhysicalDevices(handle, &num, physical_devices.data()) != VK_SUCCESS) { |
| 384 | return std::nullopt; | 402 | return std::nullopt; |
| 385 | } | 403 | } |
| 386 | return physical_devices; | 404 | SortPhysicalDevices(physical_devices, *dld); |
| 405 | return std::make_optional(std::move(physical_devices)); | ||
| 387 | } | 406 | } |
| 388 | 407 | ||
| 389 | DebugCallback Instance::TryCreateDebugCallback( | 408 | DebugCallback Instance::TryCreateDebugCallback( |