diff --git a/src/managers/vulkan/VulkanManagerInit.cpp b/src/managers/vulkan/VulkanManagerInit.cpp index 110b2e9..7540326 100644 --- a/src/managers/vulkan/VulkanManagerInit.cpp +++ b/src/managers/vulkan/VulkanManagerInit.cpp @@ -1,5 +1,23 @@ #include "VulkanManager.h" +#ifdef PB_DEBUG + +static VKAPI_ATTR VkBool32 VKAPI_CALL VulkanErrorDebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT, VkDebugUtilsMessageTypeFlagsEXT, const VkDebugUtilsMessengerCallbackDataEXT* data, void*) +{ + static std::set seenErrors; + if (seenErrors.contains(data->messageIdNumber)) + return VK_FALSE; + + seenErrors.insert(data->messageIdNumber); + + std::cout << "\nVULKAN ERROR [" << data->pMessageIdName << "]: \n" << data->pMessage << "\n" << std::endl; + return VK_FALSE; +} + +static VkDebugUtilsMessengerEXT gDebugMessenger; + +#endif // PB_DEBUG + namespace PB::Renderer { // === Custom resources === // @@ -114,23 +132,64 @@ namespace PB::Renderer createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pNext = nullptr; createInfo.pApplicationInfo = &appInfo; - createInfo.enabledLayerCount = 0; - createInfo.ppEnabledLayerNames = nullptr; - /* Imports GLFW extensions */ + if constexpr (DEBUG_MODE) + { + static const std::vector LAYERS = + { + "VK_LAYER_KHRONOS_validation", + }; + + createInfo.enabledLayerCount = LAYERS.size(); + createInfo.ppEnabledLayerNames = LAYERS.data(); + } + + else + { + createInfo.enabledLayerCount = 0; + createInfo.ppEnabledLayerNames = nullptr; + } + + /* Imports extensions */ uint32_t glfwExtensionCount = 0; const char** glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); - createInfo.enabledExtensionCount = glfwExtensionCount; - createInfo.ppEnabledExtensionNames = glfwExtensions; + + std::vector extensions(glfwExtensions, glfwExtensions + glfwExtensionCount); + if constexpr (DEBUG_MODE) + { + extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + } + + createInfo.enabledExtensionCount = extensions.size(); + createInfo.ppEnabledExtensionNames = extensions.data(); /* Creates the Vulkan instance */ VkInstance instance; - if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) + if (const VkResult result = vkCreateInstance(&createInfo, nullptr, &instance); result != VK_SUCCESS) { - std::cout << "PB::Renderer::VulkanManager::Init(): Could not create Vulkan instance" << std::endl; + std::cout << "PB::Renderer::VulkanManager::Init(): Could not create Vulkan instance: [" << result << "]" << std::endl; return false; } + /* Adds a debug messenger */ + #ifdef PB_DEBUG + + VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo; + debugCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; + debugCreateInfo.messageSeverity = + VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + debugCreateInfo.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; + debugCreateInfo.pfnUserCallback = VulkanErrorDebugCallback; + + if (const auto func = reinterpret_cast(vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT")); func != nullptr) + func(instance, &debugCreateInfo, nullptr, &gDebugMessenger); + + #endif // PB_DEBUG + s_Instance = instance; return true; }