Added Vulkan Context.
This commit is contained in:
parent
bc84716171
commit
385c6740e0
|
|
@ -0,0 +1,99 @@
|
||||||
|
// =============================================
|
||||||
|
// Aster: context.cpp
|
||||||
|
// Copyright (c) 2020-2024 Anish Bhobe
|
||||||
|
// =============================================
|
||||||
|
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
|
VKAPI_ATTR b32 VKAPI_CALL Context::debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT _message_severity, 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) {
|
||||||
|
vk::Result result;
|
||||||
|
|
||||||
|
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 = nullptr;
|
||||||
|
|
||||||
|
glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extension_count);
|
||||||
|
std::vector<const char *> 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<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr");
|
||||||
|
VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr);
|
||||||
|
|
||||||
|
tie(result, instance) = vk::createInstance({
|
||||||
|
.pNext = enable_validation_layers ? &debug_messenger_create_info : nullptr,
|
||||||
|
.pApplicationInfo = &app_info,
|
||||||
|
.enabledLayerCount = enable_validation_layers ? cast<u32>(validation_layers.size()) : 0,
|
||||||
|
.ppEnabledLayerNames = enable_validation_layers ? validation_layers.data() : nullptr,
|
||||||
|
.enabledExtensionCount = cast<u32>(vulkan_extensions.size()),
|
||||||
|
.ppEnabledExtensionNames = vulkan_extensions.data(),
|
||||||
|
});
|
||||||
|
ERROR_IF(failed(result), "Failed to create Vulkan instance with "s + to_string(result))
|
||||||
|
THEN_CRASH(result)
|
||||||
|
ELSE_INFO("Instance Created.");
|
||||||
|
VULKAN_HPP_DEFAULT_DISPATCHER.init(instance);
|
||||||
|
|
||||||
|
// Debug Messenger
|
||||||
|
if (enable_validation_layers) {
|
||||||
|
tie(result, debug_messenger) = instance.createDebugUtilsMessengerEXT(debug_messenger_create_info);
|
||||||
|
ERROR_IF(failed(result), "Debug Messenger creation failed with "s + to_string(result))
|
||||||
|
ELSE_INFO("Debug Messenger Created.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context::~Context() {
|
||||||
|
if (instance) {
|
||||||
|
if (enable_validation_layers && debug_messenger) {
|
||||||
|
instance.destroyDebugUtilsMessengerEXT(debug_messenger);
|
||||||
|
}
|
||||||
|
instance.destroy();
|
||||||
|
INFO("Context destroyed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
// =============================================
|
||||||
|
// Aster: context.h
|
||||||
|
// Copyright (c) 2020-2024 Anish Bhobe
|
||||||
|
// =============================================
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Context
|
||||||
|
*
|
||||||
|
* @brief Vulkan context to handle device initialization logic.
|
||||||
|
*
|
||||||
|
* Handles the required hardware interactions.
|
||||||
|
*/
|
||||||
|
class Context final {
|
||||||
|
public:
|
||||||
|
Context(const std::string_view &_app_name, const Version &_app_version, const b8 _enable_validation = true) :
|
||||||
|
enable_validation_layers{ _enable_validation } {
|
||||||
|
init(_app_name, _app_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
Context(const std::string_view &_app_name, const Version &_app_version, const std::vector<const char *> &_additional_device_extensions, const b8 _enable_validation = true) :
|
||||||
|
enable_validation_layers{ _enable_validation } {
|
||||||
|
device_extensions.reserve(device_extensions.size() + _additional_device_extensions.size());
|
||||||
|
device_extensions.insert(device_extensions.end(), _additional_device_extensions.begin(), _additional_device_extensions.end());
|
||||||
|
|
||||||
|
init(_app_name, _app_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
Context(const std::string_view &_app_name, const Version &_app_version, const std::vector<const char *> &_additional_device_extensions, const std::vector<const char *> &_additional_validation_layers) {
|
||||||
|
device_extensions.reserve(device_extensions.size() + _additional_device_extensions.size());
|
||||||
|
device_extensions.insert(device_extensions.end(), _additional_device_extensions.begin(), _additional_device_extensions.end());
|
||||||
|
|
||||||
|
validation_layers.reserve(validation_layers.size() + _additional_validation_layers.size());
|
||||||
|
validation_layers.insert(validation_layers.end(), _additional_validation_layers.begin(), _additional_validation_layers.end());
|
||||||
|
|
||||||
|
init(_app_name, _app_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
Context(const Context &_other) = delete;
|
||||||
|
|
||||||
|
Context(Context &&_other) noexcept :
|
||||||
|
enable_validation_layers{ _other.enable_validation_layers }, validation_layers{ std::move(_other.validation_layers) }, device_extensions{ std::move(_other.device_extensions) }, instance{ std::exchange(_other.instance, nullptr) }, debug_messenger{ std::exchange(_other.debug_messenger, nullptr) } {}
|
||||||
|
|
||||||
|
Context &operator=(const Context &_other) = delete;
|
||||||
|
|
||||||
|
Context &operator=(Context &&_other) noexcept {
|
||||||
|
if (this == &_other)
|
||||||
|
return *this;
|
||||||
|
enable_validation_layers = _other.enable_validation_layers;
|
||||||
|
validation_layers = std::move(_other.validation_layers);
|
||||||
|
device_extensions = std::move(_other.device_extensions);
|
||||||
|
instance = std::exchange(_other.instance, nullptr);
|
||||||
|
debug_messenger = std::exchange(_other.debug_messenger, nullptr);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Context();
|
||||||
|
|
||||||
|
// Fields
|
||||||
|
bool enable_validation_layers{ true };
|
||||||
|
|
||||||
|
std::vector<const char *> validation_layers = {
|
||||||
|
"VK_LAYER_KHRONOS_validation",
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<const char *> device_extensions = {
|
||||||
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||||
|
VK_KHR_MULTIVIEW_EXTENSION_NAME,
|
||||||
|
};
|
||||||
|
|
||||||
|
vk::Instance instance;
|
||||||
|
vk::DebugUtilsMessengerEXT debug_messenger;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init(const std::string_view &_app_name, const Version &_app_version);
|
||||||
|
|
||||||
|
static VKAPI_ATTR b32 VKAPI_CALL debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT _message_severity,
|
||||||
|
VkDebugUtilsMessageTypeFlagsEXT _message_type,
|
||||||
|
const VkDebugUtilsMessengerCallbackDataEXT *_callback_data,
|
||||||
|
void *_user_data);
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue