diff --git a/backends/imgui_impl_wgpu.cpp b/backends/imgui_impl_wgpu.cpp index fe5cd5832..28b3ac1e3 100644 --- a/backends/imgui_impl_wgpu.cpp +++ b/backends/imgui_impl_wgpu.cpp @@ -273,7 +273,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const c #endif WGPUShaderModuleDescriptor desc = {}; - desc.nextInChain = reinterpret_cast(&wgsl_desc); + desc.nextInChain = (WGPUChainedStruct*)&wgsl_desc; WGPUProgrammableStageDescriptor stage_desc = {}; stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc); @@ -915,6 +915,77 @@ void ImGui_ImplWGPU_NewFrame() IM_ASSERT(0 && "ImGui_ImplWGPU_CreateDeviceObjects() failed!"); } +//------------------------------------------------------------------------- +// Internal Helpers +// Those are currently used by our example applications. +//------------------------------------------------------------------------- + +#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) || defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) && !defined(__EMSCRIPTEN__) + +#if defined(__APPLE__) +// MacOS specific: is necessary to compile with "-x objective-c++" flags +// (e.g. using cmake: set_source_files_properties(${IMGUI_DIR}/backends/imgui_impl_wgpu.cpp PROPERTIES COMPILE_FLAGS "-x objective-c++") ) +#include +#include +#endif + +WGPUSurface ImGui_ImplWGPU_CreateWGPUSurfaceHelper(ImGui_ImplWGPU_CreateSurfaceInfo* info) +{ + WGPUSurfaceDescriptor surface_descriptor = {}; + WGPUSurface surface = {}; +#if defined(__APPLE__) + if (strcmp(info->System, "cocoa") == 0) + { + IM_ASSERT(info->RawWindow != nullptr); + NSWindow* ns_window = (NSWindow*)info->RawWindow; + id metal_layer = [CAMetalLayer layer]; + [ns_window.contentView setWantsLayer : YES] ; + [ns_window.contentView setLayer : metal_layer] ; + WGPUSurfaceSourceMetalLayer surface_src_metal = {}; + surface_src_metal.chain.sType = WGPUSType_SurfaceSourceMetalLayer; + surface_src_metal.layer = metal_layer; + surface_descriptor.nextInChain = &surface_src_metal.chain; + surface = wgpuInstanceCreateSurface(info->Instance, &surface_descriptor); + } +#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) + if (strcmp(info->System, "wayland") == 0) + { + IM_ASSERT(info->RawDisplay != nullptr && info->RawSurface != nullptr); + WGPUSurfaceSourceWaylandSurface surface_src_wayland = {}; + surface_src_wayland.chain.sType = WGPUSType_SurfaceSourceWaylandSurface; + surface_src_wayland.display = info->RawDisplay; + surface_src_wayland.surface = info->RawSurface; + surface_descriptor.nextInChain = &surface_src_wayland.chain; + surface = wgpuInstanceCreateSurface(info->Instance, &surface_descriptor); + } + else if (strcmp(info->System, "x11") == 0) + { + IM_ASSERT(info->RawDisplay != nullptr && info->RawWindow != nullptr); + WGPUSurfaceSourceXlibWindow surface_src_xlib = {}; + surface_src_xlib.chain.sType = WGPUSType_SurfaceSourceXlibWindow; + surface_src_xlib.display = info->RawDisplay; + surface_src_xlib.window = (uint64_t)info->RawWindow; + surface_descriptor.nextInChain = &surface_src_xlib.chain; + surface = wgpuInstanceCreateSurface(info->Instance, &surface_descriptor); + } +#elif defined(_WIN32) + if (strcmp(info->System, "win32") == 0) + { + IM_ASSERT(info->RawWindow != nullptr && info->RawInstance != nullptr); + WGPUSurfaceSourceWindowsHWND surface_src_hwnd = {}; + surface_src_hwnd.chain.sType = WGPUSType_SurfaceSourceWindowsHWND; + surface_src_hwnd.hinstance = info->RawInstance; + surface_src_hwnd.hwnd = info->RawWindow; + surface_descriptor.nextInChain = &surface_src_hwnd.chain; + surface = wgpuInstanceCreateSurface(info->Instance, &surface_descriptor); + } +#else +#error "Unsupported WebGPU native platform!" +#endif + return surface; +} +#endif + //----------------------------------------------------------------------------- #endif // #ifndef IMGUI_DISABLE diff --git a/backends/imgui_impl_wgpu.h b/backends/imgui_impl_wgpu.h index 9443106b8..6d10c53d6 100644 --- a/backends/imgui_impl_wgpu.h +++ b/backends/imgui_impl_wgpu.h @@ -81,4 +81,23 @@ struct ImGui_ImplWGPU_RenderState WGPURenderPassEncoder RenderPassEncoder; }; +//------------------------------------------------------------------------- +// Internal Helpers +// Those are currently used by our example applications. +//------------------------------------------------------------------------- + +// (Optional) Helper to create a surface on macOS/Wayland/X11/Window +#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) || defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) && !defined(__EMSCRIPTEN__) +struct ImGui_ImplWGPU_CreateSurfaceInfo +{ + WGPUInstance Instance; + const char* System; // "cocoa" | "wayland" | "x11" | "win32" + void* RawWindow; // NSWindow* | 0 | Window | HWND + void* RawDisplay; // 0 | wl_display* | Display* | 0 + void* RawSurface; // | wl_surface* | 0 | 0 + void* RawInstance; // 0 | 0 | 0 | HINSTANCE +}; +WGPUSurface ImGui_ImplWGPU_CreateWGPUSurfaceHelper(ImGui_ImplWGPU_CreateSurfaceInfo* info); +#endif + #endif // #ifndef IMGUI_DISABLE diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 7b101d6a7..f50753868 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -82,6 +82,9 @@ Other Changes: was unused in core but might be used by a direct caller). (#9027) [@achabense] - Vulkan: added IMGUI_IMPL_VULKAN_VOLK_FILENAME to configure path to Volk (default to "volk.h"). (#9008, #7722, #6582, #4854) [@mwlasiuk] + - WebGPU: added various internal/optional helpers to wrap some of the + Dawn/WGPU/Emscripten debacle quirks: (#8381) [@brutpitt] + - ImGui_ImplWGPU_CreateWGPUSurfaceHelper(). - WebGPU: update to compile with Dawn and Emscripten's 4.0.10+ '--use-port=emdawnwebgpu' ports. (#8381, #8898) [@brutpitt, @trbabb] When using Emscripten 4.0.10+, backend now defaults to IMGUI_IMPL_WEBGPU_BACKEND_DAWN