WIP: Remove desire selection criteria for PhysicalDeviceSelector

This commit is contained in:
Charles Giessen 2022-03-01 00:11:07 -07:00
parent 7cd7a6ab16
commit 1b94facbd3
3 changed files with 78 additions and 169 deletions

View File

@ -1061,13 +1061,10 @@ PhysicalDevice PhysicalDeviceSelector::populate_device_details(VkPhysicalDevice
return physical_device; return physical_device;
} }
PhysicalDevice::Suitable PhysicalDeviceSelector::is_device_suitable(PhysicalDevice const& pd) const { bool PhysicalDeviceSelector::is_device_suitable(PhysicalDevice const& pd) const {
PhysicalDevice::Suitable suitable = PhysicalDevice::Suitable::yes; if (criteria.name.size() > 0 && criteria.name != pd.properties.deviceName) return false;
if (criteria.name.size() > 0 && criteria.name != pd.properties.deviceName) return PhysicalDevice::Suitable::no; if (criteria.required_version > pd.properties.apiVersion) return false;
if (criteria.required_version > pd.properties.apiVersion) return PhysicalDevice::Suitable::no;
if (criteria.desired_version > pd.properties.apiVersion) suitable = PhysicalDevice::Suitable::partial;
bool dedicated_compute = detail::get_dedicated_queue_index(pd.queue_families, VK_QUEUE_COMPUTE_BIT, VK_QUEUE_TRANSFER_BIT) != bool dedicated_compute = detail::get_dedicated_queue_index(pd.queue_families, VK_QUEUE_COMPUTE_BIT, VK_QUEUE_TRANSFER_BIT) !=
detail::QUEUE_INDEX_MAX_VALUE; detail::QUEUE_INDEX_MAX_VALUE;
@ -1081,20 +1078,14 @@ PhysicalDevice::Suitable PhysicalDeviceSelector::is_device_suitable(PhysicalDevi
bool present_queue = detail::get_present_queue_index(pd.physical_device, instance_info.surface, pd.queue_families) != bool present_queue = detail::get_present_queue_index(pd.physical_device, instance_info.surface, pd.queue_families) !=
detail::QUEUE_INDEX_MAX_VALUE; detail::QUEUE_INDEX_MAX_VALUE;
if (criteria.require_dedicated_compute_queue && !dedicated_compute) return PhysicalDevice::Suitable::no; if (criteria.require_dedicated_compute_queue && !dedicated_compute) return false;
if (criteria.require_dedicated_transfer_queue && !dedicated_transfer) return PhysicalDevice::Suitable::no; if (criteria.require_dedicated_transfer_queue && !dedicated_transfer) return false;
if (criteria.require_separate_compute_queue && !separate_compute) return PhysicalDevice::Suitable::no; if (criteria.require_separate_compute_queue && !separate_compute) return false;
if (criteria.require_separate_transfer_queue && !separate_transfer) return PhysicalDevice::Suitable::no; if (criteria.require_separate_transfer_queue && !separate_transfer) return false;
if (criteria.require_present && !present_queue && !criteria.defer_surface_initialization) if (criteria.require_present && !present_queue && !criteria.defer_surface_initialization) return false;
return PhysicalDevice::Suitable::no;
auto required_extensions_supported = detail::check_device_extension_support(pd.extensions, criteria.required_extensions); auto required_extensions_supported = detail::check_device_extension_support(pd.extensions, criteria.required_extensions);
if (required_extensions_supported.size() != criteria.required_extensions.size()) if (required_extensions_supported.size() != criteria.required_extensions.size()) return false;
return PhysicalDevice::Suitable::no;
auto desired_extensions_supported = detail::check_device_extension_support(pd.extensions, criteria.desired_extensions);
if (desired_extensions_supported.size() != criteria.desired_extensions.size())
suitable = PhysicalDevice::Suitable::partial;
if (!criteria.defer_surface_initialization && criteria.require_present) { if (!criteria.defer_surface_initialization && criteria.require_present) {
std::vector<VkSurfaceFormatKHR> formats; std::vector<VkSurfaceFormatKHR> formats;
@ -1110,29 +1101,24 @@ PhysicalDevice::Suitable PhysicalDeviceSelector::is_device_suitable(PhysicalDevi
instance_info.surface); instance_info.surface);
if (formats_ret != VK_SUCCESS || present_modes_ret != VK_SUCCESS || formats.empty() || present_modes.empty()) { if (formats_ret != VK_SUCCESS || present_modes_ret != VK_SUCCESS || formats.empty() || present_modes.empty()) {
return PhysicalDevice::Suitable::no; return false;
} }
} }
if (!criteria.allow_any_type && pd.properties.deviceType != static_cast<VkPhysicalDeviceType>(criteria.preferred_type)) {
suitable = PhysicalDevice::Suitable::partial;
}
bool required_features_supported = detail::supports_features( bool required_features_supported = detail::supports_features(
pd.features, criteria.required_features, pd.extended_features_chain, criteria.extended_features_chain); pd.features, criteria.required_features, pd.extended_features_chain, criteria.extended_features_chain);
if (!required_features_supported) return PhysicalDevice::Suitable::no; if (!required_features_supported) return false;
for (uint32_t i = 0; i < pd.memory_properties.memoryHeapCount; i++) { for (uint32_t i = 0; i < pd.memory_properties.memoryHeapCount; i++) {
if (pd.memory_properties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) { if (pd.memory_properties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) {
if (pd.memory_properties.memoryHeaps[i].size < criteria.required_mem_size) { if (pd.memory_properties.memoryHeaps[i].size < criteria.required_mem_size) {
return PhysicalDevice::Suitable::no; return false;
} else if (pd.memory_properties.memoryHeaps[i].size < criteria.desired_mem_size) {
suitable = PhysicalDevice::Suitable::partial;
} }
} }
} }
return suitable; return true;
} }
// delegate construction to the one with an explicit surface parameter // delegate construction to the one with an explicit surface parameter
PhysicalDeviceSelector::PhysicalDeviceSelector(Instance const& instance) PhysicalDeviceSelector::PhysicalDeviceSelector(Instance const& instance)
@ -1145,10 +1131,9 @@ PhysicalDeviceSelector::PhysicalDeviceSelector(Instance const& instance, VkSurfa
instance_info.surface = surface; instance_info.surface = surface;
criteria.require_present = !instance.headless; criteria.require_present = !instance.headless;
criteria.required_version = instance.api_version; criteria.required_version = instance.api_version;
criteria.desired_version = instance.api_version;
} }
detail::Result<std::vector<PhysicalDevice>> PhysicalDeviceSelector::select_impl(DeviceSelectionMode selection) const { detail::Result<std::vector<PhysicalDevice>> PhysicalDeviceSelector::select_impl() const {
#if !defined(NDEBUG) #if !defined(NDEBUG)
// Validation // Validation
for (const auto& node : criteria.extended_features_chain) { for (const auto& node : criteria.extended_features_chain) {
@ -1190,9 +1175,6 @@ detail::Result<std::vector<PhysicalDevice>> PhysicalDeviceSelector::select_impl(
phys_dev.extensions.clear(); phys_dev.extensions.clear();
phys_dev.extensions.insert( phys_dev.extensions.insert(
phys_dev.extensions.end(), criteria.required_extensions.begin(), criteria.required_extensions.end()); phys_dev.extensions.end(), criteria.required_extensions.begin(), criteria.required_extensions.end());
auto desired_extensions_supported = detail::check_device_extension_support(phys_dev.extensions, criteria.desired_extensions);
phys_dev.extensions.insert(
phys_dev.extensions.end(), desired_extensions_supported.begin(), desired_extensions_supported.end());
if (portability_ext_available) { if (portability_ext_available) {
phys_dev.extensions.push_back("VK_KHR_portability_subset"); phys_dev.extensions.push_back("VK_KHR_portability_subset");
} }
@ -1209,32 +1191,18 @@ detail::Result<std::vector<PhysicalDevice>> PhysicalDeviceSelector::select_impl(
std::vector<PhysicalDevice> physical_devices; std::vector<PhysicalDevice> physical_devices;
for (auto& vk_physical_device : vk_physical_devices) { for (auto& vk_physical_device : vk_physical_devices) {
PhysicalDevice phys_dev = populate_device_details(vk_physical_device, criteria.extended_features_chain); PhysicalDevice phys_dev = populate_device_details(vk_physical_device, criteria.extended_features_chain);
phys_dev.suitable = is_device_suitable(phys_dev); bool suitable = is_device_suitable(phys_dev);
if (phys_dev.suitable != PhysicalDevice::Suitable::no) { if (suitable) {
physical_devices.push_back(phys_dev); physical_devices.push_back(phys_dev);
fill_out_phys_dev_with_criteria(physical_devices.back());
} }
} }
// sort the list into fully and partially suitable devices. use stable_partition to maintain relative order
const auto partition_index = std::stable_partition(physical_devices.begin(), physical_devices.end(), [](auto const& pd) {
return pd.suitable == PhysicalDevice::Suitable::yes;
});
// Remove the partially suitable elements if they aren't desired
if (selection == DeviceSelectionMode::only_fully_suitable) {
physical_devices.erase(partition_index, physical_devices.end() - 1);
}
// Make the physical device ready to be used to create a Device from it
for (auto& physical_device : physical_devices) {
fill_out_phys_dev_with_criteria(physical_device);
}
return physical_devices; return physical_devices;
} }
detail::Result<PhysicalDevice> PhysicalDeviceSelector::select(DeviceSelectionMode selection) const { detail::Result<PhysicalDevice> PhysicalDeviceSelector::select() const {
auto const selected_devices = select_impl(selection); auto const selected_devices = select_impl();
if (!selected_devices) return detail::Result<PhysicalDevice>{ selected_devices.error() }; if (!selected_devices) return detail::Result<PhysicalDevice>{ selected_devices.error() };
if (selected_devices.value().size() == 0) { if (selected_devices.value().size() == 0) {
@ -1245,8 +1213,8 @@ detail::Result<PhysicalDevice> PhysicalDeviceSelector::select(DeviceSelectionMod
} }
// Return all devices which are considered suitable - intended for applications which want to let the user pick the physical device // Return all devices which are considered suitable - intended for applications which want to let the user pick the physical device
detail::Result<std::vector<PhysicalDevice>> PhysicalDeviceSelector::select_devices(DeviceSelectionMode selection) const { detail::Result<std::vector<PhysicalDevice>> PhysicalDeviceSelector::select_devices() const {
auto const selected_devices = select_impl(selection); auto const selected_devices = select_impl();
if (!selected_devices) return detail::Result<std::vector<PhysicalDevice>>{ selected_devices.error() }; if (!selected_devices) return detail::Result<std::vector<PhysicalDevice>>{ selected_devices.error() };
if (selected_devices.value().size() == 0) { if (selected_devices.value().size() == 0) {
return detail::Result<std::vector<PhysicalDevice>>{ PhysicalDeviceError::no_suitable_device }; return detail::Result<std::vector<PhysicalDevice>>{ PhysicalDeviceError::no_suitable_device };
@ -1254,8 +1222,8 @@ detail::Result<std::vector<PhysicalDevice>> PhysicalDeviceSelector::select_devic
return selected_devices.value(); return selected_devices.value();
} }
detail::Result<std::vector<std::string>> PhysicalDeviceSelector::select_device_names(DeviceSelectionMode selection) const { detail::Result<std::vector<std::string>> PhysicalDeviceSelector::select_device_names() const {
auto const selected_devices = select_impl(selection); auto const selected_devices = select_impl();
if (!selected_devices) return detail::Result<std::vector<std::string>>{ selected_devices.error() }; if (!selected_devices) return detail::Result<std::vector<std::string>>{ selected_devices.error() };
if (selected_devices.value().size() == 0) { if (selected_devices.value().size() == 0) {
return detail::Result<std::vector<std::string>>{ PhysicalDeviceError::no_suitable_device }; return detail::Result<std::vector<std::string>>{ PhysicalDeviceError::no_suitable_device };
@ -1306,10 +1274,6 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::required_device_memory_size(VkDe
criteria.required_mem_size = size; criteria.required_mem_size = size;
return *this; return *this;
} }
PhysicalDeviceSelector& PhysicalDeviceSelector::desired_device_memory_size(VkDeviceSize size) {
criteria.desired_mem_size = size;
return *this;
}
PhysicalDeviceSelector& PhysicalDeviceSelector::add_required_extension(const char* extension) { PhysicalDeviceSelector& PhysicalDeviceSelector::add_required_extension(const char* extension) {
criteria.required_extensions.push_back(extension); criteria.required_extensions.push_back(extension);
return *this; return *this;
@ -1320,24 +1284,10 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::add_required_extensions(std::vec
} }
return *this; return *this;
} }
PhysicalDeviceSelector& PhysicalDeviceSelector::add_desired_extension(const char* extension) {
criteria.desired_extensions.push_back(extension);
return *this;
}
PhysicalDeviceSelector& PhysicalDeviceSelector::add_desired_extensions(std::vector<const char*> extensions) {
for (const auto& ext : extensions) {
criteria.desired_extensions.push_back(ext);
}
return *this;
}
PhysicalDeviceSelector& PhysicalDeviceSelector::set_minimum_version(uint32_t major, uint32_t minor) { PhysicalDeviceSelector& PhysicalDeviceSelector::set_minimum_version(uint32_t major, uint32_t minor) {
criteria.required_version = VKB_MAKE_VK_VERSION(0, major, minor, 0); criteria.required_version = VKB_MAKE_VK_VERSION(0, major, minor, 0);
return *this; return *this;
} }
PhysicalDeviceSelector& PhysicalDeviceSelector::set_desired_version(uint32_t major, uint32_t minor) {
criteria.desired_version = VKB_MAKE_VK_VERSION(0, major, minor, 0);
return *this;
}
PhysicalDeviceSelector& PhysicalDeviceSelector::disable_portability_subset() { PhysicalDeviceSelector& PhysicalDeviceSelector::disable_portability_subset() {
criteria.enable_portability_subset = false; criteria.enable_portability_subset = false;
return *this; return *this;

View File

@ -353,11 +353,11 @@ class InstanceBuilder {
// Prefer a vulkan instance API version. If the desired version isn't available, it will use the // Prefer a vulkan instance API version. If the desired version isn't available, it will use the
// highest version available. Should be constructed with VK_MAKE_VERSION or VK_MAKE_API_VERSION. // highest version available. Should be constructed with VK_MAKE_VERSION or VK_MAKE_API_VERSION.
[[deprecated("Use require_api_version + set_minimum_instance_version instead.")]] [[deprecated("Use require_api_version + set_minimum_instance_version instead.")]] InstanceBuilder&
InstanceBuilder& desire_api_version(uint32_t preferred_vulkan_version); desire_api_version(uint32_t preferred_vulkan_version);
// Prefer a vulkan instance API version. If the desired version isn't available, it will use the highest version available. // Prefer a vulkan instance API version. If the desired version isn't available, it will use the highest version available.
[[deprecated("Use require_api_version + set_minimum_instance_version instead.")]] [[deprecated("Use require_api_version + set_minimum_instance_version instead.")]] InstanceBuilder&
InstanceBuilder& desire_api_version(uint32_t major, uint32_t minor, uint32_t patch = 0); desire_api_version(uint32_t major, uint32_t minor, uint32_t patch = 0);
// Adds a layer to be enabled. Will fail to create an instance if the layer isn't available. // Adds a layer to be enabled. Will fail to create an instance if the layer isn't available.
InstanceBuilder& enable_layer(const char* layer_name); InstanceBuilder& enable_layer(const char* layer_name);
@ -498,21 +498,12 @@ struct PhysicalDevice {
VkPhysicalDeviceFeatures2KHR features2{}; VkPhysicalDeviceFeatures2KHR features2{};
#endif #endif
bool defer_surface_initialization = false; bool defer_surface_initialization = false;
enum class Suitable { yes, partial, no };
Suitable suitable = Suitable::yes;
friend class PhysicalDeviceSelector; friend class PhysicalDeviceSelector;
friend class DeviceBuilder; friend class DeviceBuilder;
}; };
enum class PreferredDeviceType { other = 0, integrated = 1, discrete = 2, virtual_gpu = 3, cpu = 4 }; enum class PreferredDeviceType { other = 0, integrated = 1, discrete = 2, virtual_gpu = 3, cpu = 4 };
enum class DeviceSelectionMode {
// return all suitable and partially suitable devices
partially_and_fully_suitable,
// return only physical devices which are fully suitable
only_fully_suitable
};
// Enumerates the physical devices on the system, and based on the added criteria, returns a physical device or list of physical devies // Enumerates the physical devices on the system, and based on the added criteria, returns a physical device or list of physical devies
// A device is considered suitable if it meets all the 'required' and 'desired' criteria. // A device is considered suitable if it meets all the 'required' and 'desired' criteria.
// A device is considered partially suitable if it meets only the 'required' criteria. // A device is considered partially suitable if it meets only the 'required' criteria.
@ -525,15 +516,13 @@ class PhysicalDeviceSelector {
// Return the first device which is suitable // Return the first device which is suitable
// use the `selection` parameter to configure if partially // use the `selection` parameter to configure if partially
detail::Result<PhysicalDevice> select(DeviceSelectionMode selection = DeviceSelectionMode::partially_and_fully_suitable) const; detail::Result<PhysicalDevice> select() const;
// Return all devices which are considered suitable - intended for applications which want to let the user pick the physical device // Return all devices which are considered suitable - intended for applications which want to let the user pick the physical device
detail::Result<std::vector<PhysicalDevice>> select_devices( detail::Result<std::vector<PhysicalDevice>> select_devices() const;
DeviceSelectionMode selection = DeviceSelectionMode::partially_and_fully_suitable) const;
// Return the names of all devices which are considered suitable - intended for applications which want to let the user pick the physical device // Return the names of all devices which are considered suitable - intended for applications which want to let the user pick the physical device
detail::Result<std::vector<std::string>> select_device_names( detail::Result<std::vector<std::string>> select_device_names() const;
DeviceSelectionMode selection = DeviceSelectionMode::partially_and_fully_suitable) const;
// Set the surface in which the physical device should render to. // Set the surface in which the physical device should render to.
// Be sure to set it if swapchain functionality is to be used. // Be sure to set it if swapchain functionality is to be used.
@ -562,21 +551,13 @@ class PhysicalDeviceSelector {
// Require a memory heap from VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT with `size` memory available. // Require a memory heap from VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT with `size` memory available.
PhysicalDeviceSelector& required_device_memory_size(VkDeviceSize size); PhysicalDeviceSelector& required_device_memory_size(VkDeviceSize size);
// Prefer a memory heap from VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT with `size` memory available. // Prefer a memory heap from VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT with `size` memory available.
PhysicalDeviceSelector& desired_device_memory_size(VkDeviceSize size);
// Require a physical device which supports a specific extension. // Require a physical device which supports a specific extension.
PhysicalDeviceSelector& add_required_extension(const char* extension); PhysicalDeviceSelector& add_required_extension(const char* extension);
// Require a physical device which supports a set of extensions. // Require a physical device which supports a set of extensions.
PhysicalDeviceSelector& add_required_extensions(std::vector<const char*> extensions); PhysicalDeviceSelector& add_required_extensions(std::vector<const char*> extensions);
// Prefer a physical device which supports a specific extension.
PhysicalDeviceSelector& add_desired_extension(const char* extension);
// Prefer a physical device which supports a set of extensions.
PhysicalDeviceSelector& add_desired_extensions(std::vector<const char*> extensions);
// Prefer a physical device that supports a (major, minor) version of vulkan.
[[deprecated("Use set_minimum_version + InstanceBuilder::require_api_version.")]]
PhysicalDeviceSelector& set_desired_version(uint32_t major, uint32_t minor);
// Require a physical device that supports a (major, minor) version of vulkan. // Require a physical device that supports a (major, minor) version of vulkan.
PhysicalDeviceSelector& set_minimum_version(uint32_t major, uint32_t minor); PhysicalDeviceSelector& set_minimum_version(uint32_t major, uint32_t minor);
@ -637,13 +618,10 @@ class PhysicalDeviceSelector {
bool require_separate_transfer_queue = false; bool require_separate_transfer_queue = false;
bool require_separate_compute_queue = false; bool require_separate_compute_queue = false;
VkDeviceSize required_mem_size = 0; VkDeviceSize required_mem_size = 0;
VkDeviceSize desired_mem_size = 0;
std::vector<std::string> required_extensions; std::vector<std::string> required_extensions;
std::vector<std::string> desired_extensions;
uint32_t required_version = VKB_VK_API_VERSION_1_0; uint32_t required_version = VKB_VK_API_VERSION_1_0;
uint32_t desired_version = VKB_VK_API_VERSION_1_0;
VkPhysicalDeviceFeatures required_features{}; VkPhysicalDeviceFeatures required_features{};
#if defined(VKB_VK_API_VERSION_1_1) #if defined(VKB_VK_API_VERSION_1_1)
@ -658,9 +636,9 @@ class PhysicalDeviceSelector {
PhysicalDevice populate_device_details(VkPhysicalDevice phys_device, PhysicalDevice populate_device_details(VkPhysicalDevice phys_device,
std::vector<detail::GenericFeaturesPNextNode> const& src_extended_features_chain) const; std::vector<detail::GenericFeaturesPNextNode> const& src_extended_features_chain) const;
PhysicalDevice::Suitable is_device_suitable(PhysicalDevice const& phys_device) const; bool is_device_suitable(PhysicalDevice const& phys_device) const;
detail::Result<std::vector<PhysicalDevice>> select_impl(DeviceSelectionMode selection) const; detail::Result<std::vector<PhysicalDevice>> select_impl() const;
}; };
// ---- Queue ---- // // ---- Queue ---- //

View File

@ -3,17 +3,13 @@
#include <catch2/catch.hpp> #include <catch2/catch.hpp>
vkb::Instance get_instance(uint32_t minor_version = 0) { vkb::Instance get_instance(uint32_t minor_version = 0) {
auto instance_ret = auto instance_ret = vkb::InstanceBuilder().request_validation_layers().require_api_version(1, minor_version).build();
vkb::InstanceBuilder().request_validation_layers().require_api_version(1, minor_version).build();
REQUIRE(instance_ret.has_value()); REQUIRE(instance_ret.has_value());
return instance_ret.value(); return instance_ret.value();
} }
vkb::Instance get_headless_instance(uint32_t minor_version = 0) { vkb::Instance get_headless_instance(uint32_t minor_version = 0) {
auto instance_ret = vkb::InstanceBuilder() auto instance_ret =
.request_validation_layers() vkb::InstanceBuilder().request_validation_layers().require_api_version(1, minor_version).set_headless().build();
.require_api_version(1, minor_version)
.set_headless()
.build();
REQUIRE(instance_ret.has_value()); REQUIRE(instance_ret.has_value());
return instance_ret.value(); return instance_ret.value();
} }
@ -59,7 +55,6 @@ TEST_CASE("Instance with surface", "[VkBootstrap.bootstrap]") {
THEN("Can select physical device with customized requirements") { THEN("Can select physical device with customized requirements") {
vkb::PhysicalDeviceSelector selector(instance); vkb::PhysicalDeviceSelector selector(instance);
auto phys_dev_ret = selector.set_surface(surface) auto phys_dev_ret = selector.set_surface(surface)
.add_desired_extension(VK_KHR_MULTIVIEW_EXTENSION_NAME)
.add_required_extension(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME) .add_required_extension(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)
.set_minimum_version(1, 0) .set_minimum_version(1, 0)
.select(); .select();
@ -87,23 +82,22 @@ TEST_CASE("instance configuration", "[VkBootstrap.bootstrap]") {
SECTION("custom debug callback") { SECTION("custom debug callback") {
vkb::InstanceBuilder builder; vkb::InstanceBuilder builder;
auto instance_ret = auto instance_ret = builder.request_validation_layers()
builder.request_validation_layers() .set_app_name("test app")
.set_app_name("test app") .set_app_version(1, 0, 0)
.set_app_version(1, 0, 0) .set_engine_name("engine_name")
.set_engine_name("engine_name") .set_engine_version(9, 9, 9)
.set_engine_version(9, 9, 9) .set_debug_callback([](VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
.set_debug_callback([](VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType,
VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void*
void* /*pUserData*/) -> VkBool32 {
/*pUserData*/) -> VkBool32 { auto ms = vkb::to_string_message_severity(messageSeverity);
auto ms = vkb::to_string_message_severity(messageSeverity); auto mt = vkb::to_string_message_type(messageType);
auto mt = vkb::to_string_message_type(messageType); printf("[%s: %s](user defined)\n%s\n", ms, mt, pCallbackData->pMessage);
printf("[%s: %s](user defined)\n%s\n", ms, mt, pCallbackData->pMessage); return VK_FALSE;
return VK_FALSE; })
}) .build();
.build();
REQUIRE(instance_ret.has_value()); REQUIRE(instance_ret.has_value());
@ -117,8 +111,7 @@ TEST_CASE("instance configuration", "[VkBootstrap.bootstrap]") {
.require_api_version(1, 0, 34) .require_api_version(1, 0, 34)
.use_default_debug_messenger() .use_default_debug_messenger()
.add_validation_feature_enable(VkValidationFeatureEnableEXT::VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT) .add_validation_feature_enable(VkValidationFeatureEnableEXT::VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT)
.add_validation_feature_disable( .add_validation_feature_disable(VkValidationFeatureDisableEXT::VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT)
VkValidationFeatureDisableEXT::VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT)
.add_validation_disable(VkValidationCheckEXT::VK_VALIDATION_CHECK_SHADERS_EXT) .add_validation_disable(VkValidationCheckEXT::VK_VALIDATION_CHECK_SHADERS_EXT)
.build(); .build();
REQUIRE(instance_ret.has_value()); REQUIRE(instance_ret.has_value());
@ -169,17 +162,15 @@ TEST_CASE("Device Configuration", "[VkBootstrap.bootstrap]") {
if ((queue_families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) && if ((queue_families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) &&
(queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0 && (queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0 &&
(queue_families[i].queueFlags & VK_QUEUE_TRANSFER_BIT) == 0) (queue_families[i].queueFlags & VK_QUEUE_TRANSFER_BIT) == 0)
queue_descriptions.push_back(vkb::CustomQueueDescription(i, queue_descriptions.push_back(vkb::CustomQueueDescription(
queue_families[i].queueCount, i, queue_families[i].queueCount, std::vector<float>(queue_families[i].queueCount, 1.0f)));
std::vector<float>(queue_families[i].queueCount, 1.0f)));
} }
} else if (phys_device.has_separate_compute_queue()) { } else if (phys_device.has_separate_compute_queue()) {
for (uint32_t i = 0; i < (uint32_t)queue_families.size(); i++) { for (uint32_t i = 0; i < (uint32_t)queue_families.size(); i++) {
if ((queue_families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) && if ((queue_families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) &&
((queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0)) { ((queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0)) {
queue_descriptions.push_back(vkb::CustomQueueDescription(i, queue_descriptions.push_back(vkb::CustomQueueDescription(
queue_families[i].queueCount, i, queue_families[i].queueCount, std::vector<float>(queue_families[i].queueCount, 1.0f)));
std::vector<float>(queue_families[i].queueCount, 1.0f)));
} }
} }
} }
@ -296,15 +287,14 @@ TEST_CASE("Swapchain", "[VkBootstrap.bootstrap]") {
AND_THEN("Swapchain configuration") { AND_THEN("Swapchain configuration") {
vkb::SwapchainBuilder swapchain_builder(device); vkb::SwapchainBuilder swapchain_builder(device);
auto swapchain_ret = auto swapchain_ret = swapchain_builder.set_desired_extent(256, 256)
swapchain_builder.set_desired_extent(256, 256) .set_desired_format({ VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR })
.set_desired_format({ VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR }) .set_desired_present_mode(VK_PRESENT_MODE_IMMEDIATE_KHR)
.set_desired_present_mode(VK_PRESENT_MODE_IMMEDIATE_KHR) .set_pre_transform_flags(VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
.set_pre_transform_flags(VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) .set_composite_alpha_flags(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)
.set_composite_alpha_flags(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) .set_clipped(false)
.set_clipped(false) .set_image_array_layer_count(1)
.set_image_array_layer_count(1) .build();
.build();
REQUIRE(swapchain_ret.has_value()); REQUIRE(swapchain_ret.has_value());
vkb::destroy_swapchain(swapchain_ret.value()); vkb::destroy_swapchain(swapchain_ret.value());
@ -345,8 +335,7 @@ TEST_CASE("Swapchain", "[VkBootstrap.bootstrap]") {
vkb::destroy_swapchain(recreated_swapchain_ret.value()); vkb::destroy_swapchain(recreated_swapchain_ret.value());
} }
AND_THEN("Swapchain can be create with default gotten handles") { AND_THEN("Swapchain can be create with default gotten handles") {
vkb::SwapchainBuilder swapchain_builder( vkb::SwapchainBuilder swapchain_builder(device.physical_device.physical_device, device.device, surface);
device.physical_device.physical_device, device.device, surface);
auto swapchain_ret = swapchain_builder.build(); auto swapchain_ret = swapchain_builder.build();
REQUIRE(swapchain_ret.has_value()); REQUIRE(swapchain_ret.has_value());
@ -488,10 +477,9 @@ TEST_CASE("Querying Required Extension Features but with 1.0", "[VkBootstrap.sel
descriptor_indexing_features.runtimeDescriptorArray = true; descriptor_indexing_features.runtimeDescriptorArray = true;
vkb::PhysicalDeviceSelector selector(instance); vkb::PhysicalDeviceSelector selector(instance);
auto phys_dev_ret = auto phys_dev_ret = selector.add_required_extension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)
selector.add_required_extension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME) .add_required_extension_features(descriptor_indexing_features)
.add_required_extension_features(descriptor_indexing_features) .select();
.select();
// Ignore if hardware support isn't true // Ignore if hardware support isn't true
REQUIRE(phys_dev_ret.has_value()); REQUIRE(phys_dev_ret.has_value());
@ -513,10 +501,9 @@ TEST_CASE("Querying Required Extension Features", "[VkBootstrap.select_features]
descriptor_indexing_features.runtimeDescriptorArray = true; descriptor_indexing_features.runtimeDescriptorArray = true;
vkb::PhysicalDeviceSelector selector(instance); vkb::PhysicalDeviceSelector selector(instance);
auto phys_dev_ret = auto phys_dev_ret = selector.add_required_extension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)
selector.add_required_extension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME) .add_required_extension_features(descriptor_indexing_features)
.add_required_extension_features(descriptor_indexing_features) .select();
.select();
// Ignore if hardware support isn't true // Ignore if hardware support isn't true
REQUIRE(phys_dev_ret.has_value()); REQUIRE(phys_dev_ret.has_value());
@ -534,8 +521,7 @@ TEST_CASE("Passing vkb classes to Vulkan handles", "[VkBootstrap.pass_class_to_h
auto instance = get_instance(); auto instance = get_instance();
// Check if we can get instance functions. // Check if we can get instance functions.
PFN_vkVoidFunction instanceFunction = instance.fp_vkGetInstanceProcAddr( PFN_vkVoidFunction instanceFunction = instance.fp_vkGetInstanceProcAddr(instance, "vkSetDebugUtilsObjectNameEXT"); // validation layers should be provided.
instance, "vkSetDebugUtilsObjectNameEXT"); // validation layers should be provided.
REQUIRE(instanceFunction != NULL); REQUIRE(instanceFunction != NULL);
auto window = create_window_glfw("Conversion operators"); auto window = create_window_glfw("Conversion operators");
@ -543,17 +529,14 @@ TEST_CASE("Passing vkb classes to Vulkan handles", "[VkBootstrap.pass_class_to_h
vkb::PhysicalDeviceSelector physicalDeviceSelector(instance); vkb::PhysicalDeviceSelector physicalDeviceSelector(instance);
auto physicalDevice = auto physicalDevice =
physicalDeviceSelector.add_required_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME) physicalDeviceSelector.add_required_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME).set_surface(surface).select();
.set_surface(surface)
.select();
REQUIRE(physicalDevice.has_value()); REQUIRE(physicalDevice.has_value());
vkb::DeviceBuilder deviceBuilder(physicalDevice.value()); vkb::DeviceBuilder deviceBuilder(physicalDevice.value());
auto device = deviceBuilder.build(); auto device = deviceBuilder.build();
REQUIRE(device.has_value()); REQUIRE(device.has_value());
// Check if we can get a device function address, passing vkb::Device to the function. // Check if we can get a device function address, passing vkb::Device to the function.
PFN_vkVoidFunction deviceFunction = PFN_vkVoidFunction deviceFunction = instance.fp_vkGetDeviceProcAddr(device.value(), "vkAcquireNextImageKHR");
instance.fp_vkGetDeviceProcAddr(device.value(), "vkAcquireNextImageKHR");
REQUIRE(deviceFunction != NULL); REQUIRE(deviceFunction != NULL);
} }
} }
@ -569,10 +552,9 @@ TEST_CASE("Querying Required Extension Features in 1.1", "[VkBootstrap.version]"
descriptor_indexing_features.runtimeDescriptorArray = true; descriptor_indexing_features.runtimeDescriptorArray = true;
vkb::PhysicalDeviceSelector selector(instance); vkb::PhysicalDeviceSelector selector(instance);
auto phys_dev_ret = auto phys_dev_ret = selector.add_required_extension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)
selector.add_required_extension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME) .add_required_extension_features(descriptor_indexing_features)
.add_required_extension_features(descriptor_indexing_features) .select();
.select();
// Ignore if hardware support isn't true // Ignore if hardware support isn't true
REQUIRE(phys_dev_ret.has_value()); REQUIRE(phys_dev_ret.has_value());
@ -601,8 +583,7 @@ TEST_CASE("Querying Vulkan 1.1 and 1.2 features", "[VkBootstrap.version]") {
features_12.bufferDeviceAddress = true; features_12.bufferDeviceAddress = true;
vkb::PhysicalDeviceSelector selector(instance); vkb::PhysicalDeviceSelector selector(instance);
auto phys_dev_ret = auto phys_dev_ret = selector.set_required_features_11(features_11).set_required_features_12(features_12).select();
selector.set_required_features_11(features_11).set_required_features_12(features_12).select();
// Ignore if hardware support isn't true // Ignore if hardware support isn't true
REQUIRE(phys_dev_ret.has_value()); REQUIRE(phys_dev_ret.has_value());