Compare commits

...

6 Commits

Author SHA1 Message Date
Elie Michel
a08faf113b
Merge 26a8ef471a into 63a7e8b7f8 2025-08-21 08:42:14 +02:00
Camilla Löwy
63a7e8b7f8 Add and update Wayland-specific notes in docs
Fixes #2746
2025-08-20 20:13:07 +02:00
Elie Michel
26a8ef471a Upgrade to runtime backend switch and new Dawn 2024-09-24 09:05:39 +02:00
Elie Michel
6cbd003914
Merge branch 'master' into webgpu 2024-02-18 13:10:25 +01:00
Elie Michel
a2f8d94a7b Minor coding style changes 2023-10-08 10:23:37 +02:00
Elie Michel
1ae5376a31 Add glfwCreateWindowWGPUSurface 2023-05-03 09:35:25 +02:00
7 changed files with 284 additions and 23 deletions

View File

@ -33,6 +33,7 @@ cmake_dependent_option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on
"WIN32" OFF)
cmake_dependent_option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON
"MSVC" OFF)
option(GLFW_BUILD_WEBGPU "Build support for WebGPU" OFF)
set(GLFW_LIBRARY_TYPE "${GLFW_LIBRARY_TYPE}" CACHE STRING
"Library type override for GLFW (SHARED, STATIC, OBJECT, or empty to follow BUILD_SHARED_LIBS)")
@ -66,6 +67,9 @@ endif()
if (GLFW_BUILD_X11)
message(STATUS "Including X11 support")
endif()
if (GLFW_BUILD_WEBGPU)
message(STATUS "Including WebGPU support")
endif()
#--------------------------------------------------------------------
# Apply Microsoft C runtime library option

View File

@ -55,6 +55,7 @@ video tutorials.
- Jason Daly
- danhambleton
- Jarrod Davis
- decce
- Olivier Delannoy
- Paul R. Deppe
- Michael Dickens

View File

@ -255,3 +255,7 @@ hardware gamma correction, which today is typically an approximation of sRGB
gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will
produce the default (usually sRGB-like) behavior.
@note @wayland An application cannot read or modify the monitor gamma ramp. The
@ref glfwGetGammaRamp, @ref glfwSetGammaRamp and @ref glfwSetGamma functions
emit @ref GLFW_FEATURE_UNAVAILABLE.

View File

@ -893,6 +893,12 @@ int xpos, ypos;
glfwGetWindowPos(window, &xpos, &ypos);
```
@note @wayland An applications cannot know the positions of its windows or
whether one has been moved. The @ref GLFW_POSITION_X and @ref GLFW_POSITION_Y
window hints are ignored. The @ref glfwGetWindowPos and @ref glfwSetWindowPos
functions emit @ref GLFW_FEATURE_UNAVAILABLE. The window position callback will
not be called.
### Window title {#window_title}
@ -1038,6 +1044,12 @@ You can also get the current iconification state with @ref glfwGetWindowAttrib.
int iconified = glfwGetWindowAttrib(window, GLFW_ICONIFIED);
```
@note @wayland An application cannot know if any of its windows have been
iconified or restore one from iconification. The @ref glfwRestoreWindow
function can only restore windows from maximization and the iconify callback
will not be called. The [GLFW_ICONIFIED](@ref GLFW_ICONIFIED_attrib) attribute
will be false. The @ref glfwIconifyWindow function works normally.
### Window maximization {#window_maximize}

View File

