summaryrefslogtreecommitdiff
path: root/third_party/glfw3webgpu
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-01-28 01:10:05 +0100
committerskal <pascal.massimino@gmail.com>2026-01-28 01:10:05 +0100
commit6cd6fb41ed44bd37bd05e5a4abf23661605c00df (patch)
treef3c5fb237b71bc6ad2d67dea62324b2edede51c3 /third_party/glfw3webgpu
parenta7bcf5e9cd6884d010b5cec0146293a0515242fc (diff)
refactor(gpu): Integrate WebGPU via system wgpu-native and glfw3webgpu
Replaces the complex wgpu-native submodule and manual platform-specific surface creation with a system-wide wgpu-native install (via Homebrew) and the glfw3webgpu helper library. - Updates scripts/project_init.sh to fetch glfw3webgpu and ensure wgpu-native is installed. - Refactors CMakeLists.txt to link against the system wgpu-native library. - Simplifies src/platform.cc to use glfwCreateWindowWGPUSurface. - Simplifies src/gpu/gpu.cc to use standard WebGPU headers. - Updates FETCH_DEPS.md with new installation instructions. - Updates PROJECT_CONTEXT.md with the new integration strategy.
Diffstat (limited to 'third_party/glfw3webgpu')
-rw-r--r--third_party/glfw3webgpu/glfw3webgpu.c181
-rw-r--r--third_party/glfw3webgpu/glfw3webgpu.h62
2 files changed, 243 insertions, 0 deletions
diff --git a/third_party/glfw3webgpu/glfw3webgpu.c b/third_party/glfw3webgpu/glfw3webgpu.c
new file mode 100644
index 0000000..27bf9ec
--- /dev/null
+++ b/third_party/glfw3webgpu/glfw3webgpu.c
@@ -0,0 +1,181 @@
+/**
+ * This is an extension of GLFW for WebGPU, abstracting away the details of
+ * OS-specific operations.
+ *
+ * This file is part of the "Learn WebGPU for C++" book.
+ * https://eliemichel.github.io/LearnWebGPU
+ *
+ * Most of this code comes from the wgpu-native triangle example:
+ * https://github.com/gfx-rs/wgpu-native/blob/master/examples/triangle/main.c
+ *
+ * MIT License
+ * Copyright (c) 2022-2025 Elie Michel and the wgpu-native authors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "glfw3webgpu.h"
+
+#include <webgpu.h>
+
+#include <GLFW/glfw3.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__
+
+#ifdef GLFW_EXPOSE_NATIVE_COCOA
+# include <Foundation/Foundation.h>
+# include <QuartzCore/CAMetalLayer.h>
+#endif
+
+#ifndef __EMSCRIPTEN__
+# include <GLFW/glfw3native.h>
+#endif
+
+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);
+
+ WGPUSurfaceSourceXlibWindow fromXlibWindow;
+ fromXlibWindow.chain.sType = WGPUSType_SurfaceSourceXlibWindow;
+ fromXlibWindow.chain.next = NULL;
+ fromXlibWindow.display = x11_display;
+ fromXlibWindow.window = x11_window;
+
+ WGPUSurfaceDescriptor surfaceDescriptor;
+ surfaceDescriptor.nextInChain = &fromXlibWindow.chain;
+ surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN };
+
+ return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
+ }
+#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);
+
+ WGPUSurfaceSourceWaylandSurface fromWaylandSurface;
+ fromWaylandSurface.chain.sType = WGPUSType_SurfaceSourceWaylandSurface;
+ fromWaylandSurface.chain.next = NULL;
+ fromWaylandSurface.display = wayland_display;
+ fromWaylandSurface.surface = wayland_surface;
+
+ WGPUSurfaceDescriptor surfaceDescriptor;
+ surfaceDescriptor.nextInChain = &fromWaylandSurface.chain;
+ surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN };
+
+ return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
+ }
+#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] ;
+
+ WGPUSurfaceSourceMetalLayer fromMetalLayer;
+ fromMetalLayer.chain.sType = WGPUSType_SurfaceSourceMetalLayer;
+ fromMetalLayer.chain.next = NULL;
+ fromMetalLayer.layer = metal_layer;
+
+ WGPUSurfaceDescriptor surfaceDescriptor;
+ surfaceDescriptor.nextInChain = &fromMetalLayer.chain;
+ surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN };
+
+ 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);
+
+ WGPUSurfaceSourceWindowsHWND fromWindowsHWND;
+ fromWindowsHWND.chain.sType = WGPUSType_SurfaceSourceWindowsHWND;
+ fromWindowsHWND.chain.next = NULL;
+ fromWindowsHWND.hinstance = hinstance;
+ fromWindowsHWND.hwnd = hwnd;
+
+ WGPUSurfaceDescriptor surfaceDescriptor;
+ surfaceDescriptor.nextInChain = &fromWindowsHWND.chain;
+ surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN };
+
+ return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
+ }
+#endif // GLFW_EXPOSE_NATIVE_WIN32
+
+#ifdef GLFW_EXPOSE_NATIVE_EMSCRIPTEN
+ case GLFW_PLATFORM_EMSCRIPTEN: {
+# ifdef WEBGPU_BACKEND_EMDAWNWEBGPU
+ WGPUEmscriptenSurfaceSourceCanvasHTMLSelector fromCanvasHTMLSelector;
+ fromCanvasHTMLSelector.chain.sType = WGPUSType_EmscriptenSurfaceSourceCanvasHTMLSelector;
+ fromCanvasHTMLSelector.selector = (WGPUStringView){ "canvas", WGPU_STRLEN };
+# else
+ WGPUSurfaceDescriptorFromCanvasHTMLSelector fromCanvasHTMLSelector;
+ fromCanvasHTMLSelector.chain.sType = WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector;
+ fromCanvasHTMLSelector.selector = "canvas";
+# endif
+ fromCanvasHTMLSelector.chain.next = NULL;
+
+ WGPUSurfaceDescriptor surfaceDescriptor;
+ surfaceDescriptor.nextInChain = &fromCanvasHTMLSelector.chain;
+# ifdef WEBGPU_BACKEND_EMDAWNWEBGPU
+ surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN };
+# else
+ surfaceDescriptor.label = NULL;
+# endif
+ return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
+ }
+#endif // GLFW_EXPOSE_NATIVE_EMSCRIPTEN
+
+ default:
+ // Unsupported platform
+ return NULL;
+ }
+}
diff --git a/third_party/glfw3webgpu/glfw3webgpu.h b/third_party/glfw3webgpu/glfw3webgpu.h
new file mode 100644
index 0000000..729afcc
--- /dev/null
+++ b/third_party/glfw3webgpu/glfw3webgpu.h
@@ -0,0 +1,62 @@
+/**
+ * This is an extension of GLFW for WebGPU, abstracting away the details of
+ * OS-specific operations.
+ *
+ * This file is part of the "Learn WebGPU for C++" book.
+ * https://eliemichel.github.io/LearnWebGPU
+ *
+ * MIT License
+ * Copyright (c) 2022-2024 Elie Michel and the wgpu-native authors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _glfw3_webgpu_h_
+#define _glfw3_webgpu_h_
+
+#include <webgpu.h>
+#include <GLFW/glfw3.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*! @brief Creates a WebGPU surface for the specified window.
+ *
+ * This function creates a WGPUSurface object for the specified window.
+ *
+ * If the surface cannot be created, this function returns `NULL`.
+ *
+ * It is the responsibility of the caller to destroy the window surface. The
+ * window surface must be destroyed using `wgpuSurfaceRelease`.
+ *
+ * @param[in] instance The WebGPU instance to create the surface in.
+ * @param[in] window The window to create the surface for.
+ * @return The handle of the surface. This is set to `NULL` if an error
+ * occurred.
+ *
+ * @ingroup webgpu
+ */
+WGPUSurface glfwCreateWindowWGPUSurface(WGPUInstance instance, GLFWwindow* window);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _glfw3_webgpu_h_