From 96688de17013dffa2c612d5da2de4dc4c96fa7d5 Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Thu, 20 Jun 2024 13:32:16 -0500 Subject: [PATCH] Add vulkan-hpp tests Since the API can accept vulkan-hpp types in a few places, it is good to have tests for those places. While the current test suite isn't exhaustive, it is enough to get the ball rolling. This PR also refactors some of the 'setup' logic for the tests into a separate file so that the hpp tests can make use of them. --- tests/CMakeLists.txt | 5 +- tests/bootstrap_tests.cpp | 63 +-------------------- tests/vulkan_hpp_tests.cpp | 109 ++++++++++++++++++++++++++++++++++++ tests/vulkan_mock.hpp | 2 + tests/vulkan_mock_setup.cpp | 60 ++++++++++++++++++++ tests/vulkan_mock_setup.hpp | 18 ++++++ 6 files changed, 194 insertions(+), 63 deletions(-) create mode 100644 tests/vulkan_hpp_tests.cpp create mode 100644 tests/vulkan_mock_setup.cpp create mode 100644 tests/vulkan_mock_setup.hpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7e0abe9..3f734c4 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -7,7 +7,7 @@ else() endif() target_link_libraries(VulkanMock PUBLIC - Vulkan::Headers vk-bootstrap + Vulkan::Headers vk-bootstrap Catch2::Catch2 PRIVATE vk-bootstrap-compiler-warnings ) @@ -23,10 +23,13 @@ endif() add_executable(vk-bootstrap-test vulkan_library_loader.hpp + vulkan_mock_setup.hpp + vulkan_mock_setup.cpp bootstrap_tests.cpp error_code_tests.cpp unit_tests.cpp include_checks.cpp + vulkan_hpp_tests.cpp ) target_link_libraries(vk-bootstrap-test diff --git a/tests/bootstrap_tests.cpp b/tests/bootstrap_tests.cpp index 39f2305..4c2b2fd 100644 --- a/tests/bootstrap_tests.cpp +++ b/tests/bootstrap_tests.cpp @@ -1,68 +1,7 @@ #include "vulkan_library_loader.hpp" #include "vulkan_mock.hpp" - -#include - -#include - -vkb::Instance get_instance(uint32_t minor_version = 0) { - auto instance_ret = vkb::InstanceBuilder().request_validation_layers().require_api_version(1, minor_version).build(); - REQUIRE(instance_ret.has_value()); - return instance_ret.value(); -} -vkb::Instance get_headless_instance(uint32_t minor_version = 0) { - auto instance_ret = - vkb::InstanceBuilder().request_validation_layers().require_api_version(1, minor_version).set_headless().build(); - REQUIRE(instance_ret.has_value()); - return instance_ret.value(); -} - -VkExtensionProperties get_extension_properties(const char* extName) { - VkExtensionProperties ext_props{}; - std::copy_n(extName, VK_MAX_EXTENSION_NAME_SIZE, ext_props.extensionName); - return ext_props; -} - -VulkanMock& get_and_setup_default() { - VulkanMock& mock = *get_vulkan_mock(); - mock.instance_extensions.push_back(get_extension_properties(VK_KHR_SURFACE_EXTENSION_NAME)); -#if defined(_WIN32) - mock.instance_extensions.push_back(get_extension_properties("VK_KHR_win32_surface")); -#elif defined(__ANDROID__) - mock.instance_extensions.push_back(get_extension_properties("VK_KHR_android_surface")); -#elif defined(_DIRECT2DISPLAY) - mock.instance_extensions.push_back(get_extension_properties("VK_KHR_android_surface")); -#elif defined(__linux__) - mock.instance_extensions.push_back(get_extension_properties("VK_KHR_xcb_surface")); - mock.instance_extensions.push_back(get_extension_properties("VK_KHR_xlib_surface")); - mock.instance_extensions.push_back(get_extension_properties("VK_KHR_wayland_surface")); -#elif defined(__APPLE__) - mock.instance_extensions.push_back(get_extension_properties("VK_EXT_metal_surface")); -#endif - mock.instance_extensions.push_back(get_extension_properties(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)); - VulkanMock::PhysicalDeviceDetails physical_device_details{}; - physical_device_details.extensions.push_back(get_extension_properties(VK_KHR_SWAPCHAIN_EXTENSION_NAME)); - physical_device_details.properties.apiVersion = VK_API_VERSION_1_0; - VkQueueFamilyProperties queue_family_properties{}; - queue_family_properties.queueCount = 1; - queue_family_properties.queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT; - queue_family_properties.minImageTransferGranularity = { 1, 1, 1 }; - physical_device_details.queue_family_properties.push_back(queue_family_properties); - mock.add_physical_device(std::move(physical_device_details)); - return mock; -} - -VulkanMock::SurfaceDetails get_basic_surface_details() { - VulkanMock::SurfaceDetails details; - details.present_modes.push_back(VK_PRESENT_MODE_FIFO_KHR); - details.surface_formats.push_back(VkSurfaceFormatKHR{ VK_FORMAT_R8G8B8_SRGB, VK_COLORSPACE_SRGB_NONLINEAR_KHR }); - details.capabilities.minImageCount = 2; - details.capabilities.minImageExtent = { 600, 800 }; - details.capabilities.currentExtent = { 600, 800 }; - details.capabilities.supportedUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - return details; -} +#include "vulkan_mock_setup.hpp" // TODO // changing present modes and/or image formats diff --git a/tests/vulkan_hpp_tests.cpp b/tests/vulkan_hpp_tests.cpp new file mode 100644 index 0000000..738f316 --- /dev/null +++ b/tests/vulkan_hpp_tests.cpp @@ -0,0 +1,109 @@ +#include "vulkan_library_loader.hpp" + +#include "vulkan_mock.hpp" +#include "vulkan_mock_setup.hpp" + +#include + + +TEST_CASE("VulkanHpp Instance with surface", "[VkBootstrap.vulkan_hpp]") { + VulkanMock& mock = get_and_setup_default(); + mock.api_version = VK_API_VERSION_1_1; + mock.physical_devices_details[0].properties.apiVersion = VK_API_VERSION_1_1; + mock.physical_devices_details[0].extensions.push_back(get_extension_properties("VK_KHR_multiview")); + mock.physical_devices_details[0].extensions.push_back(get_extension_properties("VK_KHR_driver_properties")); + mock.physical_devices_details[0].extensions.push_back(get_extension_properties("VK_EXT_robustness2")); + mock.physical_devices_details[0].extensions.push_back(get_extension_properties("VK_EXT_descriptor_indexing")); + VkPhysicalDeviceDescriptorIndexingFeatures physical_device_descriptor_indexing_features{}; + physical_device_descriptor_indexing_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES; + physical_device_descriptor_indexing_features.runtimeDescriptorArray = true; + physical_device_descriptor_indexing_features.descriptorBindingPartiallyBound = true; + mock.physical_devices_details[0].add_features_pNext_struct(physical_device_descriptor_indexing_features); + mock.physical_devices_details[0].extensions.push_back(get_extension_properties("VK_EXT_subgroup_size_control")); + VkPhysicalDeviceSubgroupSizeControlFeatures physical_device_subgroup_size_control_features{}; + physical_device_subgroup_size_control_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES; + physical_device_subgroup_size_control_features.subgroupSizeControl = true; + physical_device_subgroup_size_control_features.computeFullSubgroups = true; + mock.physical_devices_details[0].add_features_pNext_struct(physical_device_subgroup_size_control_features); + + auto surface = mock.get_new_surface(get_basic_surface_details()); + vk::SurfaceKHR hpp_surface{ surface }; + GIVEN("A window and a vulkan instance") { + + auto sys_info_ret = vkb::SystemInfo::get_system_info(); + REQUIRE(sys_info_ret); + + vkb::InstanceBuilder instance_builder; + auto instance_ret = instance_builder.require_api_version(1, 1, 0) + .set_minimum_instance_version(1, 0, 0) + .use_default_debug_messenger() + .build(); + REQUIRE(instance_ret); + vkb::Instance instance = instance_ret.value(); + vk::Instance hpp_instance{ instance }; + + GIVEN("A default selected physical device") { + vkb::PhysicalDeviceSelector phys_device_selector(instance); +#if VK_USE_64_BIT_PTR_DEFINES == 1 + auto phys_device_ret = phys_device_selector.set_surface(hpp_surface).select(); +#else + auto phys_device_ret = phys_device_selector.set_surface(static_cast(hpp_surface)).select(); +#endif + REQUIRE(phys_device_ret); + vkb::PhysicalDevice physical_device = phys_device_ret.value(); + + GIVEN("A device created with default parameters") { + vkb::DeviceBuilder device_builder(physical_device); + auto device_ret = device_builder.build(); + REQUIRE(device_ret); + vkb::Device device = device_ret.value(); + + // possible swapchain creation... + + vkb::destroy_device(device); + } + } + + THEN("Can select physical device with customized requirements") { + vkb::PhysicalDeviceSelector selector(instance); + auto phys_dev_ret = +#if VK_USE_64_BIT_PTR_DEFINES == 1 + selector + .set_surface(hpp_surface) +#else + selector + .set_surface(static_cast(hpp_surface)) +#endif + .add_required_extension_features( + vk::PhysicalDeviceSubgroupSizeControlFeatures{}.setSubgroupSizeControl(true).setComputeFullSubgroups(true)) + .set_minimum_version(1, 0) + .select(); + + REQUIRE(phys_dev_ret.has_value()); + + REQUIRE(phys_dev_ret->is_extension_present(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)); + + const std::vector extension_set_1 = { VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME }; + + REQUIRE(phys_dev_ret->enable_extensions_if_present(extension_set_1)); + + vk::PhysicalDeviceDescriptorIndexingFeatures physical_device_descriptor_indexing_features_hpp; + physical_device_descriptor_indexing_features_hpp.setRuntimeDescriptorArray(vk::True); + physical_device_descriptor_indexing_features_hpp.setDescriptorBindingPartiallyBound(vk::True); + + phys_dev_ret->enable_extension_features_if_present(physical_device_descriptor_indexing_features_hpp); + + auto device_ret = vkb::DeviceBuilder(phys_dev_ret.value()).build(); + REQUIRE(device_ret.has_value()); + vk::Device hpp_device{ device_ret.value().device }; + vkb::destroy_device(device_ret.value()); + } +#if VK_USE_64_BIT_PTR_DEFINES == 1 + vkb::destroy_surface(hpp_instance, hpp_surface); +#else + vkb::destroy_surface(hpp_instance, static_cast(hpp_surface)); +#endif + + vkb::destroy_instance(instance); + } +} diff --git a/tests/vulkan_mock.hpp b/tests/vulkan_mock.hpp index 05eb909..53590fd 100644 --- a/tests/vulkan_mock.hpp +++ b/tests/vulkan_mock.hpp @@ -22,6 +22,8 @@ inline size_t check_if_features2_struct(VkStructureType type) { return sizeof(VkPhysicalDeviceVulkan11Features); case (VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES): return sizeof(VkPhysicalDeviceVulkan12Features); + case (VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES): + return sizeof(VkPhysicalDeviceSubgroupSizeControlFeatures); default: return 0; } diff --git a/tests/vulkan_mock_setup.cpp b/tests/vulkan_mock_setup.cpp new file mode 100644 index 0000000..d39369a --- /dev/null +++ b/tests/vulkan_mock_setup.cpp @@ -0,0 +1,60 @@ + +#include "vulkan_mock_setup.hpp" + +vkb::Instance get_instance(uint32_t minor_version) { + auto instance_ret = vkb::InstanceBuilder().request_validation_layers().require_api_version(1, minor_version).build(); + REQUIRE(instance_ret.has_value()); + return instance_ret.value(); +} +vkb::Instance get_headless_instance(uint32_t minor_version) { + auto instance_ret = + vkb::InstanceBuilder().request_validation_layers().require_api_version(1, minor_version).set_headless().build(); + REQUIRE(instance_ret.has_value()); + return instance_ret.value(); +} + +VkExtensionProperties get_extension_properties(const char* extName) { + VkExtensionProperties ext_props{}; + std::copy_n(extName, VK_MAX_EXTENSION_NAME_SIZE, ext_props.extensionName); + return ext_props; +} + +VulkanMock& get_and_setup_default() { + VulkanMock& mock = *get_vulkan_mock(); + mock.instance_extensions.push_back(get_extension_properties(VK_KHR_SURFACE_EXTENSION_NAME)); +#if defined(_WIN32) + mock.instance_extensions.push_back(get_extension_properties("VK_KHR_win32_surface")); +#elif defined(__ANDROID__) + mock.instance_extensions.push_back(get_extension_properties("VK_KHR_android_surface")); +#elif defined(_DIRECT2DISPLAY) + mock.instance_extensions.push_back(get_extension_properties("VK_KHR_android_surface")); +#elif defined(__linux__) + mock.instance_extensions.push_back(get_extension_properties("VK_KHR_xcb_surface")); + mock.instance_extensions.push_back(get_extension_properties("VK_KHR_xlib_surface")); + mock.instance_extensions.push_back(get_extension_properties("VK_KHR_wayland_surface")); +#elif defined(__APPLE__) + mock.instance_extensions.push_back(get_extension_properties("VK_EXT_metal_surface")); +#endif + mock.instance_extensions.push_back(get_extension_properties(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)); + VulkanMock::PhysicalDeviceDetails physical_device_details{}; + physical_device_details.extensions.push_back(get_extension_properties(VK_KHR_SWAPCHAIN_EXTENSION_NAME)); + physical_device_details.properties.apiVersion = VK_API_VERSION_1_0; + VkQueueFamilyProperties queue_family_properties{}; + queue_family_properties.queueCount = 1; + queue_family_properties.queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT; + queue_family_properties.minImageTransferGranularity = { 1, 1, 1 }; + physical_device_details.queue_family_properties.push_back(queue_family_properties); + mock.add_physical_device(std::move(physical_device_details)); + return mock; +} + +VulkanMock::SurfaceDetails get_basic_surface_details() { + VulkanMock::SurfaceDetails details; + details.present_modes.push_back(VK_PRESENT_MODE_FIFO_KHR); + details.surface_formats.push_back(VkSurfaceFormatKHR{ VK_FORMAT_R8G8B8_SRGB, VK_COLORSPACE_SRGB_NONLINEAR_KHR }); + details.capabilities.minImageCount = 2; + details.capabilities.minImageExtent = { 600, 800 }; + details.capabilities.currentExtent = { 600, 800 }; + details.capabilities.supportedUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + return details; +} diff --git a/tests/vulkan_mock_setup.hpp b/tests/vulkan_mock_setup.hpp new file mode 100644 index 0000000..cc99e69 --- /dev/null +++ b/tests/vulkan_mock_setup.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +#include "vulkan_mock.hpp" + +#include + + +vkb::Instance get_instance(uint32_t minor_version = 0); + +vkb::Instance get_headless_instance(uint32_t minor_version = 0); + +VkExtensionProperties get_extension_properties(const char* extName); + +VulkanMock& get_and_setup_default(); + +VulkanMock::SurfaceDetails get_basic_surface_details();