#include "VulkanInstanceManager.h" #include "Logger.h" VulkanInstanceManager::VulkanInstanceManager() { } VulkanInstanceManager::~VulkanInstanceManager() { Cleanup(); } VulkanInstanceManager::VulkanInstanceManager(VulkanInstanceManager&& Other) noexcept : Instance(Other.Instance), bValidationEnabled(Other.bValidationEnabled), bVerboseLogging(Other.bVerboseLogging), VkDebugManager(std::move(Other.VkDebugManager)) { Other.Instance = VK_NULL_HANDLE; Other.bValidationEnabled = false; Other.bVerboseLogging = false; } VulkanInstanceManager& VulkanInstanceManager::operator=(VulkanInstanceManager&& Other) noexcept { if (this != &Other) { Cleanup(); Instance = Other.Instance; bValidationEnabled = Other.bValidationEnabled; bVerboseLogging = Other.bVerboseLogging; VkDebugManager = std::move(Other.VkDebugManager); Other.Instance = VK_NULL_HANDLE; } return *this; } void VulkanInstanceManager::Initialize(const FVulkanConfig& Config) { if (IsInitialized()) { Log::Warning("Already Initialized."); return; } bValidationEnabled = Config.bValidationEnabled; bVerboseLogging = Config.bVerboseLogging; if (bValidationEnabled) { Log::Info("DebugManager created with validation enabled."); VkDebugManager = std::make_unique(); } CreateInstance(); if (VkDebugManager) { VkDebugManager->Initialize(Instance); } VkDeviceManager = std::make_unique(); VkDeviceManager->Initialize(Instance); } void VulkanInstanceManager::Cleanup() { if (!IsInitialized()) { Log::Warning("Not initialized."); return; } if (VkDebugManager) { VkDebugManager->Cleanup(); } if (VkDeviceManager) { VkDeviceManager->Cleanup(); } vkDestroyInstance(Instance, nullptr); Instance = VK_NULL_HANDLE; } std::vector VulkanInstanceManager::GetRequiredExtensions() { uint32_t GlfwExtensionCount = 0; const char** GlfwExtensions; GlfwExtensions = glfwGetRequiredInstanceExtensions(&GlfwExtensionCount); std::vector Extensions(GlfwExtensions, GlfwExtensions + GlfwExtensionCount); if (VkDebugManager) { Extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); } return Extensions; } bool VulkanInstanceManager::CheckValidationLayerSupport() { uint32_t LayerCount; vkEnumerateInstanceLayerProperties(&LayerCount, nullptr); std::vector AvailableLayers(LayerCount); vkEnumerateInstanceLayerProperties(&LayerCount, AvailableLayers.data()); for (const char* LayerName : ValidationLayers) { bool bLayerFound = false; for (const auto& LayerProperties : AvailableLayers) { if (strcmp(LayerName, LayerProperties.layerName) == 0) { bLayerFound = true; break; } } if (!bLayerFound) { return false; } } return true; } void VulkanInstanceManager::CreateInstance() { Log::Info("Creating Vulkan instance."); if (bValidationEnabled && !CheckValidationLayerSupport()) { Log::Error("Validation layers requested, but not available!"); } VkApplicationInfo AppInfo{}; AppInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; AppInfo.pApplicationName = "Hello Triangle"; AppInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); AppInfo.pEngineName = "No Engine"; AppInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); AppInfo.apiVersion = VK_API_VERSION_1_0; VkInstanceCreateInfo CreateInfo{}; CreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; CreateInfo.pApplicationInfo = &AppInfo; auto Extensions = GetRequiredExtensions(); CreateInfo.enabledExtensionCount = static_cast(Extensions.size()); CreateInfo.ppEnabledExtensionNames = Extensions.data(); if (VkDebugManager) { VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo{}; CreateInfo.enabledLayerCount = static_cast(ValidationLayers.size()); CreateInfo.ppEnabledLayerNames = ValidationLayers.data(); VkDebugManager->PopulateDebugMessengerCreateInfo(debugCreateInfo); CreateInfo.pNext = (VkDebugUtilsMessengerCreateInfoEXT*)&debugCreateInfo; } else { CreateInfo.enabledLayerCount = 0; CreateInfo.pNext = nullptr; } if (vkCreateInstance(&CreateInfo, nullptr, &Instance) != VK_SUCCESS) { Log::Error("Failed to create instance!"); } }