Merge pull request #23 from LesleyLai/tests

Migrate to Catch2 & CMake file structural change
This commit is contained in:
Charles Giessen 2020-03-26 11:21:28 -06:00 committed by GitHub
commit e906cfc093
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 141 additions and 196 deletions

4
.gitignore vendored
View File

@ -1,2 +1,4 @@
*.vscode
*.vs
*.vs
*.idea
cmake-build-*

View File

@ -6,15 +6,9 @@ find_package(Vulkan REQUIRED)
add_library(vk-bootstrap src/VkBootstrap.h src/VkBootstrap.cpp)
add_library(vk-bootstrap::vk-bootstrap ALIAS vk-bootstrap)
target_include_directories(vk-bootstrap PUBLIC src)
target_include_directories(vk-bootstrap PRIVATE ${Vulkan_INCLUDE_DIR})
target_link_libraries(vk-bootstrap PRIVATE ${Vulkan_LIBRARY})
target_compile_features(vk-bootstrap PUBLIC cxx_std_11)
target_compile_options(
vk-bootstrap
PRIVATE
add_library(vk-bootstrap-compiler-warnings INTERFACE)
target_compile_options(vk-bootstrap-compiler-warnings
INTERFACE
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:
-Wall
-Wextra
@ -23,40 +17,20 @@ target_compile_options(
-Wsign-conversion>
$<$<CXX_COMPILER_ID:MSVC>:
/WX
/W4>)
/W4>
)
target_include_directories(vk-bootstrap PUBLIC src)
target_include_directories(vk-bootstrap PUBLIC ${Vulkan_INCLUDE_DIR})
target_link_libraries(vk-bootstrap
PUBLIC ${Vulkan_LIBRARY}
PRIVATE
vk-bootstrap-compiler-warnings)
option(VK_BOOTSTRAP_TEST "Test Vk-Bootstrap with glfw and Catch2" OFF)
if (VK_BOOTSTRAP_TEST)
set(GLFW_BUILD_TESTS
OFF
CACHE BOOL "" FORCE)
set(GLFW_BUILD_DOCS
OFF
CACHE BOOL "" FORCE)
set(GLFW_INSTALL
OFF
CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES
OFF
CACHE BOOL "" FORCE)
add_subdirectory(ext/glfw)
add_subdirectory(ext/Catch2)
add_executable(vk-bootstrap-test tests/run_tests.cpp)
target_link_libraries(vk-bootstrap-test vk-bootstrap)
target_link_libraries(vk-bootstrap-test glfw)
target_link_libraries(vk-bootstrap-test Catch2)
add_executable(vk-bootstrap-triangle example/triangle.cpp)
target_link_libraries(vk-bootstrap-triangle vk-bootstrap)
target_link_libraries(vk-bootstrap-triangle glfw)
add_custom_command(
TARGET vk-bootstrap-triangle
POST_BUILD
COMMAND
${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/example/shaders ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR})
if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR VK_BOOTSTRAP_TEST)
add_subdirectory(ext)
add_subdirectory(tests)
add_subdirectory(example)
endif ()

View File

