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.
This commit is contained in:
Charles Giessen 2022-02-19 12:53:51 -07:00 committed by Charles Giessen
parent 5f45b1019a
commit d3170c0657
2 changed files with 35 additions and 42 deletions

View File

@ -858,16 +858,12 @@ void destroy_debug_messenger(VkInstance const instance, VkDebugUtilsMessengerEXT
namespace detail {
std::vector<const char*> check_device_extension_support(VkPhysicalDevice device, std::vector<const char*> desired_extensions) {
std::vector<VkExtensionProperties> available_extensions;
auto available_extensions_ret = detail::get_vector<VkExtensionProperties>(
available_extensions, detail::vulkan_functions().fp_vkEnumerateDeviceExtensionProperties, device, nullptr);
if (available_extensions_ret != VK_SUCCESS) return {};
std::vector<const char*> extensions_to_enable;
for (const auto& extension : available_extensions) {
std::vector<std::string> check_device_extension_support(
std::vector<std::string> const& available_extensions, std::vector<std::string> const& desired_extensions) {
std::vector<std::string> 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<VkExtensionProperties> available_extensions;
auto available_extensions_ret = detail::get_vector<VkExtensionProperties>(
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<std::vector<PhysicalDevice>> 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<const char*> 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<const char*> 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<VkQueueFamilyProperties> PhysicalDevice::get_queue_families() const { return queue_families; }
std::vector<const char*> PhysicalDevice::get_extensions() const { return extensions_to_enable; }
std::vector<std::string> PhysicalDevice::get_extensions() const { return extensions; }
PhysicalDevice::operator VkPhysicalDevice() const { return this->physical_device; }
// ---- Queues ---- //
@ -1471,7 +1478,10 @@ detail::Result<Device> DeviceBuilder::build() const {
queueCreateInfos.push_back(queue_create_info);
}
std::vector<const char*> extensions = physical_device.extensions_to_enable;
std::vector<const char*> 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 });

View File

@ -481,7 +481,7 @@ struct PhysicalDevice {
std::vector<VkQueueFamilyProperties> get_queue_families() const;
// Query the list of extensions which should be enabled
std::vector<const char*> get_extensions() const;
std::vector<std::string> 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<const char*> extensions_to_enable;
std::vector<std::string> extensions;
std::vector<VkQueueFamilyProperties> queue_families;
std::vector<detail::GenericFeaturesPNextNode> 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<VkQueueFamilyProperties> 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<detail::GenericFeaturesPNextNode> 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<const char*> required_extensions;
std::vector<const char*> desired_extensions;
std::vector<std::string> required_extensions;
std::vector<std::string> desired_extensions;
uint32_t required_version = VKB_VK_API_VERSION_1_0;
uint32_t desired_version = VKB_VK_API_VERSION_1_0;