Revert "Revert "Collapsed ExtensionFeatures and StructureContainer together into FeaturesContainer. After the purging of the function pointers all ExtensionFeatures was doing was just wrapping StructureContainers functions.""

This reverts commit 64aeed5855.
This commit is contained in:
Charles Giessen 2021-04-18 14:14:17 -06:00
parent 9c4317e324
commit f4eb8fdffc
2 changed files with 56 additions and 88 deletions

View File

@ -846,8 +846,8 @@ std::vector<const char*> check_device_extension_support(
// clang-format off // clang-format off
bool supports_features(VkPhysicalDeviceFeatures supported, bool supports_features(VkPhysicalDeviceFeatures supported,
VkPhysicalDeviceFeatures requested, VkPhysicalDeviceFeatures requested,
std::vector<ExtensionFeatures> const& extension_supported, std::vector<FeaturesContainer> const& extension_supported,
std::vector<ExtensionFeatures> const& extension_requested) { std::vector<FeaturesContainer> const& extension_requested) {
if (requested.robustBufferAccess && !supported.robustBufferAccess) return false; if (requested.robustBufferAccess && !supported.robustBufferAccess) return false;
if (requested.fullDrawIndexUint32 && !supported.fullDrawIndexUint32) return false; if (requested.fullDrawIndexUint32 && !supported.fullDrawIndexUint32) return false;
if (requested.imageCubeArray && !supported.imageCubeArray) 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( PhysicalDeviceSelector::PhysicalDeviceDesc PhysicalDeviceSelector::populate_device_details(
uint32_t instance_version, VkPhysicalDevice phys_device, uint32_t instance_version, VkPhysicalDevice phys_device,
std::vector<detail::ExtensionFeatures> extension_features_as_template) const { std::vector<detail::FeaturesContainer> extension_features_as_template) const {
PhysicalDeviceSelector::PhysicalDeviceDesc desc{}; PhysicalDeviceSelector::PhysicalDeviceDesc desc{};
desc.phys_device = phys_device; desc.phys_device = phys_device;
auto queue_families = detail::get_vector_noerror<VkQueueFamilyProperties>( auto queue_families = detail::get_vector_noerror<VkQueueFamilyProperties>(
@ -1007,15 +1007,15 @@ PhysicalDeviceSelector::PhysicalDeviceDesc PhysicalDeviceSelector::populate_devi
desc.device_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; desc.device_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
desc.extension_features = extension_features_as_template; desc.extension_features = extension_features_as_template;
if (instance_version >= VK_API_VERSION_1_1) { if (instance_version >= VK_API_VERSION_1_1) {
detail::ExtensionFeatures* prev = nullptr; detail::FeaturesContainer* prev = nullptr;
for(auto& extension : desc.extension_features) { for(auto& extension : desc.extension_features) {
if(prev != nullptr) { if(prev != nullptr) {
prev->structure.header->pNext = extension.structure.header; prev->header->pNext = extension.header;
} }
prev = &extension; prev = &extension;
} }
if(desc.extension_features.size() > 0) { if(desc.extension_features.size() > 0) {
desc.device_features2.pNext = desc.extension_features.front().structure.header; desc.device_features2.pNext = desc.extension_features.front().header;
} }
detail::vulkan_functions().fp_vkGetPhysicalDeviceFeatures2(phys_device, &desc.device_features2); detail::vulkan_functions().fp_vkGetPhysicalDeviceFeatures2(phys_device, &desc.device_features2);
} }
@ -1402,22 +1402,20 @@ detail::Result<Device> DeviceBuilder::build() const {
#if defined(VK_API_VERSION_1_1) #if defined(VK_API_VERSION_1_1)
// Setup the pNexts of all the extension features // Setup the pNexts of all the extension features
std::vector<detail::ExtensionFeatures> match = physical_device.extension_features; std::vector<detail::FeaturesContainer> match = physical_device.extension_features;
VkPhysicalDeviceFeatures2 local_features2{}; VkPhysicalDeviceFeatures2 local_features2{};
//VkBaseOutStructure* tail = nullptr;
if (physical_device.instance_version >= VK_MAKE_VERSION(1, 1, 0) && if (physical_device.instance_version >= VK_MAKE_VERSION(1, 1, 0) &&
match.size() > 0) { match.size() > 0) {
detail::ExtensionFeatures* prev = nullptr; detail::FeaturesContainer* prev = nullptr;
for(auto& extension : match) { for(auto& extension : match) {
if(prev != nullptr) { if(prev != nullptr) {
prev->structure.header->pNext = extension.structure.header; prev->header->pNext = extension.header;
} }
prev = &extension; prev = &extension;
//tail = prev->structure;
} }
local_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; local_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
local_features2.features = physical_device.features; local_features2.features = physical_device.features;
local_features2.pNext = match.front().structure.header; local_features2.pNext = match.front().header;
has_phys_dev_features_2 = true; has_phys_dev_features_2 = true;
} }
#endif #endif
@ -1437,7 +1435,7 @@ detail::Result<Device> DeviceBuilder::build() const {
if (has_phys_dev_features_2) { if (has_phys_dev_features_2) {
device_create_info.pNext = &local_features2; device_create_info.pNext = &local_features2;
if(info.pNext_chain.size() > 0) { if(info.pNext_chain.size() > 0) {
match.back().structure.header->pNext = info.pNext_chain.front(); match.back().header->pNext = info.pNext_chain.front();
} }
} else { } else {
device_create_info.pEnabledFeatures = &physical_device.features; device_create_info.pEnabledFeatures = &physical_device.features;

View File

@ -115,90 +115,60 @@ template <typename T> class Result {
bool m_init; bool m_init;
}; };
struct ExtensionFeatures { struct FeaturesContainer {
struct StructureContainer { FeaturesContainer() = default;
struct Header { FeaturesContainer(FeaturesContainer const& other) { copy(other); }
VkStructureType sType;
void* pNext;
};
StructureContainer() = default; FeaturesContainer(FeaturesContainer&& other) { copy(other); }
StructureContainer (StructureContainer const& other) { copy(other); } FeaturesContainer& operator=(FeaturesContainer const& other) { copy(other); return *this; }
StructureContainer (StructureContainer&& other) { copy(other); } FeaturesContainer& operator=(FeaturesContainer&& other) { copy(other); return *this; }
StructureContainer& operator=(StructureContainer const& other) { copy(other); return *this; } template <typename T>
static FeaturesContainer make(T src) {
FeaturesContainer extension_features;
extension_features.set<T>(src);
return extension_features;
StructureContainer& operator=(StructureContainer&& other) { copy(other); return *this; } }
template <typename T> template <typename T>
void set(T const& features) { void set(T const& features) {
data.resize(sizeof(T)); data.resize(sizeof(T));
*reinterpret_cast<T*>(data.data()) = features; *reinterpret_cast<T*>(data.data()) = features;
count = (sizeof(T) - sizeof(Header)) / sizeof(VkBool32); count = (sizeof(T) - sizeof(VkBaseOutStructure)) / sizeof(VkBool32);
header = reinterpret_cast<Header*>(data.data()); header = reinterpret_cast<VkBaseOutStructure*>(data.data());
fields = reinterpret_cast<VkBool32*>(data.data() + sizeof(Header)); fields = reinterpret_cast<VkBool32*>(data.data() + sizeof(VkBaseOutStructure));
} }
bool match(StructureContainer const& other) const { bool match(FeaturesContainer const& other) const {
if(!header || !other.header || header->sType != other.header->sType) { return false; } if(!header || !other.header || header->sType != other.header->sType) { return false; }
for(auto i = 0; i < count; ++i) { for(auto i = 0; i < count; ++i) {
if(fields[i] == VK_TRUE && other.fields[i] == VK_FALSE) { if(fields[i] == VK_TRUE && other.fields[i] == VK_FALSE) {
return false; return false;
}
} }
return true;
} }
return true;
}
Header* header = nullptr; VkBaseOutStructure* header = nullptr;
private: private:
// Just to avoid having it copied in 4 places // Just to avoid having it copied in 4 places
void copy(StructureContainer const& other) { void copy(FeaturesContainer const& other) {
data = other.data; data = other.data;
count = other.count; count = other.count;
header = reinterpret_cast<Header*>(data.data()); header = reinterpret_cast<VkBaseOutStructure*>(data.data());
fields = reinterpret_cast<VkBool32*>(data.data() + sizeof(Header)); fields = reinterpret_cast<VkBool32*>(data.data() + sizeof(VkBaseOutStructure));
} }
std::vector<char> data; std::vector<char> data;
VkBool32* fields = nullptr; VkBool32* fields = nullptr;
void* extend = nullptr; // Future proofing void* extend = nullptr; // Future proofing
int count = 0; 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 <typename T>
static ExtensionFeatures make(T src) {
ExtensionFeatures extension_features;
extension_features.structure.set<T>(src);
return extension_features;
}
bool match(const ExtensionFeatures& other) const { return structure.match(other.structure); }
StructureContainer structure;
}; };
@ -442,7 +412,7 @@ struct PhysicalDevice {
uint32_t instance_version = VK_MAKE_VERSION(1, 0, 0); uint32_t instance_version = VK_MAKE_VERSION(1, 0, 0);
std::vector<const char*> extensions_to_enable; std::vector<const char*> extensions_to_enable;
std::vector<VkQueueFamilyProperties> queue_families; std::vector<VkQueueFamilyProperties> queue_families;
std::vector<detail::ExtensionFeatures> extension_features; std::vector<detail::FeaturesContainer> extension_features;
bool defer_surface_initialization = false; bool defer_surface_initialization = false;
friend class PhysicalDeviceSelector; friend class PhysicalDeviceSelector;
friend class DeviceBuilder; friend class DeviceBuilder;
@ -509,7 +479,7 @@ class PhysicalDeviceSelector {
PhysicalDeviceSelector& add_required_extension_features(T const& features) { PhysicalDeviceSelector& add_required_extension_features(T const& features) {
assert(features.sType != 0 && assert(features.sType != 0 &&
"Features struct sType must be filled with the struct's corresponding VkStructureType enum"); "Features struct sType must be filled with the struct's corresponding VkStructureType enum");
criteria.extension_features.push_back(detail::ExtensionFeatures::make(features)); criteria.extension_features.push_back(detail::FeaturesContainer::make(features));
return *this; return *this;
} }
#endif #endif
@ -551,7 +521,7 @@ class PhysicalDeviceSelector {
VkPhysicalDeviceMemoryProperties mem_properties{}; VkPhysicalDeviceMemoryProperties mem_properties{};
#if defined(VK_API_VERSION_1_1) #if defined(VK_API_VERSION_1_1)
VkPhysicalDeviceFeatures2 device_features2{}; VkPhysicalDeviceFeatures2 device_features2{};
std::vector<detail::ExtensionFeatures> extension_features; std::vector<detail::FeaturesContainer> extension_features;
#endif #endif
}; };
@ -560,7 +530,7 @@ class PhysicalDeviceSelector {
PhysicalDeviceDesc populate_device_details(uint32_t instance_version, PhysicalDeviceDesc populate_device_details(uint32_t instance_version,
VkPhysicalDevice phys_device, VkPhysicalDevice phys_device,
std::vector<detail::ExtensionFeatures> extension_features_as_template) const; std::vector<detail::FeaturesContainer> extension_features_as_template) const;
struct SelectionCriteria { struct SelectionCriteria {
PreferredDeviceType preferred_type = PreferredDeviceType::discrete; PreferredDeviceType preferred_type = PreferredDeviceType::discrete;
@ -582,7 +552,7 @@ class PhysicalDeviceSelector {
VkPhysicalDeviceFeatures required_features{}; VkPhysicalDeviceFeatures required_features{};
#if defined(VK_API_VERSION_1_1) #if defined(VK_API_VERSION_1_1)
VkPhysicalDeviceFeatures2 required_features2{}; VkPhysicalDeviceFeatures2 required_features2{};
std::vector<detail::ExtensionFeatures> extension_features; std::vector<detail::FeaturesContainer> extension_features;
#endif #endif
bool defer_surface_initialization = false; bool defer_surface_initialization = false;
bool use_first_gpu_unconditionally = false; bool use_first_gpu_unconditionally = false;