@ -110,10 +110,11 @@ In the project directory, run the following to get the required dependencies to
git submodule update --init
```
In the build directory, enable tests by adding `-DVK_BOOTSTRAP_TEST` to the cmake command line arguments
Tests will be enabled by default if you open this project standalone. If you include this project as a subdirectory,
you can force enable tests by adding `-DVK_BOOTSTRAP_TEST` to the cmake command line arguments
```bash
cmake ../path/to/vk-bootstrap/ -DVK_BOOTSTRAP_TEST=ON
cmake ../path/to/your-project/ -DVK_BOOTSTRAP_TEST=ON
```
## Todo's

14
example/CMakeLists.txt Normal file
View File

@ -0,0 +1,14 @@
add_executable(vk-bootstrap-triangle triangle.cpp)
target_link_libraries(vk-bootstrap-triangle
PRIVATE
glfw
vk-bootstrap
vk-bootstrap-compiler-warnings)
add_custom_command(
TARGET vk-bootstrap-triangle
POST_BUILD
COMMAND
${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/example/shaders ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR})

View File

@ -133,7 +133,7 @@ int create_render_pass (Init& init, RenderData& data) {
render_pass_info.pDependencies = &dependency;
if (vkCreateRenderPass (init.device.device, &render_pass_info, nullptr, &data.render_pass) != VK_SUCCESS) {
std::cout << "failed to create render pass\n";
std::cout << "failed to create render pass\n";
return -1; // failed to create render pass!
}
return 0;
@ -150,7 +150,7 @@ std::vector<char> readFile (const std::string& filename) {
std::vector<char> buffer (file_size);
file.seekg (0);
file.read (buffer.data (), file_size);
file.read (buffer.data (), static_cast<std::streamsize> (file_size));
file.close ();
@ -178,7 +178,7 @@ int create_graphics_pipeline (Init& init, RenderData& data) {
VkShaderModule vert_module = createShaderModule (init, vert_code);
VkShaderModule frag_module = createShaderModule (init, frag_code);
if (vert_module == VK_NULL_HANDLE || frag_module == VK_NULL_HANDLE) {
std::cout << "failed to create shader module\n";
std::cout << "failed to create shader module\n";
return -1; // failed to create shader modules
}
@ -263,7 +263,7 @@ int create_graphics_pipeline (Init& init, RenderData& data) {
if (vkCreatePipelineLayout (
init.device.device, &pipeline_layout_info, nullptr, &data.pipeline_layout) != VK_SUCCESS) {
std::cout << "failed to create pipeline layout\n";
std::cout << "failed to create pipeline layout\n";
return -1; // failed to create pipeline layout
}
@ -284,7 +284,7 @@ int create_graphics_pipeline (Init& init, RenderData& data) {
if (vkCreateGraphicsPipelines (
init.device.device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &data.graphics_pipeline) != VK_SUCCESS) {
std::cout << "failed to create pipline\n";
std::cout << "failed to create pipline\n";
return -1; // failed to create graphics pipeline
}
@ -326,7 +326,7 @@ int create_command_pool (Init& init, RenderData& data) {
pool_info.queueFamilyIndex = init.device.get_queue_index (vkb::QueueType::graphics).value ();
if (vkCreateCommandPool (init.device.device, &pool_info, nullptr, &data.command_pool) != VK_SUCCESS) {
std::cout << "failed to create command pool\n";
std::cout << "failed to create command pool\n";
return -1; // failed to create command pool
}
return 0;
@ -373,7 +373,7 @@ int create_command_buffers (Init& init, RenderData& data) {
vkCmdEndRenderPass (data.command_buffers[i]);
if (vkEndCommandBuffer (data.command_buffers[i]) != VK_SUCCESS) {
std::cout << "failed to record command buffer\n";
std::cout << "failed to record command buffer\n";
return -1; // failed to record command buffer!
}
}
@ -397,7 +397,7 @@ int create_sync_objects (Init& init, RenderData& data) {
if (vkCreateSemaphore (init.device.device, &semaphore_info, nullptr, &data.available_semaphores[i]) != VK_SUCCESS ||
vkCreateSemaphore (init.device.device, &semaphore_info, nullptr, &data.finished_semaphore[i]) != VK_SUCCESS ||
vkCreateFence (init.device.device, &fence_info, nullptr, &data.in_flight_fences[i]) != VK_SUCCESS) {
std::cout << "failed to create sync objects\n";
std::cout << "failed to create sync objects\n";
return -1; // failed to create synchronization objects for a frame
}
}
@ -439,8 +439,8 @@ int draw_frame (Init& init, RenderData& data) {
vkResetFences (init.device.device, 1, &data.in_flight_fences[data.current_frame]);
if (vkQueueSubmit (data.graphics_queue, 1, &submitInfo, data.in_flight_fences[data.current_frame]) != VK_SUCCESS) {
std::cout << "failed to submit draw command buffer\n";
return -1; //"failed to submit draw command buffer
std::cout << "failed to submit draw command buffer\n";
return -1; //"failed to submit draw command buffer
}
VkPresentInfoKHR present_info = {};
@ -493,14 +493,14 @@ int main () {
Init init;
RenderData render_data;
if(0 != device_initialization (init)) return -1;
if(0 != get_queues (init, render_data)) return -1;
if(0 != create_render_pass (init, render_data)) return -1;
if(0 != create_graphics_pipeline (init, render_data)) return -1;
if(0 != create_framebuffers (init, render_data)) return -1;
if(0 != create_command_pool (init, render_data)) return -1;
if(0 != create_command_buffers (init, render_data)) return -1;
if(0 != create_sync_objects (init, render_data)) return -1;
if (0 != device_initialization (init)) return -1;
if (0 != get_queues (init, render_data)) return -1;
if (0 != create_render_pass (init, render_data)) return -1;
if (0 != create_graphics_pipeline (init, render_data)) return -1;
if (0 != create_framebuffers (init, render_data)) return -1;
if (0 != create_command_pool (init, render_data)) return -1;
if (0 != create_command_buffers (init, render_data)) return -1;
if (0 != create_sync_objects (init, render_data)) return -1;
while (!glfwWindowShouldClose (init.window)) {
glfwPollEvents ();

14
ext/CMakeLists.txt Normal file
View File

@ -0,0 +1,14 @@
set(GLFW_BUILD_TESTS
OFF
CACHE BOOL "" FORCE)
set(GLFW_BUILD_DOCS
OFF
CACHE BOOL "" FORCE)
set(GLFW_INSTALL
OFF
CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES
OFF
CACHE BOOL "" FORCE)
add_subdirectory(glfw)
add_subdirectory(Catch2)

View File

@ -98,8 +98,8 @@ template <typename E, typename U> class Expected {
} // namespace detail
enum class InstanceError {
vulkan_unavailable,
vulkan_version_unavailable,
vulkan_unavailable,
vulkan_version_unavailable,
vulkan_version_1_1_unavailable,
vulkan_version_1_2_unavailable,
failed_create_instance,
@ -189,7 +189,7 @@ class InstanceBuilder {
InstanceBuilder& set_engine_version (uint32_t major, uint32_t minor, uint32_t patch);
// Require a vulkan instance API version. Will fail to create if this version isn't available.
InstanceBuilder& require_api_version (uint32_t major, uint32_t minor, uint32_t patch);
// 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.
InstanceBuilder& desire_api_version (uint32_t major, uint32_t minor, uint32_t patch);
// Adds a layer to be enabled. Will fail to create an instance if the layer isn't available.
@ -284,7 +284,7 @@ void destroy_debug_utils_messenger (VkInstance instance,
VkDebugUtilsMessengerEXT debugMessenger,
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE);
static VKAPI_ATTR VkBool32 VKAPI_CALL default_debug_callback (VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VKAPI_ATTR VkBool32 VKAPI_CALL default_debug_callback (VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData);

8
tests/CMakeLists.txt Normal file
View File

@ -0,0 +1,8 @@
add_executable(vk-bootstrap-test main.cpp run_tests.cpp)
target_link_libraries(vk-bootstrap-test
PRIVATE
vk-bootstrap
vk-bootstrap-compiler-warnings
glfw
Catch2
)

2
tests/main.cpp Normal file
View File

@ -0,0 +1,2 @@
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>

View File

@ -1,46 +1,61 @@
#include "common.h"
int test_happy_path () {
printf ("happy path\n");
#include <catch2/catch.hpp>
auto window = create_window_glfw ();
// TODO
// Getting queues
// get dedicated vs distinct compute queues
// Swapchain creation
// Swapchain recreation
// changing present modes and/or image formats
vkb::InstanceBuilder instance_builder;
auto instance_ret = instance_builder.use_default_debug_messenger ().build ();
if (!instance_ret) {
std::cout << static_cast<uint32_t> (instance_ret.error ().type) << "\n";
return -1; // couldn't make instance
TEST_CASE ("Instance with surface") {
GIVEN ("A window and a vulkan instance") {
auto window = create_window_glfw ();
vkb::InstanceBuilder instance_builder;
auto instance_ret = instance_builder.use_default_debug_messenger ().build ();
REQUIRE (instance_ret);
vkb::Instance instance = instance_ret.value ();
auto surface = create_surface_glfw (instance.instance, window);
GIVEN ("A default selected physical device") {
vkb::PhysicalDeviceSelector phys_device_selector (instance);
auto phys_device_ret = phys_device_selector.set_surface (surface).select ();
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 = selector.set_surface (surface)
.add_desired_extension (VK_KHR_MULTIVIEW_EXTENSION_NAME)
.add_required_extension (VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)
.set_minimum_version (1, 0)
.set_desired_version (1, 1)
.select ();
REQUIRE (phys_dev_ret.has_value ());
}
destroy_surface (instance.instance, surface);
vkb::destroy_instance (instance);
destroy_window_glfw (window);
}
vkb::Instance instance = instance_ret.value ();
printf ("made instance\n");
auto surface = create_surface_glfw (instance.instance, window);
vkb::PhysicalDeviceSelector phys_device_selector (instance);
auto phys_device_ret = phys_device_selector.set_surface (surface).select ();
if (!phys_device_ret) return -2; // couldn't select physical device
vkb::PhysicalDevice physical_device = phys_device_ret.value ();
printf ("made physical device\n");
vkb::DeviceBuilder device_builder (physical_device);
auto device_ret = device_builder.build ();
if (!device_ret) return -1; // couldn't create device
vkb::Device device = device_ret.value ();
printf ("made device\n");
// possible swapchain creation...
vkb::destroy_device (device);
destroy_surface (instance.instance, surface);
vkb::destroy_instance (instance);
destroy_window_glfw (window);
return 0;
}
int test_instance_basic () {
printf ("\nbasic instance\n");
TEST_CASE ("basic instance") {
vkb::InstanceBuilder builder;
auto instance_ret =
@ -49,7 +64,8 @@ int test_instance_basic () {
.set_debug_callback ([] (VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData) -> VkBool32 {
void *
/*pUserData*/) -> VkBool32 {
auto ms = vkb::to_string_message_severity (messageSeverity);
auto mt = vkb::to_string_message_type (messageType);
printf ("[%s: %s](user defined)\n%s\n", ms, mt, pCallbackData->pMessage);
@ -57,17 +73,13 @@ int test_instance_basic () {
})
.require_api_version (1, 2, 111)
.build ();
if (!instance_ret.has_value ()) {
return 1;
}
vkb::destroy_instance (instance_ret.value ());
return 0;
REQUIRE (instance_ret.has_value ());
vkb::destroy_instance (instance_ret.value ());
}
int test_instance_headless () {
printf ("\nheadless instance\n");
TEST_CASE ("headless instance") {
vkb::InstanceBuilder builder;
auto instance_ret =
@ -82,88 +94,6 @@ int test_instance_headless () {
.add_validation_feature_disable (VkValidationFeatureDisableEXT::VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT)
.add_validation_disable (VkValidationCheckEXT::VK_VALIDATION_CHECK_SHADERS_EXT)
.build ();
if (!instance_ret.has_value ()) {
return 1;
}
REQUIRE (instance_ret.has_value ());
vkb::destroy_instance (instance_ret.value ());
return 0;
}
int test_physical_device_selection () {
printf ("\nphysical device selection\n");
vkb::InstanceBuilder instance_builder;
auto instance_ret = instance_builder.use_default_debug_messenger ().build ();
if(!instance_ret.has_value()){
printf("\n%s",vkb::to_string(instance_ret.error().type));
return -1;
}
auto instance = instance_ret.value ();
auto window = create_window_glfw ();
auto surface = create_surface_glfw (instance.instance, window);
vkb::PhysicalDeviceSelector selector (instance);
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)
.set_minimum_version (1, 0)
.set_desired_version (1, 1)
.select ();
if (!phys_dev_ret.has_value ()) {
return -1;
}
destroy_surface (instance.instance, surface);
vkb::destroy_instance (instance);
destroy_window_glfw (window);
return 0;
}
int test_device_creation () {
printf ("\ndevice creation\n");
vkb::InstanceBuilder instance_builder;
auto instance_ret = instance_builder.use_default_debug_messenger ().build ();
if (!instance_ret.has_value ()) {
printf ("couldn't create instance %s\n", vkb::to_string (instance_ret.error ().type));
return -1;
}
auto instance = instance_ret.value ();
auto window = create_window_glfw ();
auto surface = create_surface_glfw (instance.instance, window);
vkb::PhysicalDeviceSelector selector (instance);
auto phys_dev_ret = selector.set_surface (surface).select ();
if (!phys_dev_ret.has_value ()) {
printf ("couldn't select device %s\n", vkb::to_string (phys_dev_ret.error ().type));
return -1;
}
auto phys_dev = phys_dev_ret.value ();
vkb::DeviceBuilder device_builder (phys_dev);
auto dev_ret = device_builder.build ();
if (!dev_ret.has_value ()) {
printf ("couldn't create device %s\n", vkb::to_string (dev_ret.error ().type));
return -1;
}
vkb::destroy_device (dev_ret.value ());
destroy_surface (instance.instance, surface);
vkb::destroy_instance (instance);
destroy_window_glfw (window);
return 0;
}
// TODO
// Migrate to Catch2
// Getting queues
// get dedicated vs distinct compute queues
// Swapchain creation
// Swapchain recreation
// changing present modes and/or image formats
int main () {
test_happy_path ();
test_instance_basic ();
test_instance_headless ();
test_physical_device_selection ();
test_device_creation ();
}