diff options
| author | 2020-10-07 17:13:20 -0300 | |
|---|---|---|
| committer | 2020-10-07 17:13:22 -0300 | |
| commit | cd3e959f237352f863e16ce7ca94f837c4f611db (patch) | |
| tree | 3aecb02125792de009095b91b5f81cf24b323f3d /src | |
| parent | Merge pull request #4710 from Morph1984/fix-integrated-updates (diff) | |
| download | yuzu-cd3e959f237352f863e16ce7ca94f837c4f611db.tar.gz yuzu-cd3e959f237352f863e16ce7ca94f837c4f611db.tar.xz yuzu-cd3e959f237352f863e16ce7ca94f837c4f611db.zip | |
renderer_vulkan/wrapper: Fix physical device sorting
The old code had a sort function that was invalid and it didn't work as
expected when the base vector had a different order (e.g. renderdoc was
attached).
This sorts devices as expected and fixes a debug assert on MSVC.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_vulkan/wrapper.cpp | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/src/video_core/renderer_vulkan/wrapper.cpp b/src/video_core/renderer_vulkan/wrapper.cpp index 1fb14e190..2598440fb 100644 --- a/src/video_core/renderer_vulkan/wrapper.cpp +++ b/src/video_core/renderer_vulkan/wrapper.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <exception> | 6 | #include <exception> |
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <optional> | 8 | #include <optional> |
| 9 | #include <string_view> | ||
| 9 | #include <utility> | 10 | #include <utility> |
| 10 | #include <vector> | 11 | #include <vector> |
| 11 | 12 | ||
| @@ -17,21 +18,42 @@ namespace Vulkan::vk { | |||
| 17 | 18 | ||
| 18 | namespace { | 19 | namespace { |
| 19 | 20 | ||
| 21 | template <typename Func> | ||
| 22 | void SortPhysicalDevices(std::vector<VkPhysicalDevice>& devices, const InstanceDispatch& dld, | ||
| 23 | Func&& func) { | ||
| 24 | // Calling GetProperties calls Vulkan more than needed. But they are supposed to be cheap | ||
| 25 | // functions. | ||
| 26 | std::stable_sort(devices.begin(), devices.end(), | ||
| 27 | [&dld, &func](VkPhysicalDevice lhs, VkPhysicalDevice rhs) { | ||
| 28 | return func(vk::PhysicalDevice(lhs, dld).GetProperties(), | ||
| 29 | vk::PhysicalDevice(rhs, dld).GetProperties()); | ||
| 30 | }); | ||
| 31 | } | ||
| 32 | |||
| 33 | void SortPhysicalDevicesPerVendor(std::vector<VkPhysicalDevice>& devices, | ||
| 34 | const InstanceDispatch& dld, | ||
| 35 | std::initializer_list<u32> vendor_ids) { | ||
| 36 | for (auto it = vendor_ids.end(); it != vendor_ids.begin();) { | ||
| 37 | --it; | ||
| 38 | SortPhysicalDevices(devices, dld, [id = *it](const auto& lhs, const auto& rhs) { | ||
| 39 | return lhs.vendorID == id && rhs.vendorID != id; | ||
| 40 | }); | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 20 | void SortPhysicalDevices(std::vector<VkPhysicalDevice>& devices, const InstanceDispatch& dld) { | 44 | void SortPhysicalDevices(std::vector<VkPhysicalDevice>& devices, const InstanceDispatch& dld) { |
| 21 | std::stable_sort(devices.begin(), devices.end(), [&](auto lhs, auto rhs) { | 45 | // Sort by name, this will set a base and make GPUs with higher numbers appear first |
| 22 | // This will call Vulkan more than needed, but these calls are cheap. | 46 | // (e.g. GTX 1650 will intentionally be listed before a GTX 1080). |
| 23 | const auto lhs_properties = vk::PhysicalDevice(lhs, dld).GetProperties(); | 47 | SortPhysicalDevices(devices, dld, [](const auto& lhs, const auto& rhs) { |
| 24 | const auto rhs_properties = vk::PhysicalDevice(rhs, dld).GetProperties(); | 48 | return std::string_view{lhs.deviceName} > std::string_view{rhs.deviceName}; |
| 25 | 49 | }); | |
| 26 | // Prefer discrete GPUs, Nvidia over AMD, AMD over Intel, Intel over the rest. | 50 | // Prefer discrete over non-discrete |
| 27 | const bool preferred = | 51 | SortPhysicalDevices(devices, dld, [](const auto& lhs, const auto& rhs) { |
| 28 | (lhs_properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && | 52 | return lhs.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && |
| 29 | rhs_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) || | 53 | rhs.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 | }); | 54 | }); |
| 55 | // Prefer Nvidia over AMD, AMD over Intel, Intel over the rest. | ||
| 56 | SortPhysicalDevicesPerVendor(devices, dld, {0x10DE, 0x1002, 0x8086}); | ||
| 35 | } | 57 | } |
| 36 | 58 | ||
| 37 | template <typename T> | 59 | template <typename T> |