diff --git a/Core/Core/RenderEngine.cpp b/Core/Core/RenderEngine.cpp index ea00aa8..dbf351e 100644 --- a/Core/Core/RenderEngine.cpp +++ b/Core/Core/RenderEngine.cpp @@ -1,17 +1,50 @@ #include "RenderEngine.h" #include +#include #ifdef _DEBUG +#include "Log/Log.h" #include #define VK_CHECK(res) assert(res == VK_SUCCESS) + +static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback( + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageType, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, + void* pUserData) { + + std::string msg = "validation layer: "; + msg += pCallbackData->pMessage; + Log(msg); + + return VK_FALSE; +} + +VkResult RenderEngine::enable_layer_validation(VkInstance instance, VkDebugUtilsMessengerCreateInfoEXT* create_info) +{ + PFN_vkCreateDebugUtilsMessengerEXT debug_creator = reinterpret_cast(vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT")); + return debug_creator(instance, create_info, nullptr, &debug_messenger_); +} #else -#define VK_CHECK(res) res +#define VK_CHECK(res) if ((res) != VK_SUCCESS) throw std::runtime_error("Vulkan error: " + std::to_string(res)) #endif +std::vector RenderEngine::get_required_extensions() +{ + uint32_t extensions_count = 0; + const char** glfw_extension = glfwGetRequiredInstanceExtensions(&extensions_count); + std::vector extensions(glfw_extension, glfw_extension + extensions_count); + +#ifdef _DEBUG + extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); +#endif + return extensions; +} + void RenderEngine::render_thread_func() { - window = glfwCreateWindow(640, 480, "UwU Engine", NULL, NULL); + window = glfwCreateWindow(640, 480, "UwU Engine", nullptr, nullptr); if (!window) { glfwTerminate(); @@ -27,14 +60,22 @@ void RenderEngine::render_thread_func() RenderEngine::RenderEngine(const std::string& app_name, int major_app_version, int minor_app_version, int patch_app_version, - int major_engine_version, int minor_engine_version, int patch_engine_version) + int major_engine_version, int minor_engine_version, int patch_engine_version) : + render_thread(nullptr), window(nullptr) +#ifdef _DEBUG +, debug_messenger_(nullptr) +#endif { if (!glfwInit()) throw std::runtime_error("Fail initialize GLFW"); { - uint32_t extensions_count = 0; - const char** extensions = glfwGetRequiredInstanceExtensions(&extensions_count); + std::vector extensions = get_required_extensions(); + std::vector layers = { +#ifdef _DEBUG + "VK_LAYER_KHRONOS_validation" +#endif + }; VkApplicationInfo app_info{}; app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; @@ -44,12 +85,39 @@ RenderEngine::RenderEngine(const std::string& app_name, app_info.pEngineName = "UwU Engine"; app_info.engineVersion = VK_MAKE_VERSION(major_engine_version, minor_engine_version, patch_engine_version); + VkInstanceCreateInfo instance_create_info{}; instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - instance_create_info.ppEnabledExtensionNames = extensions; - instance_create_info.enabledExtensionCount = extensions_count; instance_create_info.pApplicationInfo = &app_info; + instance_create_info.enabledExtensionCount = extensions.size(); + instance_create_info.ppEnabledExtensionNames = extensions.data(); + instance_create_info.enabledLayerCount = layers.size(); + instance_create_info.ppEnabledLayerNames = layers.data(); +#ifdef _DEBUG + VkDebugUtilsMessengerCreateInfoEXT debug_messenger_create_info{}; + debug_messenger_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; + debug_messenger_create_info.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; + debug_messenger_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; + debug_messenger_create_info.pfnUserCallback = &debugCallback; + instance_create_info.pNext = &debug_messenger_create_info; +#endif VK_CHECK(vkCreateInstance(&instance_create_info, nullptr, &instance_)); +#ifdef _DEBUG + VK_CHECK(enable_layer_validation(instance_, &debug_messenger_create_info)); +#endif + } + + { + uint32_t device_count = 0; + std::vector devices; + VK_CHECK(vkEnumeratePhysicalDevices(instance_, &device_count, nullptr)); + VK_CHECK(vkEnumeratePhysicalDevices(instance_, &device_count, devices.data())); + + for (const auto& device : devices) + { + VkPhysicalDeviceProperties device_properties; + vkGetPhysicalDeviceProperties(device, &device_properties); + } } } @@ -63,6 +131,17 @@ RenderEngine::~RenderEngine() render_thread->join(); delete render_thread; } + +#ifdef _DEBUG + if (debug_messenger_ != nullptr && instance_ != nullptr) { + PFN_vkDestroyDebugUtilsMessengerEXT destroyer_messenger = reinterpret_cast(vkGetInstanceProcAddr(instance_, "vkDestroyDebugUtilsMessengerEXT")); + destroyer_messenger(instance_, debug_messenger_, nullptr); + } +#endif + + if (instance_ != nullptr) + vkDestroyInstance(instance_, nullptr); + if (window != nullptr) glfwDestroyWindow(window); glfwTerminate(); diff --git a/Core/Core/RenderEngine.h b/Core/Core/RenderEngine.h index 081831f..8703a14 100644 --- a/Core/Core/RenderEngine.h +++ b/Core/Core/RenderEngine.h @@ -5,6 +5,7 @@ #include "Delegate/Delegate.h" #include #include +#include #include "GLFW/glfw3.h" @@ -15,6 +16,13 @@ class RenderEngine GLFWwindow* window; VkInstance instance_; + +#ifdef _DEBUG + VkResult enable_layer_validation(VkInstance instance, VkDebugUtilsMessengerCreateInfoEXT* create_info); + VkDebugUtilsMessengerEXT debug_messenger_; +#endif + + static std::vector get_required_extensions(); void render_thread_func(); public: Delegate onCloseWindow;