From 159057fbe7f633c531150417b6f50c79456fbdba Mon Sep 17 00:00:00 2001 From: Nigel Date: Tue, 19 Oct 2021 20:33:06 +0100 Subject: [PATCH] Added validation layers --- Hello_triangle/main.cpp | 149 ++++++++++++++++++++++++++++++++++++++-- readme.md | 2 +- 2 files changed, 143 insertions(+), 8 deletions(-) diff --git a/Hello_triangle/main.cpp b/Hello_triangle/main.cpp index efe924f..e008890 100644 --- a/Hello_triangle/main.cpp +++ b/Hello_triangle/main.cpp @@ -12,10 +12,27 @@ #include #include #include +#include +#include + const uint32_t WIDTH = 800; const uint32_t HEIGHT = 600; +const std::vector validationLayers ={ + //"VK_LAYER_KHRONOS_validation" + + "VK_LAYER_LUNARG_standard_validation" +}; + +#ifdef NDEBUG + const bool enableValidationLayers = false; +# else + const bool enableValidationLayers = true; +#endif + + + class HelloTriangleApplication{ public : void run (){ @@ -28,6 +45,7 @@ class HelloTriangleApplication{ private: GLFWwindow* window; VkInstance instance; + VkDebugUtilsMessengerEXT debugMessenger; void initWindow(){ glfwInit(); @@ -40,11 +58,75 @@ class HelloTriangleApplication{ void initVulkan(){ createInstance(); + setupDebugMessenger(); + } + + VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pDebugMessenger) { + auto func = (PFN_vkCreateDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT"); + if (func != nullptr) { + return func(instance, pCreateInfo, pAllocator, pDebugMessenger); + } else { + return VK_ERROR_EXTENSION_NOT_PRESENT; + } } + void setupDebugMessenger(){ + if(!enableValidationLayers) return; + + VkDebugUtilsMessengerCreateInfoEXT createinfo; + populateDebugMessengerCreateInfo(createinfo); + + if (CreateDebugUtilsMessengerEXT(instance, &createinfo, nullptr, &debugMessenger) != VK_SUCCESS) { + throw std::runtime_error("failed to set up debug messenger!"); + } + } + + bool checkValidationLayerSupport(){ + uint32_t layerCount ; + vkEnumerateInstanceLayerProperties(&layerCount, nullptr); + + std::vector availableLayers(layerCount); + vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data()); + + for( const char* layerName: validationLayers) { + bool layerFound = false; + + for (const auto & layerProperties : availableLayers){ + if( strcmp(layerName, layerProperties.layerName) == 0){ + layerFound = true; + break; + } + } + + if(!layerFound ){ + return false; + } + } + + return true; + + } + + std::vector getRequiredExtensions(){ + uint32_t glfwExtensionCount = 0; + const char** glfwExtensions; + glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); + + std::vector extensions (glfwExtensions, glfwExtensions + glfwExtensionCount); + + if(enableValidationLayers){ + extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + } + + return extensions; + } void createInstance(){ + if ( enableValidationLayers && !checkValidationLayerSupport()){ + throw std::runtime_error("Validation layer requested, but not available!"); + } + VkApplicationInfo appInfo{}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pApplicationName = "Hello Triangle"; @@ -57,14 +139,33 @@ class HelloTriangleApplication{ createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pApplicationInfo = &appInfo; - uint32_t glfwExtesionCount = 0; - const char** glfwExtensions; + VkDebugUtilsMessengerCreateInfoEXT debugcreateinfo{}; + if(enableValidationLayers){ + createInfo.enabledLayerCount = static_cast(validationLayers.size()); + createInfo.ppEnabledLayerNames = validationLayers.data(); - glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtesionCount); + populateDebugMessengerCreateInfo(debugcreateinfo); + createInfo.pNext = (VkDebugUtilsMessengerCreateInfoEXT*) &debugcreateinfo; + + } else{ + createInfo.enabledLayerCount = 0; + createInfo.pNext = nullptr; + } + + + auto extensions = getRequiredExtensions(); + createInfo.enabledExtensionCount = static_cast(extensions.size()); + createInfo.ppEnabledExtensionNames = extensions.data(); - createInfo.enabledExtensionCount = glfwExtesionCount; - createInfo.ppEnabledExtensionNames = glfwExtensions; - createInfo.enabledLayerCount = 0; + if(enableValidationLayers){ + createInfo.enabledLayerCount = static_cast (validationLayers.size()); + createInfo.ppEnabledLayerNames = validationLayers.data(); + } else{ + createInfo.enabledLayerCount = 0; + } + + + if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS ){ throw std::runtime_error("Failed to create instance!"); @@ -81,10 +182,44 @@ class HelloTriangleApplication{ } void cleanup(){ - glfwDestroyWindow(window); + if(enableValidationLayers){ + DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr); + } + vkDestroyInstance(instance, nullptr); + + + glfwDestroyWindow(window); glfwTerminate(); } + + void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo) { + createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; + createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + createInfo.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; + createInfo.pfnUserCallback = debugCallback; + } + + + void DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator) { + auto func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT"); + if (func != nullptr) { + func(instance, debugMessenger, pAllocator); + } + } + + static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback( + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageType, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, + void* pUserData){ + + + std::cerr << "Validation layer: " << pCallbackData->pMessage << std::endl; + return VK_FALSE; + } + }; diff --git a/readme.md b/readme.md index 22d50b0..636d4dc 100644 --- a/readme.md +++ b/readme.md @@ -1,3 +1,3 @@ # Vulkan API demo's -![Vulkan](https://www.vulkan.org/user/pages/01.home/Vulkan-Wide.png) \ No newline at end of file +![Vulkan](https://www.vulkan.org/user/pages/01.home/Vulkan-Wide.png) \ No newline at end of file