// ============================================= // Aster: context.cpp // Copyright (c) 2020-2024 Anish Bhobe // ============================================= #include "context.h" VKAPI_ATTR b32 VKAPI_CALL Context::debug_callback(const VkDebugUtilsMessageSeverityFlagBitsEXT _message_severity, const VkDebugUtilsMessageTypeFlagsEXT _message_type, const VkDebugUtilsMessengerCallbackDataEXT *_callback_data, [[maybe_unused]] void *_user_data) { using Severity = vk::DebugUtilsMessageSeverityFlagsEXT; using SeverityBits = vk::DebugUtilsMessageSeverityFlagBitsEXT; using MessageType = vk::DebugUtilsMessageTypeFlagsEXT; using MessageTypeBits = vk::DebugUtilsMessageTypeFlagBitsEXT; const auto severity = Severity(_message_severity); const auto message_type = MessageType(_message_type); if (message_type & MessageTypeBits::eValidation) { if (severity & SeverityBits::eError) ERROR(_callback_data->pMessage); if (severity & SeverityBits::eWarning) WARN(_callback_data->pMessage); if (severity & SeverityBits::eInfo) INFO(_callback_data->pMessage); if (severity & SeverityBits::eVerbose) VERBOSE(_callback_data->pMessage); } return false; } void Context::init(const std::string_view &_app_name, const Version &_app_version) { INFO_IF(enable_validation_layers, "Validation Layers enabled"); // Creating Instance vk::ApplicationInfo app_info = { .pApplicationName = _app_name.data(), .applicationVersion = VK_MAKE_VERSION(_app_version.major, _app_version.minor, _app_version.patch), .pEngineName = PROJECT_NAME, .engineVersion = VK_MAKE_VERSION(VERSION.major, VERSION.minor, VERSION.patch), .apiVersion = VK_API_VERSION_1_2, }; vk::DebugUtilsMessengerCreateInfoEXT debug_messenger_create_info = { .messageSeverity = vk::DebugUtilsMessageSeverityFlagBitsEXT::eError | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo, .messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation, .pfnUserCallback = debug_callback, .pUserData = nullptr, }; u32 glfw_extension_count = 0; const char **glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extension_count); std::vector vulkan_extensions(glfw_extensions, glfw_extensions + glfw_extension_count); if (enable_validation_layers) { vulkan_extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); } const vk::DynamicLoader dl; // ReSharper disable once CppInconsistentNaming const auto vkGetInstanceProcAddr = dl.getProcAddress("vkGetInstanceProcAddr"); VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr); try { instance = vk::raii::Instance{ raii_context, { .pNext = enable_validation_layers ? &debug_messenger_create_info : nullptr, .pApplicationInfo = &app_info, .enabledLayerCount = enable_validation_layers ? cast(validation_layers.size()) : 0, .ppEnabledLayerNames = enable_validation_layers ? validation_layers.data() : nullptr, .enabledExtensionCount = cast(vulkan_extensions.size()), .ppEnabledExtensionNames = vulkan_extensions.data(), } }; } catch (const std::exception &err) { ERROR("Failed to create Vulkan instance with "s + err.what()); throw; } INFO("Instance Created."); // Debug Messenger if (enable_validation_layers) { try { debug_messenger = vk::raii::DebugUtilsMessengerEXT{ instance, debug_messenger_create_info }; } catch (const std::exception &err) { ERROR("Debug Messenger creation failed with "s + err.what()); throw; } INFO("Debug Messenger Created."); } } Context::~Context() = default;