mirror of
https://github.com/charles-lunarg/vk-bootstrap.git
synced 2024-11-22 15:24:34 +00:00
Added many tests and fixed up api as a consequence
Added device::get_queue_families() to facilitate custom queue setups get_swapchain_images() renamed to get_image(), made member function to swapchain. get_swapchain_image_views() renamed to get_image_views(), also moved to member function of swapchain fixed bug with headless instance not being correct Stopped Catch2 from polluting the buildable targets
This commit is contained in:
parent
e906cfc093
commit
1f462b42f3
@ -294,10 +294,8 @@ int create_graphics_pipeline (Init& init, RenderData& data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int create_framebuffers (Init& init, RenderData& data) {
|
int create_framebuffers (Init& init, RenderData& data) {
|
||||||
data.swapchain_images = vkb::get_swapchain_images (init.swapchain).value ();
|
data.swapchain_images = init.swapchain.get_images ().value ();
|
||||||
// init.swapchain.image_count = data.swapchain_images.size ();
|
data.swapchain_image_views = init.swapchain.get_image_views ().value ();
|
||||||
data.swapchain_image_views =
|
|
||||||
vkb::get_swapchain_image_views (init.swapchain, data.swapchain_images).value ();
|
|
||||||
|
|
||||||
data.framebuffers.resize (data.swapchain_image_views.size ());
|
data.framebuffers.resize (data.swapchain_image_views.size ());
|
||||||
|
|
||||||
|
@ -11,4 +11,10 @@ set(GLFW_BUILD_EXAMPLES
|
|||||||
OFF
|
OFF
|
||||||
CACHE BOOL "" FORCE)
|
CACHE BOOL "" FORCE)
|
||||||
add_subdirectory(glfw)
|
add_subdirectory(glfw)
|
||||||
|
|
||||||
|
set(CATCH_BUILD_TESTING OFF CACHE BOOL "" FORCE)
|
||||||
|
set(CATCH_ENABLE_WERROR OFF CACHE BOOL "" FORCE)
|
||||||
|
set(CATCH_INSTALL_DOCS OFF CACHE BOOL "" FORCE)
|
||||||
|
set(CATCH_INSTALL_HELPERS OFF CACHE BOOL "" FORCE)
|
||||||
|
set_property(GLOBAL PROPERTY CTEST_TARGETS_ADDED 1) #remove Catch2 target spam
|
||||||
add_subdirectory(Catch2)
|
add_subdirectory(Catch2)
|
@ -939,6 +939,9 @@ bool PhysicalDevice::has_dedicated_transfer_queue () const {
|
|||||||
bool PhysicalDevice::has_separate_transfer_queue () const {
|
bool PhysicalDevice::has_separate_transfer_queue () const {
|
||||||
return detail::get_separate_transfer_queue_index (queue_families) >= 0;
|
return detail::get_separate_transfer_queue_index (queue_families) >= 0;
|
||||||
}
|
}
|
||||||
|
std::vector<VkQueueFamilyProperties> PhysicalDevice::get_queue_families () const {
|
||||||
|
return queue_families;
|
||||||
|
}
|
||||||
|
|
||||||
// ---- Queues ---- //
|
// ---- Queues ---- //
|
||||||
|
|
||||||
@ -1002,6 +1005,11 @@ detail::Expected<VkQueue, detail::Error<QueueError>> Device::get_dedicated_queue
|
|||||||
|
|
||||||
// ---- Device ---- //
|
// ---- Device ---- //
|
||||||
|
|
||||||
|
CustomQueueDescription::CustomQueueDescription (uint32_t index, uint32_t count, std::vector<float> priorities)
|
||||||
|
: index (index), count (count), priorities (priorities) {
|
||||||
|
assert (count == priorities.size ());
|
||||||
|
}
|
||||||
|
|
||||||
void destroy_device (Device device) {
|
void destroy_device (Device device) {
|
||||||
vkDestroyDevice (device.device, device.allocation_callbacks);
|
vkDestroyDevice (device.device, device.allocation_callbacks);
|
||||||
}
|
}
|
||||||
@ -1039,6 +1047,14 @@ detail::Expected<Device, detail::Error<DeviceError>> DeviceBuilder::build () con
|
|||||||
std::vector<const char*> extensions = info.extensions_to_enable;
|
std::vector<const char*> extensions = info.extensions_to_enable;
|
||||||
if (info.surface != VK_NULL_HANDLE) extensions.push_back ({ VK_KHR_SWAPCHAIN_EXTENSION_NAME });
|
if (info.surface != VK_NULL_HANDLE) extensions.push_back ({ VK_KHR_SWAPCHAIN_EXTENSION_NAME });
|
||||||
|
|
||||||
|
// VUID-VkDeviceCreateInfo-pNext-00373 - don't add pEnabledFeatures if the phys_dev_features_2 is present
|
||||||
|
bool has_phys_dev_features_2 = false;
|
||||||
|
for (auto& pNext_struct : info.pNext_chain) {
|
||||||
|
if (pNext_struct->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2) {
|
||||||
|
has_phys_dev_features_2 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VkDeviceCreateInfo device_create_info = {};
|
VkDeviceCreateInfo device_create_info = {};
|
||||||
device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
detail::setup_pNext_chain (device_create_info, info.pNext_chain);
|
detail::setup_pNext_chain (device_create_info, info.pNext_chain);
|
||||||
@ -1047,7 +1063,9 @@ detail::Expected<Device, detail::Error<DeviceError>> DeviceBuilder::build () con
|
|||||||
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 ();
|
||||||
|
if (!has_phys_dev_features_2) {
|
||||||
device_create_info.pEnabledFeatures = &info.features;
|
device_create_info.pEnabledFeatures = &info.features;
|
||||||
|
}
|
||||||
|
|
||||||
Device device;
|
Device device;
|
||||||
VkResult res = vkCreateDevice (info.physical_device.physical_device,
|
VkResult res = vkCreateDevice (info.physical_device.physical_device,
|
||||||
@ -1067,15 +1085,13 @@ DeviceBuilder& DeviceBuilder::custom_queue_setup (std::vector<CustomQueueDescrip
|
|||||||
info.queue_descriptions = queue_descriptions;
|
info.queue_descriptions = queue_descriptions;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
template <typename T> DeviceBuilder& DeviceBuilder::add_pNext (T* structure) {
|
|
||||||
info.pNext_chain.push_back (reinterpret_cast<VkBaseOutStructure*> (structure));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
DeviceBuilder& DeviceBuilder::set_allocation_callbacks (VkAllocationCallbacks* callbacks) {
|
DeviceBuilder& DeviceBuilder::set_allocation_callbacks (VkAllocationCallbacks* callbacks) {
|
||||||
info.allocation_callbacks = callbacks;
|
info.allocation_callbacks = callbacks;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- Swapchain ---- //
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
struct SurfaceSupportDetails {
|
struct SurfaceSupportDetails {
|
||||||
VkSurfaceCapabilitiesKHR capabilities;
|
VkSurfaceCapabilitiesKHR capabilities;
|
||||||
@ -1245,7 +1261,10 @@ detail::Expected<Swapchain, detail::Error<SwapchainError>> SwapchainBuilder::bui
|
|||||||
swapchain.device = info.device;
|
swapchain.device = info.device;
|
||||||
swapchain.image_format = surface_format.format;
|
swapchain.image_format = surface_format.format;
|
||||||
swapchain.extent = extent;
|
swapchain.extent = extent;
|
||||||
auto images = get_swapchain_images (swapchain);
|
auto images = swapchain.get_images ();
|
||||||
|
if (!images) {
|
||||||
|
return detail::Error<SwapchainError>{ SwapchainError::failed_get_swapchain_images };
|
||||||
|
}
|
||||||
swapchain.image_count = static_cast<uint32_t> (images.value ().size ());
|
swapchain.image_count = static_cast<uint32_t> (images.value ().size ());
|
||||||
swapchain.allocation_callbacks = info.allocation_callbacks;
|
swapchain.allocation_callbacks = info.allocation_callbacks;
|
||||||
return swapchain;
|
return swapchain;
|
||||||
@ -1254,27 +1273,28 @@ detail::Expected<Swapchain, detail::Error<SwapchainError>> SwapchainBuilder::rec
|
|||||||
Swapchain const& swapchain) const {
|
Swapchain const& swapchain) const {
|
||||||
return build (swapchain.swapchain);
|
return build (swapchain.swapchain);
|
||||||
}
|
}
|
||||||
detail::Expected<std::vector<VkImage>, detail::Error<SwapchainError>> get_swapchain_images (
|
detail::Expected<std::vector<VkImage>, detail::Error<SwapchainError>> Swapchain::get_images () {
|
||||||
Swapchain const& swapchain) {
|
auto swapchain_images = detail::get_vector<VkImage> (vkGetSwapchainImagesKHR, device, swapchain);
|
||||||
auto swapchain_images =
|
|
||||||
detail::get_vector<VkImage> (vkGetSwapchainImagesKHR, swapchain.device, swapchain.swapchain);
|
|
||||||
if (!swapchain_images) {
|
if (!swapchain_images) {
|
||||||
return detail::Error<SwapchainError>{ SwapchainError::failed_get_swapchain_images,
|
return detail::Error<SwapchainError>{ SwapchainError::failed_get_swapchain_images,
|
||||||
swapchain_images.error () };
|
swapchain_images.error () };
|
||||||
}
|
}
|
||||||
return swapchain_images.value ();
|
return swapchain_images.value ();
|
||||||
}
|
}
|
||||||
|
detail::Expected<std::vector<VkImageView>, detail::Error<SwapchainError>> Swapchain::get_image_views () {
|
||||||
|
|
||||||
detail::Expected<std::vector<VkImageView>, detail::Error<SwapchainError>>
|
auto swapchain_images_ret = get_images ();
|
||||||
get_swapchain_image_views (Swapchain const& swapchain, std::vector<VkImage> const& images) {
|
if (!swapchain_images_ret) return swapchain_images_ret.error ();
|
||||||
std::vector<VkImageView> views{ swapchain.image_count };
|
auto swapchain_images = swapchain_images_ret.value ();
|
||||||
|
|
||||||
for (size_t i = 0; i < swapchain.image_count; i++) {
|
std::vector<VkImageView> views{ swapchain_images.size () };
|
||||||
|
|
||||||
|
for (size_t i = 0; i < swapchain_images.size (); i++) {
|
||||||
VkImageViewCreateInfo createInfo = {};
|
VkImageViewCreateInfo createInfo = {};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
createInfo.image = images[i];
|
createInfo.image = swapchain_images[i];
|
||||||
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
createInfo.format = swapchain.image_format;
|
createInfo.format = image_format;
|
||||||
createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
@ -1285,14 +1305,17 @@ get_swapchain_image_views (Swapchain const& swapchain, std::vector<VkImage> cons
|
|||||||
createInfo.subresourceRange.baseArrayLayer = 0;
|
createInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
createInfo.subresourceRange.layerCount = 1;
|
createInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
VkResult res = vkCreateImageView (swapchain.device, &createInfo, nullptr, &views[i]);
|
VkResult res = vkCreateImageView (device, &createInfo, allocation_callbacks, &views[i]);
|
||||||
if (res != VK_SUCCESS)
|
if (res != VK_SUCCESS)
|
||||||
return detail::Error<SwapchainError>{ SwapchainError::failed_create_swapchain_image_views, res };
|
return detail::Error<SwapchainError>{ SwapchainError::failed_create_swapchain_image_views, res };
|
||||||
}
|
}
|
||||||
return views;
|
return views;
|
||||||
}
|
}
|
||||||
|
void Swapchain::destroy_image_views (std::vector<VkImageView> const& image_views) {
|
||||||
|
for (auto& image_view : image_views) {
|
||||||
|
vkDestroyImageView (device, image_view, allocation_callbacks);
|
||||||
|
}
|
||||||
|
}
|
||||||
void destroy_swapchain (Swapchain const& swapchain) {
|
void destroy_swapchain (Swapchain const& swapchain) {
|
||||||
if (swapchain.device != VK_NULL_HANDLE && swapchain.swapchain != VK_NULL_HANDLE)
|
if (swapchain.device != VK_NULL_HANDLE && swapchain.swapchain != VK_NULL_HANDLE)
|
||||||
vkDestroySwapchainKHR (swapchain.device, swapchain.swapchain, swapchain.allocation_callbacks);
|
vkDestroySwapchainKHR (swapchain.device, swapchain.swapchain, swapchain.allocation_callbacks);
|
||||||
|
@ -197,8 +197,8 @@ class InstanceBuilder {
|
|||||||
// Adds an extension to be enabled. Will fail to create an instance if the extension isn't available.
|
// Adds an extension to be enabled. Will fail to create an instance if the extension isn't available.
|
||||||
InstanceBuilder& enable_extension (const char* extension_name);
|
InstanceBuilder& enable_extension (const char* extension_name);
|
||||||
|
|
||||||
// Headless Mode does not load the required extensions for presentation. Defaults to false.
|
// Headless Mode does not load the required extensions for presentation. Defaults to true.
|
||||||
InstanceBuilder& set_headless (bool headless = false);
|
InstanceBuilder& set_headless (bool headless = true);
|
||||||
|
|
||||||
// Enables the validation layers. Will fail to create an instance if the validation layers aren't available.
|
// Enables the validation layers. Will fail to create an instance if the validation layers aren't available.
|
||||||
InstanceBuilder& enable_validation_layers (bool require_validation = true);
|
InstanceBuilder& enable_validation_layers (bool require_validation = true);
|
||||||
@ -311,6 +311,9 @@ struct PhysicalDevice {
|
|||||||
// Has a queue family that supports transfer operations but not graphics.
|
// Has a queue family that supports transfer operations but not graphics.
|
||||||
bool has_separate_transfer_queue () const;
|
bool has_separate_transfer_queue () const;
|
||||||
|
|
||||||
|
// Advanced: Get the VkQueueFamilyProperties of the device if special queue setup is needed
|
||||||
|
std::vector<VkQueueFamilyProperties> get_queue_families () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<const char*> extensions_to_enable;
|
std::vector<const char*> extensions_to_enable;
|
||||||
std::vector<VkQueueFamilyProperties> queue_families;
|
std::vector<VkQueueFamilyProperties> queue_families;
|
||||||
@ -450,16 +453,16 @@ struct Device {
|
|||||||
detail::Expected<VkQueue, detail::Error<QueueError>> get_dedicated_queue (QueueType type) const;
|
detail::Expected<VkQueue, detail::Error<QueueError>> get_dedicated_queue (QueueType type) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
void destroy_device (Device device);
|
// For advanced device queue setup
|
||||||
|
|
||||||
struct CustomQueueDescription {
|
struct CustomQueueDescription {
|
||||||
CustomQueueDescription (uint32_t index, uint32_t count, std::vector<float> priorities)
|
CustomQueueDescription (uint32_t index, uint32_t count, std::vector<float> priorities);
|
||||||
: index (index), count (count), priorities (priorities) {}
|
|
||||||
uint32_t index = 0;
|
uint32_t index = 0;
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
std::vector<float> priorities;
|
std::vector<float> priorities;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void destroy_device (Device device);
|
||||||
|
|
||||||
class DeviceBuilder {
|
class DeviceBuilder {
|
||||||
public:
|
public:
|
||||||
// Any features and extensions that are requested/required in PhysicalDeviceSelector are automatically enabled.
|
// Any features and extensions that are requested/required in PhysicalDeviceSelector are automatically enabled.
|
||||||
@ -473,7 +476,10 @@ class DeviceBuilder {
|
|||||||
|
|
||||||
// Add a structure to the pNext chain of VkDeviceCreateInfo.
|
// Add a structure to the pNext chain of VkDeviceCreateInfo.
|
||||||
// The structure must be valid when DeviceBuilder::build() is called.
|
// The structure must be valid when DeviceBuilder::build() is called.
|
||||||
template <typename T> DeviceBuilder& add_pNext (T* structure);
|
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);
|
||||||
@ -500,15 +506,18 @@ struct Swapchain {
|
|||||||
VkFormat image_format = VK_FORMAT_UNDEFINED;
|
VkFormat image_format = VK_FORMAT_UNDEFINED;
|
||||||
VkExtent2D extent = { 0, 0 };
|
VkExtent2D extent = { 0, 0 };
|
||||||
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE;
|
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
// Returns a vector of VkImage handles to the swapchain
|
||||||
|
detail::Expected<std::vector<VkImage>, detail::Error<SwapchainError>> get_images ();
|
||||||
|
|
||||||
|
// Returns a vector of VkImageView's to the VkImage's of the swapchain
|
||||||
|
// VkImageViews must be destroyed
|
||||||
|
detail::Expected<std::vector<VkImageView>, detail::Error<SwapchainError>> get_image_views ();
|
||||||
|
void destroy_image_views (std::vector<VkImageView> const& image_views);
|
||||||
};
|
};
|
||||||
|
|
||||||
void destroy_swapchain (Swapchain const& swapchain);
|
void destroy_swapchain (Swapchain const& swapchain);
|
||||||
|
|
||||||
detail::Expected<std::vector<VkImage>, detail::Error<SwapchainError>> get_swapchain_images (
|
|
||||||
Swapchain const& swapchain);
|
|
||||||
detail::Expected<std::vector<VkImageView>, detail::Error<SwapchainError>>
|
|
||||||
get_swapchain_image_views (Swapchain const& swapchain, std::vector<VkImage> const& images);
|
|
||||||
|
|
||||||
class SwapchainBuilder {
|
class SwapchainBuilder {
|
||||||
public:
|
public:
|
||||||
SwapchainBuilder (Device const& device);
|
SwapchainBuilder (Device const& device);
|
||||||
|
@ -5,8 +5,7 @@
|
|||||||
// TODO
|
// TODO
|
||||||
// Getting queues
|
// Getting queues
|
||||||
// get dedicated vs distinct compute queues
|
// get dedicated vs distinct compute queues
|
||||||
// Swapchain creation
|
|
||||||
// Swapchain recreation
|
|
||||||
// changing present modes and/or image formats
|
// changing present modes and/or image formats
|
||||||
|
|
||||||
TEST_CASE ("Instance with surface") {
|
TEST_CASE ("Instance with surface") {
|
||||||
@ -55,12 +54,16 @@ TEST_CASE ("Instance with surface") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE ("basic instance") {
|
TEST_CASE ("instance configuration") {
|
||||||
|
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")
|
.set_app_name ("test app")
|
||||||
|
.set_app_version (1, 0, 0)
|
||||||
|
.set_engine_name ("engine_name")
|
||||||
|
.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,
|
||||||
@ -71,29 +74,233 @@ TEST_CASE ("basic instance") {
|
|||||||
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;
|
||||||
})
|
})
|
||||||
.require_api_version (1, 2, 111)
|
|
||||||
.build ();
|
.build ();
|
||||||
|
|
||||||
REQUIRE (instance_ret.has_value ());
|
REQUIRE (instance_ret.has_value ());
|
||||||
|
|
||||||
vkb::destroy_instance (instance_ret.value ());
|
vkb::destroy_instance (instance_ret.value ());
|
||||||
}
|
}
|
||||||
|
SECTION ("Validation configuration") {
|
||||||
TEST_CASE ("headless instance") {
|
|
||||||
vkb::InstanceBuilder builder;
|
vkb::InstanceBuilder builder;
|
||||||
|
|
||||||
auto instance_ret =
|
auto instance_ret =
|
||||||
builder.request_validation_layers ()
|
builder.request_validation_layers ()
|
||||||
.set_headless ()
|
|
||||||
.set_app_version (4, 5, 6)
|
|
||||||
.set_app_name ("headless")
|
|
||||||
.set_engine_name ("nick")
|
|
||||||
.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 (VkValidationFeatureDisableEXT::VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT)
|
.add_validation_feature_disable (
|
||||||
|
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 ());
|
||||||
vkb::destroy_instance (instance_ret.value ());
|
vkb::destroy_instance (instance_ret.value ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE ("Headless Vulkan") {
|
||||||
|
vkb::InstanceBuilder builder;
|
||||||
|
|
||||||
|
auto instance_ret = builder.request_validation_layers ().set_headless ().build ();
|
||||||
|
REQUIRE (instance_ret.has_value ());
|
||||||
|
|
||||||
|
vkb::PhysicalDeviceSelector phys_device_selector (instance_ret.value ());
|
||||||
|
auto phys_device_ret = phys_device_selector.select ();
|
||||||
|
REQUIRE (phys_device_ret.has_value ());
|
||||||
|
auto phys_device = phys_device_ret.value ();
|
||||||
|
|
||||||
|
vkb::DeviceBuilder device_builder (phys_device);
|
||||||
|
auto device_ret = device_builder.build ();
|
||||||
|
REQUIRE (device_ret.has_value ());
|
||||||
|
vkb::destroy_device (device_ret.value ());
|
||||||
|
|
||||||
|
vkb::destroy_instance (instance_ret.value ());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE ("Device Configuration") {
|
||||||
|
|
||||||
|
auto window = create_window_glfw ();
|
||||||
|
vkb::InstanceBuilder builder;
|
||||||
|
|
||||||
|
auto instance_ret = builder.request_validation_layers ().build ();
|
||||||
|
REQUIRE (instance_ret.has_value ());
|
||||||
|
auto surface = create_surface_glfw (instance_ret.value ().instance, window);
|
||||||
|
|
||||||
|
vkb::PhysicalDeviceSelector phys_device_selector (instance_ret.value ());
|
||||||
|
|
||||||
|
auto phys_device_ret = phys_device_selector.set_surface (surface).select ();
|
||||||
|
REQUIRE (phys_device_ret.has_value ());
|
||||||
|
auto phys_device = phys_device_ret.value ();
|
||||||
|
|
||||||
|
|
||||||
|
SECTION ("Custom queue setup") {
|
||||||
|
std::vector<vkb::CustomQueueDescription> queue_descriptions;
|
||||||
|
auto queue_families = phys_device.get_queue_families ();
|
||||||
|
for (uint32_t i = 0; i < (uint32_t)queue_families.size (); i++) {
|
||||||
|
if (queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
||||||
|
queue_descriptions.push_back (vkb::CustomQueueDescription (
|
||||||
|
i, queue_families[i].queueCount, std::vector<float> (queue_families[i].queueCount, 1.0f)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (phys_device.has_dedicated_compute_queue ()) {
|
||||||
|
for (uint32_t i = 0; i < (uint32_t)queue_families.size (); i++) {
|
||||||
|
if ((queue_families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) &&
|
||||||
|
(queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0 &&
|
||||||
|
(queue_families[i].queueFlags & VK_QUEUE_TRANSFER_BIT) == 0)
|
||||||
|
queue_descriptions.push_back (vkb::CustomQueueDescription (i,
|
||||||
|
queue_families[i].queueCount,
|
||||||
|
std::vector<float> (queue_families[i].queueCount, 1.0f)));
|
||||||
|
}
|
||||||
|
} else if (phys_device.has_separate_compute_queue ()) {
|
||||||
|
for (uint32_t i = 0; i < (uint32_t)queue_families.size (); i++) {
|
||||||
|
if ((queue_families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) &&
|
||||||
|
((queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0)) {
|
||||||
|
queue_descriptions.push_back (vkb::CustomQueueDescription (i,
|
||||||
|
queue_families[i].queueCount,
|
||||||
|
std::vector<float> (queue_families[i].queueCount, 1.0f)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vkb::DeviceBuilder device_builder (phys_device);
|
||||||
|
auto device_ret = device_builder.custom_queue_setup (queue_descriptions).build ();
|
||||||
|
REQUIRE (device_ret.has_value ());
|
||||||
|
vkb::destroy_device (device_ret.value ());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION ("VkPhysicalDeviceFeatures2 in pNext Chain") {
|
||||||
|
VkPhysicalDeviceFeatures2 phys_dev_feat_2{};
|
||||||
|
|
||||||
|
vkb::DeviceBuilder device_builder (phys_device);
|
||||||
|
auto device_ret = device_builder.add_pNext (&phys_dev_feat_2).build ();
|
||||||
|
REQUIRE (device_ret.has_value ());
|
||||||
|
vkb::destroy_device (device_ret.value ());
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy_surface (instance_ret.value ().instance, surface);
|
||||||
|
vkb::destroy_instance (instance_ret.value ());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE ("Swapchain") {
|
||||||
|
GIVEN ("A working instance, window, surface, and device") {
|
||||||
|
auto window = create_window_glfw ();
|
||||||
|
vkb::InstanceBuilder builder;
|
||||||
|
|
||||||
|
auto instance_ret = builder.request_validation_layers ().build ();
|
||||||
|
REQUIRE (instance_ret.has_value ());
|
||||||
|
auto surface = create_surface_glfw (instance_ret.value ().instance, window);
|
||||||
|
|
||||||
|
vkb::PhysicalDeviceSelector phys_device_selector (instance_ret.value ());
|
||||||
|
auto phys_device_ret = phys_device_selector.set_surface (surface).select ();
|
||||||
|
REQUIRE (phys_device_ret.has_value ());
|
||||||
|
auto phys_device = phys_device_ret.value ();
|
||||||
|
|
||||||
|
vkb::DeviceBuilder device_builder (phys_device);
|
||||||
|
auto device_ret = device_builder.build ();
|
||||||
|
REQUIRE (device_ret.has_value ());
|
||||||
|
vkb::Device device = device_ret.value ();
|
||||||
|
|
||||||
|
THEN ("Swapchain can be made") {
|
||||||
|
vkb::SwapchainBuilder swapchain_builder (device);
|
||||||
|
auto swapchain_ret = swapchain_builder.build ();
|
||||||
|
REQUIRE (swapchain_ret.has_value ());
|
||||||
|
auto swapchain = swapchain_ret.value ();
|
||||||
|
|
||||||
|
THEN ("Acquire swapchain images and views") {
|
||||||
|
auto images = swapchain.get_images ();
|
||||||
|
REQUIRE (images.has_value ());
|
||||||
|
REQUIRE (images.value ().size () > 0);
|
||||||
|
|
||||||
|
auto image_views = swapchain.get_image_views ();
|
||||||
|
REQUIRE (image_views.has_value ());
|
||||||
|
REQUIRE (image_views.value ().size () > 0);
|
||||||
|
swapchain.destroy_image_views (image_views.value ());
|
||||||
|
}
|
||||||
|
|
||||||
|
vkb::destroy_swapchain (swapchain_ret.value ());
|
||||||
|
}
|
||||||
|
|
||||||
|
AND_THEN ("Swapchain configuration") {
|
||||||
|
vkb::SwapchainBuilder swapchain_builder (device);
|
||||||
|
auto swapchain_ret =
|
||||||
|
swapchain_builder.set_desired_extent (256, 256)
|
||||||
|
.set_desired_format ({ VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR })
|
||||||
|
.set_desired_present_mode (VK_PRESENT_MODE_IMMEDIATE_KHR)
|
||||||
|
.build ();
|
||||||
|
REQUIRE (swapchain_ret.has_value ());
|
||||||
|
|
||||||
|
vkb::destroy_swapchain (swapchain_ret.value ());
|
||||||
|
}
|
||||||
|
AND_THEN ("Swapchain defaults can be used") {
|
||||||
|
vkb::SwapchainBuilder swapchain_builder (device);
|
||||||
|
auto swapchain_ret = swapchain_builder.use_default_format_selection ()
|
||||||
|
.use_default_present_mode_selection ()
|
||||||
|
.build ();
|
||||||
|
REQUIRE (swapchain_ret.has_value ());
|
||||||
|
|
||||||
|
vkb::destroy_swapchain (swapchain_ret.value ());
|
||||||
|
}
|
||||||
|
AND_THEN ("Swapchain can be recreated") {
|
||||||
|
vkb::SwapchainBuilder swapchain_builder (device);
|
||||||
|
auto swapchain_ret = swapchain_builder.build ();
|
||||||
|
REQUIRE (swapchain_ret.has_value ());
|
||||||
|
|
||||||
|
auto swapchain = swapchain_ret.value ();
|
||||||
|
auto recreated_swapchain_ret = swapchain_builder.recreate (swapchain);
|
||||||
|
REQUIRE (recreated_swapchain_ret.has_value ());
|
||||||
|
|
||||||
|
vkb::destroy_swapchain (recreated_swapchain_ret.value ());
|
||||||
|
}
|
||||||
|
|
||||||
|
vkb::destroy_device (device_ret.value ());
|
||||||
|
destroy_surface (instance_ret.value ().instance, surface);
|
||||||
|
vkb::destroy_instance (instance_ret.value ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* VKAPI_PTR shim_vkAllocationFunction (
|
||||||
|
void* /*pUserData*/, size_t size, size_t /*alignment*/, VkSystemAllocationScope /*allocationScope*/) {
|
||||||
|
return malloc (size);
|
||||||
|
}
|
||||||
|
void* VKAPI_PTR shim_vkReallocationFunction (
|
||||||
|
void* /*pUserData*/, void* pOriginal, size_t size, size_t /*alignment*/, VkSystemAllocationScope /*allocationScope*/) {
|
||||||
|
return realloc (pOriginal, size);
|
||||||
|
}
|
||||||
|
void VKAPI_PTR shim_vkFreeFunction (void* /*pUserData*/, void* pMemory) { return free (pMemory); }
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE ("Allocation Callbacks") {
|
||||||
|
VkAllocationCallbacks allocation_callbacks{};
|
||||||
|
allocation_callbacks.pfnAllocation = &shim_vkAllocationFunction;
|
||||||
|
allocation_callbacks.pfnReallocation = &shim_vkReallocationFunction;
|
||||||
|
allocation_callbacks.pfnFree = &shim_vkFreeFunction;
|
||||||
|
|
||||||
|
auto window = create_window_glfw ();
|
||||||
|
vkb::InstanceBuilder builder;
|
||||||
|
|
||||||
|
auto instance_ret =
|
||||||
|
builder.request_validation_layers ().set_allocation_callbacks (&allocation_callbacks).build ();
|
||||||
|
REQUIRE (instance_ret.has_value ());
|
||||||
|
auto surface = create_surface_glfw (instance_ret.value ().instance, window);
|
||||||
|
|
||||||
|
vkb::PhysicalDeviceSelector phys_device_selector (instance_ret.value ());
|
||||||
|
|
||||||
|
auto phys_device_ret = phys_device_selector.set_surface (surface).select ();
|
||||||
|
REQUIRE (phys_device_ret.has_value ());
|
||||||
|
auto phys_device = phys_device_ret.value ();
|
||||||
|
|
||||||
|
vkb::DeviceBuilder device_builder (phys_device);
|
||||||
|
auto device_ret = device_builder.set_allocation_callbacks (&allocation_callbacks).build ();
|
||||||
|
REQUIRE (device_ret.has_value ());
|
||||||
|
vkb::Device device = device_ret.value ();
|
||||||
|
|
||||||
|
vkb::SwapchainBuilder swapchain_builder (device);
|
||||||
|
auto swapchain_ret = swapchain_builder.set_allocation_callbacks (&allocation_callbacks).build ();
|
||||||
|
REQUIRE (swapchain_ret.has_value ());
|
||||||
|
auto swapchain = swapchain_ret.value ();
|
||||||
|
|
||||||
|
vkb::destroy_swapchain (swapchain_ret.value ());
|
||||||
|
vkb::destroy_device (device_ret.value ());
|
||||||
|
|
||||||
|
destroy_surface (instance_ret.value ().instance, surface);
|
||||||
|
vkb::destroy_instance (instance_ret.value ());
|
||||||
}
|
}
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#include <catch2/catch.hpp>
|
|
||||||
|
|
||||||
#define CATCH_CONFIG_MAIN
|
|
Loading…
Reference in New Issue
Block a user