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) if (GLFW_BUILD_WEBGPU)
target_compile_definitions(glfw PRIVATE _GLFW_BUILD_WEBGPU) target_compile_definitions(glfw PRIVATE _GLFW_BUILD_WEBGPU)
if (APPLE) if (GLFW_BUILD_COCOA)
target_compile_options(glfw PRIVATE -x objective-c) target_compile_options(glfw PRIVATE -x objective-c)
target_link_libraries(glfw PRIVATE "-framework Cocoa" "-framework CoreVideo" "-framework IOKit" "-framework QuartzCore") target_link_libraries(glfw PRIVATE "-framework QuartzCore")
set(glfw_PKG_LIBS "${glfw_PKG_LIBS} -framework QuartzCore")
endif () endif ()
endif () endif ()

View File

@ -1,7 +1,7 @@
//======================================================================== //========================================================================
// GLFW 3.4 - www.glfw.org // 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. // wgpu-native authors.
// Most of the code from this file comes from the wgpu-native triangle example: // 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 // https://github.com/gfx-rs/wgpu-native/blob/master/examples/triangle/main.c
@ -31,129 +31,168 @@
#if defined(_GLFW_BUILD_WEBGPU) #if defined(_GLFW_BUILD_WEBGPU)
#include <webgpu/webgpu.h> #ifdef __EMSCRIPTEN__
# define GLFW_EXPOSE_NATIVE_EMSCRIPTEN
#define WGPU_TARGET_MACOS 1 # ifndef GLFW_PLATFORM_EMSCRIPTEN // not defined in older versions of emscripten
#define WGPU_TARGET_LINUX_X11 2 # define GLFW_PLATFORM_EMSCRIPTEN 0
#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
# endif # 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__
#if WGPU_TARGET == WGPU_TARGET_MACOS #ifdef GLFW_EXPOSE_NATIVE_COCOA
# include <Foundation/Foundation.h> # include <Foundation/Foundation.h>
# include <QuartzCore/CAMetalLayer.h> # include <QuartzCore/CAMetalLayer.h>
#endif #endif
#include <GLFW/glfw3.h> #ifndef __EMSCRIPTEN__
#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> # include <GLFW/glfw3native.h>
#endif
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW public API ////// ////// GLFW public API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
GLFWAPI WGPUSurface glfwCreateWindowWGPUSurface(WGPUInstance instance, GLFWwindow* window) { WGPUSurface glfwCreateWindowWGPUSurface(WGPUInstance instance, GLFWwindow* window) {
#if WGPU_TARGET == WGPU_TARGET_MACOS #ifndef __EMSCRIPTEN__
{ switch (glfwGetPlatform()) {
id metal_layer = NULL; #else
NSWindow* ns_window = glfwGetCocoaWindow(window); // glfwGetPlatform is not available in older versions of emscripten
[ns_window.contentView setWantsLayer : YES]; switch (GLFW_PLATFORM_EMSCRIPTEN) {
metal_layer = [CAMetalLayer layer]; #endif
[ns_window.contentView setLayer : metal_layer];
return wgpuInstanceCreateSurface( #ifdef GLFW_EXPOSE_NATIVE_X11
instance, case GLFW_PLATFORM_X11: {
&(WGPUSurfaceDescriptor){
.label = NULL,
.nextInChain =
(const WGPUChainedStruct*)&(
WGPUSurfaceDescriptorFromMetalLayer) {
.chain = (WGPUChainedStruct){
.next = NULL,
.sType = WGPUSType_SurfaceDescriptorFromMetalLayer,
},
.layer = metal_layer,
},
});
}
#elif WGPU_TARGET == WGPU_TARGET_LINUX_X11
{
Display* x11_display = glfwGetX11Display(); Display* x11_display = glfwGetX11Display();
Window x11_window = glfwGetX11Window(window); Window x11_window = glfwGetX11Window(window);
return wgpuInstanceCreateSurface(
instance, # ifdef WEBGPU_BACKEND_DAWN
&(WGPUSurfaceDescriptor){ WGPUSurfaceSourceXlibWindow fromXlibWindow;
.label = NULL, fromXlibWindow.chain.sType = WGPUSType_SurfaceSourceXlibWindow;
.nextInChain = # else
(const WGPUChainedStruct*)&( WGPUSurfaceDescriptorFromXlibWindow fromXlibWindow;
WGPUSurfaceDescriptorFromXlibWindow) { fromXlibWindow.chain.sType = WGPUSType_SurfaceDescriptorFromXlibWindow;
.chain = (WGPUChainedStruct){ # endif
.next = NULL, fromXlibWindow.chain.next = NULL;
.sType = WGPUSType_SurfaceDescriptorFromXlibWindow, fromXlibWindow.display = x11_display;
}, fromXlibWindow.window = x11_window;
.display = x11_display,
.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_display* wayland_display = glfwGetWaylandDisplay();
struct wl_surface* wayland_surface = glfwGetWaylandWindow(window); struct wl_surface* wayland_surface = glfwGetWaylandWindow(window);
return wgpuInstanceCreateSurface(
instance, # ifdef WEBGPU_BACKEND_DAWN
&(WGPUSurfaceDescriptor){ WGPUSurfaceSourceWaylandSurface fromWaylandSurface;
.label = NULL, fromWaylandSurface.chain.sType = WGPUSType_SurfaceSourceWaylandSurface;
.nextInChain = # else
(const WGPUChainedStruct*)&( WGPUSurfaceDescriptorFromWaylandSurface fromWaylandSurface;
WGPUSurfaceDescriptorFromWaylandSurface) { fromWaylandSurface.chain.sType = WGPUSType_SurfaceDescriptorFromWaylandSurface;
.chain = (WGPUChainedStruct){ # endif
.next = NULL, fromWaylandSurface.chain.next = NULL;
.sType = WGPUSType_SurfaceDescriptorFromWaylandSurface, fromWaylandSurface.display = wayland_display;
}, fromWaylandSurface.surface = wayland_surface;
.display = wayland_display,
.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); HWND hwnd = glfwGetWin32Window(window);
HINSTANCE hinstance = GetModuleHandle(NULL); HINSTANCE hinstance = GetModuleHandle(NULL);
return wgpuInstanceCreateSurface(
instance, # ifdef WEBGPU_BACKEND_DAWN
&(WGPUSurfaceDescriptor){ WGPUSurfaceSourceWindowsHWND fromWindowsHWND;
.label = NULL, fromWindowsHWND.chain.sType = WGPUSType_SurfaceSourceWindowsHWND;
.nextInChain =
(const WGPUChainedStruct*)&(
WGPUSurfaceDescriptorFromWindowsHWND) {
.chain = (WGPUChainedStruct){
.next = NULL,
.sType = WGPUSType_SurfaceDescriptorFromWindowsHWND,
},
.hinstance = hinstance,
.hwnd = hwnd,
},
});
}
# else # else
#error "Unsupported WGPU_TARGET" WGPUSurfaceDescriptorFromWindowsHWND fromWindowsHWND;
fromWindowsHWND.chain.sType = WGPUSType_SurfaceDescriptorFromWindowsHWND;
# endif # 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;
}
}
#endif /* _GLFW_BUILD_WEBGPU */ #endif /* _GLFW_BUILD_WEBGPU */