Upgrade to runtime backend switch and new Dawn

This commit is contained in:
Elie Michel 2024-09-24 09:05:39 +02:00
parent 6cbd003914
commit 26a8ef471a
2 changed files with 150 additions and 110 deletions

View File

@ -291,9 +291,10 @@ endif()
if (GLFW_BUILD_WEBGPU)
target_compile_definitions(glfw PRIVATE _GLFW_BUILD_WEBGPU)
if (APPLE)
target_compile_options(glfw PRIVATE -x objective-c)
target_link_libraries(glfw PRIVATE "-framework Cocoa" "-framework CoreVideo" "-framework IOKit" "-framework QuartzCore")
if (GLFW_BUILD_COCOA)
target_compile_options(glfw PRIVATE -x objective-c)
target_link_libraries(glfw PRIVATE "-framework QuartzCore")
set(glfw_PKG_LIBS "${glfw_PKG_LIBS} -framework QuartzCore")
endif ()
endif ()

View File

@ -1,7 +1,7 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2022-2023 Elie Michel <eliemichelfr@gmail.com> and the
// Copyright (c) 2022-2024 Elie Michel <eliemichelfr@gmail.com> and the
// wgpu-native authors.
// Most of the code from this file comes from the wgpu-native triangle example:
// https://github.com/gfx-rs/wgpu-native/blob/master/examples/triangle/main.c
@ -31,129 +31,168 @@
#if defined(_GLFW_BUILD_WEBGPU)
#include <webgpu/webgpu.h>
#ifdef __EMSCRIPTEN__
# define GLFW_EXPOSE_NATIVE_EMSCRIPTEN
# ifndef GLFW_PLATFORM_EMSCRIPTEN // not defined in older versions of emscripten
# define GLFW_PLATFORM_EMSCRIPTEN 0
# endif
#else // __EMSCRIPTEN__
# ifdef _GLFW_X11
# define GLFW_EXPOSE_NATIVE_X11
# endif
# ifdef _GLFW_WAYLAND
# define GLFW_EXPOSE_NATIVE_WAYLAND
# endif
# ifdef _GLFW_COCOA
# define GLFW_EXPOSE_NATIVE_COCOA
# endif
# ifdef _GLFW_WIN32
# define GLFW_EXPOSE_NATIVE_WIN32
# endif
#endif // __EMSCRIPTEN__
#define WGPU_TARGET_MACOS 1
#define WGPU_TARGET_LINUX_X11 2
#define WGPU_TARGET_WINDOWS 3
#define WGPU_TARGET_LINUX_WAYLAND 4
#if defined(_WIN32)
#define WGPU_TARGET WGPU_TARGET_WINDOWS
#elif defined(__APPLE__)
#define WGPU_TARGET WGPU_TARGET_MACOS
#elif defined(_GLFW_WAYLAND)
#define WGPU_TARGET WGPU_TARGET_LINUX_WAYLAND
#else
#define WGPU_TARGET WGPU_TARGET_LINUX_X11
#ifdef GLFW_EXPOSE_NATIVE_COCOA
# include <Foundation/Foundation.h>
# include <QuartzCore/CAMetalLayer.h>
#endif
#if WGPU_TARGET == WGPU_TARGET_MACOS
#include <Foundation/Foundation.h>
#include <QuartzCore/CAMetalLayer.h>
#ifndef __EMSCRIPTEN__
# include <GLFW/glfw3native.h>
#endif
#include <GLFW/glfw3.h>
#if WGPU_TARGET == WGPU_TARGET_MACOS
#define GLFW_EXPOSE_NATIVE_COCOA
#elif WGPU_TARGET == WGPU_TARGET_LINUX_X11
#define GLFW_EXPOSE_NATIVE_X11
#elif WGPU_TARGET == WGPU_TARGET_LINUX_WAYLAND
#define GLFW_EXPOSE_NATIVE_WAYLAND
#elif WGPU_TARGET == WGPU_TARGET_WINDOWS
#define GLFW_EXPOSE_NATIVE_WIN32
#endif
#include <GLFW/glfw3native.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI WGPUSurface glfwCreateWindowWGPUSurface(WGPUInstance instance, GLFWwindow* window) {
#if WGPU_TARGET == WGPU_TARGET_MACOS
{
id metal_layer = NULL;
NSWindow* ns_window = glfwGetCocoaWindow(window);
[ns_window.contentView setWantsLayer : YES];
metal_layer = [CAMetalLayer layer];
[ns_window.contentView setLayer : metal_layer];
return wgpuInstanceCreateSurface(
instance,
&(WGPUSurfaceDescriptor){
.label = NULL,
.nextInChain =
(const WGPUChainedStruct*)&(
WGPUSurfaceDescriptorFromMetalLayer) {
.chain = (WGPUChainedStruct){
.next = NULL,
.sType = WGPUSType_SurfaceDescriptorFromMetalLayer,
},
.layer = metal_layer,
},
});
}
#elif WGPU_TARGET == WGPU_TARGET_LINUX_X11
{
WGPUSurface glfwCreateWindowWGPUSurface(WGPUInstance instance, GLFWwindow* window) {
#ifndef __EMSCRIPTEN__
switch (glfwGetPlatform()) {
#else
// glfwGetPlatform is not available in older versions of emscripten
switch (GLFW_PLATFORM_EMSCRIPTEN) {
#endif
#ifdef GLFW_EXPOSE_NATIVE_X11
case GLFW_PLATFORM_X11: {
Display* x11_display = glfwGetX11Display();
Window x11_window = glfwGetX11Window(window);
return wgpuInstanceCreateSurface(
instance,
&(WGPUSurfaceDescriptor){
.label = NULL,
.nextInChain =
(const WGPUChainedStruct*)&(
WGPUSurfaceDescriptorFromXlibWindow) {
.chain = (WGPUChainedStruct){
.next = NULL,
.sType = WGPUSType_SurfaceDescriptorFromXlibWindow,
},
.display = x11_display,
.window = x11_window,
},
});
# ifdef WEBGPU_BACKEND_DAWN
WGPUSurfaceSourceXlibWindow fromXlibWindow;
fromXlibWindow.chain.sType = WGPUSType_SurfaceSourceXlibWindow;
# else
WGPUSurfaceDescriptorFromXlibWindow fromXlibWindow;
fromXlibWindow.chain.sType = WGPUSType_SurfaceDescriptorFromXlibWindow;
# endif
fromXlibWindow.chain.next = NULL;
fromXlibWindow.display = x11_display;
fromXlibWindow.window = x11_window;
WGPUSurfaceDescriptor surfaceDescriptor;
surfaceDescriptor.nextInChain = &fromXlibWindow.chain;
surfaceDescriptor.label = NULL;
return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
}
#elif WGPU_TARGET == WGPU_TARGET_LINUX_WAYLAND
{
#endif // GLFW_EXPOSE_NATIVE_X11
#ifdef GLFW_EXPOSE_NATIVE_WAYLAND
case GLFW_PLATFORM_WAYLAND: {
struct wl_display* wayland_display = glfwGetWaylandDisplay();
struct wl_surface* wayland_surface = glfwGetWaylandWindow(window);
return wgpuInstanceCreateSurface(
instance,
&(WGPUSurfaceDescriptor){
.label = NULL,
.nextInChain =
(const WGPUChainedStruct*)&(
WGPUSurfaceDescriptorFromWaylandSurface) {
.chain = (WGPUChainedStruct){
.next = NULL,
.sType = WGPUSType_SurfaceDescriptorFromWaylandSurface,
},
.display = wayland_display,
.surface = wayland_surface,
},
});
# ifdef WEBGPU_BACKEND_DAWN
WGPUSurfaceSourceWaylandSurface fromWaylandSurface;
fromWaylandSurface.chain.sType = WGPUSType_SurfaceSourceWaylandSurface;
# else
WGPUSurfaceDescriptorFromWaylandSurface fromWaylandSurface;
fromWaylandSurface.chain.sType = WGPUSType_SurfaceDescriptorFromWaylandSurface;
# endif
fromWaylandSurface.chain.next = NULL;
fromWaylandSurface.display = wayland_display;
fromWaylandSurface.surface = wayland_surface;
WGPUSurfaceDescriptor surfaceDescriptor;
surfaceDescriptor.nextInChain = &fromWaylandSurface.chain;
surfaceDescriptor.label = NULL;
return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
}
#elif WGPU_TARGET == WGPU_TARGET_WINDOWS
{
#endif // GLFW_EXPOSE_NATIVE_WAYLAND
#ifdef GLFW_EXPOSE_NATIVE_COCOA
case GLFW_PLATFORM_COCOA: {
id metal_layer = [CAMetalLayer layer];
NSWindow* ns_window = glfwGetCocoaWindow(window);
[ns_window.contentView setWantsLayer : YES] ;
[ns_window.contentView setLayer : metal_layer] ;
# ifdef WEBGPU_BACKEND_DAWN
WGPUSurfaceSourceMetalLayer fromMetalLayer;
fromMetalLayer.chain.sType = WGPUSType_SurfaceSourceMetalLayer;
# else
WGPUSurfaceDescriptorFromMetalLayer fromMetalLayer;
fromMetalLayer.chain.sType = WGPUSType_SurfaceDescriptorFromMetalLayer;
# endif
fromMetalLayer.chain.next = NULL;
fromMetalLayer.layer = metal_layer;
WGPUSurfaceDescriptor surfaceDescriptor;
surfaceDescriptor.nextInChain = &fromMetalLayer.chain;
surfaceDescriptor.label = NULL;
return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
}
#endif // GLFW_EXPOSE_NATIVE_COCOA
#ifdef GLFW_EXPOSE_NATIVE_WIN32
case GLFW_PLATFORM_WIN32: {
HWND hwnd = glfwGetWin32Window(window);
HINSTANCE hinstance = GetModuleHandle(NULL);
return wgpuInstanceCreateSurface(
instance,
&(WGPUSurfaceDescriptor){
.label = NULL,
.nextInChain =
(const WGPUChainedStruct*)&(
WGPUSurfaceDescriptorFromWindowsHWND) {
.chain = (WGPUChainedStruct){
.next = NULL,
.sType = WGPUSType_SurfaceDescriptorFromWindowsHWND,
},
.hinstance = hinstance,
.hwnd = hwnd,
},
});
# ifdef WEBGPU_BACKEND_DAWN
WGPUSurfaceSourceWindowsHWND fromWindowsHWND;
fromWindowsHWND.chain.sType = WGPUSType_SurfaceSourceWindowsHWND;
# else
WGPUSurfaceDescriptorFromWindowsHWND fromWindowsHWND;
fromWindowsHWND.chain.sType = WGPUSType_SurfaceDescriptorFromWindowsHWND;
# endif
fromWindowsHWND.chain.next = NULL;
fromWindowsHWND.hinstance = hinstance;
fromWindowsHWND.hwnd = hwnd;
WGPUSurfaceDescriptor surfaceDescriptor;
surfaceDescriptor.nextInChain = &fromWindowsHWND.chain;
surfaceDescriptor.label = NULL;
return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
}
#endif // GLFW_EXPOSE_NATIVE_X11
#ifdef GLFW_EXPOSE_NATIVE_EMSCRIPTEN
case GLFW_PLATFORM_EMSCRIPTEN: {
# ifdef WEBGPU_BACKEND_DAWN
WGPUSurfaceSourceCanvasHTMLSelector_Emscripten fromCanvasHTMLSelector;
fromCanvasHTMLSelector.chain.sType = WGPUSType_SurfaceSourceCanvasHTMLSelector_Emscripten;
# else
WGPUSurfaceDescriptorFromCanvasHTMLSelector fromCanvasHTMLSelector;
fromCanvasHTMLSelector.chain.sType = WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector;
# endif
fromCanvasHTMLSelector.chain.next = NULL;
fromCanvasHTMLSelector.selector = "canvas";
WGPUSurfaceDescriptor surfaceDescriptor;
surfaceDescriptor.nextInChain = &fromCanvasHTMLSelector.chain;
surfaceDescriptor.label = NULL;
return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
}
#endif // GLFW_EXPOSE_NATIVE_X11
default:
// Unsupported platform
return NULL;
}
#else
#error "Unsupported WGPU_TARGET"
#endif
}
#endif /* _GLFW_BUILD_WEBGPU */