From d3170c06576563de83b93f4add806de09f7fc7e8 Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Sat, 19 Feb 2022 12:53:51 -0700 Subject: [PATCH] Refactor physical device extension code to use std::string Makes it harder for lifetime issues to appear since the extension strings are owned by the PhysicalDevice class rather than assuming they are correct. --- src/VkBootstrap.cpp | 52 +++++++++++++++++++++++++++------------------ src/VkBootstrap.h | 25 ++++------------------ 2 files changed, 35 insertions(+), 42 deletions(-) diff --git a/src/VkBootstrap.cpp b/src/VkBootstrap.cpp index 62eb3f6..573bdea 100644 --- a/src/VkBootstrap.cpp +++ b/src/VkBootstrap.cpp @@ -858,16 +858,12 @@ void destroy_debug_messenger(VkInstance const instance, VkDebugUtilsMessengerEXT namespace detail { -std::vector check_device_extension_support(VkPhysicalDevice device, std::vector desired_extensions) { - std::vector available_extensions; - auto available_extensions_ret = detail::get_vector( - available_extensions, detail::vulkan_functions().fp_vkEnumerateDeviceExtensionProperties, device, nullptr); - if (available_extensions_ret != VK_SUCCESS) return {}; - - std::vector extensions_to_enable; - for (const auto& extension : available_extensions) { +std::vector check_device_extension_support( + std::vector const& available_extensions, std::vector const& desired_extensions) { + std::vector extensions_to_enable; + for (const auto& avail_ext : available_extensions) { for (auto& req_ext : desired_extensions) { - if (strcmp(req_ext, extension.extensionName) == 0) { + if (avail_ext == req_ext) { extensions_to_enable.push_back(req_ext); break; } @@ -1013,6 +1009,14 @@ PhysicalDevice PhysicalDeviceSelector::populate_device_details(VkPhysicalDevice physical_device.name = physical_device.properties.deviceName; + std::vector available_extensions; + auto available_extensions_ret = detail::get_vector( + available_extensions, detail::vulkan_functions().fp_vkEnumerateDeviceExtensionProperties, vk_phys_device, nullptr); + if (available_extensions_ret != VK_SUCCESS) return physical_device; + for (const auto& ext : available_extensions) { + physical_device.extensions.push_back(&ext.extensionName[0]); + } + #if defined(VKB_VK_API_VERSION_1_1) physical_device.features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; #else @@ -1084,11 +1088,11 @@ PhysicalDevice::Suitable PhysicalDeviceSelector::is_device_suitable(PhysicalDevi if (criteria.require_present && !present_queue && !criteria.defer_surface_initialization) return PhysicalDevice::Suitable::no; - auto required_extensions_supported = detail::check_device_extension_support(pd.physical_device, criteria.required_extensions); + auto required_extensions_supported = detail::check_device_extension_support(pd.extensions, criteria.required_extensions); if (required_extensions_supported.size() != criteria.required_extensions.size()) return PhysicalDevice::Suitable::no; - auto desired_extensions_supported = detail::check_device_extension_support(pd.physical_device, criteria.desired_extensions); + auto desired_extensions_supported = detail::check_device_extension_support(pd.extensions, criteria.desired_extensions); if (desired_extensions_supported.size() != criteria.desired_extensions.size()) suitable = PhysicalDevice::Suitable::partial; @@ -1178,12 +1182,11 @@ detail::Result> PhysicalDeviceSelector::select_impl( auto fill_out_phys_dev_with_criteria = [&](PhysicalDevice& phys_dev) { phys_dev.features = criteria.required_features; phys_dev.extended_features_chain = criteria.extended_features_chain; - phys_dev.extensions_to_enable.insert( - phys_dev.extensions_to_enable.end(), criteria.required_extensions.begin(), criteria.required_extensions.end()); - auto desired_extensions_supported = - detail::check_device_extension_support(phys_dev.physical_device, criteria.desired_extensions); - phys_dev.extensions_to_enable.insert( - phys_dev.extensions_to_enable.end(), desired_extensions_supported.begin(), desired_extensions_supported.end()); + phys_dev.extensions.insert( + phys_dev.extensions.end(), criteria.required_extensions.begin(), criteria.required_extensions.end()); + auto desired_extensions_supported = detail::check_device_extension_support(phys_dev.extensions, criteria.desired_extensions); + phys_dev.extensions.insert( + phys_dev.extensions.end(), desired_extensions_supported.begin(), desired_extensions_supported.end()); }; // if this option is set, always return only the first physical device found @@ -1298,7 +1301,9 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::add_required_extension(const cha return *this; } PhysicalDeviceSelector& PhysicalDeviceSelector::add_required_extensions(std::vector extensions) { - criteria.required_extensions.insert(criteria.required_extensions.end(), extensions.begin(), extensions.end()); + for (const auto& ext : extensions) { + criteria.required_extensions.push_back(ext); + } return *this; } PhysicalDeviceSelector& PhysicalDeviceSelector::add_desired_extension(const char* extension) { @@ -1306,7 +1311,9 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::add_desired_extension(const char return *this; } PhysicalDeviceSelector& PhysicalDeviceSelector::add_desired_extensions(std::vector extensions) { - criteria.desired_extensions.insert(criteria.desired_extensions.end(), extensions.begin(), extensions.end()); + for (const auto& ext : extensions) { + criteria.desired_extensions.push_back(ext); + } return *this; } PhysicalDeviceSelector& PhysicalDeviceSelector::set_minimum_version(uint32_t major, uint32_t minor) { @@ -1364,7 +1371,7 @@ bool PhysicalDevice::has_separate_transfer_queue() const { return detail::get_separate_queue_index(queue_families, VK_QUEUE_TRANSFER_BIT, VK_QUEUE_COMPUTE_BIT) != detail::QUEUE_INDEX_MAX_VALUE; } std::vector PhysicalDevice::get_queue_families() const { return queue_families; } -std::vector PhysicalDevice::get_extensions() const { return extensions_to_enable; } +std::vector PhysicalDevice::get_extensions() const { return extensions; } PhysicalDevice::operator VkPhysicalDevice() const { return this->physical_device; } // ---- Queues ---- // @@ -1471,7 +1478,10 @@ detail::Result DeviceBuilder::build() const { queueCreateInfos.push_back(queue_create_info); } - std::vector extensions = physical_device.extensions_to_enable; + std::vector extensions; + for (const auto& ext : physical_device.extensions) { + extensions.push_back(ext.c_str()); + } if (physical_device.surface != VK_NULL_HANDLE || physical_device.defer_surface_initialization) extensions.push_back({ VK_KHR_SWAPCHAIN_EXTENSION_NAME }); diff --git a/src/VkBootstrap.h b/src/VkBootstrap.h index cd60a93..8c7cbd8 100644 --- a/src/VkBootstrap.h +++ b/src/VkBootstrap.h @@ -481,7 +481,7 @@ struct PhysicalDevice { std::vector get_queue_families() const; // Query the list of extensions which should be enabled - std::vector get_extensions() const; + std::vector get_extensions() const; // A conversion function which allows this PhysicalDevice to be used // in places where VkPhysicalDevice would have been used. @@ -489,7 +489,7 @@ struct PhysicalDevice { private: uint32_t instance_version = VKB_VK_API_VERSION_1_0; - std::vector extensions_to_enable; + std::vector extensions; std::vector queue_families; std::vector extended_features_chain; #if defined(VKB_VK_API_VERSION_1_1) @@ -620,23 +620,6 @@ class PhysicalDeviceSelector { bool supports_properties2_ext = false; } instance_info; - struct PhysicalDeviceDesc { - VkPhysicalDevice phys_device = VK_NULL_HANDLE; - std::vector queue_families; - - VkPhysicalDeviceFeatures device_features{}; - VkPhysicalDeviceProperties device_properties{}; - VkPhysicalDeviceMemoryProperties mem_properties{}; - -// Because the KHR version is a typedef in Vulkan 1.1, it is safe to define one or the other. -#if defined(VKB_VK_API_VERSION_1_1) - VkPhysicalDeviceFeatures2 device_features2{}; -#else - VkPhysicalDeviceFeatures2KHR device_features2{}; -#endif - std::vector extended_features_chain; - }; - // We copy the extension features stored in the selector criteria under the prose of a // "template" to ensure that after fetching everything is compared 1:1 during a match. @@ -652,8 +635,8 @@ class PhysicalDeviceSelector { VkDeviceSize required_mem_size = 0; VkDeviceSize desired_mem_size = 0; - std::vector required_extensions; - std::vector desired_extensions; + std::vector required_extensions; + std::vector desired_extensions; uint32_t required_version = VKB_VK_API_VERSION_1_0; uint32_t desired_version = VKB_VK_API_VERSION_1_0;