Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add are_extension_features_present to PhysicalDevice #278

Merged
merged 5 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions src/VkBootstrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void GenericFeaturesPNextNode::combine(GenericFeaturesPNextNode const& right) no
}
}

bool GenericFeatureChain::match(GenericFeatureChain const& extension_requested) const noexcept {
bool GenericFeatureChain::match_all(GenericFeatureChain const& extension_requested) const noexcept {
// Should only be false if extension_supported was unable to be filled out, due to the
// physical device not supporting vkGetPhysicalDeviceFeatures2 in any capacity.
if (extension_requested.nodes.size() != nodes.size()) {
Expand All @@ -67,6 +67,21 @@ bool GenericFeatureChain::match(GenericFeatureChain const& extension_requested)
return true;
}

bool GenericFeatureChain::find_and_match(GenericFeatureChain const& extensions_requested) const noexcept {
for (const auto& requested_extension_node : extensions_requested.nodes) {
bool found = false;
for (const auto& supported_node : nodes) {
if (supported_node.sType == requested_extension_node.sType) {
found = true;
if (!GenericFeaturesPNextNode::match(requested_extension_node, supported_node)) return false;
break;
}
}
if (!found) return false;
}
return true;
}

void GenericFeatureChain::chain_up(VkPhysicalDeviceFeatures2& feats2) noexcept {
detail::GenericFeaturesPNextNode* prev = nullptr;
for (auto& extension : nodes) {
Expand Down Expand Up @@ -1030,8 +1045,7 @@ bool supports_features(const VkPhysicalDeviceFeatures& supported,
if (requested.variableMultisampleRate && !supported.variableMultisampleRate) return false;
if (requested.inheritedQueries && !supported.inheritedQueries) return false;


return extension_supported.match(extension_requested);
return extension_supported.match_all(extension_requested);
}
// clang-format on
// Finds the first queue which supports the desired operations. Returns QUEUE_INDEX_MAX_VALUE if none is found
Expand Down Expand Up @@ -1508,6 +1522,13 @@ bool PhysicalDevice::enable_features_if_present(const VkPhysicalDeviceFeatures&
return required_features_supported;
}

bool PhysicalDevice::is_features_node_present(detail::GenericFeaturesPNextNode const& node) const {
detail::GenericFeatureChain requested_features;
requested_features.nodes.push_back(node);

return extended_features_chain.find_and_match(requested_features);
}

bool PhysicalDevice::enable_features_node_if_present(detail::GenericFeaturesPNextNode const& node) {
VkPhysicalDeviceFeatures2 actual_pdf2{};

Expand All @@ -1522,7 +1543,7 @@ bool PhysicalDevice::enable_features_node_if_present(detail::GenericFeaturesPNex
fill_chain.chain_up(actual_pdf2);

detail::vulkan_functions().fp_vkGetPhysicalDeviceFeatures2(physical_device, &actual_pdf2);
bool required_features_supported = detail::supports_features({}, {}, fill_chain, requested_features);
bool required_features_supported = fill_chain.match_all(requested_features);
if (required_features_supported) {
extended_features_chain.combine(requested_features);
}
Expand Down
13 changes: 10 additions & 3 deletions src/VkBootstrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ struct GenericFeatureChain {
nodes.push_back(features);
}

bool match(GenericFeatureChain const& extension_requested) const noexcept;
bool match_all(GenericFeatureChain const& extension_requested) const noexcept;
bool find_and_match(GenericFeatureChain const& extension_requested) const noexcept;

void chain_up(VkPhysicalDeviceFeatures2& feats2) noexcept;

Expand Down Expand Up @@ -528,6 +529,11 @@ struct PhysicalDevice {
// Returns true if an extension should be enabled on the device
bool is_extension_present(const char* extension) const;

// Returns true if all the features are present
template <typename T> bool are_extension_features_present(T const& features) const {
return is_features_node_present(detail::GenericFeaturesPNextNode(features));
}

// If the given extension is present, make the extension be enabled on the device.
// Returns true the extension is present.
bool enable_extension_if_present(const char* extension);
Expand All @@ -537,11 +543,11 @@ struct PhysicalDevice {
bool enable_extensions_if_present(const std::vector<const char*>& extensions);

// If the features from VkPhysicalDeviceFeatures are all present, make all of the features be enable on the device.
// Returns true all of the features are present.
// Returns true if all the features are present.
bool enable_features_if_present(const VkPhysicalDeviceFeatures& features_to_enable);

// If the features from the provided features struct are all present, make all of the features be enable on the
// device. Returns true all of the features are present.
// device. Returns true if all of the features are present.
template <typename T> bool enable_extension_features_if_present(T const& features_check) {
return enable_features_node_if_present(detail::GenericFeaturesPNextNode(features_check));
}
Expand All @@ -564,6 +570,7 @@ struct PhysicalDevice {
friend class PhysicalDeviceSelector;
friend class DeviceBuilder;

bool is_features_node_present(detail::GenericFeaturesPNextNode const& node) const;
bool enable_features_node_if_present(detail::GenericFeaturesPNextNode const& node);
};

Expand Down
24 changes: 24 additions & 0 deletions tests/bootstrap_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,8 @@ TEST_CASE("Querying Required Extension Features", "[VkBootstrap.select_features]
.select();
REQUIRE(phys_dev_ret.has_value());

REQUIRE(phys_dev_ret.value().are_extension_features_present(descriptor_indexing_features));

vkb::DeviceBuilder device_builder(phys_dev_ret.value());
auto device_ret = device_builder.build();
REQUIRE(device_ret.has_value());
Expand Down Expand Up @@ -783,6 +785,19 @@ TEST_CASE("Querying Required Extension Features in 1.1", "[VkBootstrap.version]"
.select();
REQUIRE(phys_dev_ret.has_value());

REQUIRE(phys_dev_ret.value().are_extension_features_present(descriptor_indexing_features));

VkPhysicalDeviceASTCDecodeFeaturesEXT astc_features{};
astc_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT;
astc_features.decodeModeSharedExponent = true;
REQUIRE(!phys_dev_ret.value().are_extension_features_present(astc_features));

VkPhysicalDeviceDescriptorIndexingFeaturesEXT unsupported_descriptor_indexing_features{};
unsupported_descriptor_indexing_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
unsupported_descriptor_indexing_features.runtimeDescriptorArray = true;
unsupported_descriptor_indexing_features.descriptorBindingUniformTexelBufferUpdateAfterBind = true;
REQUIRE(!phys_dev_ret.value().are_extension_features_present(unsupported_descriptor_indexing_features));

vkb::DeviceBuilder device_builder(phys_dev_ret.value());
auto device_ret = device_builder.build();
REQUIRE(device_ret.has_value());
Expand All @@ -800,6 +815,13 @@ TEST_CASE("Querying Required Extension Features in 1.1", "[VkBootstrap.version]"
.select();
REQUIRE(phys_dev_ret.has_value());

REQUIRE(!phys_dev_ret.value().are_extension_features_present(descriptor_indexing_features));

VkPhysicalDeviceASTCDecodeFeaturesEXT astc_features{};
astc_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT;
astc_features.decodeModeSharedExponent = true;
REQUIRE(!phys_dev_ret.value().are_extension_features_present(astc_features));

VkPhysicalDeviceFeatures2 phys_dev_feats2{};
phys_dev_feats2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
phys_dev_feats2.pNext = reinterpret_cast<void*>(&descriptor_indexing_features);
Expand All @@ -822,6 +844,8 @@ TEST_CASE("Querying Required Extension Features in 1.1", "[VkBootstrap.version]"
.select();
REQUIRE(phys_dev_ret.has_value());

REQUIRE(phys_dev_ret.value().are_extension_features_present(descriptor_indexing_features));

VkPhysicalDeviceFeatures2 phys_dev_feats2{};
phys_dev_feats2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
phys_dev_feats2.pNext = reinterpret_cast<void*>(&descriptor_indexing_features);
Expand Down