diff --git a/backends/imgui_impl_wgpu.cpp b/backends/imgui_impl_wgpu.cpp index 28b3ac1e3..9ec2e3592 100644 --- a/backends/imgui_impl_wgpu.cpp +++ b/backends/imgui_impl_wgpu.cpp @@ -51,6 +51,9 @@ #ifndef IMGUI_DISABLE #include "imgui_impl_wgpu.h" +#include +#include +#include // One of IMGUI_IMPL_WEBGPU_BACKEND_DAWN or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be provided. See imgui_impl_wgpu.h for more details. #if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) == defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) @@ -63,9 +66,6 @@ #define IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN #endif -#include -#include - #ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN // Dawn renamed WGPUProgrammableStageDescriptor to WGPUComputeState (see: https://github.com/webgpu-native/webgpu-headers/pull/413) // Using type alias until WGPU adopts the same naming convention (#8369) @@ -920,6 +920,102 @@ void ImGui_ImplWGPU_NewFrame() // Those are currently used by our example applications. //------------------------------------------------------------------------- +bool ImGui_ImplWGPU_IsSurfaceStatusError(WGPUSurfaceGetCurrentTextureStatus status) +{ +#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) + return (status == WGPUSurfaceGetCurrentTextureStatus_Error); +#else + return (status == WGPUSurfaceGetCurrentTextureStatus_OutOfMemory || status == WGPUSurfaceGetCurrentTextureStatus_DeviceLost); +#endif +} + +bool ImGui_ImplWGPU_IsSurfaceStatusSubOptimal(WGPUSurfaceGetCurrentTextureStatus status) +{ +#if defined(__EMSCRIPTEN__) && !defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) + return (status == WGPUSurfaceGetCurrentTextureStatus_Timeout || status == WGPUSurfaceGetCurrentTextureStatus_Outdated || status == WGPUSurfaceGetCurrentTextureStatus_Lost); +#else + return (status == WGPUSurfaceGetCurrentTextureStatus_Timeout || status == WGPUSurfaceGetCurrentTextureStatus_Outdated || status == WGPUSurfaceGetCurrentTextureStatus_Lost || status == WGPUSurfaceGetCurrentTextureStatus_SuccessSuboptimal); +#endif +} + +// Helpers to obtain a string +#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) +const char* ImGui_ImplWGPU_GetErrorTypeName(WGPUErrorType type) +{ + switch (type) + { + case WGPUErrorType_Validation: return "Validation"; + case WGPUErrorType_OutOfMemory: return "OutOfMemory"; + case WGPUErrorType_Unknown: return "Unknown"; + case WGPUErrorType_Internal: return "Internal"; + default: return "Unknown"; + } +} +const char* ImGui_ImplWGPU_GetDeviceLostReasonName(WGPUDeviceLostReason type) +{ + switch (type) + { + case WGPUDeviceLostReason_Unknown: return "Unknown"; + case WGPUDeviceLostReason_Destroyed: return "Destroyed"; + case WGPUDeviceLostReason_CallbackCancelled: return "CallbackCancelled"; + case WGPUDeviceLostReason_FailedCreation: return "FailedCreation"; + default: return "Unknown"; + } +} +#elif !defined(__EMSCRIPTEN__) +const char* ImGui_ImplWGPU_GetLogLevelName(WGPULogLevel level) +{ + switch (level) + { + case WGPULogLevel_Error: return "Error"; + case WGPULogLevel_Warn: return "Warn"; + case WGPULogLevel_Info: return "Info"; + case WGPULogLevel_Debug: return "Debug"; + case WGPULogLevel_Trace: return "Trace"; + default: return "Unknown"; + } +} +#endif + +const char* ImGui_ImplWGPU_GetBackendTypeName(WGPUBackendType type) +{ + switch (type) + { + case WGPUBackendType_WebGPU: return "WebGPU"; + case WGPUBackendType_D3D11: return "D3D11"; + case WGPUBackendType_D3D12: return "D3D12"; + case WGPUBackendType_Metal: return "Metal"; + case WGPUBackendType_Vulkan: return "Vulkan"; + case WGPUBackendType_OpenGL: return "OpenGL"; + case WGPUBackendType_OpenGLES: return "OpenGLES"; + default: return "Unknown"; + } +} + +const char* ImGui_ImplWGPU_GetAdapterTypeName(WGPUAdapterType type) +{ + switch (type) + { + case WGPUAdapterType_DiscreteGPU: return "DiscreteGPU"; + case WGPUAdapterType_IntegratedGPU: return "IntegratedGPU"; + case WGPUAdapterType_CPU: return "CPU"; + default: return "Unknown"; + } +} + +void ImGui_ImplWGPU_DebugPrintAdapterInfo(const WGPUAdapter& adapter) +{ + WGPUAdapterInfo info = {}; + wgpuAdapterGetInfo(adapter, &info); + printf("description: \"%.*s\"\n", (int)info.description.length, info.description.data); + printf("vendor: \"%.*s\", vendorID: %x\n", (int)info.vendor.length, info.vendor.data, info.vendorID); + printf("architecture: \"%.*s\"\n", (int) info.architecture.length, info.architecture.data); + printf("device: \"%.*s\", deviceID: %x\n", (int)info.device.length, info.device.data, info.deviceID); + printf("backendType: \"%s\"\n", ImGui_ImplWGPU_GetBackendTypeName(info.backendType)); + printf("adapterType: \"%s\"\n", ImGui_ImplWGPU_GetAdapterTypeName(info.adapterType)); + wgpuAdapterInfoFreeMembers(info); +} + #if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) || defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) && !defined(__EMSCRIPTEN__) #if defined(__APPLE__) diff --git a/backends/imgui_impl_wgpu.h b/backends/imgui_impl_wgpu.h index 6d10c53d6..3e46849b5 100644 --- a/backends/imgui_impl_wgpu.h +++ b/backends/imgui_impl_wgpu.h @@ -41,6 +41,11 @@ #endif #include +#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) +#include // for wgpu::Device, wgpu::DeviceLostReason, wgpu::ErrorType used by validation layer callbacks. +#elif !defined(__EMSCRIPTEN__) +#include // WGPULogLevel +#endif // Initialization data, for ImGui_ImplWGPU_Init() struct ImGui_ImplWGPU_InitInfo @@ -86,6 +91,21 @@ struct ImGui_ImplWGPU_RenderState // Those are currently used by our example applications. //------------------------------------------------------------------------- +// (Optional) Helper to wrap some of the Dawn/WGPU/Emscripten quirks +bool ImGui_ImplWGPU_IsSurfaceStatusError(WGPUSurfaceGetCurrentTextureStatus status); +bool ImGui_ImplWGPU_IsSurfaceStatusSubOptimal(WGPUSurfaceGetCurrentTextureStatus status); // Return whether the texture is suboptimal and may need to be recreated. + +// (Optional) Helper for debugging/logging +void ImGui_ImplWGPU_DebugPrintAdapterInfo(const WGPUAdapter& adapter); +const char* ImGui_ImplWGPU_GetBackendTypeName(WGPUBackendType type); +const char* ImGui_ImplWGPU_GetAdapterTypeName(WGPUAdapterType type); +#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) +const char* ImGui_ImplWGPU_GetDeviceLostReasonName(WGPUDeviceLostReason type); +const char* ImGui_ImplWGPU_GetErrorTypeName(WGPUErrorType type); +#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) && !defined(__EMSCRIPTEN__) +const char* ImGui_ImplWGPU_GetLogLevelName(WGPULogLevel level); +#endif + // (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 diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index f50753868..551a166d8 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -85,6 +85,11 @@ Other Changes: - WebGPU: added various internal/optional helpers to wrap some of the Dawn/WGPU/Emscripten debacle quirks: (#8381) [@brutpitt] - ImGui_ImplWGPU_CreateWGPUSurfaceHelper(). + - ImGui_ImplWGPU_IsSurfaceStatusError(), ImGui_ImplWGPU_IsSurfaceStatusSubOptimal(). + - ImGui_ImplWGPU_DebugPrintAdapterInfo(), + - ImGui_ImplWGPU_GetBackendTypeName(), ImGui_ImplWGPU_GetAdapterTypeName(), + ImGui_ImplWGPU_GetDeviceLostReasonName(), ImGui_ImplWGPU_GetErrorTypeName(), + ImGui_ImplWGPU_GetLogLevelName(). - 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