From a94f2da6b2bcf3931042231dc242bead96c06e93 Mon Sep 17 00:00:00 2001 From: homeburger Date: Tue, 19 May 2026 20:52:05 -0500 Subject: [PATCH] improve device selection logic --- src/Device.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++++----- src/Device.hpp | 3 +++ 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/Device.cpp b/src/Device.cpp index 92caf16..1ac37b7 100644 --- a/src/Device.cpp +++ b/src/Device.cpp @@ -47,10 +47,60 @@ uint32_t Device::evaluatePhysicalDevice(vk::raii::PhysicalDevice& device) { std::cout << "[" << __FUNCTION__ << ": " << __LINE__ << "] Physical device found: " << deviceProperties.deviceName << std::endl; - if(deviceProperties.deviceType == vk::PhysicalDeviceType::eDiscreteGpu) { - return 2; - } else { - return 1; - } // i.e. a descrete gpu is preferable to an integrated gpu + uint32_t score = 0; + // TODO: this is very basic and can be improved + + // prefer discrete graphics to integrated graphics + if(deviceProperties.deviceType == vk::PhysicalDeviceType::eDiscreteGpu) { + score += 2; + } else { + std::cout << "[" << __FUNCTION__ << ": " << __LINE__ << "] Warning: physical device " << deviceProperties.deviceName << " is not a discrete device!" << std::endl; + } + + // prefer devices that support vulkan 1.3 + if(deviceProperties.apiVersion >= vk::ApiVersion14) { + score++; + } else { + std::cout << "[" << __FUNCTION__ << ": " << __LINE__ << "] Warning: physical device " << deviceProperties.deviceName << " does not support Vulkan 1.3! (" << std::endl; + } + + // prefer devices that support graphics queues + auto queueFamilies = device.getQueueFamilyProperties(); + if(std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } )) { + score++; + } else { + std::cout << "[" << __FUNCTION__ << ": " << __LINE__ << "] Warning: physical device " << deviceProperties.deviceName << " does not support graphics queue families!" << std::endl; + } + + // prefer devices that support all required extensions + auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); + bool found = false; + uint32_t missingExtensions = 0; + for(auto& requiredExtension : requiredDeviceExtensions_) { + for(auto& availableExtension: availableDeviceExtensions) { + if(strcmp(availableExtension.extensionName, requiredExtension) == 0) { + found = true; + continue; + } + } + if(found == false) { + missingExtensions++; + } + } + if(missingExtensions == 0) { + score++; + } else { + std::cout << "[" << __FUNCTION__ << ": " << __LINE__ << "] Warning: physical device " << deviceProperties.deviceName << " is missing extensions!" << std::endl; + } + + // prefer devices that support all required features + auto features = device.template getFeatures2(); + if(features.template get().dynamicRendering && features.template get().extendedDynamicState) { + score++; + } else { + std::cout << "[" << __FUNCTION__ << ": " << __LINE__ << "] Warning: physical device " << deviceProperties.deviceName << " is missing features!" << std::endl; + } + + return score; } diff --git a/src/Device.hpp b/src/Device.hpp index a70bfd2..623980e 100644 --- a/src/Device.hpp +++ b/src/Device.hpp @@ -20,5 +20,8 @@ class Device { vk::raii::Instance* instance_ = nullptr; vk::raii::PhysicalDevice physicalDevice_ = nullptr; + + // required extensions for the physical device + std::vector requiredDeviceExtensions_ = { vk::KHRSwapchainExtensionName }; };