diff options
author | vimene <vincent.menegaux@gmail.com> | 2025-06-26 01:12:08 +0200 |
---|---|---|
committer | vimene <vincent.menegaux@gmail.com> | 2025-06-26 01:12:08 +0200 |
commit | 625d18a6053e28762c77efd3dd0d79fc01b0b0ef (patch) | |
tree | bd7bd31a40b9d8061c32c9953d78412e2cf90a48 | |
parent | fc8e5fc191822c244f51335e49d44f5a047b128e (diff) | |
download | engine-625d18a6053e28762c77efd3dd0d79fc01b0b0ef.tar.gz |
added validation layers to vulkanvulkan
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile.am | 8 | ||||
-rw-r--r-- | configure.ac | 9 | ||||
-rw-r--r-- | src/engine.cpp | 128 |
4 files changed, 137 insertions, 9 deletions
@@ -29,3 +29,4 @@ Makefile.in # vim .*.swp +*~ diff --git a/Makefile.am b/Makefile.am index 60712f6..0a27d41 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,6 +5,14 @@ if ENABLE_TESTS endif ACLOCAL_AMFLAGS = -Im4 --install +CXXFLAGS = +if DEBUG +CXXFLAGS += -ggdb +else +CXXFLAGS += -DNDEBUG +endif +CXXFLAGS += -O2 + bin_PROGRAMS = engine engine_SOURCES = \ diff --git a/configure.ac b/configure.ac index 5d252bc..ebdbcad 100644 --- a/configure.ac +++ b/configure.ac @@ -42,6 +42,15 @@ PKG_CHECK_MODULES([CRITERION], [criterion >= 2.4.1], [ ], [enable_tests=no]) AM_CONDITIONAL([ENABLE_TESTS], [test x$enable_tests = xyes]) +AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [enable debugging, default: no]), + [case "${enableval}" in + yes) debug=true ;; + no) debug=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;; + esac], + [debug=false]) +AM_CONDITIONAL([DEBUG], test x"$debug" = x"true") + AC_SUBST(TESTS_DEPS_CPPFLAGS) AC_SUBST(TESTS_DEPS_LIBS) diff --git a/src/engine.cpp b/src/engine.cpp index d276d70..da28f75 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -292,6 +292,63 @@ static int main_term() { #define SCREEN_WIDTH 640 #define SCREEN_HEIGHT 480 +const std::vector<const char*> validation_layers = { + "VK_LAYER_KHRONOS_validation" +}; + +#ifdef NDEBUG +const bool enable_validation_layers = false; +#else +const bool enable_validation_layers = true; +#endif + +static bool check_validation_layer_support() { + uint32_t layer_count; + vkEnumerateInstanceLayerProperties(&layer_count, nullptr); + + std::vector<VkLayerProperties> available_layers(layer_count); + vkEnumerateInstanceLayerProperties(&layer_count, available_layers.data()); + + for (const char* layer_name : validation_layers) { + bool layer_found = false; + + for (const auto& layer_properties : available_layers) { + if (strcmp(layer_name, layer_properties.layerName) == 0) { + layer_found = true; + break; + } + } + + if (!layer_found) { + return false; + } + } + + return true; +} + +static VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback( + VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, + VkDebugUtilsMessageTypeFlagsEXT message_type, + const VkDebugUtilsMessengerCallbackDataEXT* callback_data, + void* user_data) { + std::cerr << "validation layer: " << callback_data->pMessage << std::endl; + return VK_FALSE; +} + +static void populate_msger_create_info(VkDebugUtilsMessengerCreateInfoEXT& msger_create_info) { + msger_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; + msger_create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + msger_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + msger_create_info.pfnUserCallback = debug_callback; + msger_create_info.pUserData = nullptr; +} + static int main_graphical() { // init window glfwInit(); @@ -301,6 +358,11 @@ static int main_graphical() { // init Vulkan // init Vulkan - create instance + if (enable_validation_layers && !check_validation_layer_support()) { + std::cerr << "validation layers requested, but not available!" << std::endl; + std::exit(EXIT_FAILURE); + } + VkApplicationInfo app_info{}; app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; app_info.pApplicationName = "engine - test"; @@ -309,26 +371,52 @@ static int main_graphical() { app_info.engineVersion = VK_MAKE_VERSION(1, 0, 0); app_info.apiVersion = VK_API_VERSION_1_0; - uint32_t glfw_extension_count; - const char** glfw_extensions; - glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extension_count); + std::vector<const char*> extensions; + + { + uint32_t glfw_extension_count; + const char** glfw_extensions; + glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extension_count); + extensions.insert(extensions.end(), glfw_extensions, glfw_extensions + glfw_extension_count); + } + + if (enable_validation_layers) { + extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + } uint32_t extension_count; vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr); - std::vector<VkExtensionProperties> extensions(extension_count); - vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extensions.data()); + std::vector<VkExtensionProperties> available_extensions(extension_count); + vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, available_extensions.data()); std::cout << "vulkan extensions:\n"; - for (const auto& extension : extensions) + for (const auto& extension : available_extensions) std::cout << " " << extension.extensionName << "\n"; + std::cout << "\n"; + + std::cout << "required extensions:\n"; + for (const auto& extension_name : extensions) + std::cout << " " << extension_name << "\n"; + VkInstanceCreateInfo create_info{}; create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; create_info.pApplicationInfo = &app_info; - create_info.enabledExtensionCount = glfw_extension_count; - create_info.ppEnabledExtensionNames = glfw_extensions; - create_info.enabledLayerCount = 0; + create_info.enabledExtensionCount = static_cast<uint32_t>(extensions.size()); + create_info.ppEnabledExtensionNames = extensions.data(); + + VkDebugUtilsMessengerCreateInfoEXT inst_msger_create_info{}; + if (enable_validation_layers) { + create_info.enabledLayerCount = static_cast<uint32_t>(validation_layers.size()); + create_info.ppEnabledLayerNames = validation_layers.data(); + + populate_msger_create_info(inst_msger_create_info); + create_info.pNext = (VkDebugUtilsMessengerCreateInfoEXT*) &inst_msger_create_info; + } else { + create_info.enabledLayerCount = 0; + create_info.pNext = nullptr; + } VkInstance instance; if (VkResult res = vkCreateInstance(&create_info, nullptr, &instance); res != VK_SUCCESS) { @@ -336,12 +424,34 @@ static int main_graphical() { std::exit(EXIT_FAILURE); } + VkDebugUtilsMessengerEXT debug_messenger; + if (enable_validation_layers) { + VkDebugUtilsMessengerCreateInfoEXT msger_create_info{}; + populate_msger_create_info(msger_create_info); + + auto create_debug_messenger = (PFN_vkCreateDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT"); + if (!create_debug_messenger) { + std::cerr << "failed to set up debug messenger!" << std::endl; + std::exit(EXIT_FAILURE); + } + create_debug_messenger(instance, &msger_create_info, nullptr, &debug_messenger); + } + // main loop while (!glfwWindowShouldClose(window)) { glfwPollEvents(); } // cleanup + if (enable_validation_layers) { + auto destroy_debug_messenger = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT"); + if (!destroy_debug_messenger) { + std::cerr << "failed to destroy debug messenger!" << std::endl; + std::exit(EXIT_FAILURE); + } + destroy_debug_messenger(instance, debug_messenger, nullptr); + } + vkDestroyInstance(instance, nullptr); glfwDestroyWindow(window); glfwTerminate(); |