MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
VKContext.cpp
Go to the documentation of this file.
1#include "VKContext.hpp"
3
8
9#ifdef GLFW_BACKEND
10#define GLFW_INCLUDE_VULKAN
11#include <GLFW/glfw3.h>
12#endif // GLFW_BACKEND
13
14#if defined(WIN32_BACKEND)
15#include <vulkan/vulkan_win32.h>
16#endif
17
18#if defined(WAYLAND_BACKEND)
19#include <vulkan/vulkan_wayland.h>
20#endif
21
23
24namespace MayaFlux::Core {
25
26bool VKContext::initialize(const GlobalGraphicsConfig& graphics_config, bool enable_validation,
27 const std::vector<const char*>& required_extensions)
28{
29 m_graphics_config = graphics_config;
30
33 "Vulkan context initialization requested, but graphics API is not set to Vulkan!");
34 return false;
35 }
36
37 std::vector<const char*> extensions = required_extensions;
38
39#if defined(GLFW_BACKEND)
41 GLFWSingleton::configure(graphics_config.glfw_preinit_config);
42 for (const char* ext : GLFWSingleton::get_required_instance_extensions()) {
43 if (!std::ranges::contains(extensions, ext))
44 extensions.push_back(ext);
45 }
46 }
47#elif defined(WIN32_BACKEND)
48 extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
49 extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
50#elif defined(WAYLAND_BACKEND)
51 extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
52 extensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
53#endif
54
55 if (!m_instance.initialize(enable_validation, extensions)) {
57 "Failed to initialize Vulkan instance!");
58 return false;
59 }
60
63 "Failed to initialize Vulkan device!");
64 cleanup();
65 return false;
66 }
67
69 "Vulkan context initialized successfully.");
70 return true;
71}
72
73vk::SurfaceKHR VKContext::create_surface(std::shared_ptr<Window> window)
74{
75 if (!window) {
77 "Cannot create surface: null window");
78 return nullptr;
79 }
80
81#if defined(GLFW_BACKEND)
82 auto* glfw_window = dynamic_cast<GlfwWindow*>(window.get());
83 if (!glfw_window) {
85 "Cannot create surface: window is not a GlfwWindow");
86 return nullptr;
87 }
88
89 GLFWwindow* glfw_handle = glfw_window->get_glfw_handle();
90 if (!glfw_handle) {
92 "Cannot create surface: null GLFW handle");
93 return nullptr;
94 }
95
96 VkSurfaceKHR c_surface {};
97 VkResult result = Parallel::dispatch_main_sync([&]() {
98 return glfwCreateWindowSurface(
99 static_cast<VkInstance>(m_instance.get_instance()),
100 glfw_handle,
101 nullptr,
102 &c_surface);
103 });
104
105 if (result != VK_SUCCESS) {
107 "Failed to create GLFW window surface for window '{}'",
108 window->get_create_info().title);
109 return nullptr;
110 }
111
112 vk::SurfaceKHR surface(c_surface);
113 m_surfaces.push_back(surface);
114
116 "Surface created for window '{}'", window->get_create_info().title);
117
118 return surface;
119
120#elif defined(WIN32_BACKEND)
122 auto hwnd = static_cast<HWND>(window->get_native_handle());
123 if (!hwnd) {
125 "Cannot create surface: null HWND");
126 return nullptr;
127 }
128
129 VkWin32SurfaceCreateInfoKHR info {};
130 info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
131 info.hinstance = GetModuleHandleW(nullptr);
132 info.hwnd = hwnd;
133
134 VkSurfaceKHR c_surface {};
135 if (vkCreateWin32SurfaceKHR(
136 static_cast<VkInstance>(m_instance.get_instance()),
137 &info, nullptr, &c_surface)
138 != VK_SUCCESS) {
140 "Failed to create Win32 Vulkan surface for window '{}'",
141 window->get_create_info().title);
142 return nullptr;
143 }
144
145 vk::SurfaceKHR surface(c_surface);
146 m_surfaces.push_back(surface);
148 "Win32 surface created for window '{}'", window->get_create_info().title);
149 return surface;
150 }
151#elif defined(WAYLAND_BACKEND)
152 {
153 auto* wl_display = static_cast<struct wl_display*>(window->get_native_display());
154 auto* wl_surface = static_cast<struct wl_surface*>(window->get_native_handle());
155 if (!wl_display || !wl_surface) {
157 "Cannot create surface: null Wayland display or surface handle");
158 return nullptr;
159 }
160
161 VkWaylandSurfaceCreateInfoKHR info {};
162 info.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
163 info.display = wl_display;
164 info.surface = wl_surface;
165
166 VkSurfaceKHR c_surface {};
167 if (vkCreateWaylandSurfaceKHR(
168 static_cast<VkInstance>(m_instance.get_instance()),
169 &info, nullptr, &c_surface)
170 != VK_SUCCESS) {
172 "Failed to create Wayland Vulkan surface for window '{}'",
173 window->get_create_info().title);
174 return nullptr;
175 }
176
177 vk::SurfaceKHR surface(c_surface);
178 m_surfaces.push_back(surface);
180 "Wayland surface created for window '{}'", window->get_create_info().title);
181 return surface;
182 }
183#endif
184
186 "No windowing backend available for surface creation");
187 return nullptr;
188}
189
190void VKContext::destroy_surface(vk::SurfaceKHR surface)
191{
192 if (!surface)
193 return;
194
195 auto it = std::ranges::find(m_surfaces, surface);
196 if (it != m_surfaces.end()) {
197 m_instance.get_instance().destroySurfaceKHR(*it);
198 m_surfaces.erase(it);
199 }
200}
201
202bool VKContext::update_present_family(vk::SurfaceKHR surface)
203{
204 return m_device.update_presentation_queue(surface);
205}
206
208{
209 for (auto surface : m_surfaces) {
210 if (surface) {
211 m_instance.get_instance().destroySurfaceKHR(surface);
212 }
213 }
214 m_surfaces.clear();
215
218}
219
220}
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
bool update_present_family(vk::SurfaceKHR surface)
Update presentation support for a surface.
vk::SurfaceKHR create_surface(std::shared_ptr< Window > window)
Create surface from window's native handles.
Definition VKContext.cpp:73
std::vector< vk::SurfaceKHR > m_surfaces
void cleanup()
Cleanup all Vulkan resources.
GlobalGraphicsConfig m_graphics_config
bool initialize(const GlobalGraphicsConfig &graphics_config, bool enable_validation=true, const std::vector< const char * > &required_extensions={})
Initialize Vulkan context.
Definition VKContext.cpp:26
void destroy_surface(vk::SurfaceKHR surface)
Destroy a specific surface Called when window is unregistered.
void cleanup()
Cleanup device resources.
Definition VKDevice.cpp:58
bool update_presentation_queue(vk::SurfaceKHR surface)
Update presentation queue family for a specific surface.
Definition VKDevice.cpp:186
bool initialize(vk::Instance instance, vk::SurfaceKHR temp_surface, const GraphicsBackendInfo &backend_info)
Initialize device (pick physical device and create logical device)
Definition VKDevice.cpp:49
void cleanup()
Cleanup Vulkan instance.
vk::Instance get_instance() const
Get the Vulkan instance handle.
bool initialize(bool enable_validation=true, const std::vector< const char * > &required_extensions={})
Initialize Vulkan instance.
@ GraphicsBackend
Graphics/visual rendering backend (Vulkan, OpenGL)
@ Core
Core engine, backend, subsystems.
auto dispatch_main_sync(Func &&func, Args &&... args) -> decltype(auto)
Definition Dispatch.hpp:107
GraphicsBackendInfo backend_info
Graphics backend configuration.
WindowingBackend windowing_backend
Selected windowing backend.
GraphicsApi requested_api
Selected graphics API for rendering.