This document describes the WebGPU renderer backend implementation (imgui_impl_wgpu.cpp/h), which translates Dear ImGui draw commands into WebGPU API calls for both native applications and web browsers via Emscripten. The backend handles vertex/index buffer management, texture uploads, WGSL shader compilation, and render state setup using the modern WebGPU graphics API.
Important: WebGPU has two major native implementations (Dawn and wgpu-native) with slightly different APIs. The backend requires defining either IMGUI_IMPL_WEBGPU_BACKEND_DAWN or IMGUI_IMPL_WEBGPU_BACKEND_WGPU to handle these differences. For Emscripten builds, the backend automatically selects the appropriate variant based on the Emscripten version.
For platform-specific window/input handling, see Platform Backends. For general backend architecture patterns, see Backend Architecture Overview. For web-specific integration details, see Web and Emscripten. </old_str>
<old_str>
Diagram: Initialization Sequence
The backend sets two capability flags during initialization:
ImGuiBackendFlags_RendererHasVtxOffset - supports large meshes (64k+ vertices) even with 16-bit indicesImGuiBackendFlags_RendererHasTextures - supports dynamic texture updates for font atlasSources: backends/imgui_impl_wgpu.cpp810-854 backends/imgui_impl_wgpu.cpp651-742 backends/imgui_impl_wgpu.h75-76 </old_str> <new_str> Diagram: Backend Data Structures and Flow
Sources: backends/imgui_impl_wgpu.cpp110-123 backends/imgui_impl_wgpu.h58-72 backends/imgui_impl_wgpu.cpp85-92 backends/imgui_impl_wgpu.cpp94-102
The WebGPU backend sits between Dear ImGui's core rendering abstraction (ImDrawData) and the WebGPU graphics API, managing the translation of high-level draw commands into GPU operations.
Sources: backends/imgui_impl_wgpu.cpp110-123 backends/imgui_impl_wgpu.h48-63
The ImGui_ImplWGPU_InitInfo structure configures the backend during initialization:
| Field | Type | Description |
|---|---|---|
Device | WGPUDevice | WebGPU device handle |
NumFramesInFlight | int | Number of frames buffered (default: 3) |
RenderTargetFormat | WGPUTextureFormat | Swapchain color format |
DepthStencilFormat | WGPUTextureFormat | Depth buffer format (or Undefined) |
PipelineMultisampleState | WGPUMultisampleState | MSAA configuration |
Sources: backends/imgui_impl_wgpu.h48-63
The backend handles variant-specific differences internally through conditional compilation:
Diagram: Backend Variant Handling
Key differences handled by the backend:
| Aspect | Dawn/wgpu-native | WGPU-Emscripten |
|---|---|---|
| String representation | WGPUStringView {ptr, length} | const char* |
| String macro | WGPU_STRLEN | Not used |
| Shader descriptor type | WGPUShaderSourceWGSL | WGPUShaderModuleWGSLDescriptor |
| Shader descriptor sType | WGPUSType_ShaderSourceWGSL | WGPUSType_ShaderModuleWGSLDescriptor |
| Buffer labels | Structured with length | Simple string |
The backend uses #if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN) to conditionally compile the appropriate API calls.
Sources: backends/imgui_impl_wgpu.cpp58-72 backends/imgui_impl_wgpu.cpp260-286 backends/imgui_impl_wgpu.cpp400-411 backends/imgui_impl_wgpu.cpp428-439
WebGPU has two major native implementations with slightly different APIs. The backend supports both via compile-time macros:
| Macro | Implementation | Usage |
|---|---|---|
IMGUI_IMPL_WEBGPU_BACKEND_DAWN | Google's Dawn | Native apps, Emscripten 4.0.10+ (with --use-port=emdawnwebgpu) |
IMGUI_IMPL_WEBGPU_BACKEND_WGPU | wgpu-native | Native apps, Emscripten < 4.0.10 (with -sUSE_WEBGPU=1) |
The ImGui_ImplWGPU_RenderDrawData() function processes Dear ImGui's draw data and submits WebGPU commands. This is the core rendering function called by the application each frame:
Diagram: ImGui_ImplWGPU_RenderDrawData() Flow
Sources: backends/imgui_impl_wgpu.cpp368-536
The ImGui_ImplWGPU_SetupRenderState() function configures the WebGPU render state before drawing. It is called once at the start of rendering and after any ImDrawCallback_ResetRenderState callbacks:
Diagram: Render State Configuration
| State Component | Configuration | Code Reference |
|---|---|---|
| Projection Matrix | Orthographic: maps DisplayPos to DisplayPos + DisplaySize | Uniforms::MVP[4][4] |
| Gamma Correction | 2.2 for sRGB formats (e.g., ASTC*UnormSrgb, BC*UnormSrgb, RGBA8UnormSrgb), 1.0 for linear formats | Uniforms::Gamma |
| Viewport | Full framebuffer size: DisplaySize * FramebufferScale | wgpuRenderPassEncoderSetViewport() |
| Vertex Buffer | Bound to slot 0 with sizeof(ImDrawVert) stride | wgpuRenderPassEncoderSetVertexBuffer() |
| Index Buffer | WGPUIndexFormat_Uint16 or WGPUIndexFormat_Uint32 based on sizeof(ImDrawIdx) | wgpuRenderPassEncoderSetIndexBuffer() |
| Pipeline | Pre-compiled render pipeline state (bd->pipelineState) | wgpuRenderPassEncoderSetPipeline() |
| Common BindGroup | Group 0: uniforms buffer (binding 0) and sampler (binding 1) | wgpuRenderPassEncoderSetBindGroup() |
| Blend Constant | {0.0f, 0.0f, 0.0f, 0.0f} | wgpuRenderPassEncoderSetBlendConstant() |
The uniforms buffer contains:
MVP[4][4] - Model-View-Projection matrix (64 bytes)Gamma - Gamma correction factor (4 bytes)Uniforms structure)Sources: backends/imgui_impl_wgpu.cpp300-364 backends/imgui_impl_wgpu.cpp104-108 backends/imgui_impl_wgpu.cpp318-349
The backend embeds WGSL (WebGPU Shading Language) shaders as string literals. These shaders are compiled during ImGui_ImplWGPU_CreateDeviceObjects() via ImGui_ImplWGPU_CreateShaderModule().
Vertex Shader (__shader_vert_wgsl):
Fragment Shader (__shader_frag_wgsl):
The backend maintains per-frame resources to support multiple frames in flight:
Buffer growth strategy:
TotalVtxCount + 5000 verticesTotalIdxCount + 10000 indicesSources: backends/imgui_impl_wgpu.cpp94-102 backends/imgui_impl_wgpu.cpp389-460
The backend uses a two-level bind group strategy:
| Bind Group | Slot | Contents | Lifetime |
|---|---|---|---|
| Common | 0 | Uniforms buffer, Texture sampler | Persistent |
| Image | 1 | Texture view | Per-draw, cached by texture ID hash |
Image bind groups are created on-demand during rendering and cached in ImGuiStorage:
Sources: backends/imgui_impl_wgpu.cpp288-298 backends/imgui_impl_wgpu.cpp496-503 backends/imgui_impl_wgpu.cpp526-534
The RenderResources structure contains persistent GPU resources:
| Resource | Type | Purpose |
|---|---|---|
Sampler | WGPUSampler | Linear filtering, clamp addressing (changed from repeat in 1.91.5) |
Uniforms | WGPUBuffer | MVP matrix (64 bytes) + gamma (4 bytes) |
CommonBindGroup | WGPUBindGroup | Binds uniforms and sampler to group 0 |
ImageBindGroups | ImGuiStorage | Per-texture bind group cache |
ImageBindGroupLayout | WGPUBindGroupLayout | Layout for texture bind groups |
Sources: backends/imgui_impl_wgpu.cpp85-92 backends/imgui_impl_wgpu.cpp700-715
Diagram: Shader Data Flow
Sources: backends/imgui_impl_wgpu.cpp136-188 backends/imgui_impl_wgpu.cpp260-286
Shaders are compiled during ImGui_ImplWGPU_CreateDeviceObjects() via the helper function ImGui_ImplWGPU_CreateShaderModule():
Diagram: Shader Compilation Process
Sources: backends/imgui_impl_wgpu.cpp260-286 backends/imgui_impl_wgpu.cpp674-681
The backend implements ImGuiBackendFlags_RendererHasTextures for dynamic font atlas updates. Textures are automatically updated during ImGui_ImplWGPU_RenderDrawData() by calling ImGui_ImplWGPU_UpdateTexture() for each texture with non-OK status:
The texture status transitions follow this state machine, with ImGui_ImplWGPU_UpdateTexture() handling WantCreate and WantUpdate states, while ImGui_ImplWGPU_DestroyTexture() handles WantDestroy.
Sources: backends/imgui_impl_wgpu.cpp554-640 backends/imgui_impl_wgpu.cpp376-381
The ImGui_ImplWGPU_UpdateTexture() function handles both texture creation and updates:
Diagram: Texture Upload Process
Key details:
WGPUTextureFormat_RGBA8UnormWGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDstWGPUTextureDimension_2DImTextureID stores the WGPUTextureView (not the texture itself)ImGui_ImplWGPU_Texture) stores both texture and view for cleanupSources: backends/imgui_impl_wgpu.cpp554-640 backends/imgui_impl_wgpu.cpp79-83
The ImGui_ImplWGPU_DestroyTexture() function releases WebGPU resources and marks the texture as destroyed:
| Step | Operation | Code |
|---|---|---|
| 1. Get backend data | Cast tex->BackendUserData | ImGui_ImplWGPU_Texture* backend_tex |
| 2. Verify TexID | Assert view matches stored ID | IM_ASSERT(backend_tex->TextureView == tex->TexID) |
| 3. Release view | Free WebGPU texture view | wgpuTextureViewRelease(backend_tex->TextureView) |
| 4. Release texture | Free WebGPU texture | wgpuTextureRelease(backend_tex->Texture) |
| 5. Free backend data | Delete C++ structure | IM_DELETE(backend_tex) |
| 6. Clear identifiers | Reset pointers | tex->SetTexID(ImTextureID_Invalid), tex->BackendUserData = nullptr |
| 7. Mark destroyed | Update status | tex->SetStatus(ImTextureStatus_Destroyed) |
This function can be safely called while rendering is in progress (e.g., during InvalidateDeviceObjects()), as it properly clears all identifiers.
Sources: backends/imgui_impl_wgpu.cpp538-552
The ImGui_ImplWGPU_DestroyTexture() function:
WGPUTextureView via wgpuTextureViewRelease()WGPUTexture via wgpuTextureRelease()TexID to ImTextureID_InvalidImTextureStatus_DestroyedSources: backends/imgui_impl_wgpu.cpp538-552
The render pipeline is created with the following configuration:
| Component | Configuration |
|---|---|
| Vertex Layout | 3 attributes: position (float2), uv (float2), color (unorm4) |
| Primitive | Triangle list, front face CCW, no culling |
| Depth/Stencil | Disabled (format = Undefined) |
| Multisample | Configurable via InitInfo.PipelineMultisampleState |
| Blend | Alpha blending: srcAlpha + (1-srcAlpha)*dst |
| Targets | Single color attachment with user-specified format |
Sources: backends/imgui_impl_wgpu.cpp651-742
The backend uses two bind group layouts:
Group 0 (Common Resources):
Group 1 (Per-Texture):
Sources: backends/imgui_impl_wgpu.cpp684-697
Sources: Based on integration pattern from backends/imgui_impl_wgpu.cpp1-49
The backend provides helper functions for common WebGPU operations, particularly useful for application setup:
| Function | Return Type | Purpose | Used In |
|---|---|---|---|
ImGui_ImplWGPU_IsSurfaceStatusError(status) | bool | Check if WGPUSurfaceGetCurrentTextureStatus indicates an error that requires handling | Example main loops |
ImGui_ImplWGPU_IsSurfaceStatusSubOptimal(status) | bool | Check if surface is suboptimal and may need recreation for optimal performance | Window resize handling |
ImGui_ImplWGPU_CreateWGPUSurfaceHelper(info) | WGPUSurface | Create surface for macOS (Cocoa), Windows (Win32), X11, or Wayland from platform window | Platform initialization |
ImGui_ImplWGPU_DebugPrintAdapterInfo(adapter) | void | Log adapter name, vendor, device info to console | Debugging adapter selection |
ImGui_ImplWGPU_GetBackendTypeName(type) | const char* | Get string for WGPUBackendType (Vulkan/D3D12/Metal/etc) | Logging/debugging |
ImGui_ImplWGPU_GetAdapterTypeName(type) | const char* | Get string for WGPUAdapterType (DiscreteGPU/IntegratedGPU/CPU/etc) | Logging/debugging |
Dawn-specific helpers (when IMGUI_IMPL_WEBGPU_BACKEND_DAWN is defined):
ImGui_ImplWGPU_GetDeviceLostReasonName(reason) - Convert WGPUDeviceLostReason to stringImGui_ImplWGPU_GetErrorTypeName(type) - Convert WGPUErrorType to stringWGPU-specific helpers (when IMGUI_IMPL_WEBGPU_BACKEND_WGPU is defined for native):
ImGui_ImplWGPU_GetLogLevelName(level) - Convert WGPULogLevel to stringSources: backends/imgui_impl_wgpu.h102-123 backends/imgui_impl_wgpu.cpp856-1098
The backend uses the MEMALIGN() macro to align buffer sizes to 4-byte boundaries, required by WebGPU:
MEMALIGN(TotalVtxCount * sizeof(ImDrawVert), 4)MEMALIGN(TotalIdxCount * sizeof(ImDrawIdx), 4)Sources: backends/imgui_impl_wgpu.cpp76 backends/imgui_impl_wgpu.cpp457-460
The backend minimizes buffer reallocations:
VertexBufferHost, IndexBufferHost) allocated with new[]WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex/IndexSources: backends/imgui_impl_wgpu.cpp389-445
Image bind groups are cached per texture ID to avoid recreation:
ImHashData(&tex_id, sizeof(tex_id), 0)ImGuiStorage for O(log n) lookupSources: backends/imgui_impl_wgpu.cpp496-503 backends/imgui_impl_wgpu.cpp526-534
Refresh this wiki