@ -247,6 +247,10 @@ extern "C" {
#endif /* OpenGL and OpenGL ES headers */
#if defined(GLFW_INCLUDE_WEBGPU)
#include <webgpu/webgpu.h>
#endif /* webgpu header */
#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL)
/* GLFW_DLL must be defined by applications that are linking against the DLL
* version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW
@ -2915,8 +2919,8 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_INVALID_VALUE,
* @ref GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
*
* @remark @wayland Gamma handling is a privileged protocol, this function
* will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
* @remark @wayland Monitor gamma is a privileged protocol, so this function
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
*
* @thread_safety This function must only be called from the main thread.
*
@ -2939,8 +2943,8 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR
* and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
*
* @remark @wayland Gamma handling is a privileged protocol, this function
* will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while
* @remark @wayland Monitor gamma is a privileged protocol, so this function
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while
* returning `NULL`.
*
* @pointer_lifetime The returned structure and its arrays are allocated and
@ -2983,8 +2987,8 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
*
* @remark @win32 The gamma ramp size must be 256.
*
* @remark @wayland Gamma handling is a privileged protocol, this function
* will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
* @remark @wayland Monitor gamma is a privileged protocol, so this function
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
*
* @pointer_lifetime The specified gamma ramp is copied before this function
* returns.
@ -3430,8 +3434,8 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* i
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
*
* @remark @wayland There is no way for an application to retrieve the global
* position of its windows. This function will emit @ref
* @remark @wayland Window positions are not currently part of any common
* Wayland protocol, so this function cannot be implemented and will emit @ref
* GLFW_FEATURE_UNAVAILABLE.
*
* @thread_safety This function must only be called from the main thread.
@ -3464,8 +3468,8 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
*
* @remark @wayland There is no way for an application to set the global
* position of its windows. This function will emit @ref
* @remark @wayland Window positions are not currently part of any common
* Wayland protocol, so this function cannot be implemented and will emit @ref
* GLFW_FEATURE_UNAVAILABLE.
*
* @thread_safety This function must only be called from the main thread.
@ -3807,10 +3811,6 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark @wayland Once a window is iconified, @ref glfwRestoreWindow wont
* be able to restore it. This is a design decision of the xdg-shell
* protocol.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_iconify
@ -3838,6 +3838,10 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark @wayland Restoring a window from maximization is not currently part
* of any common Wayland protocol, so this function can only restore windows
* from maximization.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_iconify
@ -4058,8 +4062,8 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
* affected by any resizing or mode switching, although you may need to update
* your viewport if the framebuffer size has changed.
*
* @remark @wayland The desired window position is ignored, as there is no way
* for an application to set this property.
* @remark @wayland Window positions are not currently part of any common
* Wayland protocol. The window position arguments are ignored.
*
* @thread_safety This function must only be called from the main thread.
*
@ -4096,8 +4100,9 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int
* errors. However, this function should not fail as long as it is passed
* valid arguments and the library has been [initialized](@ref intro_init).
*
* @remark @wayland The Wayland protocol provides no way to check whether a
* window is iconfied, so @ref GLFW_ICONIFIED always returns `GLFW_FALSE`.
* @remark @wayland Checking whether a window is iconified is not currently
* part of any common Wayland protocol, so the @ref GLFW_ICONIFIED attribute
* cannot be implemented and is always `GLFW_FALSE`.
*
* @thread_safety This function must only be called from the main thread.
*
@ -4219,8 +4224,8 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remark @wayland This callback will never be called, as there is no way for
* an application to know its global position.
* @remark @wayland This callback will not be called. The Wayland protocol
* provides no way to be notified of when a window is moved.
*
* @thread_safety This function must only be called from the main thread.
*
@ -4395,6 +4400,10 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remark @wayland This callback will not be called. The Wayland protocol
* provides no way to be notified of when a window is iconified, and no way to
* check whether a window is currently iconified.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_iconify
@ -6525,6 +6534,29 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window
#endif /*VK_VERSION_1_0*/
#if defined(WEBGPU_H_)
/*! @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.
*
* @since Added in version 3.4.
*
* @ingroup webgpu
*/
GLFWAPI WGPUSurface glfwCreateWindowWGPUSurface(WGPUInstance instance, GLFWwindow* window);
#endif /* WEBGPU_H_ */
/*************************************************************************
* Global definition cleanup

View File

@ -3,9 +3,10 @@ add_library(glfw ${GLFW_LIBRARY_TYPE}
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h"
internal.h platform.h mappings.h
context.c init.c input.c monitor.c platform.c vulkan.c window.c
egl_context.c osmesa_context.c null_platform.h null_joystick.h
null_init.c null_monitor.c null_window.c null_joystick.c)
context.c init.c input.c monitor.c platform.c vulkan.c webgpu.c
window.c egl_context.c osmesa_context.c null_platform.h
null_joystick.h null_init.c null_monitor.c null_window.c
null_joystick.c)
# The time, thread and module code is shared between all backends on a given OS,
# including the null backend, which still needs those bits to be functional
@ -265,6 +266,15 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_compile_definitions(glfw PRIVATE _DEFAULT_SOURCE)
endif()
if (GLFW_BUILD_WEBGPU)
target_compile_definitions(glfw PRIVATE _GLFW_BUILD_WEBGPU)
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 ()
if (GLFW_BUILD_SHARED_LIBRARY)
if (WIN32)
if (MINGW)

198
src/webgpu.c Normal file
View File

@ -0,0 +1,198 @@
//========================================================================
// 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 */