MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
VKInstance.cpp
Go to the documentation of this file.
1#include "VKInstance.hpp"
2
4
5VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
6
7namespace MayaFlux::Core {
8
9static const std::vector<const char*> VALIDATION_LAYERS = {
10 "VK_LAYER_KHRONOS_validation"
11};
12
17
19 : m_instance(other.m_instance)
20 , m_debug_messenger(other.m_debug_messenger)
21 , m_validation_enabled(other.m_validation_enabled)
22 , m_dynamic_dispatcher(other.m_dynamic_dispatcher)
23{
24 other.m_instance = nullptr;
25 other.m_debug_messenger = nullptr;
26}
27
29{
30 if (this != &other) {
31 cleanup();
32 m_instance = other.m_instance;
33 m_debug_messenger = other.m_debug_messenger;
34 m_validation_enabled = other.m_validation_enabled;
35 m_dynamic_dispatcher = other.m_dynamic_dispatcher;
36
37 other.m_instance = nullptr;
38 other.m_debug_messenger = nullptr;
39 }
40 return *this;
41}
42
43bool VKInstance::initialize(bool enable_validation,
44 const std::vector<const char*>& required_extensions)
45{
46 m_validation_enabled = enable_validation;
47
48 auto vkGetInstanceProcAddr = vk::detail::DynamicLoader().getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr");
49 VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr);
50
52 MF_ERROR(Journal::Component::Core, Journal::Context::GraphicsBackend, "Vulkan validation layers requested, but not available!");
53 return false;
54 }
55
56 vk::ApplicationInfo app_info {};
57 app_info.pApplicationName = "MayaFlux";
58 app_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
59 app_info.pEngineName = "MayaFlux Engine";
60 app_info.engineVersion = VK_MAKE_VERSION(1, 0, 0);
61 app_info.apiVersion = VK_API_VERSION_1_3;
62
63 vk::InstanceCreateInfo create_info {};
64 create_info.pApplicationInfo = &app_info;
65
66 std::vector<const char*> extensions = required_extensions;
67
68#ifdef MAYAFLUX_PLATFORM_MACOS
69 extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
70 create_info.flags = vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR;
71#endif
72
74 extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
75 }
76 create_info.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
77 create_info.ppEnabledExtensionNames = extensions.data();
78
79 vk::DebugUtilsMessengerCreateInfoEXT debug_create_info {};
80
82 create_info.enabledLayerCount = static_cast<uint32_t>(VALIDATION_LAYERS.size());
83 create_info.ppEnabledLayerNames = VALIDATION_LAYERS.data();
84
85 debug_create_info.messageSeverity = vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose
86 | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError;
87
88 debug_create_info.messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral
89 | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation
90 | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance;
91
92 debug_create_info.pfnUserCallback = debug_callback;
93 create_info.pNext = &debug_create_info;
94
95 } else {
96 create_info.enabledLayerCount = 0;
97 create_info.pNext = nullptr;
98 }
99
100 try {
101 m_instance = vk::createInstance(create_info);
102 m_dynamic_dispatcher = vk::detail::DispatchLoaderDynamic(m_instance, vkGetInstanceProcAddr);
103
104 VULKAN_HPP_DEFAULT_DISPATCHER.init(m_instance);
105
106 } catch (const std::exception& e) {
108 std::source_location::current(),
109 "Failed to create Vulkan instance: {}", e.what());
110 }
111
113
115 MF_ERROR(Journal::Component::Core, Journal::Context::GraphicsBackend, "Failed to set up debug messenger!");
116 return false;
117 }
118
119 return true;
120}
121
123{
124 if (m_debug_messenger) {
125 m_instance.destroyDebugUtilsMessengerEXT(m_debug_messenger, nullptr, m_dynamic_dispatcher);
126 m_debug_messenger = nullptr;
127 }
128
129 if (m_instance) {
130 m_instance.destroy();
131 m_instance = nullptr;
133 }
134}
135
136bool VKInstance::check_validation_layer_support(const std::vector<const char*>& layers)
137{
138 auto available_layers = vk::enumerateInstanceLayerProperties();
139
140 for (const char* layer_name : layers) {
141 bool layer_found = false;
142
143 for (const auto& layer_properties : available_layers) {
144 if (strcmp(layer_name, layer_properties.layerName) == 0) {
145 layer_found = true;
146 break;
147 }
148 }
149
150 if (!layer_found) {
151 return false;
152 }
153 }
154
155 return true;
156}
157
159{
160 vk::DebugUtilsMessengerCreateInfoEXT create_info {};
161
162 create_info.messageSeverity = vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose
163 | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError;
164
165 create_info.messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral
166 | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation
167 | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance;
168
169 create_info.pfnUserCallback = debug_callback;
170 create_info.pUserData = nullptr;
171
172 try {
173 m_debug_messenger = m_instance.createDebugUtilsMessengerEXT(create_info, nullptr, m_dynamic_dispatcher);
174 } catch (const std::exception& e) {
176 std::source_location::current(),
177 "Failed to set up debug messenger: {}", e.what());
178 return false;
179 }
180
181 return true;
182}
183
185 vk::DebugUtilsMessageSeverityFlagBitsEXT /*messageSeverity*/,
186 vk::DebugUtilsMessageTypeFlagsEXT /*messageTypes*/,
187 const vk::DebugUtilsMessengerCallbackDataEXT* p_callback_data,
188 void* /*pUserData*/)
189{
190 MF_INFO(Journal::Component::Core, Journal::Context::Validation, "Validation layer: {}", p_callback_data->pMessage);
191 return VK_FALSE;
192}
193
194}
#define MF_INFO(comp, ctx,...)
#define MF_LOG(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
void cleanup()
Cleanup Vulkan instance.
bool m_validation_enabled
Flag to indicate if validation layers are enabled.
vk::detail::DispatchLoaderDynamic m_dynamic_dispatcher
Dynamic dispatcher for extension functions.
bool check_validation_layer_support(const std::vector< const char * > &layers)
Check if requested validation layers are available.
VKInstance & operator=(const VKInstance &)=delete
vk::Instance m_instance
Vulkan instance handle.
bool setup_debug_messenger()
Setup debug messenger for validation layer output.
vk::DebugUtilsMessengerEXT m_debug_messenger
Debug messenger for validation layers.
bool initialize(bool enable_validation=true, const std::vector< const char * > &required_extensions={})
Initialize Vulkan instance.
static vk::Bool32 debug_callback(vk::DebugUtilsMessageSeverityFlagBitsEXT message_severity, vk::DebugUtilsMessageTypeFlagsEXT message_types, const vk::DebugUtilsMessengerCallbackDataEXT *p_callback_data, void *p_user_data)
Validation layer callback.
~VKInstance()
Destructor to clean up Vulkan instance and debug messenger.
Manages Vulkan instance creation and validation layers.
static const std::vector< const char * > VALIDATION_LAYERS
Definition VKInstance.cpp:9
@ GraphicsBackend
Graphics/visual rendering backend (Vulkan, OpenGL)
@ Core
Core engine, backend, subsystems.