From cc88b94ac4e3c4c6cb090b4ae482881cbbeb78bc Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sun, 2 Feb 2025 10:57:22 -0400 Subject: [PATCH] vulkan: pick the first device with the highest score when multiple have the same score. --- src/modules/graphics/vulkan/Graphics.cpp | 47 ++++++++++++------------ src/modules/graphics/vulkan/Graphics.h | 1 - 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index ddacf2c1f..cdc0c7a91 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -1576,6 +1576,13 @@ bool Graphics::checkValidationSupport() void Graphics::pickPhysicalDevice() { + struct DeviceRating + { + VkPhysicalDevice device; + size_t deviceIndex; + int rating; + }; + uint32_t deviceCount = 0; vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr); @@ -1585,18 +1592,28 @@ void Graphics::pickPhysicalDevice() std::vector devices(deviceCount); vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data()); - std::multimap candidates; + std::vector candidates; - for (const auto &device : devices) + for (size_t i = 0; i < devices.size(); i++) { - int score = rateDeviceSuitability(device, true); - candidates.insert(std::make_pair(score, device)); + DeviceRating r = {}; + r.device = devices[i]; + r.deviceIndex = i; + r.rating = rateDeviceSuitability(devices[i], true); + candidates.push_back(r); } - if (candidates.rbegin()->first > 0) - physicalDevice = candidates.rbegin()->second; + std::sort(candidates.begin(), candidates.end(), [](const DeviceRating &a, const DeviceRating &b) -> bool + { + if (a.rating != b.rating) + return a.rating > b.rating; + return a.deviceIndex < b.deviceIndex; + }); + + if (!candidates.empty() && candidates[0].rating > 0) + physicalDevice = candidates[0].device; else - throw love::Exception("failed to find a suitable gpu"); + throw love::Exception("Vulkan: failed to find a suitable GPU."); VkPhysicalDeviceProperties properties; vkGetPhysicalDeviceProperties(physicalDevice, &properties); @@ -1618,22 +1635,6 @@ void Graphics::pickPhysicalDevice() } } -bool Graphics::checkDeviceExtensionSupport(VkPhysicalDevice device) -{ - uint32_t extensionCount; - vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr); - - std::vector availableExtensions(extensionCount); - vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data()); - - std::set requiredExtensions(deviceExtensions.begin(), deviceExtensions.end()); - - for (const auto &extension : availableExtensions) - requiredExtensions.erase(extension.extensionName); - - return requiredExtensions.empty(); -} - // if the score is nonzero then the device is suitable. // A higher rating means generally better performance // if the score is 0 the device is unsuitable diff --git a/src/modules/graphics/vulkan/Graphics.h b/src/modules/graphics/vulkan/Graphics.h index e393fb5ff..ec5d95a40 100644 --- a/src/modules/graphics/vulkan/Graphics.h +++ b/src/modules/graphics/vulkan/Graphics.h @@ -317,7 +317,6 @@ private: void createPipelineCache(); void initVMA(); void createSurface(); - bool checkDeviceExtensionSupport(VkPhysicalDevice device); SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device); VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector &availableFormats); VkPresentModeKHR chooseSwapPresentMode(const std::vector &availablePresentModes);