vulkan: pick the first device with the highest score when multiple have the same score.

This commit is contained in:
Sasha Szpakowski
2025-02-02 10:57:22 -04:00
parent 2e0b85a005
commit cc88b94ac4
2 changed files with 24 additions and 24 deletions
+24 -23
View File
@@ -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<VkPhysicalDevice> devices(deviceCount);
vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
std::multimap<int, VkPhysicalDevice> candidates;
std::vector<DeviceRating> 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<VkExtensionProperties> availableExtensions(extensionCount);
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());
std::set<std::string> 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