#include "RenderEngine.h" #include #include #include #include "Core/CoreInstance.h" PROTECTION_FROM_GB(RenderEngine) #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) 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; } RenderEngine::RenderEngine() : window(nullptr) #ifdef _DEBUG , debug_messenger_(nullptr) #endif { onStop.bind(this, &RenderEngine::stop_render); if (glfwInit() == GLFW_FALSE) throw std::runtime_error("Fail init glfw"); { 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; app_info.apiVersion = VK_API_VERSION_1_0; app_info.applicationVersion = VK_MAKE_VERSION(0, 0, 0); app_info.pApplicationName = "UwU Engine"; app_info.pEngineName = "UwU Engine"; app_info.engineVersion = VK_MAKE_VERSION(0, 0, 0); VkInstanceCreateInfo instance_create_info{}; instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; 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); } } } RenderEngine::~RenderEngine() { #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(); } void RenderEngine::start() { window = glfwCreateWindow(640, 480, "UwU Engine", nullptr, nullptr); if (!window) { glfwTerminate(); throw std::runtime_error("Fail create window"); } while (!glfwWindowShouldClose(window)) { glfwSwapBuffers(window); glfwPollEvents(); } QuitGame(); } void RenderEngine::stop_render() { if (window != nullptr && !glfwWindowShouldClose(window)) glfwSetWindowShouldClose(window, true); }