8#if defined(COCOA_BACKEND)
9#include <vulkan/vulkan_metal.h>
12#if defined(WIN32_BACKEND)
15#include <vulkan/vulkan_win32.h>
18#if defined(WAYLAND_BACKEND)
19#include <vulkan/vulkan_wayland.h>
27 const std::vector<const char*>& required_extensions)
33 "Vulkan context initialization requested, but graphics API is not set to Vulkan!");
37 std::vector<const char*> extensions = required_extensions;
39#if defined(COCOA_BACKEND)
41 for (
const char* ext : { VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_METAL_SURFACE_EXTENSION_NAME }) {
42 if (std::ranges::none_of(extensions, [ext](
const char* e) {
return std::strcmp(e, ext) == 0; }))
43 extensions.push_back(ext);
48#if defined(WIN32_BACKEND)
49 extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
50 extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
51#elif defined(WAYLAND_BACKEND)
52 extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
53 extensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
58 "Failed to initialize Vulkan instance!");
64 "Failed to initialize Vulkan device!");
70 "Vulkan context initialized successfully.");
78 "Cannot create surface: null window");
82#if defined(COCOA_BACKEND)
84 auto* cocoa_window =
dynamic_cast<CocoaWindow*
>(
window.get());
87 "Cannot create surface: window is not a CocoaWindow");
91 const void* layer = cocoa_window->get_metal_layer();
94 "Cannot create surface: null CAMetalLayer");
99 auto create_metal_surface =
reinterpret_cast<PFN_vkCreateMetalSurfaceEXT
>(
100 vkGetInstanceProcAddr(
instance,
"vkCreateMetalSurfaceEXT"));
101 if (!create_metal_surface) {
103 "Cannot create surface: vkCreateMetalSurfaceEXT unavailable");
107 VkMetalSurfaceCreateInfoEXT info {};
108 info.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
109 info.pLayer =
static_cast<const CAMetalLayer*
>(layer);
111 VkSurfaceKHR c_surface {};
113 return create_metal_surface(
instance, &info,
nullptr, &c_surface);
116 if (result != VK_SUCCESS) {
118 "Failed to create Metal surface for window '{}'",
119 window->get_create_info().title);
123 vk::SurfaceKHR surface(c_surface);
127 "Metal surface created for window '{}'",
window->get_create_info().title);
133#if defined(WIN32_BACKEND)
135 auto hwnd =
static_cast<HWND
>(
window->get_native_handle());
138 "Cannot create surface: null HWND");
142 VkWin32SurfaceCreateInfoKHR info {};
143 info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
144 info.hinstance = GetModuleHandleW(
nullptr);
147 VkSurfaceKHR c_surface {};
148 if (vkCreateWin32SurfaceKHR(
150 &info,
nullptr, &c_surface)
153 "Failed to create Win32 Vulkan surface for window '{}'",
154 window->get_create_info().title);
158 vk::SurfaceKHR surface(c_surface);
161 "Win32 surface created for window '{}'",
window->get_create_info().title);
164#elif defined(WAYLAND_BACKEND)
166 auto* wl_display =
static_cast<struct wl_display*
>(
window->get_native_display());
167 auto* wl_surface =
static_cast<struct wl_surface*
>(
window->get_native_handle());
168 if (!wl_display || !wl_surface) {
170 "Cannot create surface: null Wayland display or surface handle");
174 VkWaylandSurfaceCreateInfoKHR info {};
175 info.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
176 info.display = wl_display;
177 info.surface = wl_surface;
179 VkSurfaceKHR c_surface {};
180 if (vkCreateWaylandSurfaceKHR(
182 &info,
nullptr, &c_surface)
185 "Failed to create Wayland Vulkan surface for window '{}'",
186 window->get_create_info().title);
190 vk::SurfaceKHR surface(c_surface);
193 "Wayland surface created for window '{}'",
window->get_create_info().title);
199 "No windowing backend available for surface creation");
208 auto it = std::ranges::find(
m_surfaces, surface);
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
std::weak_ptr< Core::Window > window
vk::SurfaceKHR create_surface(std::shared_ptr< Window > window)
Create surface from window's native handles.
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.
void destroy_surface(vk::SurfaceKHR surface)
Destroy a specific surface Called when window is unregistered.
void cleanup()
Cleanup device resources.
bool initialize(vk::Instance instance, const GraphicsBackendInfo &backend_info)
Select a physical device and create the logical device.
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)
GraphicsBackendInfo backend_info
Graphics backend configuration.
WindowingBackend windowing_backend
Selected windowing backend.
GraphicsApi requested_api
Selected graphics API for rendering.