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

This commit is contained in:
Cody Goodson 2021-04-16 18:50:17 -05:00 committed by Charles Giessen
parent 075be4900b
commit 2f69fa52cb
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,35 +115,36 @@ 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) {
@ -153,15 +154,15 @@ struct ExtensionFeatures {
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;
@ -169,37 +170,6 @@ struct ExtensionFeatures {
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;
}; };
} // namespace detail } // namespace detail
@ -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;