diff --git a/src/VkBootstrap.cpp b/src/VkBootstrap.cpp index 7fe74e9..8d5607a 100644 --- a/src/VkBootstrap.cpp +++ b/src/VkBootstrap.cpp @@ -846,8 +846,8 @@ std::vector check_device_extension_support( // clang-format off bool supports_features(VkPhysicalDeviceFeatures supported, VkPhysicalDeviceFeatures requested, - std::vector const& extension_supported, - std::vector const& extension_requested) { + std::vector const& extension_supported, + std::vector const& extension_requested) { if (requested.robustBufferAccess && !supported.robustBufferAccess) return false; if (requested.fullDrawIndexUint32 && !supported.fullDrawIndexUint32) return false; if (requested.imageCubeArray && !supported.imageCubeArray) return false; @@ -992,7 +992,7 @@ uint32_t get_present_queue_index(VkPhysicalDevice const phys_device, PhysicalDeviceSelector::PhysicalDeviceDesc PhysicalDeviceSelector::populate_device_details( uint32_t instance_version, VkPhysicalDevice phys_device, - std::vector extension_features_as_template) const { + std::vector extension_features_as_template) const { PhysicalDeviceSelector::PhysicalDeviceDesc desc{}; desc.phys_device = phys_device; auto queue_families = detail::get_vector_noerror( @@ -1007,15 +1007,15 @@ PhysicalDeviceSelector::PhysicalDeviceDesc PhysicalDeviceSelector::populate_devi desc.device_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; desc.extension_features = extension_features_as_template; if (instance_version >= VK_API_VERSION_1_1) { - detail::FeaturesContainer* prev = nullptr; + detail::ExtensionFeatures* prev = nullptr; for(auto& extension : desc.extension_features) { if(prev != nullptr) { - prev->header->pNext = extension.header; + prev->structure.header->pNext = extension.structure.header; } prev = &extension; } if(desc.extension_features.size() > 0) { - desc.device_features2.pNext = desc.extension_features.front().header; + desc.device_features2.pNext = desc.extension_features.front().structure.header; } detail::vulkan_functions().fp_vkGetPhysicalDeviceFeatures2(phys_device, &desc.device_features2); } @@ -1402,20 +1402,22 @@ detail::Result DeviceBuilder::build() const { #if defined(VK_API_VERSION_1_1) // Setup the pNexts of all the extension features - std::vector match = physical_device.extension_features; + std::vector match = physical_device.extension_features; VkPhysicalDeviceFeatures2 local_features2{}; + //VkBaseOutStructure* tail = nullptr; if (physical_device.instance_version >= VK_MAKE_VERSION(1, 1, 0) && match.size() > 0) { - detail::FeaturesContainer* prev = nullptr; + detail::ExtensionFeatures* prev = nullptr; for(auto& extension : match) { if(prev != nullptr) { - prev->header->pNext = extension.header; + prev->structure.header->pNext = extension.structure.header; } prev = &extension; + //tail = prev->structure; } local_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; local_features2.features = physical_device.features; - local_features2.pNext = match.front().header; + local_features2.pNext = match.front().structure.header; has_phys_dev_features_2 = true; } #endif @@ -1435,7 +1437,7 @@ detail::Result DeviceBuilder::build() const { if (has_phys_dev_features_2) { device_create_info.pNext = &local_features2; if(info.pNext_chain.size() > 0) { - match.back().header->pNext = info.pNext_chain.front(); + match.back().structure.header->pNext = info.pNext_chain.front(); } } else { device_create_info.pEnabledFeatures = &physical_device.features; diff --git a/src/VkBootstrap.h b/src/VkBootstrap.h index a0cc6b2..86b3c3a 100644 --- a/src/VkBootstrap.h +++ b/src/VkBootstrap.h @@ -115,60 +115,90 @@ template class Result { bool m_init; }; -struct FeaturesContainer { +struct ExtensionFeatures { - FeaturesContainer() = default; + struct StructureContainer { - FeaturesContainer(FeaturesContainer const& other) { copy(other); } + struct Header { + VkStructureType sType; + void* pNext; + }; - FeaturesContainer(FeaturesContainer&& other) { copy(other); } + StructureContainer() = default; - FeaturesContainer& operator=(FeaturesContainer const& other) { copy(other); return *this; } + StructureContainer (StructureContainer const& other) { copy(other); } - FeaturesContainer& operator=(FeaturesContainer&& other) { copy(other); return *this; } + StructureContainer (StructureContainer&& other) { copy(other); } - template - static FeaturesContainer make(T src) { - FeaturesContainer extension_features; - extension_features.set(src); - return extension_features; + StructureContainer& operator=(StructureContainer const& other) { copy(other); return *this; } - } + StructureContainer& operator=(StructureContainer&& other) { copy(other); return *this; } - template - void set(T const& features) { - data.resize(sizeof(T)); - *reinterpret_cast(data.data()) = features; - count = (sizeof(T) - sizeof(VkBaseOutStructure)) / sizeof(VkBool32); - header = reinterpret_cast(data.data()); - fields = reinterpret_cast(data.data() + sizeof(VkBaseOutStructure)); - } - - bool match(FeaturesContainer const& other) const { - if(!header || !other.header || header->sType != other.header->sType) { return false; } - for(auto i = 0; i < count; ++i) { - if(fields[i] == VK_TRUE && other.fields[i] == VK_FALSE) { - return false; - } + template + void set(T const& features) { + data.resize(sizeof(T)); + *reinterpret_cast(data.data()) = features; + count = (sizeof(T) - sizeof(Header)) / sizeof(VkBool32); + header = reinterpret_cast(data.data()); + fields = reinterpret_cast(data.data() + sizeof(Header)); } - return true; - } - VkBaseOutStructure* header = nullptr; -private: + bool match(StructureContainer const& other) const { + if(!header || !other.header || header->sType != other.header->sType) { return false; } + for(auto i = 0; i < count; ++i) { + if(fields[i] == VK_TRUE && other.fields[i] == VK_FALSE) { + return false; + } + } + return true; + } - // Just to avoid having it copied in 4 places - void copy(FeaturesContainer const& other) { - data = other.data; - count = other.count; - header = reinterpret_cast(data.data()); - fields = reinterpret_cast(data.data() + sizeof(VkBaseOutStructure)); - } + Header* header = nullptr; + private: - std::vector data; - VkBool32* fields = nullptr; - void* extend = nullptr; // Future proofing - int count = 0; + // Just to avoid having it copied in 4 places + void copy(StructureContainer const& other) { + data = other.data; + count = other.count; + header = reinterpret_cast(data.data()); + fields = reinterpret_cast(data.data() + sizeof(Header)); + } + + std::vector data; + VkBool32* fields = nullptr; + void* extend = nullptr; // Future proofing + int count = 0; + + }; + + ExtensionFeatures() = default; + + ExtensionFeatures (ExtensionFeatures const& other) : structure(other.structure) {} + + ExtensionFeatures (ExtensionFeatures&& other) : structure(std::exchange(other.structure, {})) {} + + ExtensionFeatures& operator=(ExtensionFeatures const& other) { + structure = other.structure; + return *this; + } + + ExtensionFeatures& operator=(ExtensionFeatures&& other) { + structure = std::exchange(other.structure, {}); + return *this; + } + + template + static ExtensionFeatures make(T src) { + + ExtensionFeatures extension_features; + extension_features.structure.set(src); + return extension_features; + + } + + bool match(const ExtensionFeatures& other) const { return structure.match(other.structure); } + + StructureContainer structure; }; @@ -412,7 +442,7 @@ struct PhysicalDevice { uint32_t instance_version = VK_MAKE_VERSION(1, 0, 0); std::vector extensions_to_enable; std::vector queue_families; - std::vector extension_features; + std::vector extension_features; bool defer_surface_initialization = false; friend class PhysicalDeviceSelector; friend class DeviceBuilder; @@ -479,7 +509,7 @@ class PhysicalDeviceSelector { PhysicalDeviceSelector& add_required_extension_features(T const& features) { assert(features.sType != 0 && "Features struct sType must be filled with the struct's corresponding VkStructureType enum"); - criteria.extension_features.push_back(detail::FeaturesContainer::make(features)); + criteria.extension_features.push_back(detail::ExtensionFeatures::make(features)); return *this; } #endif @@ -521,7 +551,7 @@ class PhysicalDeviceSelector { VkPhysicalDeviceMemoryProperties mem_properties{}; #if defined(VK_API_VERSION_1_1) VkPhysicalDeviceFeatures2 device_features2{}; - std::vector extension_features; + std::vector extension_features; #endif }; @@ -530,7 +560,7 @@ class PhysicalDeviceSelector { PhysicalDeviceDesc populate_device_details(uint32_t instance_version, VkPhysicalDevice phys_device, - std::vector extension_features_as_template) const; + std::vector extension_features_as_template) const; struct SelectionCriteria { PreferredDeviceType preferred_type = PreferredDeviceType::discrete; @@ -552,7 +582,7 @@ class PhysicalDeviceSelector { VkPhysicalDeviceFeatures required_features{}; #if defined(VK_API_VERSION_1_1) VkPhysicalDeviceFeatures2 required_features2{}; - std::vector extension_features; + std::vector extension_features; #endif bool defer_surface_initialization = false; bool use_first_gpu_unconditionally = false;