Examples: WebGPU: moved CreateWGPUSurface to the bottom of the file due to interference with X.h. (#8381)

This commit is contained in:
BrutPitt
2025-11-01 10:41:59 +01:00
committed by ocornut
parent 8e5e79054e
commit df3f2fff88
3 changed files with 185 additions and 186 deletions

View File

@@ -40,7 +40,8 @@ static int wgpu_surface_width = 1280;
static int wgpu_surface_height = 800;
// Forward declarations
static bool InitWGPU(GLFWwindow* window);
static bool InitWGPU(GLFWwindow* window);
static WGPUSurface CreateWGPUSurface(const WGPUInstance& instance, GLFWwindow* window);
static void glfw_error_callback(int error, const char* description)
{
@@ -290,80 +291,6 @@ int main(int, char**)
return 0;
}
// GLFW helper to create a WebGPU surface, used only in WGPU-Native. DAWN-Native already has a built-in function
// As of today (2025/10) there is no "official" support in GLFW to create a surface for WebGPU backend
// This stub uses "low level" GLFW calls to acquire information from a specific Window Manager.
// Currently supported platforms: Windows / Linux (X11 and Wayland) / MacOS. Not necessary nor available with EMSCRIPTEN.
#if !defined(__EMSCRIPTEN__) && (defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) || defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN))
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
#define GLFW_HAS_X11_OR_WAYLAND 1
#else
#define GLFW_HAS_X11_OR_WAYLAND 0
#endif
#ifdef _WIN32
#undef APIENTRY
#ifndef GLFW_EXPOSE_NATIVE_WIN32 // for glfwGetWin32Window()
#define GLFW_EXPOSE_NATIVE_WIN32
#endif
#elif defined(__APPLE__)
#ifndef GLFW_EXPOSE_NATIVE_COCOA // for glfwGetCocoaWindow()
#define GLFW_EXPOSE_NATIVE_COCOA
#endif
#elif GLFW_HAS_X11_OR_WAYLAND
#ifndef GLFW_EXPOSE_NATIVE_X11 // for glfwGetX11Display(), glfwGetX11Window() on Freedesktop (Linux, BSD, etc.)
#define GLFW_EXPOSE_NATIVE_X11
#endif
#ifndef GLFW_EXPOSE_NATIVE_WAYLAND
#if defined(__has_include) && __has_include(<wayland-client.h>)
#define GLFW_EXPOSE_NATIVE_WAYLAND
#endif
#endif
#endif
#include <GLFW/glfw3native.h>
#undef Status // X11 headers are leaking this.
#undef Success // X11 headers are leaking this.
WGPUSurface CreateWGPUSurface(const WGPUInstance& instance, GLFWwindow* window)
{
ImGui_ImplWGPU_CreateSurfaceInfo create_info = {};
create_info.Instance = instance;
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
{
create_info.System = "cocoa";
create_info.RawWindow = (void*)glfwGetCocoaWindow(window);
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND)
{
create_info.System = "wayland";
create_info.RawDisplay = (void*)glfwGetWaylandDisplay();
create_info.RawSurface = (void*)glfwGetWaylandWindow(window);
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#elif defined(GLFW_EXPOSE_NATIVE_X11)
if (glfwGetPlatform() == GLFW_PLATFORM_X11)
{
create_info.System = "x11";
create_info.RawWindow = (void*)glfwGetX11Window(window);
create_info.RawDisplay = (void*)glfwGetX11Display();
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#elif defined(GLFW_EXPOSE_NATIVE_WIN32)
{
create_info.System = "win32";
create_info.RawWindow = (void*)glfwGetWin32Window(window);
create_info.RawInstance = (void*)::GetModuleHandle(NULL);
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#else
#error "Unsupported WebGPU native platform!"
#endif
return nullptr;
}
#endif
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
static WGPUAdapter RequestAdapter(wgpu::Instance& instance)
{
@@ -574,3 +501,76 @@ static bool InitWGPU(GLFWwindow* window)
return true;
}
// GLFW helper to create a WebGPU surface, used only in WGPU-Native. DAWN-Native already has a built-in function
// As of today (2025/10) there is no "official" support in GLFW to create a surface for WebGPU backend
// This stub uses "low level" GLFW calls to acquire information from a specific Window Manager.
// Currently supported platforms: Windows / Linux (X11 and Wayland) / MacOS. Not necessary nor available with EMSCRIPTEN.
#if !defined(__EMSCRIPTEN__) && (defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) || defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN))
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
#define GLFW_HAS_X11_OR_WAYLAND 1
#else
#define GLFW_HAS_X11_OR_WAYLAND 0
#endif
#ifdef _WIN32
#undef APIENTRY
#ifndef GLFW_EXPOSE_NATIVE_WIN32 // for glfwGetWin32Window()
#define GLFW_EXPOSE_NATIVE_WIN32
#endif
#elif defined(__APPLE__)
#ifndef GLFW_EXPOSE_NATIVE_COCOA // for glfwGetCocoaWindow()
#define GLFW_EXPOSE_NATIVE_COCOA
#endif
#elif GLFW_HAS_X11_OR_WAYLAND
#ifndef GLFW_EXPOSE_NATIVE_X11 // for glfwGetX11Display(), glfwGetX11Window() on Freedesktop (Linux, BSD, etc.)
#define GLFW_EXPOSE_NATIVE_X11
#endif
#ifndef GLFW_EXPOSE_NATIVE_WAYLAND
#if defined(__has_include) && __has_include(<wayland-client.h>)
#define GLFW_EXPOSE_NATIVE_WAYLAND
#endif
#endif
#endif
#include <GLFW/glfw3native.h>
#undef Status // X11 headers are leaking this and also 'Success', 'Always', 'None', all used in DAWN api. Add #undef if necessary.
WGPUSurface CreateWGPUSurface(const WGPUInstance& instance, GLFWwindow* window)
{
ImGui_ImplWGPU_CreateSurfaceInfo create_info = {};
create_info.Instance = instance;
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
{
create_info.System = "cocoa";
create_info.RawWindow = (void*)glfwGetCocoaWindow(window);
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND)
{
create_info.System = "wayland";
create_info.RawDisplay = (void*)glfwGetWaylandDisplay();
create_info.RawSurface = (void*)glfwGetWaylandWindow(window);
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#elif defined(GLFW_EXPOSE_NATIVE_X11)
if (glfwGetPlatform() == GLFW_PLATFORM_X11)
{
create_info.System = "x11";
create_info.RawWindow = (void*)glfwGetX11Window(window);
create_info.RawDisplay = (void*)glfwGetX11Display();
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#elif defined(GLFW_EXPOSE_NATIVE_WIN32)
{
create_info.System = "win32";
create_info.RawWindow = (void*)glfwGetWin32Window(window);
create_info.RawInstance = (void*)::GetModuleHandle(NULL);
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#else
#error "Unsupported WebGPU native platform!"
#endif
return nullptr;
}
#endif

View File

@@ -24,7 +24,6 @@
#include "../libs/emscripten/emscripten_mainloop_stub.h"
#endif
#include <webgpu/webgpu.h>
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
#include <webgpu/webgpu_cpp.h>
#endif
@@ -40,6 +39,7 @@ static int wgpu_surface_height = 800;
// Forward declarations
static bool InitWGPU(SDL_Window* window);
WGPUSurface CreateWGPUSurface(const WGPUInstance& instance, SDL_Window* window);
static void ResizeSurface(int width, int height)
{
@@ -275,60 +275,6 @@ int main(int, char**)
return 0;
}
// SDL2 helper to create a WebGPU surface (exclusively!) for Native/Desktop applications: available only together with WebGPU/WGPU backend
// As of today (2025/10/31) there is no "official" support in SDL2 to create a surface for WebGPU backend.
// This stub uses "low level" SDL2 calls to acquire information from a specific Window Manager.
// Currently supported platforms: Windows / Linux (X11 and Wayland) / MacOS. Not necessary nor available with EMSCRIPTEN.
#if !defined(__EMSCRIPTEN__) && (defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) || defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN))
#include <SDL_syswm.h>
#undef Status // X11 headers are leaking this.
#undef Success // X11 headers are leaking this.
WGPUSurface CreateWGPUSurface(const WGPUInstance& instance, SDL_Window* window)
{
SDL_SysWMinfo sysWMInfo;
SDL_VERSION(&sysWMInfo.version);
SDL_GetWindowWMInfo(window, &sysWMInfo);
ImGui_ImplWGPU_CreateSurfaceInfo create_info = {};
create_info.Instance = instance;
#if defined(SDL_VIDEO_DRIVER_COCOA)
{
create_info.System = "cocoa";
create_info.RawWindow = (void*)sysWMInfo.info.cocoa.window;
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#elif defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_X11)
const char* sdl_driver = SDL_GetCurrentVideoDriver();
if (sdl_driver && strcmp(sdl_driver, "wayland") == 0)
{
create_info.System = "wayland";
create_info.RawDisplay = (void*)sysWMInfo.info.wl.display;
create_info.RawSurface = (void*)sysWMInfo.info.wl.surface;
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
else
{
create_info.System = "x11";
create_info.RawWindow = (void*)sysWMInfo.info.x11.window;
create_info.RawDisplay = (void*)sysWMInfo.info.x11.display;
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#elif defined(SDL_VIDEO_DRIVER_WINDOWS)
{
create_info.System = "win32";
create_info.RawWindow = (void*)sysWMInfo.info.win.window;
create_info.RawInstance = (void*)sysWMInfo.info.win.hinstance;
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#else
#error "Unsupported WebGPU native platform!"
#endif
return nullptr;
}
#endif
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
static WGPUAdapter RequestAdapter(wgpu::Instance& instance)
{
@@ -540,3 +486,56 @@ static bool InitWGPU(SDL_Window* window)
return true;
}
// SDL2 helper to create a WebGPU surface (exclusively!) for Native/Desktop applications: available only together with WebGPU/WGPU backend
// As of today (2025/10/31) there is no "official" support in SDL2 to create a surface for WebGPU backend.
// This stub uses "low level" SDL2 calls to acquire information from a specific Window Manager.
// Currently supported platforms: Windows / Linux (X11 and Wayland) / MacOS. Not necessary nor available with EMSCRIPTEN.
#if !defined(__EMSCRIPTEN__) && (defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) || defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN))
#include <SDL_syswm.h>
#undef Status // X11 headers are leaking this and also 'Success', 'Always', 'None', all used in DAWN api. Add #undef if necessary.
WGPUSurface CreateWGPUSurface(const WGPUInstance& instance, SDL_Window* window)
{
SDL_SysWMinfo sysWMInfo;
SDL_VERSION(&sysWMInfo.version);
SDL_GetWindowWMInfo(window, &sysWMInfo);
ImGui_ImplWGPU_CreateSurfaceInfo create_info = {};
create_info.Instance = instance;
#if defined(SDL_VIDEO_DRIVER_COCOA)
{
create_info.System = "cocoa";
create_info.RawWindow = (void*)sysWMInfo.info.cocoa.window;
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#elif defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_X11)
const char* sdl_driver = SDL_GetCurrentVideoDriver();
if (sdl_driver && strcmp(sdl_driver, "wayland") == 0)
{
create_info.System = "wayland";
create_info.RawDisplay = (void*)sysWMInfo.info.wl.display;
create_info.RawSurface = (void*)sysWMInfo.info.wl.surface;
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
else
{
create_info.System = "x11";
create_info.RawWindow = (void*)sysWMInfo.info.x11.window;
create_info.RawDisplay = (void*)sysWMInfo.info.x11.display;
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#elif defined(SDL_VIDEO_DRIVER_WINDOWS)
{
create_info.System = "win32";
create_info.RawWindow = (void*)sysWMInfo.info.win.window;
create_info.RawInstance = (void*)sysWMInfo.info.win.hinstance;
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#else
#error "Unsupported WebGPU native platform!"
#endif
return nullptr;
}
#endif

View File

@@ -26,7 +26,6 @@
#include "../libs/emscripten/emscripten_mainloop_stub.h"
#endif
#include <webgpu/webgpu.h>
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
#include <webgpu/webgpu_cpp.h>
#endif
@@ -41,7 +40,8 @@ static int wgpu_surface_width = 1280;
static int wgpu_surface_height = 800;
// Forward declarations
static bool InitWGPU(SDL_Window* window);
static bool InitWGPU(SDL_Window* window);
static WGPUSurface CreateWGPUSurface(const WGPUInstance& instance, SDL_Window* window);
static void ResizeSurface(int width, int height)
{
@@ -286,60 +286,6 @@ int main(int, char**)
return 0;
}
// SDL3 helper to create a WebGPU surface (exclusively!) for Native/Desktop applications: available only together with WebGPU/WGPU backend
// As of today (2025/10) there is no "official" support in SDL3 to create a surface for WebGPU backend
// This stub uses "low level" SDL3 calls to acquire information from a specific Window Manager.
// Currently supported platforms: Windows / Linux (X11 and Wayland) / MacOS. Not necessary nor available with EMSCRIPTEN.
#if !defined(__EMSCRIPTEN__) && (defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) || defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN))
#if defined(SDL_PLATFORM_WIN32)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
#endif
WGPUSurface CreateWGPUSurface(const WGPUInstance& instance, SDL_Window* window)
{
SDL_PropertiesID propertiesID = SDL_GetWindowProperties(window);
ImGui_ImplWGPU_CreateSurfaceInfo create_info = {};
create_info.Instance = instance;
#if defined(SDL_PLATFORM_MACOS)
{
create_info.System = "cocoa";
create_info.RawWindow = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL);
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#elif defined(SDL_PLATFORM_LINUX)
if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0)
{
create_info.System = "wayland";
create_info.RawDisplay = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, NULL);
create_info.RawSurface = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, NULL);
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
else if (!SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11"))
{
create_info.System = "x11";
create_info.RawWindow = (void*)SDL_GetNumberProperty(propertiesID, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
create_info.RawDisplay = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL);
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#elif defined(SDL_PLATFORM_WIN32)
{
create_info.System = "win32";
create_info.RawWindow = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
create_info.RawInstance = (void*)::GetModuleHandle(NULL);
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#else
#error "Unsupported WebGPU native platform!"
#endif
return nullptr;
}
#endif
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
static WGPUAdapter RequestAdapter(wgpu::Instance& instance)
{
@@ -551,3 +497,57 @@ static bool InitWGPU(SDL_Window* window)
return true;
}
// SDL3 helper to create a WebGPU surface (exclusively!) for Native/Desktop applications: available only together with WebGPU/WGPU backend
// As of today (2025/10) there is no "official" support in SDL3 to create a surface for WebGPU backend
// This stub uses "low level" SDL3 calls to acquire information from a specific Window Manager.
// Currently supported platforms: Windows / Linux (X11 and Wayland) / MacOS. Not necessary nor available with EMSCRIPTEN.
#if !defined(__EMSCRIPTEN__) && (defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) || defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN))
#if defined(SDL_PLATFORM_WIN32)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
#endif
static WGPUSurface CreateWGPUSurface(const WGPUInstance& instance, SDL_Window* window)
{
SDL_PropertiesID propertiesID = SDL_GetWindowProperties(window);
ImGui_ImplWGPU_CreateSurfaceInfo create_info = {};
create_info.Instance = instance;
#if defined(SDL_PLATFORM_MACOS)
{
create_info.System = "cocoa";
create_info.RawWindow = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL);
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#elif defined(SDL_PLATFORM_LINUX)
if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0)
{
create_info.System = "wayland";
create_info.RawDisplay = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, NULL);
create_info.RawSurface = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, NULL);
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
else if (!SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11"))
{
create_info.System = "x11";
create_info.RawWindow = (void*)SDL_GetNumberProperty(propertiesID, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
create_info.RawDisplay = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL);
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#elif defined(SDL_PLATFORM_WIN32)
{
create_info.System = "win32";
create_info.RawWindow = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
create_info.RawInstance = (void*)::GetModuleHandle(NULL);
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
}
#else
#error "Unsupported WebGPU native platform!"
#endif
return nullptr;
}
#endif