Implement sdl2+wgpu backend for macos+metal

This commit is contained in:
Nikita Lisitsa 2026-06-30 23:47:25 +03:00
parent c5b8eb4f49
commit 77d359fa52
3 changed files with 42 additions and 3 deletions

View file

@ -3,11 +3,29 @@ find_package(SDL2 REQUIRED)
file(GLOB_RECURSE PSEMEK_SDL2_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "include/*.hpp")
file(GLOB_RECURSE PSEMEK_SDL2_SOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "source/*.cpp")
psemek_add_library(psemek-sdl2 ${PSEMEK_SDL2_HEADERS} ${PSEMEK_SDL2_SOURCES})
set(PSEMEK_SDL2_PLATFORM_SOURCES)
if(APPLE)
file(GLOB_RECURSE PSEMEK_SDL2_PLATFORM_SOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "platform/apple/*.m")
endif()
psemek_add_library(psemek-sdl2 ${PSEMEK_SDL2_HEADERS} ${PSEMEK_SDL2_SOURCES} ${PSEMEK_SDL2_PLATFORM_SOURCES})
target_include_directories(psemek-sdl2 PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(psemek-sdl2 PUBLIC psemek-log psemek-util psemek-audio psemek-app SDL2)
if(PSEMEK_GRAPHICS_API STREQUAL OPENGL)
target_link_libraries(psemek-sdl2 PUBLIC psemek-gfx)
elseif(PSEMEK_GRAPHICS_API STREQUAL WEBGPU)
target_link_libraries(psemek-sdl2 PUBLIC psemek-wgpu)
# TODO: shouldn't these come from SDL2 dependencies?
find_library(FOUNDATION_FRAMEWORK Foundation REQUIRED)
find_library(METAL_FRAMEWORK Metal REQUIRED)
find_library(QUARTZCORE_FRAMEWORK QuartzCore REQUIRED)
target_link_libraries(psemek-sdl2
PUBLIC
psemek-wgpu
PRIVATE
${FOUNDATION_FRAMEWORK}
${METAL_FRAMEWORK}
${QUARTZCORE_FRAMEWORK}
)
endif()

View file

@ -0,0 +1,14 @@
#ifdef __APPLE__
#include <Foundation/Foundation.h>
#include <QuartzCore/CAMetalLayer.h>
#include <Cocoa/Cocoa.h>
void * metal_layer_from_nswindow(void * nswindow_raw)
{
NSWindow * ns_window = (NSWindow*)nswindow_raw;
[ns_window.contentView setWantsLayer : YES];
id metal_layer = [CAMetalLayer layer];
[ns_window.contentView setLayer : metal_layer];
return metal_layer;
}
#endif

View file

@ -10,6 +10,9 @@
#include <psemek/wgpu/instance.hpp>
#include <psemek/wgpu/logging.hpp>
#include <psemek/wgpu/version.hpp>
#ifdef __APPLE__
extern "C" void * metal_layer_from_nswindow(void * nswindow);
#endif
#endif
#include <SDL2/SDL_syswm.h>
@ -86,8 +89,12 @@ namespace psemek::sdl2
wgpu::surface::descriptor surface_descriptor;
#if defined(_WIN32)
surface_descriptor.chain = {wgpu::surface::from_windows_hwnd{ .hinstance = wminfo.info.win.hinstance, .hwnd = wminfo.info.win.window }};
#else
#elif defined(__linux__)
surface_descriptor.chain = {wgpu::surface::from_xlib_window{ .display = wminfo.info.x11.display, .window = wminfo.info.x11.window }};
#elif defined(__APPLE__)
surface_descriptor.chain = {wgpu::surface::from_metal_layer{ .layer = metal_layer_from_nswindow(wminfo.info.cocoa.window) }};
#else
#error Unknown platform
#endif
wgpu_surface_ = wgpu_instance_.create_surface(surface_descriptor);