Revert "Simplified structures and plugged into existing logic."

This reverts commit 6ee81abdd3.
This commit is contained in:
Charles Giessen 2021-04-18 14:09:12 -06:00
parent db55cb8f27
commit 2a352b5a25
3 changed files with 98 additions and 87 deletions

View File

@ -690,9 +690,6 @@ detail::Result<Instance> InstanceBuilder::build() const {
VkInstanceCreateInfo instance_create_info = {}; VkInstanceCreateInfo instance_create_info = {};
instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
detail::setup_pNext_chain(instance_create_info, pNext_chain); detail::setup_pNext_chain(instance_create_info, pNext_chain);
for(auto& node : pNext_chain) {
assert(node->sType != VK_STRUCTURE_TYPE_APPLICATION_INFO);
}
instance_create_info.flags = info.flags; instance_create_info.flags = info.flags;
instance_create_info.pApplicationInfo = &app_info; instance_create_info.pApplicationInfo = &app_info;
instance_create_info.enabledExtensionCount = static_cast<uint32_t>(extensions.size()); instance_create_info.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
@ -849,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<GenericFeaturesPNextNode> const& extension_supported, std::vector<FeaturesContainer> const& extension_supported,
std::vector<GenericFeaturesPNextNode> 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;
@ -908,8 +905,7 @@ bool supports_features(VkPhysicalDeviceFeatures supported,
if (requested.inheritedQueries && !supported.inheritedQueries) return false; if (requested.inheritedQueries && !supported.inheritedQueries) return false;
for(auto i = 0; i < extension_requested.size(); ++i) { for(auto i = 0; i < extension_requested.size(); ++i) {
//auto res = extension_requested[i].match(extension_supported[i]); auto res = extension_requested[i].match(extension_supported[i]);
auto res = GenericFeaturesPNextNode::match(extension_requested[i], extension_supported[i]);
if(!res) return false; if(!res) return false;
} }
@ -996,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::GenericFeaturesPNextNode> const& src_extended_features_chain) 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>(
@ -1009,28 +1005,20 @@ PhysicalDeviceSelector::PhysicalDeviceDesc PhysicalDeviceSelector::populate_devi
#if defined(VK_API_VERSION_1_1) #if defined(VK_API_VERSION_1_1)
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;
auto fill_chain = src_extended_features_chain; if (instance_version >= VK_API_VERSION_1_1) {
detail::FeaturesContainer* prev = nullptr;
if(!fill_chain.empty() && instance_version >= VK_API_VERSION_1_1) { for(auto& extension : desc.extension_features) {
if(prev != nullptr) {
detail::GenericFeaturesPNextNode* prev = nullptr; prev->header->pNext = extension.header;
for (auto& extension : fill_chain) {
if (prev != nullptr) {
prev->pNext = &extension;
} }
prev = &extension; prev = &extension;
} }
if(desc.extension_features.size() > 0) {
VkPhysicalDeviceFeatures2 local_features{}; desc.device_features2.pNext = desc.extension_features.front().header;
local_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; }
local_features.pNext = &fill_chain.front(); detail::vulkan_functions().fp_vkGetPhysicalDeviceFeatures2(phys_device, &desc.device_features2);
detail::vulkan_functions().fp_vkGetPhysicalDeviceFeatures2(phys_device, &local_features);
} }
desc.extended_features_chain = fill_chain;
#endif #endif
return desc; return desc;
} }
@ -1101,7 +1089,7 @@ PhysicalDeviceSelector::Suitable PhysicalDeviceSelector::is_device_suitable(Phys
} }
bool required_features_supported = detail::supports_features(pd.device_features, criteria.required_features, bool required_features_supported = detail::supports_features(pd.device_features, criteria.required_features,
pd.extended_features_chain, criteria.extended_features_chain); pd.extension_features, criteria.extension_features);
if (!required_features_supported) return Suitable::no; if (!required_features_supported) return Suitable::no;
bool has_required_memory = false; bool has_required_memory = false;
@ -1154,7 +1142,7 @@ detail::Result<PhysicalDevice> PhysicalDeviceSelector::select() const {
for (auto& phys_device : physical_devices) { for (auto& phys_device : physical_devices) {
phys_device_descriptions.push_back(populate_device_details(instance_info.version, phys_device_descriptions.push_back(populate_device_details(instance_info.version,
phys_device, phys_device,
criteria.extended_features_chain)); criteria.extension_features));
} }
PhysicalDeviceDesc selected_device{}; PhysicalDeviceDesc selected_device{};
@ -1180,7 +1168,7 @@ detail::Result<PhysicalDevice> PhysicalDeviceSelector::select() const {
out_device.physical_device = selected_device.phys_device; out_device.physical_device = selected_device.phys_device;
out_device.surface = instance_info.surface; out_device.surface = instance_info.surface;
out_device.features = criteria.required_features; out_device.features = criteria.required_features;
out_device.extended_features_chain = criteria.extended_features_chain; out_device.extension_features = criteria.extension_features;
out_device.properties = selected_device.device_properties; out_device.properties = selected_device.device_properties;
out_device.memory_properties = selected_device.mem_properties; out_device.memory_properties = selected_device.mem_properties;
out_device.queue_families = selected_device.queue_families; out_device.queue_families = selected_device.queue_families;
@ -1411,17 +1399,24 @@ detail::Result<Device> DeviceBuilder::build() const {
extensions.push_back({ VK_KHR_SWAPCHAIN_EXTENSION_NAME }); extensions.push_back({ VK_KHR_SWAPCHAIN_EXTENSION_NAME });
bool has_phys_dev_features_2 = false; bool has_phys_dev_features_2 = false;
std::vector<VkBaseOutStructure*> final_pnext_chain;
#if defined(VK_API_VERSION_1_1) #if defined(VK_API_VERSION_1_1)
// Setup the pNexts of all the extension features
std::vector<detail::FeaturesContainer> match = physical_device.extension_features;
VkPhysicalDeviceFeatures2 local_features2{}; VkPhysicalDeviceFeatures2 local_features2{};
local_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; if (physical_device.instance_version >= VK_MAKE_VERSION(1, 1, 0) &&
auto physical_device_extension_features_copy = physical_device.extended_features_chain; match.size() > 0) {
if (physical_device.instance_version >= VK_MAKE_VERSION(1, 1, 0)) { detail::FeaturesContainer* prev = nullptr;
has_phys_dev_features_2 = true; for(auto& extension : match) {
for(auto& features_node : physical_device_extension_features_copy) { if(prev != nullptr) {
final_pnext_chain.push_back(reinterpret_cast<VkBaseOutStructure*>(&features_node)); prev->header->pNext = extension.header;
} }
prev = &extension;
}
local_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
local_features2.features = physical_device.features;
local_features2.pNext = match.front().header;
has_phys_dev_features_2 = true;
} }
#endif #endif
@ -1433,23 +1428,15 @@ detail::Result<Device> DeviceBuilder::build() const {
device_create_info.enabledExtensionCount = static_cast<uint32_t>(extensions.size()); device_create_info.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
device_create_info.ppEnabledExtensionNames = extensions.data(); device_create_info.ppEnabledExtensionNames = extensions.data();
for(auto& pnext : info.pNext_chain) { detail::setup_pNext_chain(device_create_info, info.pNext_chain);
final_pnext_chain.push_back(pnext);
}
detail::setup_pNext_chain(device_create_info, final_pnext_chain);
for(auto& node : final_pnext_chain) {
assert(node->sType != VK_STRUCTURE_TYPE_APPLICATION_INFO);
}
#if defined(VK_API_VERSION_1_1) #if defined(VK_API_VERSION_1_1)
// VUID-VkDeviceCreateInfo-pNext-00373 - don't add pEnabledFeatures if the phys_dev_features_2 is present // VUID-VkDeviceCreateInfo-pNext-00373 - don't add pEnabledFeatures if the phys_dev_features_2 is present
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(!final_pnext_chain.empty()) { if(info.pNext_chain.size() > 0) {
local_features2.pNext = final_pnext_chain.front(); match.back().header->pNext = info.pNext_chain.front();
} }
device_create_info.pEnabledFeatures = nullptr;
} else { } else {
device_create_info.pEnabledFeatures = &physical_device.features; device_create_info.pEnabledFeatures = &physical_device.features;
} }
@ -1691,9 +1678,6 @@ detail::Result<Swapchain> SwapchainBuilder::build() const {
VkSwapchainCreateInfoKHR swapchain_create_info = {}; VkSwapchainCreateInfoKHR swapchain_create_info = {};
swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
detail::setup_pNext_chain(swapchain_create_info, info.pNext_chain); detail::setup_pNext_chain(swapchain_create_info, info.pNext_chain);
for(auto& node : info.pNext_chain) {
assert(node->sType != VK_STRUCTURE_TYPE_APPLICATION_INFO);
}
swapchain_create_info.flags = info.create_flags; swapchain_create_info.flags = info.create_flags;
swapchain_create_info.surface = info.surface; swapchain_create_info.surface = info.surface;
swapchain_create_info.minImageCount = image_count; swapchain_create_info.minImageCount = image_count;

View File

@ -115,32 +115,61 @@ template <typename T> class Result {
bool m_init; bool m_init;
}; };
struct GenericFeaturesPNextNode { struct FeaturesContainer {
FeaturesContainer() = default;
FeaturesContainer(FeaturesContainer const& other) { copy(other); }
FeaturesContainer(FeaturesContainer&& other) { copy(other); }
FeaturesContainer& operator=(FeaturesContainer const& other) { copy(other); return *this; }
FeaturesContainer& operator=(FeaturesContainer&& other) { copy(other); return *this; }
template <typename T>
static FeaturesContainer make(T src) {
FeaturesContainer extension_features;
extension_features.set<T>(src);
return extension_features;
GenericFeaturesPNextNode() : sType(static_cast<VkStructureType>(0)),
pNext(nullptr) {
memset(fields, 0, sizeof(fields));
} }
VkStructureType sType = static_cast<VkStructureType>(0);
void* pNext = nullptr;
VkBool32 fields[256];
template <typename T> template <typename T>
void set(T const& features) { void set(T const& features) {
GenericFeaturesPNextNode node; data.resize(sizeof(T));
*reinterpret_cast<T*>(this) = features; *reinterpret_cast<T*>(data.data()) = features;
count = (sizeof(T) - sizeof(VkBaseOutStructure)) / sizeof(VkBool32);
header = reinterpret_cast<VkBaseOutStructure*>(data.data());
fields = reinterpret_cast<VkBool32*>(data.data() + sizeof(VkBaseOutStructure));
} }
static bool match(GenericFeaturesPNextNode const& requested, GenericFeaturesPNextNode const& supported) { bool match(FeaturesContainer const& other) const {
assert(requested.sType == supported.sType && if(!header || !other.header || header->sType != other.header->sType) { return false; }
"Non-matching sTypes in features nodes!"); for(auto i = 0; i < count; ++i) {
for (uint32_t i = 0; i < (sizeof(fields) / sizeof(VkBool32)); i++) { if(fields[i] == VK_TRUE && other.fields[i] == VK_FALSE) {
if (requested.fields[i] && !supported.fields[i]) return false; return false;
}
} }
return true; return true;
} }
VkBaseOutStructure* header = nullptr;
private:
// Just to avoid having it copied in 4 places
void copy(FeaturesContainer const& other) {
data = other.data;
count = other.count;
header = reinterpret_cast<VkBaseOutStructure*>(data.data());
fields = reinterpret_cast<VkBool32*>(data.data() + sizeof(VkBaseOutStructure));
}
std::vector<char> data;
VkBool32* fields = nullptr;
void* extend = nullptr; // Future proofing
int count = 0;
}; };
} // namespace detail } // namespace detail
@ -383,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::GenericFeaturesPNextNode> extended_features_chain; 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;
@ -450,9 +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");
detail::GenericFeaturesPNextNode node; criteria.extension_features.push_back(detail::FeaturesContainer::make(features));
node.set(features);
criteria.extended_features_chain.push_back(node);
return *this; return *this;
} }
#endif #endif
@ -494,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::GenericFeaturesPNextNode> extended_features_chain; std::vector<detail::FeaturesContainer> extension_features;
#endif #endif
}; };
@ -503,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::GenericFeaturesPNextNode> const& src_extended_features_chain) const; std::vector<detail::FeaturesContainer> extension_features_as_template) const;
struct SelectionCriteria { struct SelectionCriteria {
PreferredDeviceType preferred_type = PreferredDeviceType::discrete; PreferredDeviceType preferred_type = PreferredDeviceType::discrete;
@ -525,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::GenericFeaturesPNextNode> extended_features_chain; 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;

View File

@ -106,7 +106,7 @@ TEST_CASE("instance configuration", "[VkBootstrap.bootstrap]") {
TEST_CASE("Headless Vulkan", "[VkBootstrap.bootstrap]") { TEST_CASE("Headless Vulkan", "[VkBootstrap.bootstrap]") {
vkb::InstanceBuilder builder; vkb::InstanceBuilder builder;
auto instance_ret = builder.request_validation_layers().set_headless().use_default_debug_messenger().build(); auto instance_ret = builder.request_validation_layers().set_headless().build();
REQUIRE(instance_ret.has_value()); REQUIRE(instance_ret.has_value());
vkb::PhysicalDeviceSelector phys_device_selector(instance_ret.value()); vkb::PhysicalDeviceSelector phys_device_selector(instance_ret.value());
@ -127,7 +127,7 @@ TEST_CASE("Device Configuration", "[VkBootstrap.bootstrap]") {
auto window = create_window_glfw("Device Configuration"); auto window = create_window_glfw("Device Configuration");
vkb::InstanceBuilder builder; vkb::InstanceBuilder builder;
auto instance_ret = builder.request_validation_layers().require_api_version(1, 1).use_default_debug_messenger().build(); auto instance_ret = builder.request_validation_layers().require_api_version(1, 1).build();
REQUIRE(instance_ret.has_value()); REQUIRE(instance_ret.has_value());
auto surface = create_surface_glfw(instance_ret.value().instance, window); auto surface = create_surface_glfw(instance_ret.value().instance, window);
@ -192,7 +192,7 @@ TEST_CASE("Swapchain", "[VkBootstrap.bootstrap]") {
auto window = create_window_glfw("Swapchain"); auto window = create_window_glfw("Swapchain");
vkb::InstanceBuilder builder; vkb::InstanceBuilder builder;
auto instance_ret = builder.request_validation_layers().use_default_debug_messenger().build(); auto instance_ret = builder.request_validation_layers().build();
REQUIRE(instance_ret.has_value()); REQUIRE(instance_ret.has_value());
auto surface = create_surface_glfw(instance_ret.value().instance, window); auto surface = create_surface_glfw(instance_ret.value().instance, window);
@ -320,7 +320,7 @@ TEST_CASE("Allocation Callbacks", "[VkBootstrap.bootstrap]") {
vkb::InstanceBuilder builder; vkb::InstanceBuilder builder;
auto instance_ret = auto instance_ret =
builder.request_validation_layers().set_allocation_callbacks(&allocation_callbacks).use_default_debug_messenger().build(); builder.request_validation_layers().set_allocation_callbacks(&allocation_callbacks).build();
REQUIRE(instance_ret.has_value()); REQUIRE(instance_ret.has_value());
auto surface = create_surface_glfw(instance_ret.value().instance, window); auto surface = create_surface_glfw(instance_ret.value().instance, window);
@ -417,7 +417,7 @@ TEST_CASE("Querying Required Extension Features", "[VkBootstrap.version]") {
vkb::InstanceBuilder builder; vkb::InstanceBuilder builder;
auto instance_ret = auto instance_ret =
builder.request_validation_layers().require_api_version(1, 2).set_headless().use_default_debug_messenger().build(); builder.request_validation_layers().require_api_version(1, 2).set_headless().build();
REQUIRE(instance_ret.has_value()); REQUIRE(instance_ret.has_value());
// Requires a device that supports runtime descriptor arrays via descriptor indexing extension. // Requires a device that supports runtime descriptor arrays via descriptor indexing extension.
{ {
@ -449,7 +449,7 @@ TEST_CASE("Querying Vulkan 1.1 and 1.2 features", "[VkBootstrap.version]") {
vkb::InstanceBuilder builder; vkb::InstanceBuilder builder;
auto instance_ret = auto instance_ret =
builder.request_validation_layers().require_api_version(1, 2).set_headless().use_default_debug_messenger().build(); builder.request_validation_layers().require_api_version(1, 2).set_headless().build();
REQUIRE(instance_ret.has_value()); REQUIRE(instance_ret.has_value());
// Requires a device that supports multiview and bufferDeviceAddress // Requires a device that supports multiview and bufferDeviceAddress
{ {