From 4a464a61aa9eceb330f7cabc52b25bfcaf34227c Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Thu, 6 Feb 2020 16:56:50 -0700 Subject: [PATCH] Made it possible to specify the desired queue priorities. If none are provided, it will use 1.0f for everything. --- src/VkBootstrap.cpp | 111 +++++++++++++++++++++++++++++++++----------- src/VkBootstrap.h | 34 ++++++++++---- 2 files changed, 111 insertions(+), 34 deletions(-) diff --git a/src/VkBootstrap.cpp b/src/VkBootstrap.cpp index d7e7412..a6f9db7 100644 --- a/src/VkBootstrap.cpp +++ b/src/VkBootstrap.cpp @@ -560,11 +560,11 @@ PhysicalDeviceSelector::Suitable PhysicalDeviceSelector::is_device_suitable (VkP VkPhysicalDeviceProperties device_properties; vkGetPhysicalDeviceProperties (phys_device, &device_properties); - if ((criteria.preferred_type == PreferredDevice::discrete && + if ((criteria.preferred_type == PreferredDeviceType::discrete && device_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) || - (criteria.preferred_type == PreferredDevice::integrated && + (criteria.preferred_type == PreferredDeviceType::integrated && device_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) || - (criteria.preferred_type == PreferredDevice::virtual_gpu && + (criteria.preferred_type == PreferredDeviceType::virtual_gpu && device_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU)) { if (criteria.allow_fallback) suitable = Suitable::partial; @@ -598,15 +598,22 @@ detail::Expected PhysicalDeviceSelector::select () { if (!physical_devices.has_value ()) { return detail::Error{ physical_devices.error ().error_code, "Failed to find physical devices" }; } + if (physical_devices.value ().size () == 0) { + return detail::Error{ VK_ERROR_INITIALIZATION_FAILED, "No physical devices found" }; + } PhysicalDevice physical_device; - for (const auto& device : physical_devices.value ()) { - auto suitable = is_device_suitable (device); - if (suitable == Suitable::yes) { - physical_device.phys_device = device; - break; - } else if (suitable == Suitable::partial) { - physical_device.phys_device = device; + if (criteria.use_first_gpu_unconditionally) { + physical_device.phys_device = physical_devices.value ().at (0); + } else { + for (const auto& device : physical_devices.value ()) { + auto suitable = is_device_suitable (device); + if (suitable == Suitable::yes) { + physical_device.phys_device = device; + break; + } else if (suitable == Suitable::partial) { + physical_device.phys_device = device; + } } } @@ -638,19 +645,11 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::set_surface (VkSurfaceKHR surfac info.headless = false; return *this; } -PhysicalDeviceSelector& PhysicalDeviceSelector::prefer_discrete () { - criteria.preferred_type = PreferredDevice::discrete; +PhysicalDeviceSelector& PhysicalDeviceSelector::prefer_gpu_device_type (PreferredDeviceType type) { + criteria.preferred_type = type; return *this; } -PhysicalDeviceSelector& PhysicalDeviceSelector::prefer_integrated () { - criteria.preferred_type = PreferredDevice::integrated; - return *this; -} -PhysicalDeviceSelector& PhysicalDeviceSelector::prefer_virtual_gpu () { - criteria.preferred_type = PreferredDevice::virtual_gpu; - return *this; -} -PhysicalDeviceSelector& PhysicalDeviceSelector::allow_fallback (bool fallback) { +PhysicalDeviceSelector& PhysicalDeviceSelector::allow_fallback_gpu (bool fallback) { criteria.allow_fallback = fallback; return *this; } @@ -678,10 +677,20 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::add_required_extension (std::str criteria.required_extensions.push_back (extension); return *this; } +PhysicalDeviceSelector& PhysicalDeviceSelector::add_required_extensions (std::vector extensions) { + criteria.required_extensions.insert ( + criteria.required_extensions.end (), extensions.begin (), extensions.end ()); + return *this; +} PhysicalDeviceSelector& PhysicalDeviceSelector::add_desired_extension (std::string extension) { criteria.desired_extensions.push_back (extension); return *this; } +PhysicalDeviceSelector& PhysicalDeviceSelector::add_desired_extensions (std::vector extensions) { + criteria.desired_extensions.insert ( + criteria.desired_extensions.end (), extensions.begin (), extensions.end ()); + return *this; +} PhysicalDeviceSelector& PhysicalDeviceSelector::set_minimum_version (uint32_t major, uint32_t minor) { criteria.required_version = VK_MAKE_VERSION (major, minor, 0); return *this; @@ -694,6 +703,14 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::set_required_features (VkPhysica criteria.required_features = features; return *this; } +PhysicalDeviceSelector& PhysicalDeviceSelector::set_desired_features (VkPhysicalDeviceFeatures features) { + criteria.desired_features = features; + return *this; +} +PhysicalDeviceSelector& PhysicalDeviceSelector::select_first_device_unconditionally (bool unconditionally) { + criteria.use_first_gpu_unconditionally = unconditionally; + return *this; +} // ---- Device ---- // @@ -711,16 +728,33 @@ DeviceBuilder::DeviceBuilder (PhysicalDevice phys_device) { detail::Expected DeviceBuilder::build () { auto& queue_properties = info.physical_device.queue_family_properties; std::vector families; - families.push_back ({ queue_properties.graphics, std::vector (queue_properties.count_graphics) }); - if (queue_properties.compute != -1 && queue_properties.compute != queue_properties.graphics) - families.push_back ({ queue_properties.compute, std::vector (queue_properties.count_compute) }); + + families.push_back ({ queue_properties.graphics, + info.graphics_queue_priorities.size () == 0 ? + std::vector (info.use_multiple_queues_per_family ? queue_properties.count_graphics : 1, 1.0f) : + info.graphics_queue_priorities }); + + if (queue_properties.compute != -1 && queue_properties.compute != queue_properties.graphics) { + families.push_back ({ queue_properties.compute, + info.compute_queue_priorities.size () == 0 ? + std::vector (info.use_multiple_queues_per_family ? queue_properties.count_compute : 1, 1.0f) : + info.compute_queue_priorities }); + } + if (queue_properties.transfer != -1 && queue_properties.transfer != queue_properties.graphics && queue_properties.transfer != queue_properties.compute) - families.push_back ({ queue_properties.transfer, std::vector (queue_properties.count_transfer) }); + families.push_back ({ queue_properties.transfer, + info.transfer_queue_priorities.size () == 0 ? + std::vector (info.use_multiple_queues_per_family ? queue_properties.count_transfer : 1, 1.0f) : + info.transfer_queue_priorities }); + if (queue_properties.sparse != -1 && queue_properties.sparse != queue_properties.graphics && queue_properties.sparse != queue_properties.compute && queue_properties.sparse != queue_properties.transfer) - families.push_back ({ queue_properties.sparse, std::vector (queue_properties.count_sparse) }); + families.push_back ({ queue_properties.sparse, + info.sparse_queue_priorities.size () == 0 ? + std::vector (info.use_multiple_queues_per_family ? queue_properties.count_sparse : 1, 1.0f) : + info.sparse_queue_priorities }); std::vector queueCreateInfos; for (auto& queue : families) { @@ -763,6 +797,31 @@ template DeviceBuilder& DeviceBuilder::add_pNext (T* structure) { info.pNext_chain.push_back (reinterpret_cast (structure)); return *this; } +DeviceBuilder& DeviceBuilder::use_multiple_queues_per_family (bool multi_queue) { + info.use_multiple_queues_per_family = true; + return *this; +} +DeviceBuilder& DeviceBuilder::set_graphics_queue_priorities (std::vector priorities) { + if (info.physical_device.queue_family_properties.count_graphics >= priorities.size ()) + info.graphics_queue_priorities = priorities; + return *this; +} +DeviceBuilder& DeviceBuilder::set_compute_queue_priorities (std::vector priorities) { + if (info.physical_device.queue_family_properties.count_compute >= priorities.size ()) + info.compute_queue_priorities = priorities; + return *this; +} +DeviceBuilder& DeviceBuilder::set_transfer_queue_priorities (std::vector priorities) { + if (info.physical_device.queue_family_properties.count_transfer >= priorities.size ()) + info.transfer_queue_priorities = priorities; + return *this; +} +DeviceBuilder& DeviceBuilder::set_sparse_queue_priorities (std::vector priorities) { + if (info.physical_device.queue_family_properties.count_sparse >= priorities.size ()) + info.sparse_queue_priorities = priorities; + return *this; +} + // ---- Queue ---- // diff --git a/src/VkBootstrap.h b/src/VkBootstrap.h index 6788846..590db40 100644 --- a/src/VkBootstrap.h +++ b/src/VkBootstrap.h @@ -236,11 +236,9 @@ struct PhysicalDeviceSelector { PhysicalDeviceSelector& set_surface (VkSurfaceKHR instance); - PhysicalDeviceSelector& prefer_discrete (); - PhysicalDeviceSelector& prefer_integrated (); - PhysicalDeviceSelector& prefer_virtual_gpu (); - - PhysicalDeviceSelector& allow_fallback (bool fallback = true); + enum PreferredDeviceType { discrete, integrated, virtual_gpu, cpu, dont_care }; + PhysicalDeviceSelector& prefer_gpu_device_type (PreferredDeviceType type = PreferredDeviceType::discrete); + PhysicalDeviceSelector& allow_fallback_gpu (bool fallback = true); PhysicalDeviceSelector& require_present (bool require = true); PhysicalDeviceSelector& require_dedicated_transfer_queue (); @@ -250,12 +248,18 @@ struct PhysicalDeviceSelector { PhysicalDeviceSelector& desired_device_memory_size (VkDeviceSize size); PhysicalDeviceSelector& add_required_extension (std::string extension); + PhysicalDeviceSelector& add_required_extensions (std::vector extensions); + PhysicalDeviceSelector& add_desired_extension (std::string extension); + PhysicalDeviceSelector& add_desired_extensions (std::vector extensions); PhysicalDeviceSelector& set_desired_version (uint32_t major, uint32_t minor); PhysicalDeviceSelector& set_minimum_version (uint32_t major = 1, uint32_t minor = 0); PhysicalDeviceSelector& set_required_features (VkPhysicalDeviceFeatures features); + PhysicalDeviceSelector& set_desired_features (VkPhysicalDeviceFeatures features); + + PhysicalDeviceSelector& select_first_device_unconditionally (bool unconditionally = true); private: struct PhysicalDeviceInfo { @@ -264,10 +268,8 @@ struct PhysicalDeviceSelector { bool headless = false; } info; - enum PreferredDevice { discrete, integrated, virtual_gpu, cpu, dont_care }; - struct SelectionCriteria { - PreferredDevice preferred_type = PreferredDevice::discrete; + PreferredDeviceType preferred_type = PreferredDeviceType::discrete; bool allow_fallback = true; bool require_present = true; bool require_dedicated_transfer_queue = false; @@ -284,6 +286,7 @@ struct PhysicalDeviceSelector { VkPhysicalDeviceFeatures required_features{}; VkPhysicalDeviceFeatures desired_features{}; + bool use_first_gpu_unconditionally = false; } criteria; enum class Suitable { yes, partial, no }; @@ -308,12 +311,27 @@ class DeviceBuilder { template DeviceBuilder& add_pNext (T* structure); + DeviceBuilder& use_multiple_queues_per_family (bool multi_queue = true); + + DeviceBuilder& set_graphics_queue_priorities (std::vector priorities); + DeviceBuilder& set_compute_queue_priorities (std::vector priorities); + DeviceBuilder& set_transfer_queue_priorities (std::vector priorities); + DeviceBuilder& set_sparse_queue_priorities (std::vector priorities); + + private: struct DeviceInfo { VkDeviceCreateFlags flags; std::vector pNext_chain; PhysicalDevice physical_device; std::vector extensions; + + bool use_multiple_queues_per_family = false; + std::vector graphics_queue_priorities; + std::vector compute_queue_priorities; + std::vector transfer_queue_priorities; + std::vector sparse_queue_priorities; + } info; };