mirror of
https://github.com/charles-lunarg/vk-bootstrap.git
synced 2024-11-22 07:24:34 +00:00
Revert "Revert "- Restored removed functions - Restored pNext chain to device (appends to the end of the ExtentionFeatures chain) - Style changes - Migrated ExtensionFeatures into detail""
This reverts commit 4bfc21f8be
.
This commit is contained in:
parent
e8100dd16c
commit
8a3c1ac6ed
@ -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,
|
||||||
const std::vector<ExtensionFeatures>& extension_supported,
|
std::vector<ExtensionFeatures> const& extension_supported,
|
||||||
const std::vector<ExtensionFeatures>& extension_requested) {
|
std::vector<ExtensionFeatures> 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<ExtensionFeatures> extension_features_as_template) const {
|
std::vector<detail::ExtensionFeatures> 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,7 +1007,7 @@ 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) {
|
||||||
ExtensionFeatures* prev = nullptr;
|
detail::ExtensionFeatures* prev = nullptr;
|
||||||
for(auto& extension : desc.extension_features) {
|
for(auto& extension : desc.extension_features) {
|
||||||
if(prev != nullptr) {
|
if(prev != nullptr) {
|
||||||
prev->structure->pNext = extension.structure;
|
prev->structure->pNext = extension.structure;
|
||||||
@ -1260,12 +1260,12 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::set_desired_version(uint32_t maj
|
|||||||
// Just calls add_required_features
|
// Just calls add_required_features
|
||||||
PhysicalDeviceSelector& PhysicalDeviceSelector::set_required_features_11(
|
PhysicalDeviceSelector& PhysicalDeviceSelector::set_required_features_11(
|
||||||
VkPhysicalDeviceVulkan11Features const& features_11) {
|
VkPhysicalDeviceVulkan11Features const& features_11) {
|
||||||
add_required_features(features_11);
|
add_required_extension_features(features_11);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
PhysicalDeviceSelector& PhysicalDeviceSelector::set_required_features_12(
|
PhysicalDeviceSelector& PhysicalDeviceSelector::set_required_features_12(
|
||||||
VkPhysicalDeviceVulkan12Features const& features_12) {
|
VkPhysicalDeviceVulkan12Features const& features_12) {
|
||||||
add_required_features(features_12);
|
add_required_extension_features(features_12);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1401,21 +1401,24 @@ detail::Result<Device> DeviceBuilder::build() const {
|
|||||||
|
|
||||||
bool has_phys_dev_features_2 = false;
|
bool has_phys_dev_features_2 = false;
|
||||||
|
|
||||||
// Setup the pNexts of all the extension features
|
|
||||||
#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::ExtensionFeatures> 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) &&
|
||||||
physical_device.extension_features.size() > 0) {
|
match.size() > 0) {
|
||||||
ExtensionFeatures* prev = nullptr;
|
detail::ExtensionFeatures* prev = nullptr;
|
||||||
for(auto& extension : physical_device.extension_features) {
|
for(auto& extension : match) {
|
||||||
if(prev != nullptr) {
|
if(prev != nullptr) {
|
||||||
prev->structure->pNext = extension.structure;
|
prev->structure->pNext = extension.structure;
|
||||||
}
|
}
|
||||||
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 = physical_device.extension_features[0].structure;
|
local_features2.pNext = match.front().structure;
|
||||||
has_phys_dev_features_2 = true;
|
has_phys_dev_features_2 = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1427,19 +1430,31 @@ detail::Result<Device> DeviceBuilder::build() const {
|
|||||||
device_create_info.pQueueCreateInfos = queueCreateInfos.data();
|
device_create_info.pQueueCreateInfos = queueCreateInfos.data();
|
||||||
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();
|
||||||
|
|
||||||
|
detail::setup_pNext_chain(device_create_info, info.pNext_chain);
|
||||||
|
|
||||||
|
#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.pEnabledFeatures = &physical_device.features;
|
|
||||||
} else {
|
|
||||||
device_create_info.pNext = &local_features2;
|
device_create_info.pNext = &local_features2;
|
||||||
}
|
if(info.pNext_chain.size() > 0) {
|
||||||
|
match.back().structure->pNext = info.pNext_chain.front();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
device_create_info.pEnabledFeatures = &physical_device.features;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
device_create_info.pEnabledFeatures = &physical_device.features;
|
||||||
|
#endif
|
||||||
|
|
||||||
Device device;
|
Device device;
|
||||||
|
|
||||||
VkResult res = detail::vulkan_functions().fp_vkCreateDevice(
|
VkResult res = detail::vulkan_functions().fp_vkCreateDevice(
|
||||||
physical_device.physical_device, &device_create_info, info.allocation_callbacks, &device.device);
|
physical_device.physical_device, &device_create_info, info.allocation_callbacks, &device.device);
|
||||||
if (res != VK_SUCCESS) {
|
if (res != VK_SUCCESS) {
|
||||||
return { DeviceError::failed_create_device, res };
|
return { DeviceError::failed_create_device, res };
|
||||||
}
|
}
|
||||||
|
|
||||||
device.physical_device = physical_device;
|
device.physical_device = physical_device;
|
||||||
device.surface = physical_device.surface;
|
device.surface = physical_device.surface;
|
||||||
device.queue_families = physical_device.queue_families;
|
device.queue_families = physical_device.queue_families;
|
||||||
|
@ -115,86 +115,6 @@ template <typename T> class Result {
|
|||||||
bool m_init;
|
bool m_init;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
enum class InstanceError {
|
|
||||||
vulkan_unavailable,
|
|
||||||
vulkan_version_unavailable,
|
|
||||||
vulkan_version_1_1_unavailable,
|
|
||||||
vulkan_version_1_2_unavailable,
|
|
||||||
failed_create_instance,
|
|
||||||
failed_create_debug_messenger,
|
|
||||||
requested_layers_not_present,
|
|
||||||
requested_extensions_not_present,
|
|
||||||
windowing_extensions_not_present,
|
|
||||||
};
|
|
||||||
enum class PhysicalDeviceError {
|
|
||||||
no_surface_provided,
|
|
||||||
failed_enumerate_physical_devices,
|
|
||||||
no_physical_devices_found,
|
|
||||||
no_suitable_device,
|
|
||||||
};
|
|
||||||
enum class QueueError {
|
|
||||||
present_unavailable,
|
|
||||||
graphics_unavailable,
|
|
||||||
compute_unavailable,
|
|
||||||
transfer_unavailable,
|
|
||||||
queue_index_out_of_range,
|
|
||||||
invalid_queue_family_index
|
|
||||||
};
|
|
||||||
enum class DeviceError {
|
|
||||||
failed_create_device,
|
|
||||||
};
|
|
||||||
enum class SwapchainError {
|
|
||||||
surface_handle_not_provided,
|
|
||||||
failed_query_surface_support_details,
|
|
||||||
failed_create_swapchain,
|
|
||||||
failed_get_swapchain_images,
|
|
||||||
failed_create_swapchain_image_views,
|
|
||||||
};
|
|
||||||
|
|
||||||
std::error_code make_error_code(InstanceError instance_error);
|
|
||||||
std::error_code make_error_code(PhysicalDeviceError physical_device_error);
|
|
||||||
std::error_code make_error_code(QueueError queue_error);
|
|
||||||
std::error_code make_error_code(DeviceError device_error);
|
|
||||||
std::error_code make_error_code(SwapchainError swapchain_error);
|
|
||||||
|
|
||||||
const char* to_string_message_severity(VkDebugUtilsMessageSeverityFlagBitsEXT s);
|
|
||||||
const char* to_string_message_type(VkDebugUtilsMessageTypeFlagsEXT s);
|
|
||||||
|
|
||||||
const char* to_string(InstanceError err);
|
|
||||||
const char* to_string(PhysicalDeviceError err);
|
|
||||||
const char* to_string(QueueError err);
|
|
||||||
const char* to_string(DeviceError err);
|
|
||||||
const char* to_string(SwapchainError err);
|
|
||||||
|
|
||||||
// Gathers useful information about the available vulkan capabilities, like layers and instance
|
|
||||||
// extensions. Use this for enabling features conditionally, ie if you would like an extension but
|
|
||||||
// can use a fallback if it isn't supported but need to know if support is available first.
|
|
||||||
struct SystemInfo {
|
|
||||||
private:
|
|
||||||
SystemInfo();
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Use get_system_info to create a SystemInfo struct. This is because loading vulkan could fail.
|
|
||||||
static detail::Result<SystemInfo> get_system_info();
|
|
||||||
static detail::Result<SystemInfo> get_system_info(PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcAddr);
|
|
||||||
|
|
||||||
// Returns true if a layer is available
|
|
||||||
bool is_layer_available(const char* layer_name) const;
|
|
||||||
// Returns true if an extension is available
|
|
||||||
bool is_extension_available(const char* extension_name) const;
|
|
||||||
|
|
||||||
std::vector<VkLayerProperties> available_layers;
|
|
||||||
std::vector<VkExtensionProperties> available_extensions;
|
|
||||||
bool validation_layers_available = false;
|
|
||||||
bool debug_utils_available = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class InstanceBuilder;
|
|
||||||
class PhysicalDeviceSelector;
|
|
||||||
|
|
||||||
struct ExtensionFeatures {
|
struct ExtensionFeatures {
|
||||||
|
|
||||||
using DeleteProc = void(*)(ExtensionFeatures&);
|
using DeleteProc = void(*)(ExtensionFeatures&);
|
||||||
@ -313,6 +233,86 @@ struct ExtensionFeatures {
|
|||||||
CopyProc copy_proc = nullptr;
|
CopyProc copy_proc = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
enum class InstanceError {
|
||||||
|
vulkan_unavailable,
|
||||||
|
vulkan_version_unavailable,
|
||||||
|
vulkan_version_1_1_unavailable,
|
||||||
|
vulkan_version_1_2_unavailable,
|
||||||
|
failed_create_instance,
|
||||||
|
failed_create_debug_messenger,
|
||||||
|
requested_layers_not_present,
|
||||||
|
requested_extensions_not_present,
|
||||||
|
windowing_extensions_not_present,
|
||||||
|
};
|
||||||
|
enum class PhysicalDeviceError {
|
||||||
|
no_surface_provided,
|
||||||
|
failed_enumerate_physical_devices,
|
||||||
|
no_physical_devices_found,
|
||||||
|
no_suitable_device,
|
||||||
|
};
|
||||||
|
enum class QueueError {
|
||||||
|
present_unavailable,
|
||||||
|
graphics_unavailable,
|
||||||
|
compute_unavailable,
|
||||||
|
transfer_unavailable,
|
||||||
|
queue_index_out_of_range,
|
||||||
|
invalid_queue_family_index
|
||||||
|
};
|
||||||
|
enum class DeviceError {
|
||||||
|
failed_create_device,
|
||||||
|
};
|
||||||
|
enum class SwapchainError {
|
||||||
|
surface_handle_not_provided,
|
||||||
|
failed_query_surface_support_details,
|
||||||
|
failed_create_swapchain,
|
||||||
|
failed_get_swapchain_images,
|
||||||
|
failed_create_swapchain_image_views,
|
||||||
|
};
|
||||||
|
|
||||||
|
std::error_code make_error_code(InstanceError instance_error);
|
||||||
|
std::error_code make_error_code(PhysicalDeviceError physical_device_error);
|
||||||
|
std::error_code make_error_code(QueueError queue_error);
|
||||||
|
std::error_code make_error_code(DeviceError device_error);
|
||||||
|
std::error_code make_error_code(SwapchainError swapchain_error);
|
||||||
|
|
||||||
|
const char* to_string_message_severity(VkDebugUtilsMessageSeverityFlagBitsEXT s);
|
||||||
|
const char* to_string_message_type(VkDebugUtilsMessageTypeFlagsEXT s);
|
||||||
|
|
||||||
|
const char* to_string(InstanceError err);
|
||||||
|
const char* to_string(PhysicalDeviceError err);
|
||||||
|
const char* to_string(QueueError err);
|
||||||
|
const char* to_string(DeviceError err);
|
||||||
|
const char* to_string(SwapchainError err);
|
||||||
|
|
||||||
|
// Gathers useful information about the available vulkan capabilities, like layers and instance
|
||||||
|
// extensions. Use this for enabling features conditionally, ie if you would like an extension but
|
||||||
|
// can use a fallback if it isn't supported but need to know if support is available first.
|
||||||
|
struct SystemInfo {
|
||||||
|
private:
|
||||||
|
SystemInfo();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Use get_system_info to create a SystemInfo struct. This is because loading vulkan could fail.
|
||||||
|
static detail::Result<SystemInfo> get_system_info();
|
||||||
|
static detail::Result<SystemInfo> get_system_info(PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcAddr);
|
||||||
|
|
||||||
|
// Returns true if a layer is available
|
||||||
|
bool is_layer_available(const char* layer_name) const;
|
||||||
|
// Returns true if an extension is available
|
||||||
|
bool is_extension_available(const char* extension_name) const;
|
||||||
|
|
||||||
|
std::vector<VkLayerProperties> available_layers;
|
||||||
|
std::vector<VkExtensionProperties> available_extensions;
|
||||||
|
bool validation_layers_available = false;
|
||||||
|
bool debug_utils_available = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class InstanceBuilder;
|
||||||
|
class PhysicalDeviceSelector;
|
||||||
|
|
||||||
struct Instance {
|
struct Instance {
|
||||||
VkInstance instance = VK_NULL_HANDLE;
|
VkInstance instance = VK_NULL_HANDLE;
|
||||||
VkDebugUtilsMessengerEXT debug_messenger = VK_NULL_HANDLE;
|
VkDebugUtilsMessengerEXT debug_messenger = VK_NULL_HANDLE;
|
||||||
@ -473,7 +473,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;
|
||||||
mutable std::vector<ExtensionFeatures> extension_features;
|
std::vector<detail::ExtensionFeatures> extension_features;
|
||||||
bool defer_surface_initialization = false;
|
bool defer_surface_initialization = false;
|
||||||
friend class PhysicalDeviceSelector;
|
friend class PhysicalDeviceSelector;
|
||||||
friend class DeviceBuilder;
|
friend class DeviceBuilder;
|
||||||
@ -534,16 +534,15 @@ class PhysicalDeviceSelector {
|
|||||||
// 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);
|
||||||
|
|
||||||
// Require a physical device which supports a specific set of general/extension features.
|
// Require a physical device which supports a specific set of general/extension features.
|
||||||
template <typename T>
|
|
||||||
PhysicalDeviceSelector& add_required_features(T const& features) {
|
|
||||||
#if defined(VK_API_VERSION_1_1)
|
#if defined(VK_API_VERSION_1_1)
|
||||||
criteria.extension_features.push_back(ExtensionFeatures::make(features));
|
template <typename T>
|
||||||
#endif
|
PhysicalDeviceSelector& add_required_extension_features(T const& features) {
|
||||||
|
criteria.extension_features.push_back(detail::ExtensionFeatures::make(features));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
template<>
|
#endif
|
||||||
PhysicalDeviceSelector& add_required_features<VkPhysicalDeviceFeatures>(VkPhysicalDeviceFeatures const& features) {
|
PhysicalDeviceSelector& set_required_features(VkPhysicalDeviceFeatures const& features) {
|
||||||
criteria.required_features = features;
|
criteria.required_features = features;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -581,7 +580,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<ExtensionFeatures> extension_features;
|
std::vector<detail::ExtensionFeatures> extension_features;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -590,7 +589,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<ExtensionFeatures> extension_features_as_template) const;
|
std::vector<detail::ExtensionFeatures> extension_features_as_template) const;
|
||||||
|
|
||||||
struct SelectionCriteria {
|
struct SelectionCriteria {
|
||||||
PreferredDeviceType preferred_type = PreferredDeviceType::discrete;
|
PreferredDeviceType preferred_type = PreferredDeviceType::discrete;
|
||||||
@ -612,7 +611,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<ExtensionFeatures> extension_features;
|
std::vector<detail::ExtensionFeatures> 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;
|
||||||
@ -670,6 +669,13 @@ class DeviceBuilder {
|
|||||||
// If a custom queue setup is provided, getting the queues and queue indexes is up to the application.
|
// If a custom queue setup is provided, getting the queues and queue indexes is up to the application.
|
||||||
DeviceBuilder& custom_queue_setup(std::vector<CustomQueueDescription> queue_descriptions);
|
DeviceBuilder& custom_queue_setup(std::vector<CustomQueueDescription> queue_descriptions);
|
||||||
|
|
||||||
|
// Add a structure to the pNext chain of VkDeviceCreateInfo.
|
||||||
|
// The structure must be valid when DeviceBuilder::build() is called.
|
||||||
|
template <typename T> DeviceBuilder& add_pNext(T* structure) {
|
||||||
|
info.pNext_chain.push_back(reinterpret_cast<VkBaseOutStructure*>(structure));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
// Provide custom allocation callbacks.
|
// Provide custom allocation callbacks.
|
||||||
DeviceBuilder& set_allocation_callbacks(VkAllocationCallbacks* callbacks);
|
DeviceBuilder& set_allocation_callbacks(VkAllocationCallbacks* callbacks);
|
||||||
|
|
||||||
@ -677,6 +683,7 @@ class DeviceBuilder {
|
|||||||
PhysicalDevice physical_device;
|
PhysicalDevice physical_device;
|
||||||
struct DeviceInfo {
|
struct DeviceInfo {
|
||||||
VkDeviceCreateFlags flags = 0;
|
VkDeviceCreateFlags flags = 0;
|
||||||
|
std::vector<VkBaseOutStructure*> pNext_chain;
|
||||||
std::vector<CustomQueueDescription> queue_descriptions;
|
std::vector<CustomQueueDescription> queue_descriptions;
|
||||||
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE;
|
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE;
|
||||||
} info;
|
} info;
|
||||||
|
@ -411,6 +411,38 @@ TEST_CASE("ReLoading Vulkan Manually", "[VkBootstrap.loading]") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(VK_API_VERSION_1_1)
|
||||||
|
TEST_CASE("Querying Required Extension Features", "[VkBootstrap.version]") {
|
||||||
|
GIVEN("A working instance") {
|
||||||
|
vkb::InstanceBuilder builder;
|
||||||
|
|
||||||
|
auto instance_ret =
|
||||||
|
builder.request_validation_layers().require_api_version(1, 2).set_headless().build();
|
||||||
|
REQUIRE(instance_ret.has_value());
|
||||||
|
// Requires a device that supports runtime descriptor arrays via descriptor indexing extension.
|
||||||
|
{
|
||||||
|
VkPhysicalDeviceDescriptorIndexingFeaturesEXT descriptor_indexing_features{};
|
||||||
|
descriptor_indexing_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
|
||||||
|
descriptor_indexing_features.runtimeDescriptorArray = true;
|
||||||
|
|
||||||
|
vkb::PhysicalDeviceSelector selector(instance_ret.value());
|
||||||
|
auto phys_dev_ret =
|
||||||
|
selector.add_required_extension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME).
|
||||||
|
add_required_extension_features(descriptor_indexing_features).select();
|
||||||
|
// Ignore if hardware support isn't true
|
||||||
|
REQUIRE(phys_dev_ret.has_value());
|
||||||
|
|
||||||
|
vkb::DeviceBuilder device_builder(phys_dev_ret.value());
|
||||||
|
auto device_ret = device_builder.build();
|
||||||
|
REQUIRE(device_ret.has_value());
|
||||||
|
vkb::destroy_device(device_ret.value());
|
||||||
|
}
|
||||||
|
vkb::destroy_instance(instance_ret.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(VK_API_VERSION_1_2)
|
#if defined(VK_API_VERSION_1_2)
|
||||||
TEST_CASE("Querying Vulkan 1.1 and 1.2 features", "[VkBootstrap.version]") {
|
TEST_CASE("Querying Vulkan 1.1 and 1.2 features", "[VkBootstrap.version]") {
|
||||||
GIVEN("A working instance") {
|
GIVEN("A working instance") {
|
||||||
|
Loading…
Reference in New Issue
Block a user