glfw/src/webgpu.c
2024-09-24 09:05:39 +02:00

199 lines
7.2 KiB
C

//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// 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
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#if defined(_GLFW_BUILD_WEBGPU)
#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
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
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);
# 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);
}
#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);
# 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);
}
#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);
# 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;
}
}
#endif /* _GLFW_BUILD_WEBGPU */