mirror of
https://github.com/ocornut/imgui.git
synced 2025-09-27 05:38:30 +00:00
Misc amends (8381)
This commit is contained in:
@@ -117,6 +117,10 @@
|
|||||||
#define GLFW_EXPOSE_NATIVE_COCOA
|
#define GLFW_EXPOSE_NATIVE_COCOA
|
||||||
#endif
|
#endif
|
||||||
#include <GLFW/glfw3native.h>
|
#include <GLFW/glfw3native.h>
|
||||||
|
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||||
|
#include <Foundation/Foundation.h>
|
||||||
|
#include <QuartzCore/CAMetalLayer.h>
|
||||||
|
#endif
|
||||||
#elif !defined(__EMSCRIPTEN__)
|
#elif !defined(__EMSCRIPTEN__)
|
||||||
#ifndef GLFW_EXPOSE_NATIVE_X11 // for glfwGetX11Window() on Freedesktop (Linux, BSD, etc.)
|
#ifndef GLFW_EXPOSE_NATIVE_X11 // for glfwGetX11Window() on Freedesktop (Linux, BSD, etc.)
|
||||||
#define GLFW_EXPOSE_NATIVE_X11
|
#define GLFW_EXPOSE_NATIVE_X11
|
||||||
@@ -1049,26 +1053,17 @@ void ImGui_ImplGlfw_InstallEmscriptenCallbacks(GLFWwindow* window, const char* c
|
|||||||
}
|
}
|
||||||
#endif // #ifdef EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3
|
#endif // #ifdef EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3
|
||||||
|
|
||||||
// GLFW helper to create a WebGPU surface, used only in WGPU-Native, DAWN-Native already has a built-in function
|
// GLFW helper to create a WebGPU surface, used only in WGPU-Native. DAWN-Native already has a built-in function
|
||||||
// At current date (jun/2025) there is no "official" support in GLFW to create a surface for WebGPU backend
|
// At current date (jun/2025) 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.
|
// This stub uses "low level" GLFW calls to acquire information from a specific Window Manager.
|
||||||
// Currently supported platforms: Windows / Linux (X11 and Wayland) / MacOS
|
// Currently supported platforms: Windows / Linux (X11 and Wayland) / MacOS. Not necessary/available with EMSCRIPTEN
|
||||||
// Not necessary/available with EMSCRIPTEN
|
// MacOS specific: need to compile with "-x objective-c++" flags
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) && !defined(__EMSCRIPTEN__)
|
|
||||||
// GLFW native necessary to get information about current platform / Window Manager
|
|
||||||
#include <GLFW/glfw3native.h>
|
|
||||||
// MacOS specific: is necessary to compile with "-x objective-c++" flags
|
|
||||||
// (e.g. using cmake: set_source_files_properties(${IMGUI_DIR}/backends/imgui_impl_glfw.cpp PROPERTIES COMPILE_FLAGS "-x objective-c++") )
|
// (e.g. using cmake: set_source_files_properties(${IMGUI_DIR}/backends/imgui_impl_glfw.cpp PROPERTIES COMPILE_FLAGS "-x objective-c++") )
|
||||||
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) && !defined(__EMSCRIPTEN__)
|
||||||
#include <Foundation/Foundation.h>
|
WGPUSurface ImGui_ImplGLFW_CreateWGPUSurface(WGPUInstance instance, GLFWwindow* window)
|
||||||
#include <QuartzCore/CAMetalLayer.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WGPUSurface ImGui_ImplGLFW_CreateWGPUSurface_Helper(WGPUInstance instance, GLFWwindow* window)
|
|
||||||
{
|
{
|
||||||
WGPUSurfaceDescriptor surfaceDescriptor = {};
|
WGPUSurfaceDescriptor surfaceDescriptor = {};
|
||||||
WGPUChainedStruct chainedStruct = {};
|
WGPUChainedStruct chainedStruct = {};
|
||||||
|
|
||||||
WGPUSurface surface = {};
|
WGPUSurface surface = {};
|
||||||
|
|
||||||
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
|
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
|
||||||
@@ -1078,68 +1073,57 @@ WGPUSurface ImGui_ImplGLFW_CreateWGPUSurface_Helper(WGPUInstance instance, GLFWw
|
|||||||
[ns_window.contentView setWantsLayer:YES];
|
[ns_window.contentView setWantsLayer:YES];
|
||||||
metal_layer = [CAMetalLayer layer];
|
metal_layer = [CAMetalLayer layer];
|
||||||
[ns_window.contentView setLayer:metal_layer];
|
[ns_window.contentView setLayer:metal_layer];
|
||||||
|
|
||||||
chainedStruct.sType = WGPUSType_SurfaceSourceMetalLayer;
|
chainedStruct.sType = WGPUSType_SurfaceSourceMetalLayer;
|
||||||
|
|
||||||
WGPUSurfaceSourceMetalLayer surfaceMetal = {};
|
WGPUSurfaceSourceMetalLayer surfaceMetal = {};
|
||||||
surfaceMetal.chain = chainedStruct;
|
surfaceMetal.chain = chainedStruct;
|
||||||
surfaceMetal.layer = metal_layer;
|
surfaceMetal.layer = metal_layer;
|
||||||
|
|
||||||
surfaceDescriptor.nextInChain = &surfaceMetal.chain;
|
surfaceDescriptor.nextInChain = &surfaceMetal.chain;
|
||||||
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||||
}
|
}
|
||||||
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND) && defined(GLFW_EXPOSE_NATIVE_X11)
|
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND) && defined(GLFW_EXPOSE_NATIVE_X11)
|
||||||
if (glfwGetPlatform() == GLFW_PLATFORM_X11) {
|
if (glfwGetPlatform() == GLFW_PLATFORM_X11)
|
||||||
|
{
|
||||||
Display* x11_display = glfwGetX11Display();
|
Display* x11_display = glfwGetX11Display();
|
||||||
Window x11_window = glfwGetX11Window(window);
|
Window x11_window = glfwGetX11Window(window);
|
||||||
|
|
||||||
chainedStruct.sType = WGPUSType_SurfaceSourceXlibWindow;
|
chainedStruct.sType = WGPUSType_SurfaceSourceXlibWindow;
|
||||||
|
|
||||||
WGPUSurfaceSourceXlibWindow surfaceXlib = {};
|
WGPUSurfaceSourceXlibWindow surfaceXlib = {};
|
||||||
surfaceXlib.chain = chainedStruct;
|
surfaceXlib.chain = chainedStruct;
|
||||||
surfaceXlib.display = x11_display;
|
surfaceXlib.display = x11_display;
|
||||||
surfaceXlib.window = x11_window;
|
surfaceXlib.window = x11_window;
|
||||||
|
|
||||||
surfaceDescriptor.nextInChain = &surfaceXlib.chain;
|
surfaceDescriptor.nextInChain = &surfaceXlib.chain;
|
||||||
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||||
}
|
}
|
||||||
if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) {
|
if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND)
|
||||||
|
{
|
||||||
struct wl_display* wayland_display = glfwGetWaylandDisplay();
|
struct wl_display* wayland_display = glfwGetWaylandDisplay();
|
||||||
struct wl_surface* wayland_surface = glfwGetWaylandWindow(window);
|
struct wl_surface* wayland_surface = glfwGetWaylandWindow(window);
|
||||||
|
|
||||||
chainedStruct.sType = WGPUSType_SurfaceSourceWaylandSurface;
|
chainedStruct.sType = WGPUSType_SurfaceSourceWaylandSurface;
|
||||||
|
|
||||||
WGPUSurfaceSourceWaylandSurface surfaceWayland = {};
|
WGPUSurfaceSourceWaylandSurface surfaceWayland = {};
|
||||||
surfaceWayland.chain = chainedStruct;
|
surfaceWayland.chain = chainedStruct;
|
||||||
surfaceWayland.display = wayland_display;
|
surfaceWayland.display = wayland_display;
|
||||||
surfaceWayland.surface = wayland_surface;
|
surfaceWayland.surface = wayland_surface;
|
||||||
|
|
||||||
surfaceDescriptor.nextInChain = &surfaceWayland.chain;
|
surfaceDescriptor.nextInChain = &surfaceWayland.chain;
|
||||||
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||||
}
|
}
|
||||||
#elif defined(GLFW_EXPOSE_NATIVE_WIN32)
|
#elif defined(GLFW_EXPOSE_NATIVE_WIN32)
|
||||||
{
|
{
|
||||||
HWND hwnd = glfwGetWin32Window(window);
|
HWND hwnd = glfwGetWin32Window(window);
|
||||||
HINSTANCE hinstance = GetModuleHandle(NULL);
|
HINSTANCE hinstance = ::GetModuleHandle(NULL);
|
||||||
|
|
||||||
chainedStruct.sType = WGPUSType_SurfaceSourceWindowsHWND;
|
chainedStruct.sType = WGPUSType_SurfaceSourceWindowsHWND;
|
||||||
|
|
||||||
WGPUSurfaceSourceWindowsHWND surfaceHWND = {};
|
WGPUSurfaceSourceWindowsHWND surfaceHWND = {};
|
||||||
surfaceHWND.chain = chainedStruct;
|
surfaceHWND.chain = chainedStruct;
|
||||||
surfaceHWND.hinstance = hinstance;
|
surfaceHWND.hinstance = hinstance;
|
||||||
surfaceHWND.hwnd = hwnd;
|
surfaceHWND.hwnd = hwnd;
|
||||||
|
|
||||||
surfaceDescriptor.nextInChain = &surfaceHWND.chain;
|
surfaceDescriptor.nextInChain = &surfaceHWND.chain;
|
||||||
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||||
}
|
}
|
||||||
#elif
|
#elif
|
||||||
#error "Unsupported GLFW/WebGPU native platform"
|
#error "Unsupported GLFW+WebGPU native platform"
|
||||||
#endif
|
#endif
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
#endif // defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) && !defined(__EMSCRIPTEN__)
|
#endif // defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) && !defined(__EMSCRIPTEN__)
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
|
@@ -66,10 +66,10 @@ IMGUI_IMPL_API void ImGui_ImplGlfw_Sleep(int milliseconds);
|
|||||||
IMGUI_IMPL_API float ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window);
|
IMGUI_IMPL_API float ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window);
|
||||||
IMGUI_IMPL_API float ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor);
|
IMGUI_IMPL_API float ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor);
|
||||||
|
|
||||||
// GLFW helper to create a WebGPU surface for Native/Desktop applications: used only in WGPU-Native, DAWN-Native already has a built-in function
|
// GLFW helpers for native/desktop WebGPU applications (used only in WGPU-Native, DAWN-Native already has a built-in function)
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) && !defined(__EMSCRIPTEN__)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) && !defined(__EMSCRIPTEN__)
|
||||||
#include <webgpu/webgpu.h>
|
#include <webgpu/webgpu.h>
|
||||||
WGPUSurface ImGui_ImplGLFW_CreateWGPUSurface_Helper(WGPUInstance instance, GLFWwindow* window);
|
WGPUSurface ImGui_ImplGLFW_CreateWGPUSurface(WGPUInstance instance, GLFWwindow* window);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@@ -912,53 +912,48 @@ void ImGui_ImplSDL2_NewFrame()
|
|||||||
#include <QuartzCore/CAMetalLayer.h>
|
#include <QuartzCore/CAMetalLayer.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WGPUSurface ImGui_ImplSDL2_CreateWGPUSurface_Helper(WGPUInstance instance, SDL_Window* window)
|
WGPUSurface ImGui_ImplSDL2_CreateWGPUSurface(WGPUInstance instance, SDL_Window* window)
|
||||||
{
|
{
|
||||||
WGPUSurfaceDescriptor surfaceDescriptor = {};
|
WGPUSurfaceDescriptor surfaceDescriptor = {};
|
||||||
WGPUChainedStruct chainedStruct = {};
|
WGPUChainedStruct chainedStruct = {};
|
||||||
|
WGPUSurface surface = {};
|
||||||
|
|
||||||
SDL_SysWMinfo sysWMInfo;
|
SDL_SysWMinfo sysWMInfo;
|
||||||
SDL_VERSION(&sysWMInfo.version);
|
SDL_VERSION(&sysWMInfo.version);
|
||||||
SDL_GetWindowWMInfo(window, &sysWMInfo);
|
SDL_GetWindowWMInfo(window, &sysWMInfo);
|
||||||
|
|
||||||
WGPUSurface surface = {};
|
|
||||||
|
|
||||||
#if defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_X11)
|
#if defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_X11)
|
||||||
const char *vidDrv = SDL_GetHint(SDL_HINT_VIDEODRIVER);
|
const char* video_driver = SDL_GetHint(SDL_HINT_VIDEODRIVER);
|
||||||
if(!vidDrv) return NULL;
|
if (!video_driver)
|
||||||
|
return nullptr;
|
||||||
if(tolower(vidDrv[0])=='w' && tolower(vidDrv[1])=='a' && tolower(vidDrv[2])=='y' &&
|
|
||||||
tolower(vidDrv[3])=='l' && tolower(vidDrv[4])=='a' && tolower(vidDrv[5])=='n' && tolower(vidDrv[6])=='d') { // wayland
|
|
||||||
|
|
||||||
|
if (strncmp(video_driver, "wayland", 7) == 0)
|
||||||
|
{
|
||||||
chainedStruct.sType = WGPUSType_SurfaceSourceWaylandSurface;
|
chainedStruct.sType = WGPUSType_SurfaceSourceWaylandSurface;
|
||||||
|
|
||||||
WGPUSurfaceSourceWaylandSurface surfaceWayland = {};
|
WGPUSurfaceSourceWaylandSurface surfaceWayland = {};
|
||||||
surfaceWayland.chain = chainedStruct;
|
surfaceWayland.chain = chainedStruct;
|
||||||
surfaceWayland.display = sysWMInfo.info.wl.display;
|
surfaceWayland.display = sysWMInfo.info.wl.display;
|
||||||
surfaceWayland.surface = sysWMInfo.info.wl.surface;
|
surfaceWayland.surface = sysWMInfo.info.wl.surface;
|
||||||
|
|
||||||
surfaceDescriptor.nextInChain = &surfaceWayland.chain;
|
surfaceDescriptor.nextInChain = &surfaceWayland.chain;
|
||||||
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||||
|
}
|
||||||
} else { // x11
|
else
|
||||||
|
{
|
||||||
chainedStruct.sType = WGPUSType_SurfaceSourceXlibWindow;
|
chainedStruct.sType = WGPUSType_SurfaceSourceXlibWindow;
|
||||||
|
|
||||||
WGPUSurfaceSourceXlibWindow surfaceXlib = {};
|
WGPUSurfaceSourceXlibWindow surfaceXlib = {};
|
||||||
surfaceXlib.chain = chainedStruct;
|
surfaceXlib.chain = chainedStruct;
|
||||||
surfaceXlib.display = sysWMInfo.info.x11.display;
|
surfaceXlib.display = sysWMInfo.info.x11.display;
|
||||||
surfaceXlib.window = sysWMInfo.info.x11.window;
|
surfaceXlib.window = sysWMInfo.info.x11.window;
|
||||||
|
|
||||||
surfaceDescriptor.nextInChain = &surfaceXlib.chain;
|
surfaceDescriptor.nextInChain = &surfaceXlib.chain;
|
||||||
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||||
}
|
}
|
||||||
#elif defined(SDL_VIDEO_DRIVER_WINDOWS)
|
#elif defined(SDL_VIDEO_DRIVER_WINDOWS)
|
||||||
{
|
{
|
||||||
chainedStruct.sType = WGPUSType_SurfaceSourceWindowsHWND;
|
chainedStruct.sType = WGPUSType_SurfaceSourceWindowsHWND;
|
||||||
|
|
||||||
WGPUSurfaceSourceWindowsHWND surfaceHWND = {};
|
WGPUSurfaceSourceWindowsHWND surfaceHWND = {};
|
||||||
surfaceHWND.chain = chainedStruct;
|
surfaceHWND.chain = chainedStruct;
|
||||||
surfaceHWND.hinstance = sysWMInfo.info.win.hinstance;
|
surfaceHWND.hinstance = sysWMInfo.info.win.hinstance;
|
||||||
surfaceHWND.hwnd = sysWMInfo.info.win.window;
|
surfaceHWND.hwnd = sysWMInfo.info.win.window;
|
||||||
|
|
||||||
surfaceDescriptor.nextInChain = &surfaceHWND.chain;
|
surfaceDescriptor.nextInChain = &surfaceHWND.chain;
|
||||||
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||||
}
|
}
|
||||||
@@ -968,18 +963,15 @@ WGPUSurface ImGui_ImplSDL2_CreateWGPUSurface_Helper(WGPUInstance instance, SDL_W
|
|||||||
NSWindow* ns_window = sysWMInfo.info.cocoa.window;
|
NSWindow* ns_window = sysWMInfo.info.cocoa.window;
|
||||||
[ns_window.contentView setWantsLayer:YES];
|
[ns_window.contentView setWantsLayer:YES];
|
||||||
[ns_window.contentView setLayer:metal_layer];
|
[ns_window.contentView setLayer:metal_layer];
|
||||||
|
|
||||||
chainedStruct.sType = WGPUSType_SurfaceSourceMetalLayer;
|
chainedStruct.sType = WGPUSType_SurfaceSourceMetalLayer;
|
||||||
|
|
||||||
WGPUSurfaceSourceMetalLayer surfaceMetal = {};
|
WGPUSurfaceSourceMetalLayer surfaceMetal = {};
|
||||||
surfaceMetal.chain = chainedStruct;
|
surfaceMetal.chain = chainedStruct;
|
||||||
surfaceMetal.layer = metal_layer;
|
surfaceMetal.layer = metal_layer;
|
||||||
|
|
||||||
surfaceDescriptor.nextInChain = &surfaceMetal.chain;
|
surfaceDescriptor.nextInChain = &surfaceMetal.chain;
|
||||||
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#error "Unsupported SDL2/WebGPU Backend"
|
#error "Unsupported SDL2+WebGPU Backend"
|
||||||
#endif
|
#endif
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
@@ -47,10 +47,10 @@ IMGUI_IMPL_API float ImGui_ImplSDL2_GetContentScaleForDisplay(int display_ind
|
|||||||
enum ImGui_ImplSDL2_GamepadMode { ImGui_ImplSDL2_GamepadMode_AutoFirst, ImGui_ImplSDL2_GamepadMode_AutoAll, ImGui_ImplSDL2_GamepadMode_Manual };
|
enum ImGui_ImplSDL2_GamepadMode { ImGui_ImplSDL2_GamepadMode_AutoFirst, ImGui_ImplSDL2_GamepadMode_AutoAll, ImGui_ImplSDL2_GamepadMode_Manual };
|
||||||
IMGUI_IMPL_API void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_GameController** manual_gamepads_array = nullptr, int manual_gamepads_count = -1);
|
IMGUI_IMPL_API void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_GameController** manual_gamepads_array = nullptr, int manual_gamepads_count = -1);
|
||||||
|
|
||||||
// SDL2 helper to create a WebGPU surface (exclusively!) for Native/Desktop applications: available only together with WebGPU/WGPU backend
|
// SDL2 helpers for native/desktop WebGPU applications.
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) || defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) && !defined(__EMSCRIPTEN__)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) || defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) && !defined(__EMSCRIPTEN__)
|
||||||
#include <webgpu/webgpu.h>
|
#include <webgpu/webgpu.h>
|
||||||
WGPUSurface ImGui_ImplSDL2_CreateWGPUSurface_Helper(WGPUInstance instance, SDL_Window* window);
|
WGPUSurface ImGui_ImplSDL2_CreateWGPUSurface(WGPUInstance instance, SDL_Window* window);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
@@ -854,10 +854,10 @@ void ImGui_ImplSDL3_NewFrame()
|
|||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WGPUSurface ImGui_ImplSDL3_CreateWGPUSurface_Helper(WGPUInstance instance, SDL_Window* window) {
|
WGPUSurface ImGui_ImplSDL3_CreateWGPUSurface(WGPUInstance instance, SDL_Window* window)
|
||||||
|
{
|
||||||
SDL_PropertiesID propertiesID = SDL_GetWindowProperties(window);
|
SDL_PropertiesID propertiesID = SDL_GetWindowProperties(window);
|
||||||
WGPUSurfaceDescriptor surfaceDescriptor = {};
|
WGPUSurfaceDescriptor surfaceDescriptor = {};
|
||||||
|
|
||||||
WGPUSurface surface = {};
|
WGPUSurface surface = {};
|
||||||
|
|
||||||
#if defined(SDL_PLATFORM_MACOS)
|
#if defined(SDL_PLATFORM_MACOS)
|
||||||
@@ -868,37 +868,36 @@ WGPUSurface ImGui_ImplSDL3_CreateWGPUSurface_Helper(WGPUInstance instance, SDL_W
|
|||||||
[ns_window.contentView setWantsLayer : YES];
|
[ns_window.contentView setWantsLayer : YES];
|
||||||
metal_layer = [CAMetalLayer layer];
|
metal_layer = [CAMetalLayer layer];
|
||||||
[ns_window.contentView setLayer : metal_layer];
|
[ns_window.contentView setLayer : metal_layer];
|
||||||
|
|
||||||
WGPUSurfaceSourceMetalLayer surfaceMetal = {};
|
WGPUSurfaceSourceMetalLayer surfaceMetal = {};
|
||||||
surfaceMetal.chain.sType = WGPUSType_SurfaceSourceMetalLayer;
|
surfaceMetal.chain.sType = WGPUSType_SurfaceSourceMetalLayer;
|
||||||
surfaceMetal.layer = metal_layer;
|
surfaceMetal.layer = metal_layer;
|
||||||
|
|
||||||
surfaceDescriptor.nextInChain = &surfaceMetal.chain;
|
surfaceDescriptor.nextInChain = &surfaceMetal.chain;
|
||||||
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||||
}
|
}
|
||||||
#elif defined(SDL_PLATFORM_LINUX)
|
#elif defined(SDL_PLATFORM_LINUX)
|
||||||
if (!SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland")) {
|
if (!SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland"))
|
||||||
|
{
|
||||||
void* w_display = SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, NULL);
|
void* w_display = SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, NULL);
|
||||||
void* w_surface = SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, NULL);
|
void* w_surface = SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, NULL);
|
||||||
if (!w_display || !w_surface) return NULL;
|
if (!w_display || !w_surface)
|
||||||
|
return NULL;
|
||||||
WGPUSurfaceSourceWaylandSurface surfaceWayland = {};
|
WGPUSurfaceSourceWaylandSurface surfaceWayland = {};
|
||||||
surfaceWayland.chain.sType = WGPUSType_SurfaceSourceWaylandSurface;
|
surfaceWayland.chain.sType = WGPUSType_SurfaceSourceWaylandSurface;
|
||||||
surfaceWayland.display = w_display;
|
surfaceWayland.display = w_display;
|
||||||
surfaceWayland.surface = w_surface;
|
surfaceWayland.surface = w_surface;
|
||||||
|
|
||||||
surfaceDescriptor.nextInChain = &surfaceWayland.chain;
|
surfaceDescriptor.nextInChain = &surfaceWayland.chain;
|
||||||
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||||
} else if (!SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11")) {
|
}
|
||||||
|
else if (!SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11"))
|
||||||
|
{
|
||||||
void* x_display = SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL);
|
void* x_display = SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL);
|
||||||
uint64_t x_window = SDL_GetNumberProperty(propertiesID, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
|
uint64_t x_window = SDL_GetNumberProperty(propertiesID, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
|
||||||
if (!x_display || !x_window) return NULL;
|
if (!x_display || !x_window)
|
||||||
|
return NULL;
|
||||||
WGPUSurfaceSourceXlibWindow surfaceXlib = {};
|
WGPUSurfaceSourceXlibWindow surfaceXlib = {};
|
||||||
surfaceXlib.chain.sType = WGPUSType_SurfaceSourceXlibWindow;
|
surfaceXlib.chain.sType = WGPUSType_SurfaceSourceXlibWindow;
|
||||||
surfaceXlib.display = x_display;
|
surfaceXlib.display = x_display;
|
||||||
surfaceXlib.window = x_window;
|
surfaceXlib.window = x_window;
|
||||||
|
|
||||||
surfaceDescriptor.nextInChain = &surfaceXlib.chain;
|
surfaceDescriptor.nextInChain = &surfaceXlib.chain;
|
||||||
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||||
}
|
}
|
||||||
@@ -906,19 +905,18 @@ WGPUSurface ImGui_ImplSDL3_CreateWGPUSurface_Helper(WGPUInstance instance, SDL_W
|
|||||||
#elif defined(SDL_PLATFORM_WIN32)
|
#elif defined(SDL_PLATFORM_WIN32)
|
||||||
{
|
{
|
||||||
HWND hwnd = (HWND)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
|
HWND hwnd = (HWND)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
|
||||||
if (!hwnd) return NULL;
|
if (!hwnd)
|
||||||
HINSTANCE hinstance = GetModuleHandle(NULL);
|
return NULL;
|
||||||
|
HINSTANCE hinstance = ::GetModuleHandle(NULL);
|
||||||
WGPUSurfaceSourceWindowsHWND surfaceHWND = {};
|
WGPUSurfaceSourceWindowsHWND surfaceHWND = {};
|
||||||
surfaceHWND.chain.sType = WGPUSType_SurfaceSourceWindowsHWND;
|
surfaceHWND.chain.sType = WGPUSType_SurfaceSourceWindowsHWND;
|
||||||
surfaceHWND.hinstance = hinstance;
|
surfaceHWND.hinstance = hinstance;
|
||||||
surfaceHWND.hwnd = hwnd;
|
surfaceHWND.hwnd = hwnd;
|
||||||
|
|
||||||
surfaceDescriptor.nextInChain = &surfaceHWND.chain;
|
surfaceDescriptor.nextInChain = &surfaceHWND.chain;
|
||||||
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
surface = wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#error "Unsupported SDL3/WebGPU Backend"
|
#error "Unsupported SDL3+WebGPU Backend"
|
||||||
#endif
|
#endif
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
@@ -44,10 +44,10 @@ IMGUI_IMPL_API bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event);
|
|||||||
enum ImGui_ImplSDL3_GamepadMode { ImGui_ImplSDL3_GamepadMode_AutoFirst, ImGui_ImplSDL3_GamepadMode_AutoAll, ImGui_ImplSDL3_GamepadMode_Manual };
|
enum ImGui_ImplSDL3_GamepadMode { ImGui_ImplSDL3_GamepadMode_AutoFirst, ImGui_ImplSDL3_GamepadMode_AutoAll, ImGui_ImplSDL3_GamepadMode_Manual };
|
||||||
IMGUI_IMPL_API void ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode mode, SDL_Gamepad** manual_gamepads_array = nullptr, int manual_gamepads_count = -1);
|
IMGUI_IMPL_API void ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode mode, SDL_Gamepad** manual_gamepads_array = nullptr, int manual_gamepads_count = -1);
|
||||||
|
|
||||||
// SDL3 helper to create a WebGPU surface for Native/Desktop applications: available only with WebGPU/WGPU backend
|
// SDL2 helpers for native/desktop WebGPU applications.
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) || defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) && !defined(__EMSCRIPTEN__)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) || defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) && !defined(__EMSCRIPTEN__)
|
||||||
#include <webgpu/webgpu.h>
|
#include <webgpu/webgpu.h>
|
||||||
WGPUSurface ImGui_ImplSDL3_CreateWGPUSurface_Helper(WGPUInstance instance, SDL_Window* window);
|
WGPUSurface ImGui_ImplSDL3_CreateWGPUSurface(WGPUInstance instance, SDL_Window* window);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
@@ -841,15 +841,15 @@ bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info)
|
|||||||
io.BackendRendererUserData = (void*)bd;
|
io.BackendRendererUserData = (void*)bd;
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
||||||
#if defined(__EMSCRIPTEN__)
|
#if defined(__EMSCRIPTEN__)
|
||||||
io.BackendRendererName = "imgui_impl_webgpu_dawn_emscripten"; // compiled & linked using EMSCRIPTEN with "--use-port=emdawnwebgpu" flag
|
io.BackendRendererName = "imgui_impl_wgpu (Dawn, Emscripten)"; // compiled & linked using EMSCRIPTEN with "--use-port=emdawnwebgpu" flag
|
||||||
#else
|
#else
|
||||||
io.BackendRendererName = "imgui_impl_webgpu_dawn"; // DAWN-Native
|
io.BackendRendererName = "imgui_impl_wgpu (Dawn)"; // DAWN-Native
|
||||||
#endif
|
#endif
|
||||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
#if defined(__EMSCRIPTEN__)
|
#if defined(__EMSCRIPTEN__)
|
||||||
io.BackendRendererName = "imgui_impl_webgpu_wgpu_emscripten"; // linked using EMSCRIPTEN with "-sUSE_WEBGPU=1" flag, deprecated from EMSCRIPTEN 4.0.10
|
io.BackendRendererName = "imgui_impl_wgpu (WGPU, Emscripten)"; // linked using EMSCRIPTEN with "-sUSE_WEBGPU=1" flag, deprecated from EMSCRIPTEN 4.0.10
|
||||||
#else
|
#else
|
||||||
io.BackendRendererName = "imgui_impl_webgpu_wgpu"; // WGPU-Native
|
io.BackendRendererName = "imgui_impl_wgpu (WGPU)"; // WGPU-Native
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
@@ -915,71 +915,13 @@ void ImGui_ImplWGPU_NewFrame()
|
|||||||
IM_ASSERT(0 && "ImGui_ImplWGPU_CreateDeviceObjects() failed!");
|
IM_ASSERT(0 && "ImGui_ImplWGPU_CreateDeviceObjects() failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
// WebGPU Helpers
|
// WebGPU Helpers
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
// Check if the status of surface texture is optimal
|
||||||
// DAWN Validation Layer callback: reason for device loss
|
// Return true when the surface texture has an optimal status and we can use it, false if it's necessary to reconfigure the surface teture.
|
||||||
void ImGui_ImplWGPU_DAWN_DeviceLostCallback_Helper(const wgpu::Device&, wgpu::DeviceLostReason reason, wgpu::StringView message)
|
// FIXME: Can abort on unrecoverable errors.
|
||||||
{
|
|
||||||
const char* reasonName = "";
|
|
||||||
switch (reason) {
|
|
||||||
case wgpu::DeviceLostReason::Unknown: reasonName = "Unknown"; break;
|
|
||||||
case wgpu::DeviceLostReason::Destroyed: reasonName = "Destroyed"; break;
|
|
||||||
case wgpu::DeviceLostReason::CallbackCancelled: reasonName = "InstanceDropped"; break;
|
|
||||||
case wgpu::DeviceLostReason::FailedCreation: reasonName = "FailedCreation"; break;
|
|
||||||
default: reasonName = "UNREACHABLE"; break;
|
|
||||||
}
|
|
||||||
fprintf(stderr, "%s device message: %s\n", reasonName, message.data);
|
|
||||||
}
|
|
||||||
// DAWN Validation Layer callback: print error type
|
|
||||||
void ImGui_ImplWGPU_DAWN_ErrorCallback_Helper(const wgpu::Device&, wgpu::ErrorType type, wgpu::StringView message)
|
|
||||||
{
|
|
||||||
const char* errorTypeName = "";
|
|
||||||
switch (type) {
|
|
||||||
case wgpu::ErrorType::Validation: errorTypeName = "Validation"; break;
|
|
||||||
case wgpu::ErrorType::OutOfMemory: errorTypeName = "Out of memory"; break;
|
|
||||||
case wgpu::ErrorType::Unknown: errorTypeName = "Unknown"; break;
|
|
||||||
case wgpu::ErrorType::Internal: errorTypeName = "Internal"; break;
|
|
||||||
default: errorTypeName = "UNREACHABLE"; break;
|
|
||||||
}
|
|
||||||
fprintf(stderr, "%s error: %s\n", errorTypeName, message.data);
|
|
||||||
}
|
|
||||||
#elif !defined(__EMSCRIPTEN__)
|
|
||||||
// WGPU-Native LOG callback: print information based on request level
|
|
||||||
void ImGui_ImplWGPU_WGPU_LogCallback_Helper(WGPULogLevel level, WGPUStringView message, void *userdata)
|
|
||||||
{
|
|
||||||
const char *level_str = "";
|
|
||||||
switch (level) {
|
|
||||||
case WGPULogLevel_Error: level_str = "error"; break;
|
|
||||||
case WGPULogLevel_Warn: level_str = "warn"; break;
|
|
||||||
case WGPULogLevel_Info: level_str = "info"; break;
|
|
||||||
case WGPULogLevel_Debug: level_str = "debug"; break;
|
|
||||||
case WGPULogLevel_Trace: level_str = "trace"; break;
|
|
||||||
default: level_str = "unknown_level";
|
|
||||||
}
|
|
||||||
fprintf(stderr, "[wgpu] [%s] %.*s\n", level_str, (int) message.length, message.data);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Print Adapter info
|
|
||||||
///@param[in] adapter const WGPUAdapter & : reference to acquired and valid WGPUAdapter
|
|
||||||
///@note The function prints: "selected Adapter - drivers version, BackendType (#)"
|
|
||||||
void ImGui_ImplWGPU_PrintAdapterInfo_Helper(const WGPUAdapter &adapter)
|
|
||||||
{
|
|
||||||
WGPUAdapterInfo info = {};
|
|
||||||
wgpuAdapterGetInfo(adapter, &info);
|
|
||||||
#ifdef __EMSCRIPTEN__
|
|
||||||
printf("BackendType (%u)\n", info.backendType);
|
|
||||||
#else
|
|
||||||
printf("Using: %.*s - %.*s, BackendType (%u)\n", (int) info.device.length, info.device.data, (int) info.description.length, info.description.data, info.backendType);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if the Status of SurfaceTexture is Optimal
|
|
||||||
///@param[in] status WGPUSurfaceGetCurrentTextureStatus : current WGPUSurfaceTexture .status (value to check)
|
|
||||||
///@return true (bool) : SurfaceTexture have an optimal status and we can use it
|
|
||||||
///@return false (bool) : it's necessary to re-configure the SurfaceTexture
|
|
||||||
///@note : with "unrecoverable error" the program aborts
|
|
||||||
bool ImGui_ImplWGPU_CheckSurfaceTextureOptimalStatus_Helper(WGPUSurfaceGetCurrentTextureStatus status)
|
bool ImGui_ImplWGPU_CheckSurfaceTextureOptimalStatus_Helper(WGPUSurfaceGetCurrentTextureStatus status)
|
||||||
{
|
{
|
||||||
switch (status)
|
switch (status)
|
||||||
@@ -995,7 +937,6 @@ bool ImGui_ImplWGPU_CheckSurfaceTextureOptimalStatus_Helper(WGPUSurfaceGetCurren
|
|||||||
case WGPUSurfaceGetCurrentTextureStatus_Timeout:
|
case WGPUSurfaceGetCurrentTextureStatus_Timeout:
|
||||||
case WGPUSurfaceGetCurrentTextureStatus_Outdated:
|
case WGPUSurfaceGetCurrentTextureStatus_Outdated:
|
||||||
case WGPUSurfaceGetCurrentTextureStatus_Lost:
|
case WGPUSurfaceGetCurrentTextureStatus_Lost:
|
||||||
// if the status is NOT Optimal it's necessary try to reconfigure the surface
|
|
||||||
return false;
|
return false;
|
||||||
// Unrecoverable errors
|
// Unrecoverable errors
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
||||||
@@ -1007,14 +948,75 @@ bool ImGui_ImplWGPU_CheckSurfaceTextureOptimalStatus_Helper(WGPUSurfaceGetCurren
|
|||||||
case WGPUSurfaceGetCurrentTextureStatus_Force32:
|
case WGPUSurfaceGetCurrentTextureStatus_Force32:
|
||||||
// Fatal error
|
// Fatal error
|
||||||
fprintf(stderr, "Unrecoverable Error Check Surface Texture status=%#.8x\n", status);
|
fprintf(stderr, "Unrecoverable Error Check Surface Texture status=%#.8x\n", status);
|
||||||
abort();
|
IM_ASSERT(0);
|
||||||
|
return false;
|
||||||
default: // should never be reached
|
default:
|
||||||
|
// Should never be reached
|
||||||
fprintf(stderr, "Unexpected Error Check Surface Texture status=%#.8x\n", status);
|
fprintf(stderr, "Unexpected Error Check Surface Texture status=%#.8x\n", status);
|
||||||
abort();
|
IM_ASSERT(0);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
||||||
|
// DAWN Validation Layer callback: reason for device loss
|
||||||
|
void ImGui_ImplWGPU_DAWN_DeviceLostCallback_Helper(const wgpu::Device&, wgpu::DeviceLostReason reason, wgpu::StringView msg)
|
||||||
|
{
|
||||||
|
const char* reasonName = "";
|
||||||
|
switch (reason)
|
||||||
|
{
|
||||||
|
case wgpu::DeviceLostReason::Unknown: reasonName = "Unknown"; break;
|
||||||
|
case wgpu::DeviceLostReason::Destroyed: reasonName = "Destroyed"; break;
|
||||||
|
case wgpu::DeviceLostReason::CallbackCancelled: reasonName = "InstanceDropped"; break;
|
||||||
|
case wgpu::DeviceLostReason::FailedCreation: reasonName = "FailedCreation"; break;
|
||||||
|
default: reasonName = "UNREACHABLE"; break;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "%s device message: %s\n", reasonName, msg.data);
|
||||||
|
}
|
||||||
|
// DAWN Validation Layer callback: print error type
|
||||||
|
void ImGui_ImplWGPU_DAWN_ErrorCallback_Helper(const wgpu::Device&, wgpu::ErrorType type, wgpu::StringView msg)
|
||||||
|
{
|
||||||
|
const char* errorTypeName = "";
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case wgpu::ErrorType::Validation: errorTypeName = "Validation"; break;
|
||||||
|
case wgpu::ErrorType::OutOfMemory: errorTypeName = "Out of memory"; break;
|
||||||
|
case wgpu::ErrorType::Unknown: errorTypeName = "Unknown"; break;
|
||||||
|
case wgpu::ErrorType::Internal: errorTypeName = "Internal"; break;
|
||||||
|
default: errorTypeName = "UNREACHABLE"; break;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "%s error: %s\n", errorTypeName, msg.data);
|
||||||
|
}
|
||||||
|
#elif !defined(__EMSCRIPTEN__)
|
||||||
|
// WGPU-Native LOG callback: print information based on request level
|
||||||
|
void ImGui_ImplWGPU_WGPU_LogCallback_Helper(WGPULogLevel level, WGPUStringView msg, void* userdata)
|
||||||
|
{
|
||||||
|
const char* level_str = "";
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case WGPULogLevel_Error: level_str = "error"; break;
|
||||||
|
case WGPULogLevel_Warn: level_str = "warn"; break;
|
||||||
|
case WGPULogLevel_Info: level_str = "info"; break;
|
||||||
|
case WGPULogLevel_Debug: level_str = "debug"; break;
|
||||||
|
case WGPULogLevel_Trace: level_str = "trace"; break;
|
||||||
|
default: level_str = "unknown_level";
|
||||||
|
}
|
||||||
|
fprintf(stderr, "[wgpu] [%s] %.*s\n", level_str, (int)msg.length, msg.data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void ImGui_ImplWGPU_PrintAdapterInfo_Helper(const WGPUAdapter& adapter)
|
||||||
|
{
|
||||||
|
WGPUAdapterInfo info = {};
|
||||||
|
wgpuAdapterGetInfo(adapter, &info);
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
printf("BackendType (%u)\n", info.backendType);
|
||||||
|
#else
|
||||||
|
printf("Using: %.*s - %.*s, BackendType (%u)\n", (int)info.device.length, info.device.data, (int)info.description.length, info.description.data, info.backendType);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
@@ -28,13 +28,10 @@
|
|||||||
#ifndef IMGUI_DISABLE
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
#include <webgpu/webgpu.h>
|
#include <webgpu/webgpu.h>
|
||||||
|
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
||||||
// DAWN "wgpu::" classes (e.g. used in Validation Layers Callbacks)
|
#include <webgpu/webgpu_cpp.h> // for wgpu::Device, wgpu::DeviceLostReason, wgpu::ErrorType used by validation layer callbacks.
|
||||||
#include <webgpu/webgpu_cpp.h>
|
|
||||||
#elif !defined(__EMSCRIPTEN__)
|
#elif !defined(__EMSCRIPTEN__)
|
||||||
// WGPU-Native specific data structure (e.g. used in WGPULogLevel)
|
#include <webgpu/wgpu.h> // WGPULogLevel
|
||||||
#include <webgpu/wgpu.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Initialization data, for ImGui_ImplWGPU_Init()
|
// Initialization data, for ImGui_ImplWGPU_Init()
|
||||||
@@ -76,20 +73,14 @@ struct ImGui_ImplWGPU_RenderState
|
|||||||
WGPURenderPassEncoder RenderPassEncoder;
|
WGPURenderPassEncoder RenderPassEncoder;
|
||||||
};
|
};
|
||||||
|
|
||||||
// WebGPU Helpers
|
// (Optional) WebGPU Helpers
|
||||||
|
bool ImGui_ImplWGPU_CheckSurfaceTextureOptimalStatus_Helper(WGPUSurfaceGetCurrentTextureStatus status); // Check if the status of surface texture is optimal
|
||||||
// Check if the Status of SurfaceTexture is Optimal
|
|
||||||
bool ImGui_ImplWGPU_CheckSurfaceTextureOptimalStatus_Helper(WGPUSurfaceGetCurrentTextureStatus status);
|
|
||||||
// Print Adapter info
|
|
||||||
void ImGui_ImplWGPU_PrintAdapterInfo_Helper(const WGPUAdapter& adapter);
|
void ImGui_ImplWGPU_PrintAdapterInfo_Helper(const WGPUAdapter& adapter);
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) // DAWN both Native / EMSCRIPTEN
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) // DAWN both Native / EMSCRIPTEN
|
||||||
// DAWN Validation Layer callback: reason for device loss
|
void ImGui_ImplWGPU_DAWN_DeviceLostCallback_Helper(const wgpu::Device&, wgpu::DeviceLostReason reason, wgpu::StringView msg);// DAWN Validation Layer callback: reason for device loss
|
||||||
void ImGui_ImplWGPU_DAWN_DeviceLostCallback_Helper(const wgpu::Device&, wgpu::DeviceLostReason reason, wgpu::StringView message);
|
void ImGui_ImplWGPU_DAWN_ErrorCallback_Helper(const wgpu::Device&, wgpu::ErrorType type, wgpu::StringView msg); // DAWN Validation Layer callback: print error type
|
||||||
// DAWN Validation Layer callback: print error type
|
|
||||||
void ImGui_ImplWGPU_DAWN_ErrorCallback_Helper(const wgpu::Device&, wgpu::ErrorType type, wgpu::StringView message);
|
|
||||||
#elif !defined(__EMSCRIPTEN__) // WGPU-Native
|
#elif !defined(__EMSCRIPTEN__) // WGPU-Native
|
||||||
// WGPU-Native LOG callback: print information based on request level
|
void ImGui_ImplWGPU_WGPU_LogCallback_Helper(WGPULogLevel level, WGPUStringView msg, void* userdata); // WGPU-Native log callback: print information based on request level.
|
||||||
void ImGui_ImplWGPU_WGPU_LogCallback_Helper(WGPULogLevel level, WGPUStringView message, void *userdata);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Dear ImGui: standalone example application for using GLFW + WebGPU
|
// Dear ImGui: standalone example application for GLFW + WebGPU
|
||||||
// - Emscripten is supported for publishing on web. See https://emscripten.org.
|
// - Emscripten is supported for publishing on web. See https://emscripten.org.
|
||||||
// - Dawn is used as a WebGPU implementation on desktop.
|
// - Dawn is used as a WebGPU implementation on desktop.
|
||||||
|
|
||||||
@@ -13,8 +13,9 @@
|
|||||||
#include "imgui_impl_wgpu.h"
|
#include "imgui_impl_wgpu.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
// This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details.
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
#include <emscripten.h>
|
#include <emscripten.h>
|
||||||
#include <emscripten/html5.h>
|
#include <emscripten/html5.h>
|
||||||
@@ -30,7 +31,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Global WebGPU required states
|
// Data
|
||||||
static WGPUInstance wgpu_instance = nullptr;
|
static WGPUInstance wgpu_instance = nullptr;
|
||||||
static WGPUDevice wgpu_device = nullptr;
|
static WGPUDevice wgpu_device = nullptr;
|
||||||
static WGPUSurface wgpu_surface = nullptr;
|
static WGPUSurface wgpu_surface = nullptr;
|
||||||
@@ -51,7 +52,6 @@ static void ResizeSurface(int width, int height)
|
|||||||
{
|
{
|
||||||
wgpu_surface_configuration.width = wgpu_surface_width = width;
|
wgpu_surface_configuration.width = wgpu_surface_width = width;
|
||||||
wgpu_surface_configuration.height = wgpu_surface_height = height;
|
wgpu_surface_configuration.height = wgpu_surface_height = height;
|
||||||
|
|
||||||
wgpuSurfaceConfigure(wgpu_surface, &wgpu_surface_configuration);
|
wgpuSurfaceConfigure(wgpu_surface, &wgpu_surface_configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,21 +68,26 @@ int main(int, char**)
|
|||||||
{
|
{
|
||||||
glfwSetErrorCallback(glfw_error_callback);
|
glfwSetErrorCallback(glfw_error_callback);
|
||||||
if (!glfwInit())
|
if (!glfwInit())
|
||||||
return EXIT_FAILURE;
|
return 1;
|
||||||
|
|
||||||
// Make sure GLFW does not initialize any graphics context.
|
// Make sure GLFW does not initialize any graphics context.
|
||||||
// This needs to be done explicitly later.
|
// This needs to be done explicitly later.
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
|
|
||||||
|
// Create window
|
||||||
|
float main_scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfwGetPrimaryMonitor()); // Valid on GLFW 3.3+ only // FIXME-WGPU: Verify
|
||||||
|
wgpu_surface_width *= main_scale;
|
||||||
|
wgpu_surface_height *= main_scale;
|
||||||
GLFWwindow* window = glfwCreateWindow(wgpu_surface_width, wgpu_surface_height, "Dear ImGui GLFW+WebGPU example", nullptr, nullptr);
|
GLFWwindow* window = glfwCreateWindow(wgpu_surface_width, wgpu_surface_height, "Dear ImGui GLFW+WebGPU example", nullptr, nullptr);
|
||||||
if (window == nullptr)
|
if (window == nullptr)
|
||||||
return EXIT_FAILURE;
|
return 1;
|
||||||
|
|
||||||
// Initialize the WebGPU environment
|
// Initialize the WebGPU environment
|
||||||
if (!InitWGPU(window))
|
if (!InitWGPU(window))
|
||||||
{
|
{
|
||||||
glfwDestroyWindow(window);
|
glfwDestroyWindow(window);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
return EXIT_FAILURE;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwShowWindow(window);
|
glfwShowWindow(window);
|
||||||
@@ -98,6 +103,11 @@ int main(int, char**)
|
|||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
|
||||||
|
// Setup scaling
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||||
|
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||||
|
|
||||||
// Setup Platform/Renderer backends
|
// Setup Platform/Renderer backends
|
||||||
ImGui_ImplGlfw_InitForOther(window, true);
|
ImGui_ImplGlfw_InitForOther(window, true);
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
@@ -114,19 +124,18 @@ int main(int, char**)
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
// - Emscripten allows preloading a file or folder to be accessible at runtime. See Makefile for details.
|
// - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See Makefile.emscripten for details.
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
//io.Fonts->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
#ifndef IMGUI_DISABLE_FILE_FUNCTIONS
|
#ifndef IMGUI_DISABLE_FILE_FUNCTIONS
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/ProggyTiny.ttf", 10.0f);
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("fonts/ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -162,7 +171,7 @@ int main(int, char**)
|
|||||||
glfwGetFramebufferSize((GLFWwindow*)window, &width, &height);
|
glfwGetFramebufferSize((GLFWwindow*)window, &width, &height);
|
||||||
if (width != wgpu_surface_width || height != wgpu_surface_height)
|
if (width != wgpu_surface_width || height != wgpu_surface_height)
|
||||||
{
|
{
|
||||||
ImGui_ImplWGPU_InvalidateDeviceObjects();
|
ImGui_ImplWGPU_InvalidateDeviceObjects(); // FIXME-WGPU: Why doing this? this will recreate all font textures etc.
|
||||||
ResizeSurface(width, height);
|
ResizeSurface(width, height);
|
||||||
ImGui_ImplWGPU_CreateDeviceObjects();
|
ImGui_ImplWGPU_CreateDeviceObjects();
|
||||||
}
|
}
|
||||||
@@ -170,8 +179,9 @@ int main(int, char**)
|
|||||||
WGPUSurfaceTexture surfaceTexture;
|
WGPUSurfaceTexture surfaceTexture;
|
||||||
wgpuSurfaceGetCurrentTexture(wgpu_surface, &surfaceTexture);
|
wgpuSurfaceGetCurrentTexture(wgpu_surface, &surfaceTexture);
|
||||||
|
|
||||||
// Check SurfaceTexture status, if NOT optimal status we try to re-configure Surface
|
// Check if surface texture is not optimal and try to re-configure Surface
|
||||||
if (!ImGui_ImplWGPU_CheckSurfaceTextureOptimalStatus_Helper(surfaceTexture.status)) {
|
if (!ImGui_ImplWGPU_CheckSurfaceTextureOptimalStatus_Helper(surfaceTexture.status))
|
||||||
|
{
|
||||||
ReleaseTextureAndConfigureSurface(surfaceTexture.texture, width, height);
|
ReleaseTextureAndConfigureSurface(surfaceTexture.texture, width, height);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -284,17 +294,17 @@ int main(int, char**)
|
|||||||
glfwDestroyWindow(window);
|
glfwDestroyWindow(window);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
||||||
static WGPUAdapter GetAdapter(wgpu::Instance& instance)
|
static WGPUAdapter GetAdapter(wgpu::Instance& instance)
|
||||||
{
|
{
|
||||||
wgpu::Adapter acquiredAdapter;
|
wgpu::Adapter acquiredAdapter;
|
||||||
wgpu::RequestAdapterOptions adapterOptions;
|
wgpu::RequestAdapterOptions adapterOptions;
|
||||||
|
|
||||||
auto onRequestAdapter = [&](wgpu::RequestAdapterStatus status, wgpu::Adapter adapter, wgpu::StringView message) {
|
auto onRequestAdapter = [&](wgpu::RequestAdapterStatus status, wgpu::Adapter adapter, wgpu::StringView message)
|
||||||
|
{
|
||||||
if (status != wgpu::RequestAdapterStatus::Success)
|
if (status != wgpu::RequestAdapterStatus::Success)
|
||||||
{
|
{
|
||||||
printf("Failed to get an adapter: %s\n", message.data);
|
printf("Failed to get an adapter: %s\n", message.data);
|
||||||
@@ -306,7 +316,7 @@ static WGPUAdapter GetAdapter(wgpu::Instance &instance)
|
|||||||
// Synchronously (wait until) acquire Adapter
|
// Synchronously (wait until) acquire Adapter
|
||||||
wgpu::Future waitAdapterFunc { instance.RequestAdapter(&adapterOptions, wgpu::CallbackMode::WaitAnyOnly, onRequestAdapter) };
|
wgpu::Future waitAdapterFunc { instance.RequestAdapter(&adapterOptions, wgpu::CallbackMode::WaitAnyOnly, onRequestAdapter) };
|
||||||
wgpu::WaitStatus waitStatusAdapter = instance.WaitAny(waitAdapterFunc, UINT64_MAX);
|
wgpu::WaitStatus waitStatusAdapter = instance.WaitAny(waitAdapterFunc, UINT64_MAX);
|
||||||
assert(acquiredAdapter != nullptr && waitStatusAdapter == wgpu::WaitStatus::Success && "Error on Adapter request");
|
IM_ASSERT(acquiredAdapter != nullptr && waitStatusAdapter == wgpu::WaitStatus::Success && "Error on Adapter request");
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
ImGui_ImplWGPU_PrintAdapterInfo_Helper(acquiredAdapter.Get());
|
ImGui_ImplWGPU_PrintAdapterInfo_Helper(acquiredAdapter.Get());
|
||||||
#endif
|
#endif
|
||||||
@@ -321,7 +331,8 @@ static WGPUDevice GetDevice(wgpu::Instance &instance, wgpu::Adapter &adapter)
|
|||||||
deviceDesc.SetUncapturedErrorCallback(ImGui_ImplWGPU_DAWN_ErrorCallback_Helper);
|
deviceDesc.SetUncapturedErrorCallback(ImGui_ImplWGPU_DAWN_ErrorCallback_Helper);
|
||||||
|
|
||||||
wgpu::Device acquiredDevice;
|
wgpu::Device acquiredDevice;
|
||||||
auto onRequestDevice = [&](wgpu::RequestDeviceStatus status, wgpu::Device localDevice, wgpu::StringView message) {
|
auto onRequestDevice = [&](wgpu::RequestDeviceStatus status, wgpu::Device localDevice, wgpu::StringView message)
|
||||||
|
{
|
||||||
if (status != wgpu::RequestDeviceStatus::Success)
|
if (status != wgpu::RequestDeviceStatus::Success)
|
||||||
{
|
{
|
||||||
printf("Failed to get an device: %s\n", message.data);
|
printf("Failed to get an device: %s\n", message.data);
|
||||||
@@ -333,7 +344,7 @@ static WGPUDevice GetDevice(wgpu::Instance &instance, wgpu::Adapter &adapter)
|
|||||||
// Synchronously (wait until) get Device
|
// Synchronously (wait until) get Device
|
||||||
wgpu::Future waitDeviceFunc { adapter.RequestDevice(&deviceDesc, wgpu::CallbackMode::WaitAnyOnly, onRequestDevice) };
|
wgpu::Future waitDeviceFunc { adapter.RequestDevice(&deviceDesc, wgpu::CallbackMode::WaitAnyOnly, onRequestDevice) };
|
||||||
wgpu::WaitStatus waitStatusDevice = instance.WaitAny(waitDeviceFunc, UINT64_MAX);
|
wgpu::WaitStatus waitStatusDevice = instance.WaitAny(waitDeviceFunc, UINT64_MAX);
|
||||||
assert(acquiredDevice != nullptr && waitStatusDevice == wgpu::WaitStatus::Success && "Error on Device request");
|
IM_ASSERT(acquiredDevice != nullptr && waitStatusDevice == wgpu::WaitStatus::Success && "Error on Device request");
|
||||||
return acquiredDevice.MoveToCHandle();
|
return acquiredDevice.MoveToCHandle();
|
||||||
}
|
}
|
||||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
@@ -356,8 +367,10 @@ static void handle_request_adapter(WGPURequestAdapterStatus status, WGPUAdapter
|
|||||||
*extAdapter = adapter;
|
*extAdapter = adapter;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
printf("Request_adapter status=%#.8x message=%.*s\n", status, (int) message.length, message.data);
|
printf("Request_adapter status=%#.8x message=%.*s\n", status, (int) message.length, message.data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* userdata1, void* userdata2)
|
static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* userdata1, void* userdata2)
|
||||||
{
|
{
|
||||||
@@ -367,8 +380,10 @@ static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice dev
|
|||||||
*extDevice = device;
|
*extDevice = device;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
printf("Request_device status=%#.8x message=%.*s\n", status, (int) message.length, message.data);
|
printf("Request_device status=%#.8x message=%.*s\n", status, (int) message.length, message.data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static WGPUAdapter GetAdapter(WGPUInstance& instance)
|
static WGPUAdapter GetAdapter(WGPUInstance& instance)
|
||||||
{
|
{
|
||||||
@@ -380,8 +395,8 @@ static WGPUAdapter GetAdapter(WGPUInstance &instance)
|
|||||||
adapterCallbackInfo.userdata1 = &localAdapter;
|
adapterCallbackInfo.userdata1 = &localAdapter;
|
||||||
|
|
||||||
wgpuInstanceRequestAdapter(wgpu_instance, &adapterOptions, adapterCallbackInfo);
|
wgpuInstanceRequestAdapter(wgpu_instance, &adapterOptions, adapterCallbackInfo);
|
||||||
assert(localAdapter && "Error on Adapter request");
|
|
||||||
|
|
||||||
|
IM_ASSERT(localAdapter && "Error on Adapter request");
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
ImGui_ImplWGPU_PrintAdapterInfo_Helper(localAdapter);
|
ImGui_ImplWGPU_PrintAdapterInfo_Helper(localAdapter);
|
||||||
#endif
|
#endif
|
||||||
@@ -397,7 +412,7 @@ static WGPUDevice GetDevice(WGPUAdapter &adapter)
|
|||||||
deviceCallbackInfo.userdata1 = &localDevice;
|
deviceCallbackInfo.userdata1 = &localDevice;
|
||||||
|
|
||||||
wgpuAdapterRequestDevice(adapter, NULL, deviceCallbackInfo);
|
wgpuAdapterRequestDevice(adapter, NULL, deviceCallbackInfo);
|
||||||
assert(localDevice && "Error on Device request");
|
IM_ASSERT(localDevice && "Error on Device request");
|
||||||
|
|
||||||
return localDevice;
|
return localDevice;
|
||||||
}
|
}
|
||||||
@@ -448,7 +463,7 @@ static bool InitWGPU(void* window)
|
|||||||
getAdapterAndDeviceViaJS();
|
getAdapterAndDeviceViaJS();
|
||||||
|
|
||||||
wgpu_device = emscripten_webgpu_get_device();
|
wgpu_device = emscripten_webgpu_get_device();
|
||||||
assert(wgpu_device != nullptr && "Error creating the Device");
|
IM_ASSERT(wgpu_device != nullptr && "Error creating the Device");
|
||||||
|
|
||||||
WGPUSurfaceDescriptorFromCanvasHTMLSelector html_surface_desc = {};
|
WGPUSurfaceDescriptorFromCanvasHTMLSelector html_surface_desc = {};
|
||||||
html_surface_desc.chain.sType = WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector;
|
html_surface_desc.chain.sType = WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector;
|
||||||
@@ -468,8 +483,7 @@ static bool InitWGPU(void* window)
|
|||||||
wgpu_device = GetDevice(adapter);
|
wgpu_device = GetDevice(adapter);
|
||||||
|
|
||||||
// Create the surface.
|
// Create the surface.
|
||||||
wgpu_surface = ImGui_ImplGLFW_CreateWGPUSurface_Helper( wgpu_instance, (GLFWwindow*) window);
|
wgpu_surface = ImGui_ImplGLFW_CreateWGPUSurface(wgpu_instance, (GLFWwindow*)window);
|
||||||
|
|
||||||
if (!wgpu_surface)
|
if (!wgpu_surface)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -489,7 +503,6 @@ static bool InitWGPU(void* window)
|
|||||||
wgpu_surface_configuration.format = preferred_fmt;
|
wgpu_surface_configuration.format = preferred_fmt;
|
||||||
|
|
||||||
wgpuSurfaceConfigure(wgpu_surface, &wgpu_surface_configuration);
|
wgpuSurfaceConfigure(wgpu_surface, &wgpu_surface_configuration);
|
||||||
|
|
||||||
wgpu_queue = wgpuDeviceGetQueue(wgpu_device);
|
wgpu_queue = wgpuDeviceGetQueue(wgpu_device);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Dear ImGui: standalone example application for using GLFW + WebGPU
|
// Dear ImGui: standalone example application for using SDL2 + WebGPU
|
||||||
// - Emscripten is supported for publishing on web. See https://emscripten.org.
|
// - Emscripten is supported for publishing on web. See https://emscripten.org.
|
||||||
// - Dawn is used as a WebGPU implementation on desktop.
|
// - Dawn is used as a WebGPU implementation on desktop.
|
||||||
|
|
||||||
@@ -8,40 +8,35 @@
|
|||||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
// - Introduction, links and more at the top of imgui.cpp
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#include "imgui_impl_sdl2.h"
|
#include "imgui_impl_sdl2.h"
|
||||||
#include "imgui_impl_wgpu.h"
|
#include "imgui_impl_wgpu.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
// This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details.
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
#include <emscripten.h>
|
#include <emscripten.h>
|
||||||
#include <emscripten/html5.h>
|
#include <emscripten/html5.h>
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
#include <emscripten/html5_webgpu.h>
|
#include <emscripten/html5_webgpu.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../libs/emscripten/emscripten_mainloop_stub.h"
|
#include "../libs/emscripten/emscripten_mainloop_stub.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <SDL.h>
|
|
||||||
#include <webgpu/webgpu.h>
|
#include <webgpu/webgpu.h>
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
||||||
#include <webgpu/webgpu_cpp.h>
|
#include <webgpu/webgpu_cpp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details.
|
// Data
|
||||||
#ifdef __EMSCRIPTEN__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Global WebGPU required states
|
|
||||||
WGPUInstance wgpu_instance = nullptr;
|
WGPUInstance wgpu_instance = nullptr;
|
||||||
WGPUDevice wgpu_device = nullptr;
|
WGPUDevice wgpu_device = nullptr;
|
||||||
WGPUSurface wgpu_surface = nullptr;
|
WGPUSurface wgpu_surface = nullptr;
|
||||||
WGPUQueue wgpu_queue = nullptr;
|
WGPUQueue wgpu_queue = nullptr;
|
||||||
WGPUSurfaceConfiguration wgpu_surface_configuration {};
|
WGPUSurfaceConfiguration wgpu_surface_configuration {};
|
||||||
int wgpu_surface_width = 1280;
|
int wgpu_surface_width = 1280;
|
||||||
int wgpu_surface_height = 720;
|
int wgpu_surface_height = 800;
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
static bool InitWGPU(void* window);
|
static bool InitWGPU(void* window);
|
||||||
@@ -50,7 +45,6 @@ static void ResizeSurface(int width, int height)
|
|||||||
{
|
{
|
||||||
wgpu_surface_configuration.width = wgpu_surface_width = width;
|
wgpu_surface_configuration.width = wgpu_surface_width = width;
|
||||||
wgpu_surface_configuration.height = wgpu_surface_height = height;
|
wgpu_surface_configuration.height = wgpu_surface_height = height;
|
||||||
|
|
||||||
wgpuSurfaceConfigure(wgpu_surface, (WGPUSurfaceConfiguration*)&wgpu_surface_configuration);
|
wgpuSurfaceConfigure(wgpu_surface, (WGPUSurfaceConfiguration*)&wgpu_surface_configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,17 +59,18 @@ static void ReleaseTextureAndConfigureSurface(WGPUTexture &texture, int fb_width
|
|||||||
// Main code
|
// Main code
|
||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
|
// Setup SDL
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
// it's necessary to specify "x11" or "wayland": default is "x11" it works also in wayland
|
// It's necessary to specify "x11" or "wayland": default is "x11" it works also in wayland
|
||||||
|
// Or comment the line and export SDL_VIDEODRIVER environment variable:
|
||||||
|
// export SDL_VIDEODRIVER=wayland // To set wayland session type
|
||||||
|
// export SDL_VIDEODRIVER=$XDG_SESSION_TYPE // To get current session type from WM: x11 | wayland
|
||||||
SDL_SetHint(SDL_HINT_VIDEODRIVER, "x11");
|
SDL_SetHint(SDL_HINT_VIDEODRIVER, "x11");
|
||||||
// or comment the previous line and export SDL_VIDEODRIVER environment variable:
|
|
||||||
// export SDL_VIDEODRIVER=wayland (to set wayland session type)
|
|
||||||
// export SDL_VIDEODRIVER=$XDG_SESSION_TYPE (to get current session type from WM: x11 | wayland)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Init SDL
|
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER);
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
// Create window
|
||||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+WebGPU example", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, wgpu_surface_width, wgpu_surface_height, SDL_WINDOW_RESIZABLE);
|
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+WebGPU example", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, wgpu_surface_width, wgpu_surface_height, SDL_WINDOW_RESIZABLE);
|
||||||
|
|
||||||
// Initialize WGPU
|
// Initialize WGPU
|
||||||
@@ -92,9 +87,13 @@ int main(int, char**)
|
|||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
|
||||||
|
// Setup scaling
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||||
|
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||||
|
|
||||||
// Setup Platform/Renderer backends
|
// Setup Platform/Renderer backends
|
||||||
ImGui_ImplSDL2_InitForOther(window);
|
ImGui_ImplSDL2_InitForOther(window);
|
||||||
|
|
||||||
ImGui_ImplWGPU_InitInfo init_info;
|
ImGui_ImplWGPU_InitInfo init_info;
|
||||||
init_info.Device = wgpu_device;
|
init_info.Device = wgpu_device;
|
||||||
init_info.NumFramesInFlight = 3;
|
init_info.NumFramesInFlight = 3;
|
||||||
@@ -106,19 +105,18 @@ int main(int, char**)
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
// - Emscripten allows preloading a file or folder to be accessible at runtime. See Makefile for details.
|
// - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See Makefile.emscripten for details.
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
//io.Fonts->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
#ifndef IMGUI_DISABLE_FILE_FUNCTIONS
|
#ifndef IMGUI_DISABLE_FILE_FUNCTIONS
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/ProggyTiny.ttf", 10.0f);
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("fonts/ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -127,48 +125,48 @@ int main(int, char**)
|
|||||||
bool show_another_window = false;
|
bool show_another_window = false;
|
||||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||||
|
|
||||||
SDL_Event event;
|
|
||||||
bool canCloseWindow = false;
|
|
||||||
// Main loop
|
// Main loop
|
||||||
|
bool done = false;
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
// For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file.
|
// For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file.
|
||||||
// You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.
|
// You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.
|
||||||
io.IniFilename = nullptr;
|
io.IniFilename = nullptr;
|
||||||
EMSCRIPTEN_MAINLOOP_BEGIN
|
EMSCRIPTEN_MAINLOOP_BEGIN
|
||||||
#else
|
#else
|
||||||
while (!canCloseWindow)
|
while (!done)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
while (SDL_PollEvent(&event))
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL2_ProcessEvent(&event);
|
|
||||||
if (event.type == SDL_QUIT ||
|
|
||||||
(event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE &&
|
|
||||||
event.window.windowID == SDL_GetWindowID(window)))
|
|
||||||
canCloseWindow = true;
|
|
||||||
}
|
|
||||||
// Poll and handle events (inputs, window resize, etc.)
|
// Poll and handle events (inputs, window resize, etc.)
|
||||||
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
||||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event))
|
||||||
|
{
|
||||||
|
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||||
|
if (event.type == SDL_QUIT)
|
||||||
|
done = true;
|
||||||
|
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
|
||||||
// React to changes in screen size
|
// React to changes in screen size
|
||||||
int width, height;
|
int width, height;
|
||||||
SDL_GetWindowSize(window, &width, &height);
|
SDL_GetWindowSize(window, &width, &height);
|
||||||
if (width != wgpu_surface_width || height != wgpu_surface_height)
|
if (width != wgpu_surface_width || height != wgpu_surface_height)
|
||||||
{
|
{
|
||||||
ImGui_ImplWGPU_InvalidateDeviceObjects();
|
ImGui_ImplWGPU_InvalidateDeviceObjects(); // FIXME-WGPU: Why doing this? this will recreate all font textures etc.
|
||||||
ResizeSurface(width, height);
|
ResizeSurface(width, height);
|
||||||
ImGui_ImplWGPU_CreateDeviceObjects();
|
ImGui_ImplWGPU_CreateDeviceObjects();
|
||||||
//continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WGPUSurfaceTexture surfaceTexture;
|
WGPUSurfaceTexture surfaceTexture;
|
||||||
wgpuSurfaceGetCurrentTexture(wgpu_surface, &surfaceTexture);
|
wgpuSurfaceGetCurrentTexture(wgpu_surface, &surfaceTexture);
|
||||||
|
|
||||||
// Check SurfaceTexture status, if NOT optimal status we try to re-configure Surface
|
// Check if surface texture is not optimal and try to re-configure Surface
|
||||||
if (!ImGui_ImplWGPU_CheckSurfaceTextureOptimalStatus_Helper(surfaceTexture.status)) {
|
if (!ImGui_ImplWGPU_CheckSurfaceTextureOptimalStatus_Helper(surfaceTexture.status))
|
||||||
|
{
|
||||||
ReleaseTextureAndConfigureSurface(surfaceTexture.texture, width, height);
|
ReleaseTextureAndConfigureSurface(surfaceTexture.texture, width, height);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -277,11 +275,10 @@ int main(int, char**)
|
|||||||
wgpuDeviceRelease(wgpu_device);
|
wgpuDeviceRelease(wgpu_device);
|
||||||
wgpuInstanceRelease(wgpu_instance);
|
wgpuInstanceRelease(wgpu_instance);
|
||||||
|
|
||||||
// Terminate SDL
|
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
||||||
@@ -290,7 +287,8 @@ static WGPUAdapter GetAdapter(wgpu::Instance &instance)
|
|||||||
wgpu::Adapter acquiredAdapter;
|
wgpu::Adapter acquiredAdapter;
|
||||||
wgpu::RequestAdapterOptions adapterOptions;
|
wgpu::RequestAdapterOptions adapterOptions;
|
||||||
|
|
||||||
auto onRequestAdapter = [&](wgpu::RequestAdapterStatus status, wgpu::Adapter adapter, wgpu::StringView message) {
|
auto onRequestAdapter = [&](wgpu::RequestAdapterStatus status, wgpu::Adapter adapter, wgpu::StringView message)
|
||||||
|
{
|
||||||
if (status != wgpu::RequestAdapterStatus::Success)
|
if (status != wgpu::RequestAdapterStatus::Success)
|
||||||
{
|
{
|
||||||
printf("Failed to get an adapter: %s\n", message.data);
|
printf("Failed to get an adapter: %s\n", message.data);
|
||||||
@@ -302,7 +300,7 @@ static WGPUAdapter GetAdapter(wgpu::Instance &instance)
|
|||||||
// Synchronously (wait until) acquire Adapter
|
// Synchronously (wait until) acquire Adapter
|
||||||
wgpu::Future waitAdapterFunc { instance.RequestAdapter(&adapterOptions, wgpu::CallbackMode::WaitAnyOnly, onRequestAdapter) };
|
wgpu::Future waitAdapterFunc { instance.RequestAdapter(&adapterOptions, wgpu::CallbackMode::WaitAnyOnly, onRequestAdapter) };
|
||||||
wgpu::WaitStatus waitStatusAdapter = instance.WaitAny(waitAdapterFunc, UINT64_MAX);
|
wgpu::WaitStatus waitStatusAdapter = instance.WaitAny(waitAdapterFunc, UINT64_MAX);
|
||||||
assert(acquiredAdapter != nullptr && waitStatusAdapter == wgpu::WaitStatus::Success && "Error on Adapter request");
|
IM_ASSERT(acquiredAdapter != nullptr && waitStatusAdapter == wgpu::WaitStatus::Success && "Error on Adapter request");
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
ImGui_ImplWGPU_PrintAdapterInfo_Helper(acquiredAdapter.Get());
|
ImGui_ImplWGPU_PrintAdapterInfo_Helper(acquiredAdapter.Get());
|
||||||
#endif
|
#endif
|
||||||
@@ -317,7 +315,8 @@ static WGPUDevice GetDevice(wgpu::Instance &instance, wgpu::Adapter &adapter)
|
|||||||
deviceDesc.SetUncapturedErrorCallback(ImGui_ImplWGPU_DAWN_ErrorCallback_Helper);
|
deviceDesc.SetUncapturedErrorCallback(ImGui_ImplWGPU_DAWN_ErrorCallback_Helper);
|
||||||
|
|
||||||
wgpu::Device acquiredDevice;
|
wgpu::Device acquiredDevice;
|
||||||
auto onRequestDevice = [&](wgpu::RequestDeviceStatus status, wgpu::Device localDevice, wgpu::StringView message) {
|
auto onRequestDevice = [&](wgpu::RequestDeviceStatus status, wgpu::Device localDevice, wgpu::StringView message)
|
||||||
|
{
|
||||||
if (status != wgpu::RequestDeviceStatus::Success)
|
if (status != wgpu::RequestDeviceStatus::Success)
|
||||||
{
|
{
|
||||||
printf("Failed to get an device: %s\n", message.data);
|
printf("Failed to get an device: %s\n", message.data);
|
||||||
@@ -329,7 +328,7 @@ static WGPUDevice GetDevice(wgpu::Instance &instance, wgpu::Adapter &adapter)
|
|||||||
// Synchronously (wait until) get Device
|
// Synchronously (wait until) get Device
|
||||||
wgpu::Future waitDeviceFunc { adapter.RequestDevice(&deviceDesc, wgpu::CallbackMode::WaitAnyOnly, onRequestDevice) };
|
wgpu::Future waitDeviceFunc { adapter.RequestDevice(&deviceDesc, wgpu::CallbackMode::WaitAnyOnly, onRequestDevice) };
|
||||||
wgpu::WaitStatus waitStatusDevice = instance.WaitAny(waitDeviceFunc, UINT64_MAX);
|
wgpu::WaitStatus waitStatusDevice = instance.WaitAny(waitDeviceFunc, UINT64_MAX);
|
||||||
assert(acquiredDevice != nullptr && waitStatusDevice == wgpu::WaitStatus::Success && "Error on Device request");
|
IM_ASSERT(acquiredDevice != nullptr && waitStatusDevice == wgpu::WaitStatus::Success && "Error on Device request");
|
||||||
return acquiredDevice.MoveToCHandle();
|
return acquiredDevice.MoveToCHandle();
|
||||||
}
|
}
|
||||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
@@ -337,8 +336,8 @@ static WGPUDevice GetDevice(wgpu::Instance &instance, wgpu::Adapter &adapter)
|
|||||||
// Adapter and device initialization via JS
|
// Adapter and device initialization via JS
|
||||||
EM_ASYNC_JS( void, getAdapterAndDeviceViaJS, (),
|
EM_ASYNC_JS( void, getAdapterAndDeviceViaJS, (),
|
||||||
{
|
{
|
||||||
if (!navigator.gpu) throw Error("WebGPU not supported.");
|
if (!navigator.gpu)
|
||||||
|
throw Error("WebGPU not supported.");
|
||||||
const adapter = await navigator.gpu.requestAdapter();
|
const adapter = await navigator.gpu.requestAdapter();
|
||||||
const device = await adapter.requestDevice();
|
const device = await adapter.requestDevice();
|
||||||
Module.preinitializedWebGPUDevice = device;
|
Module.preinitializedWebGPUDevice = device;
|
||||||
@@ -352,8 +351,10 @@ static void handle_request_adapter(WGPURequestAdapterStatus status, WGPUAdapter
|
|||||||
*extAdapter = adapter;
|
*extAdapter = adapter;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
printf("Request_adapter status=%#.8x message=%.*s\n", status, (int)message.length, message.data);
|
printf("Request_adapter status=%#.8x message=%.*s\n", status, (int)message.length, message.data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* userdata1, void* userdata2)
|
static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* userdata1, void* userdata2)
|
||||||
{
|
{
|
||||||
@@ -363,8 +364,10 @@ static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice dev
|
|||||||
*extDevice = device;
|
*extDevice = device;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
printf("Request_device status=%#.8x message=%.*s\n", status, (int)message.length, message.data);
|
printf("Request_device status=%#.8x message=%.*s\n", status, (int)message.length, message.data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static WGPUAdapter GetAdapter(WGPUInstance& instance)
|
static WGPUAdapter GetAdapter(WGPUInstance& instance)
|
||||||
{
|
{
|
||||||
@@ -376,7 +379,7 @@ static WGPUAdapter GetAdapter(WGPUInstance &instance)
|
|||||||
adapterCallbackInfo.userdata1 = &localAdapter;
|
adapterCallbackInfo.userdata1 = &localAdapter;
|
||||||
|
|
||||||
wgpuInstanceRequestAdapter(wgpu_instance, &adapterOptions, adapterCallbackInfo);
|
wgpuInstanceRequestAdapter(wgpu_instance, &adapterOptions, adapterCallbackInfo);
|
||||||
assert(localAdapter && "Error on Adapter request");
|
IM_ASSERT(localAdapter && "Error on Adapter request");
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
ImGui_ImplWGPU_PrintAdapterInfo_Helper(localAdapter);
|
ImGui_ImplWGPU_PrintAdapterInfo_Helper(localAdapter);
|
||||||
@@ -393,7 +396,7 @@ static WGPUDevice GetDevice(WGPUAdapter &adapter)
|
|||||||
deviceCallbackInfo.userdata1 = &localDevice;
|
deviceCallbackInfo.userdata1 = &localDevice;
|
||||||
|
|
||||||
wgpuAdapterRequestDevice(adapter, NULL, deviceCallbackInfo);
|
wgpuAdapterRequestDevice(adapter, NULL, deviceCallbackInfo);
|
||||||
assert(localDevice && "Error on Device request");
|
IM_ASSERT(localDevice && "Error on Device request");
|
||||||
|
|
||||||
return localDevice;
|
return localDevice;
|
||||||
}
|
}
|
||||||
@@ -422,7 +425,7 @@ static bool InitWGPU(void* window)
|
|||||||
surfaceDesc.nextInChain = &canvasDesc;
|
surfaceDesc.nextInChain = &canvasDesc;
|
||||||
wgpu::Surface surface = instance.CreateSurface(&surfaceDesc);
|
wgpu::Surface surface = instance.CreateSurface(&surfaceDesc);
|
||||||
#else
|
#else
|
||||||
wgpu::Surface surface = ImGui_ImplSDL2_CreateWGPUSurface_Helper(instance.Get(), (SDL_Window *) window);
|
wgpu::Surface surface = ImGui_ImplSDL2_CreateWGPUSurface(instance.Get(), (SDL_Window*)window);
|
||||||
#endif
|
#endif
|
||||||
if (!surface)
|
if (!surface)
|
||||||
return false;
|
return false;
|
||||||
@@ -464,8 +467,7 @@ static bool InitWGPU(void* window)
|
|||||||
wgpu_device = GetDevice(adapter);
|
wgpu_device = GetDevice(adapter);
|
||||||
|
|
||||||
// Create the surface.
|
// Create the surface.
|
||||||
wgpu_surface = ImGui_ImplSDL2_CreateWGPUSurface_Helper(wgpu_instance, (SDL_Window *) window);
|
wgpu_surface = ImGui_ImplSDL2_CreateWGPUSurface(wgpu_instance, (SDL_Window*)window);
|
||||||
|
|
||||||
if (!wgpu_surface)
|
if (!wgpu_surface)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Dear ImGui: standalone example application for using GLFW + WebGPU
|
// Dear ImGui: standalone example application for using SDL3 + WebGPU
|
||||||
// - Emscripten is supported for publishing on web. See https://emscripten.org.
|
// - Emscripten is supported for publishing on web. See https://emscripten.org.
|
||||||
// - Dawn is used as a WebGPU implementation on desktop.
|
// - Dawn is used as a WebGPU implementation on desktop.
|
||||||
|
|
||||||
@@ -14,36 +14,31 @@
|
|||||||
#include "imgui_impl_wgpu.h"
|
#include "imgui_impl_wgpu.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
// This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details.
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
#include <emscripten.h>
|
#include <emscripten.h>
|
||||||
#include <emscripten/html5.h>
|
#include <emscripten/html5.h>
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
#include <emscripten/html5_webgpu.h>
|
#include <emscripten/html5_webgpu.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../libs/emscripten/emscripten_mainloop_stub.h"
|
#include "../libs/emscripten/emscripten_mainloop_stub.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <SDL3/SDL.h>
|
|
||||||
|
|
||||||
#include <webgpu/webgpu.h>
|
#include <webgpu/webgpu.h>
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
||||||
#include <webgpu/webgpu_cpp.h>
|
#include <webgpu/webgpu_cpp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details.
|
// Data
|
||||||
#ifdef __EMSCRIPTEN__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Global WebGPU required states
|
|
||||||
WGPUInstance wgpu_instance = nullptr;
|
WGPUInstance wgpu_instance = nullptr;
|
||||||
WGPUDevice wgpu_device = nullptr;
|
WGPUDevice wgpu_device = nullptr;
|
||||||
WGPUSurface wgpu_surface = nullptr;
|
WGPUSurface wgpu_surface = nullptr;
|
||||||
WGPUQueue wgpu_queue = nullptr;
|
WGPUQueue wgpu_queue = nullptr;
|
||||||
WGPUSurfaceConfiguration wgpu_surface_configuration {};
|
WGPUSurfaceConfiguration wgpu_surface_configuration {};
|
||||||
int wgpu_surface_width = 1280;
|
int wgpu_surface_width = 1280;
|
||||||
int wgpu_surface_height = 720;
|
int wgpu_surface_height = 800;
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
static bool InitWGPU(void* window);
|
static bool InitWGPU(void* window);
|
||||||
@@ -52,7 +47,6 @@ void ResizeSurface(int width, int height)
|
|||||||
{
|
{
|
||||||
wgpu_surface_configuration.width = wgpu_surface_width = width;
|
wgpu_surface_configuration.width = wgpu_surface_width = width;
|
||||||
wgpu_surface_configuration.height = wgpu_surface_height = height;
|
wgpu_surface_configuration.height = wgpu_surface_height = height;
|
||||||
|
|
||||||
wgpuSurfaceConfigure( wgpu_surface, (WGPUSurfaceConfiguration*)&wgpu_surface_configuration );
|
wgpuSurfaceConfigure( wgpu_surface, (WGPUSurfaceConfiguration*)&wgpu_surface_configuration );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,23 +61,22 @@ static void ReleaseTextureAndConfigureSurface(WGPUTexture &texture, int fb_width
|
|||||||
// Main code
|
// Main code
|
||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
#if defined(__linux__)
|
// Setup SDL
|
||||||
// SDL3 default is "x11" (it works also in "wayland"), uncomment the line below to use "wayland"
|
// [If using SDL_MAIN_USE_CALLBACKS: all code below until the main loop starts would likely be your SDL_AppInit() function]
|
||||||
// SDL_SetHint(SDL_HINT_VIDEO_DRIVER, "wayland");
|
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
|
||||||
#endif
|
|
||||||
|
|
||||||
// Init SDL
|
|
||||||
if (!SDL_Init(SDL_INIT_VIDEO ))
|
|
||||||
{
|
{
|
||||||
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||||
return EXIT_FAILURE;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create SDL window graphics context
|
||||||
|
float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()); // FIXME-WGPU: Test this?
|
||||||
SDL_WindowFlags window_flags = SDL_WINDOW_RESIZABLE;
|
SDL_WindowFlags window_flags = SDL_WINDOW_RESIZABLE;
|
||||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+WebGPU example", wgpu_surface_width, wgpu_surface_height, window_flags);
|
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+WebGPU example", wgpu_surface_width, wgpu_surface_height, window_flags);
|
||||||
if (window == nullptr)
|
if (window == nullptr)
|
||||||
{
|
{
|
||||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||||
return EXIT_FAILURE;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize WGPU
|
// Initialize WGPU
|
||||||
@@ -100,6 +93,11 @@ int main(int, char**)
|
|||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
|
||||||
|
// Setup scaling
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||||
|
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||||
|
|
||||||
// Setup Platform/Renderer backends
|
// Setup Platform/Renderer backends
|
||||||
ImGui_ImplSDL3_InitForOther(window);
|
ImGui_ImplSDL3_InitForOther(window);
|
||||||
|
|
||||||
@@ -114,19 +112,18 @@ int main(int, char**)
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
// - Emscripten allows preloading a file or folder to be accessible at runtime. See Makefile for details.
|
// - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See Makefile.emscripten for details.
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
//io.Fonts->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
#ifndef IMGUI_DISABLE_FILE_FUNCTIONS
|
#ifndef IMGUI_DISABLE_FILE_FUNCTIONS
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/ProggyTiny.ttf", 10.0f);
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("fonts/ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -135,47 +132,50 @@ int main(int, char**)
|
|||||||
bool show_another_window = false;
|
bool show_another_window = false;
|
||||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||||
|
|
||||||
SDL_Event event;
|
|
||||||
bool canCloseWindow = false;
|
|
||||||
// Main loop
|
// Main loop
|
||||||
|
bool done = false;
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
// For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file.
|
// For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file.
|
||||||
// You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.
|
// You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.
|
||||||
io.IniFilename = nullptr;
|
io.IniFilename = nullptr;
|
||||||
EMSCRIPTEN_MAINLOOP_BEGIN
|
EMSCRIPTEN_MAINLOOP_BEGIN
|
||||||
#else
|
#else
|
||||||
while (!canCloseWindow)
|
while (!done)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
while (SDL_PollEvent(&event))
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ProcessEvent(&event);
|
|
||||||
if (event.type == SDL_EVENT_QUIT ||
|
|
||||||
(event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window)))
|
|
||||||
canCloseWindow = true;
|
|
||||||
}
|
|
||||||
// Poll and handle events (inputs, window resize, etc.)
|
// Poll and handle events (inputs, window resize, etc.)
|
||||||
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
||||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||||
|
// [If using SDL_MAIN_USE_CALLBACKS: call ImGui_ImplSDL3_ProcessEvent() from your SDL_AppEvent() function]
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event))
|
||||||
|
{
|
||||||
|
ImGui_ImplSDL3_ProcessEvent(&event);
|
||||||
|
if (event.type == SDL_EVENT_QUIT)
|
||||||
|
done = true;
|
||||||
|
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppIterate() function]
|
||||||
// React to changes in screen size
|
// React to changes in screen size
|
||||||
int width, height;
|
int width, height;
|
||||||
SDL_GetWindowSize(window, &width, &height);
|
SDL_GetWindowSize(window, &width, &height);
|
||||||
if (width != wgpu_surface_width || height != wgpu_surface_height)
|
if (width != wgpu_surface_width || height != wgpu_surface_height)
|
||||||
{
|
{
|
||||||
ImGui_ImplWGPU_InvalidateDeviceObjects();
|
ImGui_ImplWGPU_InvalidateDeviceObjects(); // FIXME-WGPU: Why doing this? this will recreate all font textures etc.
|
||||||
ResizeSurface(width, height);
|
ResizeSurface(width, height);
|
||||||
ImGui_ImplWGPU_CreateDeviceObjects();
|
ImGui_ImplWGPU_CreateDeviceObjects();
|
||||||
//continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WGPUSurfaceTexture surfaceTexture;
|
WGPUSurfaceTexture surfaceTexture;
|
||||||
wgpuSurfaceGetCurrentTexture(wgpu_surface, &surfaceTexture);
|
wgpuSurfaceGetCurrentTexture(wgpu_surface, &surfaceTexture);
|
||||||
|
|
||||||
// Check SurfaceTexture status, if NOT optimal status we try to re-configure Surface
|
// Check if surface texture is not optimal and try to re-configure Surface
|
||||||
if (!ImGui_ImplWGPU_CheckSurfaceTextureOptimalStatus_Helper(surfaceTexture.status)) {
|
if (!ImGui_ImplWGPU_CheckSurfaceTextureOptimalStatus_Helper(surfaceTexture.status))
|
||||||
|
{
|
||||||
ReleaseTextureAndConfigureSurface(surfaceTexture.texture, width, height);
|
ReleaseTextureAndConfigureSurface(surfaceTexture.texture, width, height);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -274,6 +274,7 @@ int main(int, char**)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
|
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppQuit() function]
|
||||||
ImGui_ImplWGPU_Shutdown();
|
ImGui_ImplWGPU_Shutdown();
|
||||||
ImGui_ImplSDL3_Shutdown();
|
ImGui_ImplSDL3_Shutdown();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
@@ -284,11 +285,10 @@ int main(int, char**)
|
|||||||
wgpuDeviceRelease(wgpu_device);
|
wgpuDeviceRelease(wgpu_device);
|
||||||
wgpuInstanceRelease(wgpu_instance);
|
wgpuInstanceRelease(wgpu_instance);
|
||||||
|
|
||||||
// Terminate SDL
|
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
||||||
@@ -297,19 +297,20 @@ static WGPUAdapter GetAdapter(wgpu::Instance &instance)
|
|||||||
wgpu::Adapter acquiredAdapter;
|
wgpu::Adapter acquiredAdapter;
|
||||||
wgpu::RequestAdapterOptions adapterOptions;
|
wgpu::RequestAdapterOptions adapterOptions;
|
||||||
|
|
||||||
auto onRequestAdapter = [&](wgpu::RequestAdapterStatus status, wgpu::Adapter adapter, wgpu::StringView message) {
|
auto onRequestAdapter = [&](wgpu::RequestAdapterStatus status, wgpu::Adapter adapter, wgpu::StringView message)
|
||||||
|
{
|
||||||
if (status != wgpu::RequestAdapterStatus::Success)
|
if (status != wgpu::RequestAdapterStatus::Success)
|
||||||
{
|
{
|
||||||
printf("Failed to get an adapter: %s\n", message.data);
|
printf("Failed to get an adapter: %s\n", message.data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
acquiredAdapter = std::move(adapter);
|
acquiredAdapter = std::move(adapter); // FIXME-WGPU: no need to use std::move?
|
||||||
};
|
};
|
||||||
|
|
||||||
// Synchronously (wait until) acquire Adapter
|
// Synchronously (wait until) acquire Adapter
|
||||||
wgpu::Future waitAdapterFunc { instance.RequestAdapter(&adapterOptions, wgpu::CallbackMode::WaitAnyOnly, onRequestAdapter) };
|
wgpu::Future waitAdapterFunc { instance.RequestAdapter(&adapterOptions, wgpu::CallbackMode::WaitAnyOnly, onRequestAdapter) };
|
||||||
wgpu::WaitStatus waitStatusAdapter = instance.WaitAny(waitAdapterFunc, UINT64_MAX);
|
wgpu::WaitStatus waitStatusAdapter = instance.WaitAny(waitAdapterFunc, UINT64_MAX);
|
||||||
assert(acquiredAdapter != nullptr && waitStatusAdapter == wgpu::WaitStatus::Success && "Error on Adapter request");
|
IM_ASSERT(acquiredAdapter != nullptr && waitStatusAdapter == wgpu::WaitStatus::Success && "Error on Adapter request");
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
ImGui_ImplWGPU_PrintAdapterInfo_Helper(acquiredAdapter.Get());
|
ImGui_ImplWGPU_PrintAdapterInfo_Helper(acquiredAdapter.Get());
|
||||||
#endif
|
#endif
|
||||||
@@ -324,7 +325,8 @@ static WGPUDevice GetDevice(wgpu::Instance &instance, wgpu::Adapter &adapter)
|
|||||||
deviceDesc.SetUncapturedErrorCallback(ImGui_ImplWGPU_DAWN_ErrorCallback_Helper);
|
deviceDesc.SetUncapturedErrorCallback(ImGui_ImplWGPU_DAWN_ErrorCallback_Helper);
|
||||||
|
|
||||||
wgpu::Device acquiredDevice;
|
wgpu::Device acquiredDevice;
|
||||||
auto onRequestDevice = [&](wgpu::RequestDeviceStatus status, wgpu::Device localDevice, wgpu::StringView message) {
|
auto onRequestDevice = [&](wgpu::RequestDeviceStatus status, wgpu::Device localDevice, wgpu::StringView message)
|
||||||
|
{
|
||||||
if (status != wgpu::RequestDeviceStatus::Success)
|
if (status != wgpu::RequestDeviceStatus::Success)
|
||||||
{
|
{
|
||||||
printf("Failed to get an device: %s\n", message.data);
|
printf("Failed to get an device: %s\n", message.data);
|
||||||
@@ -336,7 +338,7 @@ static WGPUDevice GetDevice(wgpu::Instance &instance, wgpu::Adapter &adapter)
|
|||||||
// Synchronously (wait until) get Device
|
// Synchronously (wait until) get Device
|
||||||
wgpu::Future waitDeviceFunc { adapter.RequestDevice(&deviceDesc, wgpu::CallbackMode::WaitAnyOnly, onRequestDevice) };
|
wgpu::Future waitDeviceFunc { adapter.RequestDevice(&deviceDesc, wgpu::CallbackMode::WaitAnyOnly, onRequestDevice) };
|
||||||
wgpu::WaitStatus waitStatusDevice = instance.WaitAny(waitDeviceFunc, UINT64_MAX);
|
wgpu::WaitStatus waitStatusDevice = instance.WaitAny(waitDeviceFunc, UINT64_MAX);
|
||||||
assert(acquiredDevice != nullptr && waitStatusDevice == wgpu::WaitStatus::Success && "Error on Device request");
|
IM_ASSERT(acquiredDevice != nullptr && waitStatusDevice == wgpu::WaitStatus::Success && "Error on Device request");
|
||||||
return acquiredDevice.MoveToCHandle();
|
return acquiredDevice.MoveToCHandle();
|
||||||
}
|
}
|
||||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
@@ -344,8 +346,8 @@ static WGPUDevice GetDevice(wgpu::Instance &instance, wgpu::Adapter &adapter)
|
|||||||
// Adapter and device initialization via JS
|
// Adapter and device initialization via JS
|
||||||
EM_ASYNC_JS( void, getAdapterAndDeviceViaJS, (),
|
EM_ASYNC_JS( void, getAdapterAndDeviceViaJS, (),
|
||||||
{
|
{
|
||||||
if (!navigator.gpu) throw Error("WebGPU not supported.");
|
if (!navigator.gpu)
|
||||||
|
throw Error("WebGPU not supported.");
|
||||||
const adapter = await navigator.gpu.requestAdapter();
|
const adapter = await navigator.gpu.requestAdapter();
|
||||||
const device = await adapter.requestDevice();
|
const device = await adapter.requestDevice();
|
||||||
Module.preinitializedWebGPUDevice = device;
|
Module.preinitializedWebGPUDevice = device;
|
||||||
@@ -359,8 +361,10 @@ static void handle_request_adapter(WGPURequestAdapterStatus status, WGPUAdapter
|
|||||||
*extAdapter = adapter;
|
*extAdapter = adapter;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
printf("Request_adapter status=%#.8x message=%.*s\n", status, (int)message.length, message.data);
|
printf("Request_adapter status=%#.8x message=%.*s\n", status, (int)message.length, message.data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* userdata1, void* userdata2)
|
static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* userdata1, void* userdata2)
|
||||||
{
|
{
|
||||||
@@ -370,7 +374,9 @@ static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice dev
|
|||||||
*extDevice = device;
|
*extDevice = device;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
printf("Request_device status=%#.8x message=%.*s\n", status, (int) message.length, message.data);
|
{
|
||||||
|
printf("Request_device status=%#.8x message=%.*s\n", status, (int message.length, message.data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static WGPUAdapter GetAdapter(WGPUInstance& instance)
|
static WGPUAdapter GetAdapter(WGPUInstance& instance)
|
||||||
@@ -383,7 +389,7 @@ static WGPUAdapter GetAdapter(WGPUInstance &instance)
|
|||||||
adapterCallbackInfo.userdata1 = &localAdapter;
|
adapterCallbackInfo.userdata1 = &localAdapter;
|
||||||
|
|
||||||
wgpuInstanceRequestAdapter(wgpu_instance, &adapterOptions, adapterCallbackInfo);
|
wgpuInstanceRequestAdapter(wgpu_instance, &adapterOptions, adapterCallbackInfo);
|
||||||
assert(localAdapter && "Error on Adapter request");
|
IM_ASSERT(localAdapter && "Error on Adapter request");
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
ImGui_ImplWGPU_PrintAdapterInfo_Helper(localAdapter);
|
ImGui_ImplWGPU_PrintAdapterInfo_Helper(localAdapter);
|
||||||
@@ -400,7 +406,7 @@ static WGPUDevice GetDevice(WGPUAdapter &adapter)
|
|||||||
deviceCallbackInfo.userdata1 = &localDevice;
|
deviceCallbackInfo.userdata1 = &localDevice;
|
||||||
|
|
||||||
wgpuAdapterRequestDevice(adapter, NULL, deviceCallbackInfo);
|
wgpuAdapterRequestDevice(adapter, NULL, deviceCallbackInfo);
|
||||||
assert(localDevice && "Error on Device request");
|
IM_ASSERT(localDevice && "Error on Device request");
|
||||||
|
|
||||||
return localDevice;
|
return localDevice;
|
||||||
}
|
}
|
||||||
@@ -429,7 +435,7 @@ static bool InitWGPU(void* window)
|
|||||||
surfaceDesc.nextInChain = &canvasDesc;
|
surfaceDesc.nextInChain = &canvasDesc;
|
||||||
wgpu::Surface surface = instance.CreateSurface(&surfaceDesc) ;
|
wgpu::Surface surface = instance.CreateSurface(&surfaceDesc) ;
|
||||||
#else
|
#else
|
||||||
wgpu::Surface surface = ImGui_ImplSDL3_CreateWGPUSurface_Helper(instance.Get(), (SDL_Window *) window);
|
wgpu::Surface surface = ImGui_ImplSDL3_CreateWGPUSurface(instance.Get(), (SDL_Window*)window);
|
||||||
#endif
|
#endif
|
||||||
if (!surface)
|
if (!surface)
|
||||||
return false;
|
return false;
|
||||||
@@ -471,8 +477,7 @@ static bool InitWGPU(void* window)
|
|||||||
wgpu_device = GetDevice(adapter);
|
wgpu_device = GetDevice(adapter);
|
||||||
|
|
||||||
// Create the surface.
|
// Create the surface.
|
||||||
wgpu_surface = ImGui_ImplSDL3_CreateWGPUSurface_Helper(wgpu_instance, (SDL_Window *) window);
|
wgpu_surface = ImGui_ImplSDL3_CreateWGPUSurface(wgpu_instance, (SDL_Window*)window);
|
||||||
|
|
||||||
if (!wgpu_surface)
|
if (!wgpu_surface)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -492,7 +497,6 @@ static bool InitWGPU(void* window)
|
|||||||
wgpu_surface_configuration.format = preferred_fmt;
|
wgpu_surface_configuration.format = preferred_fmt;
|
||||||
|
|
||||||
wgpuSurfaceConfigure(wgpu_surface, &wgpu_surface_configuration);
|
wgpuSurfaceConfigure(wgpu_surface, &wgpu_surface_configuration);
|
||||||
|
|
||||||
wgpu_queue = wgpuDeviceGetQueue(wgpu_device);
|
wgpu_queue = wgpuDeviceGetQueue(wgpu_device);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
Reference in New Issue
Block a user