Browse Source

Merge pull request #259 from floooh/webgpu

Experimental WebGPU backend, plus some API cleanup.
Andre Weissflog 5 years ago
parent
commit
223f11314b
8 changed files with 1728 additions and 309 deletions
  1. 29 8
      README.md
  2. 396 92
      sokol_app.h
  3. 505 203
      sokol_gfx.h
  4. 133 0
      sokol_glue.h
  5. 224 1
      util/sokol_fontstash.h
  6. 13 1
      util/sokol_gfx_imgui.h
  7. 222 2
      util/sokol_gl.h
  8. 206 2
      util/sokol_imgui.h

+ 29 - 8
README.md

@@ -6,7 +6,7 @@ Simple
 [STB-style](https://github.com/nothings/stb/blob/master/docs/stb_howto.txt)
 cross-platform libraries for C and C++, written in C.
 
-[See what's new](#updates) (**30-Jan-2020**: some internal code cleanup in sokol_gfx.h)
+[See what's new](#updates) (**30-Apr-2020**: experimental WebGPU backend and minor breaking changes)
 
 [Live Samples](https://floooh.github.io/sokol-html5/index.html) via WASM.
 
@@ -170,18 +170,13 @@ to split the Objective-C code from the C code of the sample):
 ```cpp
 #include "sokol_app.h"
 #include "sokol_gfx.h"
+#include "sokol_glue.h"
 
 sg_pass_action pass_action;
 
 void init(void) {
     sg_setup(&(sg_desc){
-        .mtl_device = sapp_metal_get_device(),
-        .mtl_renderpass_descriptor_cb = sapp_metal_get_renderpass_descriptor,
-        .mtl_drawable_cb = sapp_metal_get_drawable,
-        .d3d11_device = sapp_d3d11_get_device(),
-        .d3d11_device_context = sapp_d3d11_get_device_context(),
-        .d3d11_render_target_view_cb = sapp_d3d11_get_render_target_view,
-        .d3d11_depth_stencil_view_cb = sapp_d3d11_get_depth_stencil_view
+        .context = sapp_sgcontext()
     });
     pass_action = (sg_pass_action) {
         .colors[0] = { .action=SG_ACTION_CLEAR, .val={1.0f, 0.0f, 0.0f, 1.0f} }
@@ -465,6 +460,32 @@ Mainly some "missing features" for desktop apps:
 
 # Updates
 
+- **30-Apr-2020**: experimental WebGPU backend and a minor breaking change:
+    - sokol_gfx.h: a new WebGPU backend, expect frequent breakage for a while
+      because the WebGPU backend is still in flux
+    - a new header sokol_glue.h, with interop helper functions when specific combinations
+      of sokol headers are used together
+    - changes in the way sokol_gfx.h is initialized via a new layout of the
+      sg_desc structure
+    - sokol_gfx.h: a new ```sg_sampler_type``` enum which is required for
+      shader creation to tell the WebGPU backend about the sampler data types
+      (float, signed int, or unsigned int) used in the shader
+    - sokol_app.h: a handful new functions to query default framebuffer attributes (color- and
+      depth-buffer pixel formats, and MSAA sample count)
+    - sokol_app.h: WebGPU device and swapchain initialization (currently only
+      in the emscripten code path)
+    - [sokol-shdc](https://github.com/floooh/sokol-tools/blob/master/docs/sokol-shdc.md) has
+      been updated with WebGPU support (currently outputs SPIRV bytecode), and to output the new
+      ```sg_sampler_type``` enum in ```sg_shader_image_desc```
+    - [sokol-samples](https://github.com/floooh/sokol-samples/) has a new set of
+      backend-specific WebGPU samples, and the other samples have been updated
+      for the new sokol-gfx initialization
+    - ```pre-webgpu``` tags have been added to the [sokol](https://github.com/floooh/sokol/releases/tag/pre-webgpu), [sokol-samples](https://github.com/floooh/sokol-samples/releases/tag/pre-webgpu), [sokol-tools](https://github.com/floooh/sokol-tools/releases/tag/pre-webgpu)
+      and [sokol-tools-bin](https://github.com/floooh/sokol-tools-bin/releases/tag/pre-webgpu) github repositories (in case you need to continue working with
+      the older versions)
+    - please see this [blog post](https://floooh.github.io/2020/04/26/sokol-spring-2020-update.html)
+      for more details
+
 - **05-Apr-2020**: A bugfix in sokol_gl.h, the (fairly recent) optimization for
     merging draw calls contained a bug that could be triggered in an "empty"
     sgl_begin/sgl_end pair (with no vertices recorded inbetween). This could

+ 396 - 92
sokol_app.h

@@ -9,23 +9,36 @@
     before you include this file in *one* C or C++ file to create the
     implementation.
 
+    In the same place define one of the following to select the 3D-API
+    which should be initialized by sokol_app.h:
+
+        #define SOKOL_GLCORE33
+        #define SOKOL_GLES2
+        #define SOKOL_GLES3
+        #define SOKOL_D3D11
+        #define SOKOL_METAL
+        #define SOKOL_WGPU
+
+    If sokol_app.h is used together with sokol_gfx.h, the selected 3D-APIs
+    backend match.
+
     Optionally provide the following defines with your own implementations:
 
-    SOKOL_ASSERT(c)     - your own assert macro (default: assert(c))
-    SOKOL_LOG(msg)      - your own logging function (default: puts(msg))
-    SOKOL_UNREACHABLE() - a guard macro for unreachable code (default: assert(false))
-    SOKOL_ABORT()       - called after an unrecoverable error (default: abort())
-    SOKOL_WIN32_FORCE_MAIN  - define this on Win32 to use a main() entry point instead of WinMain
-    SOKOL_NO_ENTRY      - define this if sokol_app.h shouldn't "hijack" the main() function
-    SOKOL_API_DECL      - public function declaration prefix (default: extern)
-    SOKOL_API_IMPL      - public function implementation prefix (default: -)
-    SOKOL_CALLOC        - your own calloc function (default: calloc(n, s))
-    SOKOL_FREE          - your own free function (default: free(p))
+        SOKOL_ASSERT(c)     - your own assert macro (default: assert(c))
+        SOKOL_LOG(msg)      - your own logging function (default: puts(msg))
+        SOKOL_UNREACHABLE() - a guard macro for unreachable code (default: assert(false))
+        SOKOL_ABORT()       - called after an unrecoverable error (default: abort())
+        SOKOL_WIN32_FORCE_MAIN  - define this on Win32 to use a main() entry point instead of WinMain
+        SOKOL_NO_ENTRY      - define this if sokol_app.h shouldn't "hijack" the main() function
+        SOKOL_API_DECL      - public function declaration prefix (default: extern)
+        SOKOL_API_IMPL      - public function implementation prefix (default: -)
+        SOKOL_CALLOC        - your own calloc function (default: calloc(n, s))
+        SOKOL_FREE          - your own free function (default: free(p))
 
     Optionally define the following to force debug checks and validations
     even in release mode:
 
-    SOKOL_DEBUG         - by default this is defined if _DEBUG is defined
+        SOKOL_DEBUG         - by default this is defined if _DEBUG is defined
 
     If sokol_app.h is compiled as a DLL, define the following before
     including the declaration or implementation:
@@ -205,6 +218,20 @@
         int sapp_height(void)
             Likewise, returns the current height of the default framebuffer.
 
+        sapp_pixel_format sapp_color_format(void)
+        sapp_pixel_format sapp_depth_format(void)
+            The color and depth-stencil pixelformats of the default framebuffer,
+            as enum values which are compatible with sokol-gfx's
+            sg_pixel_format enum:
+
+                SAPP_PIXELFORMAT_RGBA8 == 23 == SG_PIXELFORMAT_RGBA8
+                SAPP_PIXELFORMAT_BGRA8 == 27 == SG_PIXELFORMAT_BGRA8
+                SAPP_PIXELFORMAT_DEPTH == 41 == SG_PIXELFORMAT_DEPTH
+                SAPP_PIXELFORMAT_DEPTH_STENCIL == 42 == SG_PIXELFORMAT_DEPTH_STENCIL
+
+        int sapp_sample_count(void)
+            Return the MSAA sample count of the default framebuffer.
+
         bool sapp_gles2(void)
             Returns true if a GLES2 or WebGL context has been created. This
             is useful when a GLES3/WebGL2 context was requested but is not
@@ -237,10 +264,10 @@
             HWND has been cast to a void pointer in order to be tunneled
             through code which doesn't include Windows.h.
 
-        const void* sapp_d3d11_get_device(void);
-        const void* sapp_d3d11_get_device_context(void);
-        const void* sapp_d3d11_get_render_target_view(void);
-        const void* sapp_d3d11_get_depth_stencil_view(void);
+        const void* sapp_d3d11_get_device(void)
+        const void* sapp_d3d11_get_device_context(void)
+        const void* sapp_d3d11_get_render_target_view(void)
+        const void* sapp_d3d11_get_depth_stencil_view(void)
             Similar to the sapp_metal_* functions, the sapp_d3d11_* functions
             return pointers to D3D11 API objects required for rendering,
             only if the D3D11 backend has been selected. Otherwise they
@@ -248,6 +275,14 @@
             render-target-view and depth-stencil-view may change from one
             frame to the next!
 
+        const void* sapp_wgpu_get_device(void)
+        const void* sapp_wgpu_get_render_view(void)
+        const void* sapp_wgpu_get_resolve_view(void)
+        const void* sapp_wgpu_get_depth_stencil_view(void)
+            These are the WebGPU-specific functions to get the WebGPU
+            objects and values required for rendering. If sokol_app.h
+            is not compiled with SOKOL_WGPU, these functions return null.
+
         const void* sapp_android_get_native_activity(void);
             On Android, get the native activity ANativeActivity pointer, otherwise
             a null pointer.
@@ -575,6 +610,14 @@ enum {
     SAPP_MAX_KEYCODES = 512,
 };
 
+/* NOTE: the pixel format values *must* be compatible with sg_pixel_format */
+typedef enum sapp_pixel_format {
+    SAPP_PIXELFORMAT_RGBA8 = 23,
+    SAPP_PIXELFORMAT_BGRA8 = 27,
+    SAPP_PIXELFORMAT_DEPTH = 41,
+    SAPP_PIXELFORMAT_DEPTH_STENCIL = 42
+} sapp_pixel_format;
+
 typedef enum sapp_event_type {
     SAPP_EVENTTYPE_INVALID,
     SAPP_EVENTTYPE_KEY_DOWN,
@@ -812,6 +855,12 @@ SOKOL_API_DECL bool sapp_isvalid(void);
 SOKOL_API_DECL int sapp_width(void);
 /* returns the current framebuffer height in pixels */
 SOKOL_API_DECL int sapp_height(void);
+/* get default framebuffer color pixel format */
+SOKOL_API_DECL sapp_pixel_format sapp_color_format(void);
+/* get default framebuffer depth pixel format */
+SOKOL_API_DECL sapp_pixel_format sapp_depth_format(void);
+/* get default framebuffer sample count */
+SOKOL_API_DECL int sapp_sample_count(void);
 /* returns true when high_dpi was requested and actually running in a high-dpi scenario */
 SOKOL_API_DECL bool sapp_high_dpi(void);
 /* returns the dpi scaling factor (window pixels to framebuffer pixels) */
@@ -874,6 +923,15 @@ SOKOL_API_DECL const void* sapp_d3d11_get_depth_stencil_view(void);
 /* Win32: get the HWND window handle */
 SOKOL_API_DECL const void* sapp_win32_get_hwnd(void);
 
+/* WebGPU: get WGPUDevice handle */
+SOKOL_API_DECL const void* sapp_wgpu_get_device(void);
+/* WebGPU: get swapchain's WGPUTextureView handle for rendering */
+SOKOL_API_DECL const void* sapp_wgpu_get_render_view(void);
+/* WebGPU: get swapchain's MSAA-resolve WGPUTextureView (may return null) */
+SOKOL_API_DECL const void* sapp_wgpu_get_resolve_view(void);
+/* WebGPU: get swapchain's WGPUTextureView for the depth-stencil surface */
+SOKOL_API_DECL const void* sapp_wgpu_get_depth_stencil_view(void);
+
 /* Android: get native activity handle */
 SOKOL_API_DECL const void* sapp_android_get_native_activity(void);
 
@@ -917,8 +975,8 @@ SOKOL_API_DECL const void* sapp_android_get_native_activity(void);
     #endif
 #elif defined(__EMSCRIPTEN__)
     /* emscripten (asm.js or wasm) */
-    #if !defined(SOKOL_GLES3) && !defined(SOKOL_GLES2)
-    #error("sokol_app.h: unknown 3D API selected for emscripten, must be SOKOL_GLES3 or SOKOL_GLES2")
+    #if !defined(SOKOL_GLES3) && !defined(SOKOL_GLES2) && !defined(SOKOL_WGPU)
+    #error("sokol_app.h: unknown 3D API selected for emscripten, must be SOKOL_GLES3, SOKOL_GLES2 or SOKOL_WGPU")
     #endif
 #elif defined(_WIN32)
     /* Windows (D3D11 or GL) */
@@ -954,6 +1012,9 @@ SOKOL_API_DECL const void* sapp_android_get_native_activity(void);
     #include <assert.h>
     #define SOKOL_ASSERT(c) assert(c)
 #endif
+#ifndef SOKOL_UNREACHABLE
+    #define SOKOL_UNREACHABLE SOKOL_ASSERT(false)
+#endif
 #if !defined(SOKOL_CALLOC) || !defined(SOKOL_FREE)
     #include <stdlib.h>
 #endif
@@ -2173,19 +2234,36 @@ _SOKOL_PRIVATE void _sapp_ios_touch_event(sapp_event_type type, NSSet<UITouch *>
 #if defined(__EMSCRIPTEN__)
 #if defined(SOKOL_GLES3)
 #include <GLES3/gl3.h>
-#else
+#elif defined(SOKOL_GLES2)
 #ifndef GL_EXT_PROTOTYPES
 #define GL_GLEXT_PROTOTYPES
 #endif
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
+#elif defined(SOKOL_WGPU)
+#include <webgpu/webgpu.h>
 #endif
 #include <emscripten/emscripten.h>
 #include <emscripten/html5.h>
 
-static bool _sapp_emsc_input_created;
-static bool _sapp_emsc_wants_show_keyboard;
-static bool _sapp_emsc_wants_hide_keyboard;
+static struct {
+    bool textfield_created;
+    bool wants_show_keyboard;
+    bool wants_hide_keyboard;
+    #if defined(SOKOL_WGPU)
+    struct {
+        int state;
+        WGPUDevice device;
+        WGPUSwapChain swapchain;
+        WGPUTextureFormat render_format;
+        WGPUTexture msaa_tex;
+        WGPUTexture depth_stencil_tex;
+        WGPUTextureView swapchain_view;
+        WGPUTextureView msaa_view;
+        WGPUTextureView depth_stencil_view;
+    } wgpu;
+    #endif
+} _sapp_emsc;
 
 /* this function is called from a JS event handler when the user hides
     the onscreen keyboard pressing the 'dismiss keyboard key'
@@ -2279,22 +2357,22 @@ _SOKOL_PRIVATE void _sapp_emsc_set_clipboard_string(const char* str) {
     the request will be ignored by the browser
 */
 _SOKOL_PRIVATE void _sapp_emsc_update_keyboard_state(void) {
-    if (_sapp_emsc_wants_show_keyboard) {
+    if (_sapp_emsc.wants_show_keyboard) {
         /* create input text field on demand */
-        if (!_sapp_emsc_input_created) {
-            _sapp_emsc_input_created = true;
+        if (!_sapp_emsc.textfield_created) {
+            _sapp_emsc.textfield_created = true;
             sapp_js_create_textfield();
         }
         /* focus the text input field, this will bring up the keyboard */
         _sapp.onscreen_keyboard_shown = true;
-        _sapp_emsc_wants_show_keyboard = false;
+        _sapp_emsc.wants_show_keyboard = false;
         sapp_js_focus_textfield();
     }
-    if (_sapp_emsc_wants_hide_keyboard) {
+    if (_sapp_emsc.wants_hide_keyboard) {
         /* unfocus the text input field */
-        if (_sapp_emsc_input_created) {
+        if (_sapp_emsc.textfield_created) {
             _sapp.onscreen_keyboard_shown = false;
-            _sapp_emsc_wants_hide_keyboard = false;
+            _sapp_emsc.wants_hide_keyboard = false;
             sapp_js_unfocus_textfield();
         }
     }
@@ -2306,13 +2384,18 @@ _SOKOL_PRIVATE void _sapp_emsc_update_keyboard_state(void) {
 */
 _SOKOL_PRIVATE void _sapp_emsc_show_keyboard(bool show) {
     if (show) {
-        _sapp_emsc_wants_show_keyboard = true;
+        _sapp_emsc.wants_show_keyboard = true;
     }
     else {
-        _sapp_emsc_wants_hide_keyboard = true;
+        _sapp_emsc.wants_hide_keyboard = true;
     }
 }
 
+#if defined(SOKOL_WGPU)
+_SOKOL_PRIVATE void _sapp_emsc_wgpu_surfaces_create(void);
+_SOKOL_PRIVATE void _sapp_emsc_wgpu_surfaces_discard(void);
+#endif
+
 _SOKOL_PRIVATE EM_BOOL _sapp_emsc_size_changed(int event_type, const EmscriptenUiEvent* ui_event, void* user_data) {
     double w, h;
     emscripten_get_element_css_size(_sapp.html5_canvas_name, &w, &h);
@@ -2355,6 +2438,11 @@ _SOKOL_PRIVATE EM_BOOL _sapp_emsc_size_changed(int event_type, const EmscriptenU
     _sapp.framebuffer_height = (int) (h * _sapp.dpi_scale);
     SOKOL_ASSERT((_sapp.framebuffer_width > 0) && (_sapp.framebuffer_height > 0));
     emscripten_set_canvas_element_size(_sapp.html5_canvas_name, _sapp.framebuffer_width, _sapp.framebuffer_height);
+    #if defined(SOKOL_WGPU)
+        /* on WebGPU: recreate size-dependent rendering surfaces */
+        _sapp_emsc_wgpu_surfaces_discard();
+        _sapp_emsc_wgpu_surfaces_create();
+    #endif
     if (_sapp_events_enabled()) {
         _sapp_init_event(SAPP_EVENTTYPE_RESIZED);
         _sapp_call_event(&_sapp.event);
@@ -2362,27 +2450,6 @@ _SOKOL_PRIVATE EM_BOOL _sapp_emsc_size_changed(int event_type, const EmscriptenU
     return true;
 }
 
-_SOKOL_PRIVATE EM_BOOL _sapp_emsc_frame(double time, void* userData) {
-    _SOKOL_UNUSED(time);
-    _SOKOL_UNUSED(userData);
-    _sapp_frame();
-    return EM_TRUE;
-}
-
-_SOKOL_PRIVATE EM_BOOL _sapp_emsc_context_cb(int emsc_type, const void* reserved, void* user_data) {
-    sapp_event_type type;
-    switch (emsc_type) {
-        case EMSCRIPTEN_EVENT_WEBGLCONTEXTLOST:     type = SAPP_EVENTTYPE_SUSPENDED; break;
-        case EMSCRIPTEN_EVENT_WEBGLCONTEXTRESTORED: type = SAPP_EVENTTYPE_RESUMED; break;
-        default:                                    type = SAPP_EVENTTYPE_INVALID; break;
-    }
-    if (_sapp_events_enabled() && (SAPP_EVENTTYPE_INVALID != type)) {
-        _sapp_init_event(type);
-        _sapp_call_event(&_sapp.event);
-    }
-    return true;
-}
-
 _SOKOL_PRIVATE EM_BOOL _sapp_emsc_mouse_cb(int emsc_type, const EmscriptenMouseEvent* emsc_event, void* user_data) {
     _sapp.mouse_x = (emsc_event->targetX * _sapp.dpi_scale);
     _sapp.mouse_y = (emsc_event->targetY * _sapp.dpi_scale);
@@ -2659,7 +2726,7 @@ _SOKOL_PRIVATE EM_BOOL _sapp_emsc_touch_cb(int emsc_type, const EmscriptenTouchE
     return retval;
 }
 
-_SOKOL_PRIVATE void _sapp_emsc_init_keytable(void) {
+_SOKOL_PRIVATE void _sapp_emsc_keytable_init(void) {
     _sapp.keycodes[8]   = SAPP_KEYCODE_BACKSPACE;
     _sapp.keycodes[9]   = SAPP_KEYCODE_TAB;
     _sapp.keycodes[13]  = SAPP_KEYCODE_ENTER;
@@ -2763,34 +2830,42 @@ _SOKOL_PRIVATE void _sapp_emsc_init_keytable(void) {
     _sapp.keycodes[224] = SAPP_KEYCODE_LEFT_SUPER;
 }
 
-_SOKOL_PRIVATE void _sapp_emsc_init_clipboard(void) {
+_SOKOL_PRIVATE void _sapp_emsc_clipboard_init(void) {
     sapp_js_init_clipboard();
 }
 
-_SOKOL_PRIVATE void _sapp_run(const sapp_desc* desc) {
-    _sapp_init_state(desc);
-    _sapp_emsc_init_keytable();
-    if (_sapp.clipboard_enabled) {
-        _sapp_emsc_init_clipboard();
-    }
-    double w, h;
-    if (_sapp.desc.html5_canvas_resize) {
-        w = (double) _sapp.desc.width;
-        h = (double) _sapp.desc.height;
-    }
-    else {
-        emscripten_get_element_css_size(_sapp.html5_canvas_name, &w, &h);
-        emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, false, _sapp_emsc_size_changed);
+_SOKOL_PRIVATE void _sapp_emsc_register_eventhandlers(void) {
+    emscripten_set_mousedown_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_mouse_cb);
+    emscripten_set_mouseup_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_mouse_cb);
+    emscripten_set_mousemove_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_mouse_cb);
+    emscripten_set_mouseenter_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_mouse_cb);
+    emscripten_set_mouseleave_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_mouse_cb);
+    emscripten_set_wheel_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_wheel_cb);
+    emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, true, _sapp_emsc_key_cb);
+    emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, true, _sapp_emsc_key_cb);
+    emscripten_set_keypress_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, true, _sapp_emsc_key_cb);
+    emscripten_set_touchstart_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_touch_cb);
+    emscripten_set_touchmove_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_touch_cb);
+    emscripten_set_touchend_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_touch_cb);
+    emscripten_set_touchcancel_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_touch_cb);
+}
+
+#if defined(SOKOL_GLES2) || defined(SOKOL_GLES3)
+_SOKOL_PRIVATE EM_BOOL _sapp_emsc_webgl_context_cb(int emsc_type, const void* reserved, void* user_data) {
+    sapp_event_type type;
+    switch (emsc_type) {
+        case EMSCRIPTEN_EVENT_WEBGLCONTEXTLOST:     type = SAPP_EVENTTYPE_SUSPENDED; break;
+        case EMSCRIPTEN_EVENT_WEBGLCONTEXTRESTORED: type = SAPP_EVENTTYPE_RESUMED; break;
+        default:                                    type = SAPP_EVENTTYPE_INVALID; break;
     }
-    if (_sapp.desc.high_dpi) {
-        _sapp.dpi_scale = emscripten_get_device_pixel_ratio();
+    if (_sapp_events_enabled() && (SAPP_EVENTTYPE_INVALID != type)) {
+        _sapp_init_event(type);
+        _sapp_call_event(&_sapp.event);
     }
-    _sapp.window_width = (int) w;
-    _sapp.window_height = (int) h;
-    _sapp.framebuffer_width = (int) (w * _sapp.dpi_scale);
-    _sapp.framebuffer_height = (int) (h * _sapp.dpi_scale);
-    emscripten_set_canvas_element_size(_sapp.html5_canvas_name, _sapp.framebuffer_width, _sapp.framebuffer_height);
+    return true;
+}
 
+_SOKOL_PRIVATE void _sapp_emsc_webgl_init(void) {
     EmscriptenWebGLContextAttributes attrs;
     emscripten_webgl_init_context_attributes(&attrs);
     attrs.alpha = _sapp.desc.alpha;
@@ -2820,27 +2895,184 @@ _SOKOL_PRIVATE void _sapp_run(const sapp_desc* desc) {
     /* some WebGL extension are not enabled automatically by emscripten */
     emscripten_webgl_enable_extension(ctx, "WEBKIT_WEBGL_compressed_texture_pvrtc");
 
-    _sapp.valid = true;
-    emscripten_set_mousedown_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_mouse_cb);
-    emscripten_set_mouseup_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_mouse_cb);
-    emscripten_set_mousemove_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_mouse_cb);
-    emscripten_set_mouseenter_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_mouse_cb);
-    emscripten_set_mouseleave_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_mouse_cb);
-    emscripten_set_wheel_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_wheel_cb);
-    emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, true, _sapp_emsc_key_cb);
-    emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, true, _sapp_emsc_key_cb);
-    emscripten_set_keypress_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, true, _sapp_emsc_key_cb);
-    emscripten_set_touchstart_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_touch_cb);
-    emscripten_set_touchmove_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_touch_cb);
-    emscripten_set_touchend_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_touch_cb);
-    emscripten_set_touchcancel_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_touch_cb);
-    emscripten_set_webglcontextlost_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_context_cb);
-    emscripten_set_webglcontextrestored_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_context_cb);
-    emscripten_request_animation_frame_loop(_sapp_emsc_frame, 0);
+    emscripten_set_webglcontextlost_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_webgl_context_cb);
+    emscripten_set_webglcontextrestored_callback(_sapp.html5_canvas_name, 0, true, _sapp_emsc_webgl_context_cb);
+}
+#endif
+
+#if defined(SOKOL_WGPU)
+#define _SAPP_EMSC_WGPU_STATE_INITIAL (0)
+#define _SAPP_EMSC_WGPU_STATE_READY (1)
+#define _SAPP_EMSC_WGPU_STATE_RUNNING (2)
+
+/* called when the asynchronous WebGPU device + swapchain init code in JS has finished */
+EMSCRIPTEN_KEEPALIVE void _sapp_emsc_wgpu_ready(int device_id, int swapchain_id, int swapchain_fmt) {
+    SOKOL_ASSERT(0 == _sapp_emsc.wgpu.device);
+    _sapp_emsc.wgpu.device = (WGPUDevice) device_id;
+    _sapp_emsc.wgpu.swapchain = (WGPUSwapChain) swapchain_id;
+    _sapp_emsc.wgpu.render_format = (WGPUTextureFormat) swapchain_fmt;
+    _sapp_emsc.wgpu.state = _SAPP_EMSC_WGPU_STATE_READY;
+}
+
+/* embedded JS function to handle all the asynchronous WebGPU setup */
+EM_JS(void, _sapp_emsc_wgpu_init, (), {
+    WebGPU.initManagers();
+    // FIXME: the extension activation must be more clever here
+    navigator.gpu.requestAdapter().then(function(adapter) {
+        console.log("wgpu adapter extensions: " + adapter.extensions);
+        adapter.requestDevice({ extensions: ["textureCompressionBC"]}).then(function(device) {
+            var gpuContext = document.getElementById("canvas").getContext("gpupresent");
+            console.log("wgpu device extensions: " + adapter.extensions);
+            gpuContext.getSwapChainPreferredFormat(device).then(function(fmt) {
+                var swapChainDescriptor = { device: device, format: fmt };
+                var swapChain = gpuContext.configureSwapChain(swapChainDescriptor);
+                var deviceId = WebGPU.mgrDevice.create(device);
+                var swapChainId = WebGPU.mgrSwapChain.create(swapChain);
+                var fmtId = WebGPU.TextureFormat.findIndex(function(elm) { return elm==fmt; });
+                console.log("wgpu device: " + device);
+                console.log("wgpu swap chain: " + swapChain);
+                console.log("wgpu preferred format: " + fmt + " (" + fmtId + ")");
+                __sapp_emsc_wgpu_ready(deviceId, swapChainId, fmtId);
+            });
+        });
+    });
+});
+
+_SOKOL_PRIVATE void _sapp_emsc_wgpu_surfaces_create(void) {
+    SOKOL_ASSERT(_sapp_emsc.wgpu.device);
+    SOKOL_ASSERT(_sapp_emsc.wgpu.swapchain);
+    SOKOL_ASSERT(0 == _sapp_emsc.wgpu.depth_stencil_tex);
+    SOKOL_ASSERT(0 == _sapp_emsc.wgpu.depth_stencil_view);
+    SOKOL_ASSERT(0 == _sapp_emsc.wgpu.msaa_tex);
+    SOKOL_ASSERT(0 == _sapp_emsc.wgpu.msaa_view);
+
+    WGPUTextureDescriptor ds_desc;
+    memset(&ds_desc, 0, sizeof(ds_desc));
+    ds_desc.usage = WGPUTextureUsage_OutputAttachment;
+    ds_desc.dimension = WGPUTextureDimension_2D;
+    ds_desc.size.width = (uint32_t) _sapp.framebuffer_width;
+    ds_desc.size.height = (uint32_t) _sapp.framebuffer_height;
+    ds_desc.size.depth = 1;
+    ds_desc.arrayLayerCount = 1;
+    ds_desc.format = WGPUTextureFormat_Depth24PlusStencil8;
+    ds_desc.mipLevelCount = 1;
+    ds_desc.sampleCount = _sapp.sample_count;
+    _sapp_emsc.wgpu.depth_stencil_tex = wgpuDeviceCreateTexture(_sapp_emsc.wgpu.device, &ds_desc);
+    _sapp_emsc.wgpu.depth_stencil_view = wgpuTextureCreateView(_sapp_emsc.wgpu.depth_stencil_tex, 0);
+
+    if (_sapp.sample_count > 1) {
+        WGPUTextureDescriptor msaa_desc;
+        memset(&msaa_desc, 0, sizeof(msaa_desc));
+        msaa_desc.usage = WGPUTextureUsage_OutputAttachment;
+        msaa_desc.dimension = WGPUTextureDimension_2D;
+        msaa_desc.size.width = (uint32_t) _sapp.framebuffer_width;
+        msaa_desc.size.height = (uint32_t) _sapp.framebuffer_height;
+        msaa_desc.size.depth = 1;
+        msaa_desc.arrayLayerCount = 1;
+        msaa_desc.format = _sapp_emsc.wgpu.render_format;
+        msaa_desc.mipLevelCount = 1;
+        msaa_desc.sampleCount = _sapp.sample_count;
+        _sapp_emsc.wgpu.msaa_tex = wgpuDeviceCreateTexture(_sapp_emsc.wgpu.device, &msaa_desc);
+        _sapp_emsc.wgpu.msaa_view = wgpuTextureCreateView(_sapp_emsc.wgpu.msaa_tex, 0);
+    }
+}
+
+_SOKOL_PRIVATE void _sapp_emsc_wgpu_surfaces_discard(void) {
+    if (_sapp_emsc.wgpu.msaa_tex) {
+        wgpuTextureRelease(_sapp_emsc.wgpu.msaa_tex);
+        _sapp_emsc.wgpu.msaa_tex = 0;
+    }
+    if (_sapp_emsc.wgpu.msaa_view) {
+        wgpuTextureViewRelease(_sapp_emsc.wgpu.msaa_view);
+        _sapp_emsc.wgpu.msaa_view = 0;
+    }
+    if (_sapp_emsc.wgpu.depth_stencil_tex) {
+        wgpuTextureRelease(_sapp_emsc.wgpu.depth_stencil_tex);
+        _sapp_emsc.wgpu.depth_stencil_tex = 0;
+    }
+    if (_sapp_emsc.wgpu.depth_stencil_view) {
+        wgpuTextureViewRelease(_sapp_emsc.wgpu.depth_stencil_view);
+        _sapp_emsc.wgpu.depth_stencil_view = 0;
+    }
+}
+
+_SOKOL_PRIVATE void _sapp_emsc_wgpu_next_frame(void) {
+    if (_sapp_emsc.wgpu.swapchain_view) {
+        wgpuTextureViewRelease(_sapp_emsc.wgpu.swapchain_view);
+    }
+    _sapp_emsc.wgpu.swapchain_view = wgpuSwapChainGetCurrentTextureView(_sapp_emsc.wgpu.swapchain);
+}
+#endif
+
+_SOKOL_PRIVATE EM_BOOL _sapp_emsc_frame(double time, void* userData) {
+    _SOKOL_UNUSED(time);
+    _SOKOL_UNUSED(userData);
 
+    #if defined(SOKOL_WGPU)
+        /*
+            on WebGPU, the emscripten frame callback will already be called while
+            the asynchronous WebGPU device and swapchain initialization is still
+            in progress
+        */
+        switch (_sapp_emsc.wgpu.state) {
+            case _SAPP_EMSC_WGPU_STATE_INITIAL:
+                /* async JS init hasn't finished yet */
+                break;
+            case _SAPP_EMSC_WGPU_STATE_READY:
+                /* perform post-async init stuff */
+                _sapp_emsc_wgpu_surfaces_create();
+                _sapp_emsc.wgpu.state = _SAPP_EMSC_WGPU_STATE_RUNNING;
+                break;
+            case _SAPP_EMSC_WGPU_STATE_RUNNING:
+                /* a regular frame */
+                _sapp_emsc_wgpu_next_frame();
+                _sapp_frame();
+                break;
+        }
+    #else
+        /* WebGL code path */
+        _sapp_frame();
+    #endif
+    return EM_TRUE;
+}
+
+_SOKOL_PRIVATE void _sapp_run(const sapp_desc* desc) {
+    memset(&_sapp_emsc, 0, sizeof(_sapp_emsc));
+    _sapp_init_state(desc);
+    _sapp_emsc_keytable_init();
+    if (_sapp.clipboard_enabled) {
+        _sapp_emsc_clipboard_init();
+    }
+    double w, h;
+    if (_sapp.desc.html5_canvas_resize) {
+        w = (double) _sapp.desc.width;
+        h = (double) _sapp.desc.height;
+    }
+    else {
+        emscripten_get_element_css_size(_sapp.html5_canvas_name, &w, &h);
+        emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, false, _sapp_emsc_size_changed);
+    }
+    if (_sapp.desc.high_dpi) {
+        _sapp.dpi_scale = emscripten_get_device_pixel_ratio();
+    }
+    _sapp.window_width = (int) w;
+    _sapp.window_height = (int) h;
+    _sapp.framebuffer_width = (int) (w * _sapp.dpi_scale);
+    _sapp.framebuffer_height = (int) (h * _sapp.dpi_scale);
+    emscripten_set_canvas_element_size(_sapp.html5_canvas_name, _sapp.framebuffer_width, _sapp.framebuffer_height);
+    #if defined(SOKOL_GLES2) || defined(SOKOL_GLES3)
+        _sapp_emsc_webgl_init();
+    #elif defined(SOKOL_WGPU)
+        _sapp_emsc_wgpu_init();
+    #endif
+    _sapp.valid = true;
+    _sapp_emsc_register_eventhandlers();
     sapp_js_hook_beforeunload();
 
-    // NOT A BUG: do not call _sapp_discard_state()
+    /* start the frame loop */
+    emscripten_request_animation_frame_loop(_sapp_emsc_frame, 0);
+
+    /* NOT A BUG: do not call _sapp_discard_state() */
 }
 
 #if !defined(SOKOL_NO_ENTRY)
@@ -7371,6 +7603,32 @@ SOKOL_API_IMPL int sapp_width(void) {
     return (_sapp.framebuffer_width > 0) ? _sapp.framebuffer_width : 1;
 }
 
+SOKOL_API_IMPL sapp_pixel_format sapp_color_format(void) {
+    #if defined(SOKOL_WGPU)
+        switch (_sapp_emsc.wgpu.render_format) {
+            case WGPUTextureFormat_RGBA8Unorm:
+                return SAPP_PIXELFORMAT_RGBA8;
+            case WGPUTextureFormat_BGRA8Unorm:
+                return SAPP_PIXELFORMAT_BGRA8;
+            default:
+                SOKOL_UNREACHABLE;
+                return 0;
+        }
+    #elif defined(SOKOL_METAL) || defined(SOKOL_D3D11)
+        return SAPP_PIXELFORMAT_BGRA8;
+    #else
+        return SAPP_PIXELFORMAT_RGBA8;
+    #endif
+}
+
+SOKOL_API_IMPL sapp_pixel_format sapp_depth_format(void) {
+    return SAPP_PIXELFORMAT_DEPTH_STENCIL;
+}
+
+SOKOL_API_IMPL int sapp_sample_count(void) {
+    return _sapp.sample_count;
+}
+
 SOKOL_API_IMPL int sapp_height(void) {
     return (_sapp.framebuffer_height > 0) ? _sapp.framebuffer_height : 1;
 }
@@ -7568,6 +7826,52 @@ SOKOL_API_IMPL const void* sapp_win32_get_hwnd(void) {
     #endif
 }
 
+SOKOL_API_IMPL const void* sapp_wgpu_get_device(void) {
+    SOKOL_ASSERT(_sapp.valid);
+    #if defined(SOKOL_WGPU)
+        return (const void*) _sapp_emsc.wgpu.device;
+    #else
+        return 0;
+    #endif
+}
+
+SOKOL_API_IMPL const void* sapp_wgpu_get_render_view(void) {
+    SOKOL_ASSERT(_sapp.valid);
+    #if defined(SOKOL_WGPU)
+        if (_sapp.sample_count > 1) {
+            return (const void*) _sapp_emsc.wgpu.msaa_view;
+        }
+        else {
+            return (const void*) _sapp_emsc.wgpu.swapchain_view;
+        }
+    #else
+        return 0;
+    #endif
+}
+
+SOKOL_API_IMPL const void* sapp_wgpu_get_resolve_view(void) {
+    SOKOL_ASSERT(_sapp.valid);
+    #if defined(SOKOL_WGPU)
+        if (_sapp.sample_count > 1) {
+            return (const void*) _sapp_emsc.wgpu.swapchain_view;
+        }
+        else {
+            return 0;
+        }
+    #else
+        return 0;
+    #endif
+}
+
+SOKOL_API_IMPL const void* sapp_wgpu_get_depth_stencil_view(void) {
+    SOKOL_ASSERT(_sapp.valid);
+    #if defined(SOKOL_WGPU)
+        return (const void*) _sapp_emsc.wgpu.depth_stencil_view;
+    #else
+        return 0;
+    #endif
+}
+
 SOKOL_API_IMPL const void* sapp_android_get_native_activity(void) {
     SOKOL_ASSERT(_sapp.valid);
     #if defined(__ANDROID__)

File diff suppressed because it is too large
+ 505 - 203
sokol_gfx.h


+ 133 - 0
sokol_glue.h

@@ -0,0 +1,133 @@
+#ifndef SOKOL_GLUE_INCLUDED
+/*
+    sokol_glue.h -- glue helper functions for sokol headers
+
+    Project URL: https://github.com/floooh/sokol
+
+    Do this:
+        #define SOKOL_IMPL
+    before you include this file in *one* C or C++ file to create the
+    implementation.
+
+    ...optionally provide the following macros to override defaults:
+
+    SOKOL_ASSERT(c)     - your own assert macro (default: assert(c))
+    SOKOL_API_DECL      - public function declaration prefix (default: extern)
+    SOKOL_API_IMPL      - public function implementation prefix (default: -)
+
+    If sokol_glue.h is compiled as a DLL, define the following before
+    including the declaration or implementation:
+
+    SOKOL_DLL
+
+    On Windows, SOKOL_DLL will define SOKOL_API_DECL as __declspec(dllexport)
+    or __declspec(dllimport) as needed.
+
+    OVERVIEW
+    ========
+    The sokol core headers should not depend on each other, but sometimes
+    it's useful to have a set of helper functions as "glue" between
+    two or more sokol headers.
+
+    This is what sokol_glue.h is for. Simply include the header after other
+    sokol headers (both for the implementation and declaration), and
+    depending on what headers have been included before, sokol_glue.h
+    will make available "glue functions".
+
+    PROVIDED FUNCTIONS
+    ==================
+
+    - if sokol_app.h and sokol_gfx.h is included:
+
+        sg_context_desc sapp_sgcontext(void):
+
+            Returns an initialized sg_context_desc function initialized
+            by calling sokol_app.h functions.
+
+    LICENSE
+    =======
+    zlib/libpng license
+
+    Copyright (c) 2018 Andre Weissflog
+
+    This software is provided 'as-is', without any express or implied warranty.
+    In no event will the authors be held liable for any damages arising from the
+    use of this software.
+
+    Permission is granted to anyone to use this software for any purpose,
+    including commercial applications, and to alter it and redistribute it
+    freely, subject to the following restrictions:
+
+        1. The origin of this software must not be misrepresented; you must not
+        claim that you wrote the original software. If you use this software in a
+        product, an acknowledgment in the product documentation would be
+        appreciated but is not required.
+
+        2. Altered source versions must be plainly marked as such, and must not
+        be misrepresented as being the original software.
+
+        3. This notice may not be removed or altered from any source
+        distribution.
+*/
+#define SOKOL_GLUE_INCLUDED
+
+#ifndef SOKOL_API_DECL
+#if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_IMPL)
+#define SOKOL_API_DECL __declspec(dllexport)
+#elif defined(_WIN32) && defined(SOKOL_DLL)
+#define SOKOL_API_DECL __declspec(dllimport)
+#else
+#define SOKOL_API_DECL extern
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(SOKOL_GFX_INCLUDED) && defined(SOKOL_APP_INCLUDED)
+SOKOL_API_DECL sg_context_desc sapp_sgcontext(void);
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+#endif /* SOKOL_GLUE_INCLUDED */
+
+/*-- IMPLEMENTATION ----------------------------------------------------------*/
+#ifdef SOKOL_IMPL
+#define SOKOL_GLUE_IMPL_INCLUDED (1)
+#include <string.h> /* memset */
+
+#ifndef SOKOL_API_IMPL
+    #define SOKOL_API_IMPL
+#endif
+
+#if defined(SOKOL_GFX_INCLUDED) && defined(SOKOL_APP_INCLUDED)
+SOKOL_API_IMPL sg_context_desc sapp_sgcontext(void) {
+    SOKOL_ASSERT(SAPP_PIXELFORMAT_RGBA8 == (sapp_pixel_format) SG_PIXELFORMAT_RGBA8);
+    SOKOL_ASSERT(SAPP_PIXELFORMAT_BGRA8 == (sapp_pixel_format) SG_PIXELFORMAT_BGRA8);
+    SOKOL_ASSERT(SAPP_PIXELFORMAT_DEPTH == (sapp_pixel_format) SG_PIXELFORMAT_DEPTH);
+    SOKOL_ASSERT(SAPP_PIXELFORMAT_DEPTH_STENCIL == (sapp_pixel_format) SG_PIXELFORMAT_DEPTH_STENCIL);
+    sg_context_desc desc;
+    memset(&desc, 0, sizeof(desc));
+    desc.color_format = (sg_pixel_format) sapp_color_format();
+    desc.depth_format = (sg_pixel_format) sapp_depth_format();
+    desc.sample_count = sapp_sample_count();
+    desc.gl.force_gles2 = sapp_gles2();
+    desc.metal.device = sapp_metal_get_device();
+    desc.metal.renderpass_descriptor_cb = sapp_metal_get_renderpass_descriptor;
+    desc.metal.drawable_cb = sapp_metal_get_drawable;
+    desc.d3d11.device = sapp_d3d11_get_device();
+    desc.d3d11.device_context = sapp_d3d11_get_device_context();
+    desc.d3d11.render_target_view_cb = sapp_d3d11_get_render_target_view;
+    desc.d3d11.depth_stencil_view_cb = sapp_d3d11_get_depth_stencil_view;
+    desc.wgpu.device = sapp_wgpu_get_device();
+    desc.wgpu.render_view_cb = sapp_wgpu_get_render_view;
+    desc.wgpu.resolve_view_cb = sapp_wgpu_get_resolve_view;
+    desc.wgpu.depth_stencil_view_cb = sapp_wgpu_get_depth_stencil_view;
+    return desc;
+}
+#endif
+
+#endif /* SOKOL_IMPL */

+ 224 - 1
util/sokol_fontstash.h

@@ -622,9 +622,232 @@ static uint8_t _sfons_fs_bin[] = {
       0,   0,   0,   0,   0,   0,
       0,   0
 };
+#elif defined(SOKOL_WGPU)
+/*
+    WebGPU shader blobs:
+
+    Vertex shader source:
+
+    #version 450
+
+    layout(set = 0, binding = 0, std140) uniform vs_params
+    {
+        mat4 mvp;
+        mat4 tm;
+    } _20;
+
+    layout(location = 0) in vec4 position;
+    layout(location = 0) out vec4 uv;
+    layout(location = 1) in vec2 texcoord0;
+    layout(location = 1) out vec4 color;
+    layout(location = 2) in vec4 color0;
+
+    void main()
+    {
+        gl_Position = _20.mvp * position;
+        uv = _20.tm * vec4(texcoord0, 0.0, 1.0);
+        color = color0;
+    }
+
+    Fragment shader source:
+
+    #version 450
+
+    layout(location = 0, set = 2, binding = 0) uniform sampler2D tex;
+
+    layout(location = 0) out vec4 frag_color;
+    layout(location = 0) in vec4 uv;
+    layout(location = 1) in vec4 color;
+
+    void main()
+    {
+        frag_color = vec4(1.0, 1.0, 1.0, texture(tex, uv.xy).x) * color;
+    }
+*/
+static const uint8_t _sfons_vs_bin[1800] = {
+    0x03,0x02,0x23,0x07,0x00,0x00,0x01,0x00,0x08,0x00,0x08,0x00,0x2f,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x11,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x06,0x00,
+    0x02,0x00,0x00,0x00,0x47,0x4c,0x53,0x4c,0x2e,0x73,0x74,0x64,0x2e,0x34,0x35,0x30,
+    0x00,0x00,0x00,0x00,0x0e,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x0f,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x6d,0x61,0x69,0x6e,
+    0x00,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,
+    0x24,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x07,0x00,0x03,0x00,
+    0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x37,0x00,0x02,0x00,0x00,0x00,
+    0xc2,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,
+    0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x63,0x6c,0x69,
+    0x65,0x6e,0x74,0x20,0x76,0x75,0x6c,0x6b,0x61,0x6e,0x31,0x30,0x30,0x0a,0x2f,0x2f,
+    0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,
+    0x65,0x64,0x20,0x63,0x6c,0x69,0x65,0x6e,0x74,0x20,0x6f,0x70,0x65,0x6e,0x67,0x6c,
+    0x31,0x30,0x30,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,
+    0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2d,
+    0x65,0x6e,0x76,0x20,0x76,0x75,0x6c,0x6b,0x61,0x6e,0x31,0x2e,0x30,0x0a,0x2f,0x2f,
+    0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,
+    0x65,0x64,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2d,0x65,0x6e,0x76,0x20,0x6f,0x70,
+    0x65,0x6e,0x67,0x6c,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,
+    0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x65,0x6e,0x74,0x72,0x79,0x2d,
+    0x70,0x6f,0x69,0x6e,0x74,0x20,0x6d,0x61,0x69,0x6e,0x0a,0x23,0x6c,0x69,0x6e,0x65,
+    0x20,0x31,0x0a,0x00,0x05,0x00,0x04,0x00,0x05,0x00,0x00,0x00,0x6d,0x61,0x69,0x6e,
+    0x00,0x00,0x00,0x00,0x05,0x00,0x06,0x00,0x0c,0x00,0x00,0x00,0x67,0x6c,0x5f,0x50,
+    0x65,0x72,0x56,0x65,0x72,0x74,0x65,0x78,0x00,0x00,0x00,0x00,0x06,0x00,0x06,0x00,
+    0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,
+    0x69,0x6f,0x6e,0x00,0x06,0x00,0x07,0x00,0x0c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x67,0x6c,0x5f,0x50,0x6f,0x69,0x6e,0x74,0x53,0x69,0x7a,0x65,0x00,0x00,0x00,0x00,
+    0x06,0x00,0x07,0x00,0x0c,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x67,0x6c,0x5f,0x43,
+    0x6c,0x69,0x70,0x44,0x69,0x73,0x74,0x61,0x6e,0x63,0x65,0x00,0x06,0x00,0x07,0x00,
+    0x0c,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x67,0x6c,0x5f,0x43,0x75,0x6c,0x6c,0x44,
+    0x69,0x73,0x74,0x61,0x6e,0x63,0x65,0x00,0x05,0x00,0x03,0x00,0x0e,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x05,0x00,0x05,0x00,0x12,0x00,0x00,0x00,0x76,0x73,0x5f,0x70,
+    0x61,0x72,0x61,0x6d,0x73,0x00,0x00,0x00,0x06,0x00,0x04,0x00,0x12,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x6d,0x76,0x70,0x00,0x06,0x00,0x04,0x00,0x12,0x00,0x00,0x00,
+    0x01,0x00,0x00,0x00,0x74,0x6d,0x00,0x00,0x05,0x00,0x03,0x00,0x14,0x00,0x00,0x00,
+    0x5f,0x32,0x30,0x00,0x05,0x00,0x05,0x00,0x19,0x00,0x00,0x00,0x70,0x6f,0x73,0x69,
+    0x74,0x69,0x6f,0x6e,0x00,0x00,0x00,0x00,0x05,0x00,0x03,0x00,0x1e,0x00,0x00,0x00,
+    0x75,0x76,0x00,0x00,0x05,0x00,0x05,0x00,0x24,0x00,0x00,0x00,0x74,0x65,0x78,0x63,
+    0x6f,0x6f,0x72,0x64,0x30,0x00,0x00,0x00,0x05,0x00,0x04,0x00,0x2c,0x00,0x00,0x00,
+    0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0x05,0x00,0x04,0x00,0x2d,0x00,0x00,0x00,
+    0x63,0x6f,0x6c,0x6f,0x72,0x30,0x00,0x00,0x48,0x00,0x05,0x00,0x0c,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x05,0x00,
+    0x0c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x48,0x00,0x05,0x00,0x0c,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,
+    0x03,0x00,0x00,0x00,0x48,0x00,0x05,0x00,0x0c,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
+    0x0b,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x47,0x00,0x03,0x00,0x0c,0x00,0x00,0x00,
+    0x02,0x00,0x00,0x00,0x48,0x00,0x04,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x05,0x00,0x00,0x00,0x48,0x00,0x05,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x05,0x00,0x12,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x48,0x00,0x04,0x00,
+    0x12,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x48,0x00,0x05,0x00,
+    0x12,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x40,0x00,0x00,0x00,
+    0x48,0x00,0x05,0x00,0x12,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+    0x10,0x00,0x00,0x00,0x47,0x00,0x03,0x00,0x12,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x14,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x14,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x19,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x1e,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x24,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x2c,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x2d,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+    0x13,0x00,0x02,0x00,0x03,0x00,0x00,0x00,0x21,0x00,0x03,0x00,0x04,0x00,0x00,0x00,
+    0x03,0x00,0x00,0x00,0x16,0x00,0x03,0x00,0x07,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+    0x17,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+    0x15,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x2b,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x1c,0x00,0x04,0x00,0x0b,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,
+    0x1e,0x00,0x06,0x00,0x0c,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+    0x0b,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x0d,0x00,0x00,0x00,
+    0x03,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x0d,0x00,0x00,0x00,
+    0x0e,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x15,0x00,0x04,0x00,0x0f,0x00,0x00,0x00,
+    0x20,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x2b,0x00,0x04,0x00,0x0f,0x00,0x00,0x00,
+    0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x04,0x00,0x11,0x00,0x00,0x00,
+    0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x1e,0x00,0x04,0x00,0x12,0x00,0x00,0x00,
+    0x11,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x13,0x00,0x00,0x00,
+    0x02,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x13,0x00,0x00,0x00,
+    0x14,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x15,0x00,0x00,0x00,
+    0x02,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x18,0x00,0x00,0x00,
+    0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x18,0x00,0x00,0x00,
+    0x19,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x1c,0x00,0x00,0x00,
+    0x03,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x1c,0x00,0x00,0x00,
+    0x1e,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x2b,0x00,0x04,0x00,0x0f,0x00,0x00,0x00,
+    0x1f,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x17,0x00,0x04,0x00,0x22,0x00,0x00,0x00,
+    0x07,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x23,0x00,0x00,0x00,
+    0x01,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x23,0x00,0x00,0x00,
+    0x24,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x2b,0x00,0x04,0x00,0x07,0x00,0x00,0x00,
+    0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2b,0x00,0x04,0x00,0x07,0x00,0x00,0x00,
+    0x27,0x00,0x00,0x00,0x00,0x00,0x80,0x3f,0x3b,0x00,0x04,0x00,0x1c,0x00,0x00,0x00,
+    0x2c,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x18,0x00,0x00,0x00,
+    0x2d,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x36,0x00,0x05,0x00,0x03,0x00,0x00,0x00,
+    0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xf8,0x00,0x02,0x00,
+    0x06,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0x01,0x00,0x00,0x00,0x11,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x41,0x00,0x05,0x00,0x15,0x00,0x00,0x00,0x16,0x00,0x00,0x00,
+    0x14,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,0x11,0x00,0x00,0x00,
+    0x17,0x00,0x00,0x00,0x16,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,0x08,0x00,0x00,0x00,
+    0x1a,0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x91,0x00,0x05,0x00,0x08,0x00,0x00,0x00,
+    0x1b,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x1a,0x00,0x00,0x00,0x41,0x00,0x05,0x00,
+    0x1c,0x00,0x00,0x00,0x1d,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
+    0x3e,0x00,0x03,0x00,0x1d,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x08,0x00,0x04,0x00,
+    0x01,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x05,0x00,
+    0x15,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
+    0x3d,0x00,0x04,0x00,0x11,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+    0x3d,0x00,0x04,0x00,0x22,0x00,0x00,0x00,0x25,0x00,0x00,0x00,0x24,0x00,0x00,0x00,
+    0x51,0x00,0x05,0x00,0x07,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x25,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x51,0x00,0x05,0x00,0x07,0x00,0x00,0x00,0x29,0x00,0x00,0x00,
+    0x25,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x50,0x00,0x07,0x00,0x08,0x00,0x00,0x00,
+    0x2a,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x29,0x00,0x00,0x00,0x26,0x00,0x00,0x00,
+    0x27,0x00,0x00,0x00,0x91,0x00,0x05,0x00,0x08,0x00,0x00,0x00,0x2b,0x00,0x00,0x00,
+    0x21,0x00,0x00,0x00,0x2a,0x00,0x00,0x00,0x3e,0x00,0x03,0x00,0x1e,0x00,0x00,0x00,
+    0x2b,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0x01,0x00,0x00,0x00,0x13,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x2e,0x00,0x00,0x00,
+    0x2d,0x00,0x00,0x00,0x3e,0x00,0x03,0x00,0x2c,0x00,0x00,0x00,0x2e,0x00,0x00,0x00,
+    0xfd,0x00,0x01,0x00,0x38,0x00,0x01,0x00,
+};
+static const uint8_t _sfons_fs_bin[980] = {
+    0x03,0x02,0x23,0x07,0x00,0x00,0x01,0x00,0x08,0x00,0x08,0x00,0x1e,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x11,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x06,0x00,
+    0x02,0x00,0x00,0x00,0x47,0x4c,0x53,0x4c,0x2e,0x73,0x74,0x64,0x2e,0x34,0x35,0x30,
+    0x00,0x00,0x00,0x00,0x0e,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x0f,0x00,0x08,0x00,0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x6d,0x61,0x69,0x6e,
+    0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,
+    0x10,0x00,0x03,0x00,0x05,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x03,0x00,
+    0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x37,0x00,0x02,0x00,0x00,0x00,
+    0xc2,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,
+    0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x63,0x6c,0x69,
+    0x65,0x6e,0x74,0x20,0x76,0x75,0x6c,0x6b,0x61,0x6e,0x31,0x30,0x30,0x0a,0x2f,0x2f,
+    0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,
+    0x65,0x64,0x20,0x63,0x6c,0x69,0x65,0x6e,0x74,0x20,0x6f,0x70,0x65,0x6e,0x67,0x6c,
+    0x31,0x30,0x30,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,
+    0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2d,
+    0x65,0x6e,0x76,0x20,0x76,0x75,0x6c,0x6b,0x61,0x6e,0x31,0x2e,0x30,0x0a,0x2f,0x2f,
+    0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,
+    0x65,0x64,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2d,0x65,0x6e,0x76,0x20,0x6f,0x70,
+    0x65,0x6e,0x67,0x6c,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,
+    0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x65,0x6e,0x74,0x72,0x79,0x2d,
+    0x70,0x6f,0x69,0x6e,0x74,0x20,0x6d,0x61,0x69,0x6e,0x0a,0x23,0x6c,0x69,0x6e,0x65,
+    0x20,0x31,0x0a,0x00,0x05,0x00,0x04,0x00,0x05,0x00,0x00,0x00,0x6d,0x61,0x69,0x6e,
+    0x00,0x00,0x00,0x00,0x05,0x00,0x05,0x00,0x0a,0x00,0x00,0x00,0x66,0x72,0x61,0x67,
+    0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x05,0x00,0x03,0x00,0x0f,0x00,0x00,0x00,
+    0x74,0x65,0x78,0x00,0x05,0x00,0x03,0x00,0x12,0x00,0x00,0x00,0x75,0x76,0x00,0x00,
+    0x05,0x00,0x04,0x00,0x1b,0x00,0x00,0x00,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x0a,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x0f,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x0f,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x0f,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x12,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x1b,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x13,0x00,0x02,0x00,0x03,0x00,0x00,0x00,0x21,0x00,0x03,0x00,0x04,0x00,0x00,0x00,
+    0x03,0x00,0x00,0x00,0x16,0x00,0x03,0x00,0x07,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+    0x17,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+    0x20,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
+    0x3b,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
+    0x2b,0x00,0x04,0x00,0x07,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x80,0x3f,
+    0x19,0x00,0x09,0x00,0x0c,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x1b,0x00,0x03,0x00,0x0d,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,
+    0x20,0x00,0x04,0x00,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,
+    0x3b,0x00,0x04,0x00,0x0e,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x20,0x00,0x04,0x00,0x11,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
+    0x3b,0x00,0x04,0x00,0x11,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x17,0x00,0x04,0x00,0x13,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+    0x3b,0x00,0x04,0x00,0x11,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x36,0x00,0x05,0x00,0x03,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x04,0x00,0x00,0x00,0xf8,0x00,0x02,0x00,0x06,0x00,0x00,0x00,0x08,0x00,0x04,0x00,
+    0x01,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,
+    0x0d,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,
+    0x08,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x4f,0x00,0x07,0x00,
+    0x13,0x00,0x00,0x00,0x15,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x57,0x00,0x05,0x00,0x08,0x00,0x00,0x00,
+    0x16,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x15,0x00,0x00,0x00,0x51,0x00,0x05,0x00,
+    0x07,0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x50,0x00,0x07,0x00,0x08,0x00,0x00,0x00,0x1a,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,
+    0x0b,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,
+    0x08,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x85,0x00,0x05,0x00,
+    0x08,0x00,0x00,0x00,0x1d,0x00,0x00,0x00,0x1a,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,
+    0x3e,0x00,0x03,0x00,0x0a,0x00,0x00,0x00,0x1d,0x00,0x00,0x00,0xfd,0x00,0x01,0x00,
+    0x38,0x00,0x01,0x00,
+};
 #elif defined(SOKOL_DUMMY_BACKEND)
 static const char* _sfons_vs_src = "";
 static const char* _sfons_fs_src = "";
+#else
+#error "Please define one of SOKOL_GLCORE33, SOKOL_GLES2, SOKOL_GLES3, SOKOL_D3D11, SOKOL_METAL, SOKOL_WGPU or SOKOL_DUMMY_BACKEND!"
 #endif
 
 typedef struct _sfons_t {
@@ -657,7 +880,7 @@ static int _sfons_render_create(void* user_ptr, int width, int height) {
         ub->uniforms[1].type = SG_UNIFORMTYPE_MAT4;
         shd_desc.fs.images[0].name = "tex";
         shd_desc.fs.images[0].type = SG_IMAGETYPE_2D;
-        #if defined(SOKOL_D3D11)
+        #if defined(SOKOL_D3D11) || defined(SOKOL_WGPU)
             shd_desc.vs.byte_code = _sfons_vs_bin;
             shd_desc.vs.byte_code_size = sizeof(_sfons_vs_bin);
             shd_desc.fs.byte_code = _sfons_fs_bin;

+ 13 - 1
util/sokol_gfx_imgui.h

@@ -861,6 +861,15 @@ _SOKOL_PRIVATE const char* _sg_imgui_imagetype_string(sg_image_type t) {
     }
 }
 
+_SOKOL_PRIVATE const char* _sg_imgui_samplertype_string(sg_sampler_type t) {
+    switch (t) {
+        case SG_SAMPLERTYPE_FLOAT:  return "SG_SAMPLERTYPE_FLOAT";
+        case SG_SAMPLERTYPE_SINT:   return "SG_SAMPLERTYPE_SINT";
+        case SG_SAMPLERTYPE_UINT:   return "SG_SAMPLERTYPE_UINT";
+        default:                    return "???";
+    }
+}
+
 _SOKOL_PRIVATE const char* _sg_imgui_pixelformat_string(sg_pixel_format fmt) {
     switch (fmt) {
         case SG_PIXELFORMAT_NONE: return "SG_PIXELFORMAT_NONE";
@@ -2783,7 +2792,10 @@ _SOKOL_PRIVATE void _sg_imgui_draw_shader_stage(sg_imgui_t* ctx, const sg_shader
             for (int i = 0; i < SG_MAX_SHADERSTAGE_IMAGES; i++) {
                 const sg_shader_image_desc* sid = &stage->images[i];
                 if (sid->type != _SG_IMAGETYPE_DEFAULT) {
-                    igText("%s %s", _sg_imgui_imagetype_string(sid->type), sid->name ? sid->name : "");
+                    igText("slot: %d\n  name: %s\n  type: %s\n  sampler_type: %s",
+                        i, sid->name ? sid->name : "NONE",
+                        _sg_imgui_imagetype_string(sid->type),
+                        _sg_imgui_samplertype_string(sid->sampler_type));
                 }
                 else {
                     break;

+ 222 - 2
util/sokol_gl.h

@@ -18,6 +18,7 @@
     SOKOL_GLES3
     SOKOL_D3D11
     SOKOL_METAL
+    SOKOL_WGPU
 
     ...optionally provide the following macros to override defaults:
 
@@ -936,7 +937,7 @@ static const uint8_t _sgl_vs_bin[] = {
       0,   0,   0,   0,   0,   0,
       0,   0,   0,   0
 };
-static uint8_t _sgl_fs_bin[] = {
+static const uint8_t _sgl_fs_bin[] = {
      68,  88,  66,  67, 145, 182,
      34, 101, 114, 183,  46,   3,
     176, 243, 147, 199, 109,  42,
@@ -1053,9 +1054,228 @@ static uint8_t _sgl_fs_bin[] = {
       0,   0,   0,   0,   0,   0,
       0,   0,   0,   0
 };
+#elif defined(SOKOL_WGPU)
+/*
+    Shader blobs for WebGPU.
+
+    Vertex shader source:
+
+    #version 450
+
+    layout(set = 0, binding = 0, std140) uniform vs_params
+    {
+        mat4 mvp;
+        mat4 tm;
+    } _20;
+
+    layout(location = 0) in vec4 position;
+    layout(location = 0) out vec4 uv;
+    layout(location = 1) in vec2 texcoord0;
+    layout(location = 1) out vec4 color;
+    layout(location = 2) in vec4 color0;
+
+    void main()
+    {
+        gl_Position = _20.mvp * position;
+        uv = _20.tm * vec4(texcoord0, 0.0, 1.0);
+        color = color0;
+    }
+
+    Fragment shader source:
+
+    #version 450
+
+    layout(location = 0, set = 2, binding = 0) uniform sampler2D tex;
+
+    layout(location = 0) out vec4 frag_color;
+    layout(location = 0) in vec4 uv;
+    layout(location = 1) in vec4 color;
+
+    void main()
+    {
+        frag_color = texture(tex, uv.xy) * color;
+    }
+*/
+static const uint8_t _sgl_vs_bin[1800] = {
+    0x03,0x02,0x23,0x07,0x00,0x00,0x01,0x00,0x08,0x00,0x08,0x00,0x2f,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x11,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x06,0x00,
+    0x02,0x00,0x00,0x00,0x47,0x4c,0x53,0x4c,0x2e,0x73,0x74,0x64,0x2e,0x34,0x35,0x30,
+    0x00,0x00,0x00,0x00,0x0e,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x0f,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x6d,0x61,0x69,0x6e,
+    0x00,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,
+    0x24,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x07,0x00,0x03,0x00,
+    0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x37,0x00,0x02,0x00,0x00,0x00,
+    0xc2,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,
+    0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x63,0x6c,0x69,
+    0x65,0x6e,0x74,0x20,0x76,0x75,0x6c,0x6b,0x61,0x6e,0x31,0x30,0x30,0x0a,0x2f,0x2f,
+    0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,
+    0x65,0x64,0x20,0x63,0x6c,0x69,0x65,0x6e,0x74,0x20,0x6f,0x70,0x65,0x6e,0x67,0x6c,
+    0x31,0x30,0x30,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,
+    0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2d,
+    0x65,0x6e,0x76,0x20,0x76,0x75,0x6c,0x6b,0x61,0x6e,0x31,0x2e,0x30,0x0a,0x2f,0x2f,
+    0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,
+    0x65,0x64,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2d,0x65,0x6e,0x76,0x20,0x6f,0x70,
+    0x65,0x6e,0x67,0x6c,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,
+    0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x65,0x6e,0x74,0x72,0x79,0x2d,
+    0x70,0x6f,0x69,0x6e,0x74,0x20,0x6d,0x61,0x69,0x6e,0x0a,0x23,0x6c,0x69,0x6e,0x65,
+    0x20,0x31,0x0a,0x00,0x05,0x00,0x04,0x00,0x05,0x00,0x00,0x00,0x6d,0x61,0x69,0x6e,
+    0x00,0x00,0x00,0x00,0x05,0x00,0x06,0x00,0x0c,0x00,0x00,0x00,0x67,0x6c,0x5f,0x50,
+    0x65,0x72,0x56,0x65,0x72,0x74,0x65,0x78,0x00,0x00,0x00,0x00,0x06,0x00,0x06,0x00,
+    0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,
+    0x69,0x6f,0x6e,0x00,0x06,0x00,0x07,0x00,0x0c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x67,0x6c,0x5f,0x50,0x6f,0x69,0x6e,0x74,0x53,0x69,0x7a,0x65,0x00,0x00,0x00,0x00,
+    0x06,0x00,0x07,0x00,0x0c,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x67,0x6c,0x5f,0x43,
+    0x6c,0x69,0x70,0x44,0x69,0x73,0x74,0x61,0x6e,0x63,0x65,0x00,0x06,0x00,0x07,0x00,
+    0x0c,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x67,0x6c,0x5f,0x43,0x75,0x6c,0x6c,0x44,
+    0x69,0x73,0x74,0x61,0x6e,0x63,0x65,0x00,0x05,0x00,0x03,0x00,0x0e,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x05,0x00,0x05,0x00,0x12,0x00,0x00,0x00,0x76,0x73,0x5f,0x70,
+    0x61,0x72,0x61,0x6d,0x73,0x00,0x00,0x00,0x06,0x00,0x04,0x00,0x12,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x6d,0x76,0x70,0x00,0x06,0x00,0x04,0x00,0x12,0x00,0x00,0x00,
+    0x01,0x00,0x00,0x00,0x74,0x6d,0x00,0x00,0x05,0x00,0x03,0x00,0x14,0x00,0x00,0x00,
+    0x5f,0x32,0x30,0x00,0x05,0x00,0x05,0x00,0x19,0x00,0x00,0x00,0x70,0x6f,0x73,0x69,
+    0x74,0x69,0x6f,0x6e,0x00,0x00,0x00,0x00,0x05,0x00,0x03,0x00,0x1e,0x00,0x00,0x00,
+    0x75,0x76,0x00,0x00,0x05,0x00,0x05,0x00,0x24,0x00,0x00,0x00,0x74,0x65,0x78,0x63,
+    0x6f,0x6f,0x72,0x64,0x30,0x00,0x00,0x00,0x05,0x00,0x04,0x00,0x2c,0x00,0x00,0x00,
+    0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0x05,0x00,0x04,0x00,0x2d,0x00,0x00,0x00,
+    0x63,0x6f,0x6c,0x6f,0x72,0x30,0x00,0x00,0x48,0x00,0x05,0x00,0x0c,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x05,0x00,
+    0x0c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x48,0x00,0x05,0x00,0x0c,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,
+    0x03,0x00,0x00,0x00,0x48,0x00,0x05,0x00,0x0c,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
+    0x0b,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x47,0x00,0x03,0x00,0x0c,0x00,0x00,0x00,
+    0x02,0x00,0x00,0x00,0x48,0x00,0x04,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x05,0x00,0x00,0x00,0x48,0x00,0x05,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x05,0x00,0x12,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x48,0x00,0x04,0x00,
+    0x12,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x48,0x00,0x05,0x00,
+    0x12,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x40,0x00,0x00,0x00,
+    0x48,0x00,0x05,0x00,0x12,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+    0x10,0x00,0x00,0x00,0x47,0x00,0x03,0x00,0x12,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x14,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x14,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x19,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x1e,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x24,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x2c,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x2d,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+    0x13,0x00,0x02,0x00,0x03,0x00,0x00,0x00,0x21,0x00,0x03,0x00,0x04,0x00,0x00,0x00,
+    0x03,0x00,0x00,0x00,0x16,0x00,0x03,0x00,0x07,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+    0x17,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+    0x15,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x2b,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x1c,0x00,0x04,0x00,0x0b,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,
+    0x1e,0x00,0x06,0x00,0x0c,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+    0x0b,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x0d,0x00,0x00,0x00,
+    0x03,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x0d,0x00,0x00,0x00,
+    0x0e,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x15,0x00,0x04,0x00,0x0f,0x00,0x00,0x00,
+    0x20,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x2b,0x00,0x04,0x00,0x0f,0x00,0x00,0x00,
+    0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x04,0x00,0x11,0x00,0x00,0x00,
+    0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x1e,0x00,0x04,0x00,0x12,0x00,0x00,0x00,
+    0x11,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x13,0x00,0x00,0x00,
+    0x02,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x13,0x00,0x00,0x00,
+    0x14,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x15,0x00,0x00,0x00,
+    0x02,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x18,0x00,0x00,0x00,
+    0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x18,0x00,0x00,0x00,
+    0x19,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x1c,0x00,0x00,0x00,
+    0x03,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x1c,0x00,0x00,0x00,
+    0x1e,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x2b,0x00,0x04,0x00,0x0f,0x00,0x00,0x00,
+    0x1f,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x17,0x00,0x04,0x00,0x22,0x00,0x00,0x00,
+    0x07,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x23,0x00,0x00,0x00,
+    0x01,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x23,0x00,0x00,0x00,
+    0x24,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x2b,0x00,0x04,0x00,0x07,0x00,0x00,0x00,
+    0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2b,0x00,0x04,0x00,0x07,0x00,0x00,0x00,
+    0x27,0x00,0x00,0x00,0x00,0x00,0x80,0x3f,0x3b,0x00,0x04,0x00,0x1c,0x00,0x00,0x00,
+    0x2c,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x18,0x00,0x00,0x00,
+    0x2d,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x36,0x00,0x05,0x00,0x03,0x00,0x00,0x00,
+    0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xf8,0x00,0x02,0x00,
+    0x06,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0x01,0x00,0x00,0x00,0x11,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x41,0x00,0x05,0x00,0x15,0x00,0x00,0x00,0x16,0x00,0x00,0x00,
+    0x14,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,0x11,0x00,0x00,0x00,
+    0x17,0x00,0x00,0x00,0x16,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,0x08,0x00,0x00,0x00,
+    0x1a,0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x91,0x00,0x05,0x00,0x08,0x00,0x00,0x00,
+    0x1b,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x1a,0x00,0x00,0x00,0x41,0x00,0x05,0x00,
+    0x1c,0x00,0x00,0x00,0x1d,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
+    0x3e,0x00,0x03,0x00,0x1d,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x08,0x00,0x04,0x00,
+    0x01,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x05,0x00,
+    0x15,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
+    0x3d,0x00,0x04,0x00,0x11,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+    0x3d,0x00,0x04,0x00,0x22,0x00,0x00,0x00,0x25,0x00,0x00,0x00,0x24,0x00,0x00,0x00,
+    0x51,0x00,0x05,0x00,0x07,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x25,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x51,0x00,0x05,0x00,0x07,0x00,0x00,0x00,0x29,0x00,0x00,0x00,
+    0x25,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x50,0x00,0x07,0x00,0x08,0x00,0x00,0x00,
+    0x2a,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x29,0x00,0x00,0x00,0x26,0x00,0x00,0x00,
+    0x27,0x00,0x00,0x00,0x91,0x00,0x05,0x00,0x08,0x00,0x00,0x00,0x2b,0x00,0x00,0x00,
+    0x21,0x00,0x00,0x00,0x2a,0x00,0x00,0x00,0x3e,0x00,0x03,0x00,0x1e,0x00,0x00,0x00,
+    0x2b,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0x01,0x00,0x00,0x00,0x13,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x2e,0x00,0x00,0x00,
+    0x2d,0x00,0x00,0x00,0x3e,0x00,0x03,0x00,0x2c,0x00,0x00,0x00,0x2e,0x00,0x00,0x00,
+    0xfd,0x00,0x01,0x00,0x38,0x00,0x01,0x00,
+};
+static const uint8_t _sgl_fs_bin[916] = {
+    0x03,0x02,0x23,0x07,0x00,0x00,0x01,0x00,0x08,0x00,0x08,0x00,0x19,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x11,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x06,0x00,
+    0x02,0x00,0x00,0x00,0x47,0x4c,0x53,0x4c,0x2e,0x73,0x74,0x64,0x2e,0x34,0x35,0x30,
+    0x00,0x00,0x00,0x00,0x0e,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x0f,0x00,0x08,0x00,0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x6d,0x61,0x69,0x6e,
+    0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x16,0x00,0x00,0x00,
+    0x10,0x00,0x03,0x00,0x05,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x03,0x00,
+    0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x37,0x00,0x02,0x00,0x00,0x00,
+    0xc2,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,
+    0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x63,0x6c,0x69,
+    0x65,0x6e,0x74,0x20,0x76,0x75,0x6c,0x6b,0x61,0x6e,0x31,0x30,0x30,0x0a,0x2f,0x2f,
+    0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,
+    0x65,0x64,0x20,0x63,0x6c,0x69,0x65,0x6e,0x74,0x20,0x6f,0x70,0x65,0x6e,0x67,0x6c,
+    0x31,0x30,0x30,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,
+    0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2d,
+    0x65,0x6e,0x76,0x20,0x76,0x75,0x6c,0x6b,0x61,0x6e,0x31,0x2e,0x30,0x0a,0x2f,0x2f,
+    0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,
+    0x65,0x64,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2d,0x65,0x6e,0x76,0x20,0x6f,0x70,
+    0x65,0x6e,0x67,0x6c,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,
+    0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x65,0x6e,0x74,0x72,0x79,0x2d,
+    0x70,0x6f,0x69,0x6e,0x74,0x20,0x6d,0x61,0x69,0x6e,0x0a,0x23,0x6c,0x69,0x6e,0x65,
+    0x20,0x31,0x0a,0x00,0x05,0x00,0x04,0x00,0x05,0x00,0x00,0x00,0x6d,0x61,0x69,0x6e,
+    0x00,0x00,0x00,0x00,0x05,0x00,0x05,0x00,0x0a,0x00,0x00,0x00,0x66,0x72,0x61,0x67,
+    0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x05,0x00,0x03,0x00,0x0e,0x00,0x00,0x00,
+    0x74,0x65,0x78,0x00,0x05,0x00,0x03,0x00,0x11,0x00,0x00,0x00,0x75,0x76,0x00,0x00,
+    0x05,0x00,0x04,0x00,0x16,0x00,0x00,0x00,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x0a,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x0e,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x0e,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x0e,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x11,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x16,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x13,0x00,0x02,0x00,0x03,0x00,0x00,0x00,0x21,0x00,0x03,0x00,0x04,0x00,0x00,0x00,
+    0x03,0x00,0x00,0x00,0x16,0x00,0x03,0x00,0x07,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+    0x17,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+    0x20,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
+    0x3b,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
+    0x19,0x00,0x09,0x00,0x0b,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x1b,0x00,0x03,0x00,0x0c,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,
+    0x20,0x00,0x04,0x00,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,
+    0x3b,0x00,0x04,0x00,0x0d,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x20,0x00,0x04,0x00,0x10,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
+    0x3b,0x00,0x04,0x00,0x10,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x17,0x00,0x04,0x00,0x12,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+    0x3b,0x00,0x04,0x00,0x10,0x00,0x00,0x00,0x16,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x36,0x00,0x05,0x00,0x03,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x04,0x00,0x00,0x00,0xf8,0x00,0x02,0x00,0x06,0x00,0x00,0x00,0x08,0x00,0x04,0x00,
+    0x01,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,
+    0x0c,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,
+    0x08,0x00,0x00,0x00,0x13,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x4f,0x00,0x07,0x00,
+    0x12,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x13,0x00,0x00,0x00,0x13,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x57,0x00,0x05,0x00,0x08,0x00,0x00,0x00,
+    0x15,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,
+    0x08,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x16,0x00,0x00,0x00,0x85,0x00,0x05,0x00,
+    0x08,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x15,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
+    0x3e,0x00,0x03,0x00,0x0a,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0xfd,0x00,0x01,0x00,
+    0x38,0x00,0x01,0x00,
+};
 #elif defined(SOKOL_DUMMY_BACKEND)
 static const char* _sgl_vs_src = "";
 static const char* _sgl_fs_src = "";
+#else
+#error "Please define one of SOKOL_GLCORE33, SOKOL_GLES2, SOKOL_GLES3, SOKOL_D3D11, SOKOL_METAL, SOKOL_WGPU or SOKOL_DUMMY_BACKEND!"
 #endif
 
 typedef enum {
@@ -1828,7 +2048,7 @@ SOKOL_API_IMPL void sgl_setup(const sgl_desc_t* desc) {
     ub->uniforms[1].type = SG_UNIFORMTYPE_MAT4;
     shd_desc.fs.images[0].name = "tex";
     shd_desc.fs.images[0].type = SG_IMAGETYPE_2D;
-    #if defined(SOKOL_D3D11)
+    #if defined(SOKOL_D3D11) || defined(SOKOL_WGPU)
         shd_desc.vs.byte_code = _sgl_vs_bin;
         shd_desc.vs.byte_code_size = sizeof(_sgl_vs_bin);
         shd_desc.fs.byte_code = _sgl_fs_bin;

+ 206 - 2
util/sokol_imgui.h

@@ -28,6 +28,7 @@
     SOKOL_GLES3
     SOKOL_D3D11
     SOKOL_METAL
+    SOKOL_WGPU
 
     Optionally provide the following configuration defines before including the
     implementation:
@@ -707,8 +708,211 @@ static const uint8_t _simgui_fs_bin[] = {
       0,   0,   0,   0,   0,   0,
       0,   0,   0,   0
 };
+#elif defined(SOKOL_WGPU)
+/*
+    Compiled with sokol-shdc:
+
+     @vs vs
+     uniform vs_params {
+         vec2 disp_size;
+     };
+     in vec2 position;
+     in vec2 texcoord0;
+     in vec4 color0;
+     out vec2 uv;
+     out vec4 color;
+     void main() {
+         gl_Position = vec4(((position/disp_size)-0.5)*vec2(2.0,-2.0), 0.5, 1.0);
+         uv = texcoord0;
+         color = color0;
+     }
+     @end
+
+     @fs fs
+     uniform sampler2D tex;
+     in vec2 uv;
+     in vec4 color;
+     out vec4 frag_color;
+     void main() {
+         frag_color = texture(tex, uv) * color;
+     }
+     @end
+
+     @program imgui vs fs
+*/
+static const uint8_t _simgui_vs_bin[1736] = {
+    0x03,0x02,0x23,0x07,0x00,0x00,0x01,0x00,0x08,0x00,0x08,0x00,0x31,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x11,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x06,0x00,
+    0x02,0x00,0x00,0x00,0x47,0x4c,0x53,0x4c,0x2e,0x73,0x74,0x64,0x2e,0x34,0x35,0x30,
+    0x00,0x00,0x00,0x00,0x0e,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x0f,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x6d,0x61,0x69,0x6e,
+    0x00,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x13,0x00,0x00,0x00,0x2a,0x00,0x00,0x00,
+    0x2b,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x2f,0x00,0x00,0x00,0x07,0x00,0x03,0x00,
+    0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x37,0x00,0x02,0x00,0x00,0x00,
+    0xc2,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,
+    0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x63,0x6c,0x69,
+    0x65,0x6e,0x74,0x20,0x76,0x75,0x6c,0x6b,0x61,0x6e,0x31,0x30,0x30,0x0a,0x2f,0x2f,
+    0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,
+    0x65,0x64,0x20,0x63,0x6c,0x69,0x65,0x6e,0x74,0x20,0x6f,0x70,0x65,0x6e,0x67,0x6c,
+    0x31,0x30,0x30,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,
+    0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2d,
+    0x65,0x6e,0x76,0x20,0x76,0x75,0x6c,0x6b,0x61,0x6e,0x31,0x2e,0x30,0x0a,0x2f,0x2f,
+    0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,
+    0x65,0x64,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2d,0x65,0x6e,0x76,0x20,0x6f,0x70,
+    0x65,0x6e,0x67,0x6c,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,
+    0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x65,0x6e,0x74,0x72,0x79,0x2d,
+    0x70,0x6f,0x69,0x6e,0x74,0x20,0x6d,0x61,0x69,0x6e,0x0a,0x23,0x6c,0x69,0x6e,0x65,
+    0x20,0x31,0x0a,0x00,0x05,0x00,0x04,0x00,0x05,0x00,0x00,0x00,0x6d,0x61,0x69,0x6e,
+    0x00,0x00,0x00,0x00,0x05,0x00,0x06,0x00,0x0c,0x00,0x00,0x00,0x67,0x6c,0x5f,0x50,
+    0x65,0x72,0x56,0x65,0x72,0x74,0x65,0x78,0x00,0x00,0x00,0x00,0x06,0x00,0x06,0x00,
+    0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,
+    0x69,0x6f,0x6e,0x00,0x06,0x00,0x07,0x00,0x0c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x67,0x6c,0x5f,0x50,0x6f,0x69,0x6e,0x74,0x53,0x69,0x7a,0x65,0x00,0x00,0x00,0x00,
+    0x06,0x00,0x07,0x00,0x0c,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x67,0x6c,0x5f,0x43,
+    0x6c,0x69,0x70,0x44,0x69,0x73,0x74,0x61,0x6e,0x63,0x65,0x00,0x06,0x00,0x07,0x00,
+    0x0c,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x67,0x6c,0x5f,0x43,0x75,0x6c,0x6c,0x44,
+    0x69,0x73,0x74,0x61,0x6e,0x63,0x65,0x00,0x05,0x00,0x03,0x00,0x0e,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x05,0x00,0x05,0x00,0x13,0x00,0x00,0x00,0x70,0x6f,0x73,0x69,
+    0x74,0x69,0x6f,0x6e,0x00,0x00,0x00,0x00,0x05,0x00,0x05,0x00,0x15,0x00,0x00,0x00,
+    0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x00,0x00,0x00,0x06,0x00,0x06,0x00,
+    0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64,0x69,0x73,0x70,0x5f,0x73,0x69,0x7a,
+    0x65,0x00,0x00,0x00,0x05,0x00,0x03,0x00,0x17,0x00,0x00,0x00,0x5f,0x32,0x33,0x00,
+    0x05,0x00,0x03,0x00,0x2a,0x00,0x00,0x00,0x75,0x76,0x00,0x00,0x05,0x00,0x05,0x00,
+    0x2b,0x00,0x00,0x00,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x00,0x00,0x00,
+    0x05,0x00,0x04,0x00,0x2d,0x00,0x00,0x00,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,
+    0x05,0x00,0x04,0x00,0x2f,0x00,0x00,0x00,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x00,0x00,
+    0x48,0x00,0x05,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x48,0x00,0x05,0x00,0x0c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x0b,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,0x00,0x05,0x00,0x0c,0x00,0x00,0x00,
+    0x02,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x48,0x00,0x05,0x00,
+    0x0c,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+    0x47,0x00,0x03,0x00,0x0c,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x47,0x00,0x04,0x00,
+    0x13,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x05,0x00,
+    0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x03,0x00,0x15,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x47,0x00,0x04,0x00,
+    0x17,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x47,0x00,0x04,0x00,
+    0x17,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x47,0x00,0x04,0x00,
+    0x2a,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x47,0x00,0x04,0x00,
+    0x2b,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x47,0x00,0x04,0x00,
+    0x2d,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x47,0x00,0x04,0x00,
+    0x2f,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x13,0x00,0x02,0x00,
+    0x03,0x00,0x00,0x00,0x21,0x00,0x03,0x00,0x04,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
+    0x16,0x00,0x03,0x00,0x07,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x17,0x00,0x04,0x00,
+    0x08,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x15,0x00,0x04,0x00,
+    0x09,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2b,0x00,0x04,0x00,
+    0x09,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x1c,0x00,0x04,0x00,
+    0x0b,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x1e,0x00,0x06,0x00,
+    0x0c,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,
+    0x0b,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x0d,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
+    0x0c,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x0d,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,
+    0x03,0x00,0x00,0x00,0x15,0x00,0x04,0x00,0x0f,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+    0x01,0x00,0x00,0x00,0x2b,0x00,0x04,0x00,0x0f,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x17,0x00,0x04,0x00,0x11,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+    0x02,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x12,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x11,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x12,0x00,0x00,0x00,0x13,0x00,0x00,0x00,
+    0x01,0x00,0x00,0x00,0x1e,0x00,0x03,0x00,0x15,0x00,0x00,0x00,0x11,0x00,0x00,0x00,
+    0x20,0x00,0x04,0x00,0x16,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x15,0x00,0x00,0x00,
+    0x3b,0x00,0x04,0x00,0x16,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+    0x20,0x00,0x04,0x00,0x18,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x11,0x00,0x00,0x00,
+    0x2b,0x00,0x04,0x00,0x07,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,
+    0x2c,0x00,0x05,0x00,0x11,0x00,0x00,0x00,0x1d,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,
+    0x1c,0x00,0x00,0x00,0x2b,0x00,0x04,0x00,0x07,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x40,0x2b,0x00,0x04,0x00,0x07,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+    0x00,0x00,0x00,0xc0,0x2c,0x00,0x05,0x00,0x11,0x00,0x00,0x00,0x21,0x00,0x00,0x00,
+    0x1f,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x2b,0x00,0x04,0x00,0x07,0x00,0x00,0x00,
+    0x23,0x00,0x00,0x00,0x00,0x00,0x80,0x3f,0x20,0x00,0x04,0x00,0x27,0x00,0x00,0x00,
+    0x03,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x29,0x00,0x00,0x00,
+    0x03,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x29,0x00,0x00,0x00,
+    0x2a,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x12,0x00,0x00,0x00,
+    0x2b,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x27,0x00,0x00,0x00,
+    0x2d,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x2e,0x00,0x00,0x00,
+    0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x2e,0x00,0x00,0x00,
+    0x2f,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x36,0x00,0x05,0x00,0x03,0x00,0x00,0x00,
+    0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xf8,0x00,0x02,0x00,
+    0x06,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,0x11,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
+    0x13,0x00,0x00,0x00,0x41,0x00,0x05,0x00,0x18,0x00,0x00,0x00,0x19,0x00,0x00,0x00,
+    0x17,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,0x11,0x00,0x00,0x00,
+    0x1a,0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x88,0x00,0x05,0x00,0x11,0x00,0x00,0x00,
+    0x1b,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x1a,0x00,0x00,0x00,0x83,0x00,0x05,0x00,
+    0x11,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x1d,0x00,0x00,0x00,
+    0x85,0x00,0x05,0x00,0x11,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,
+    0x21,0x00,0x00,0x00,0x51,0x00,0x05,0x00,0x07,0x00,0x00,0x00,0x24,0x00,0x00,0x00,
+    0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0x00,0x05,0x00,0x07,0x00,0x00,0x00,
+    0x25,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x50,0x00,0x07,0x00,
+    0x08,0x00,0x00,0x00,0x26,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x25,0x00,0x00,0x00,
+    0x1c,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x41,0x00,0x05,0x00,0x27,0x00,0x00,0x00,
+    0x28,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x3e,0x00,0x03,0x00,
+    0x28,0x00,0x00,0x00,0x26,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0x01,0x00,0x00,0x00,
+    0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,0x11,0x00,0x00,0x00,
+    0x2c,0x00,0x00,0x00,0x2b,0x00,0x00,0x00,0x3e,0x00,0x03,0x00,0x2a,0x00,0x00,0x00,
+    0x2c,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0x01,0x00,0x00,0x00,0x12,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x30,0x00,0x00,0x00,
+    0x2f,0x00,0x00,0x00,0x3e,0x00,0x03,0x00,0x2d,0x00,0x00,0x00,0x30,0x00,0x00,0x00,
+    0xfd,0x00,0x01,0x00,0x38,0x00,0x01,0x00,
+};
+static const uint8_t _simgui_fs_bin[904] = {
+    0x03,0x02,0x23,0x07,0x00,0x00,0x01,0x00,0x08,0x00,0x08,0x00,0x19,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x11,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x06,0x00,
+    0x02,0x00,0x00,0x00,0x47,0x4c,0x53,0x4c,0x2e,0x73,0x74,0x64,0x2e,0x34,0x35,0x30,
+    0x00,0x00,0x00,0x00,0x0e,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x0f,0x00,0x08,0x00,0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x6d,0x61,0x69,0x6e,
+    0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x16,0x00,0x00,0x00,
+    0x10,0x00,0x03,0x00,0x05,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x03,0x00,
+    0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x37,0x00,0x02,0x00,0x00,0x00,
+    0xc2,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,
+    0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x63,0x6c,0x69,
+    0x65,0x6e,0x74,0x20,0x76,0x75,0x6c,0x6b,0x61,0x6e,0x31,0x30,0x30,0x0a,0x2f,0x2f,
+    0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,
+    0x65,0x64,0x20,0x63,0x6c,0x69,0x65,0x6e,0x74,0x20,0x6f,0x70,0x65,0x6e,0x67,0x6c,
+    0x31,0x30,0x30,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,
+    0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2d,
+    0x65,0x6e,0x76,0x20,0x76,0x75,0x6c,0x6b,0x61,0x6e,0x31,0x2e,0x30,0x0a,0x2f,0x2f,
+    0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,
+    0x65,0x64,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2d,0x65,0x6e,0x76,0x20,0x6f,0x70,
+    0x65,0x6e,0x67,0x6c,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,
+    0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x65,0x6e,0x74,0x72,0x79,0x2d,
+    0x70,0x6f,0x69,0x6e,0x74,0x20,0x6d,0x61,0x69,0x6e,0x0a,0x23,0x6c,0x69,0x6e,0x65,
+    0x20,0x31,0x0a,0x00,0x05,0x00,0x04,0x00,0x05,0x00,0x00,0x00,0x6d,0x61,0x69,0x6e,
+    0x00,0x00,0x00,0x00,0x05,0x00,0x05,0x00,0x0a,0x00,0x00,0x00,0x66,0x72,0x61,0x67,
+    0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x05,0x00,0x03,0x00,0x0e,0x00,0x00,0x00,
+    0x74,0x65,0x78,0x00,0x05,0x00,0x03,0x00,0x12,0x00,0x00,0x00,0x75,0x76,0x00,0x00,
+    0x05,0x00,0x04,0x00,0x16,0x00,0x00,0x00,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x0a,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x0e,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x0e,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x0e,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x12,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x47,0x00,0x04,0x00,0x16,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x13,0x00,0x02,0x00,0x03,0x00,0x00,0x00,0x21,0x00,0x03,0x00,0x04,0x00,0x00,0x00,
+    0x03,0x00,0x00,0x00,0x16,0x00,0x03,0x00,0x07,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+    0x17,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+    0x20,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
+    0x3b,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
+    0x19,0x00,0x09,0x00,0x0b,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,0x1b,0x00,0x03,0x00,0x0c,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,
+    0x20,0x00,0x04,0x00,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,
+    0x3b,0x00,0x04,0x00,0x0d,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x17,0x00,0x04,0x00,0x10,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+    0x20,0x00,0x04,0x00,0x11,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
+    0x3b,0x00,0x04,0x00,0x11,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x20,0x00,0x04,0x00,0x15,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
+    0x3b,0x00,0x04,0x00,0x15,0x00,0x00,0x00,0x16,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+    0x36,0x00,0x05,0x00,0x03,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x04,0x00,0x00,0x00,0xf8,0x00,0x02,0x00,0x06,0x00,0x00,0x00,0x08,0x00,0x04,0x00,
+    0x01,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,
+    0x0c,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,
+    0x10,0x00,0x00,0x00,0x13,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x57,0x00,0x05,0x00,
+    0x08,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x13,0x00,0x00,0x00,
+    0x3d,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x16,0x00,0x00,0x00,
+    0x85,0x00,0x05,0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
+    0x17,0x00,0x00,0x00,0x3e,0x00,0x03,0x00,0x0a,0x00,0x00,0x00,0x18,0x00,0x00,0x00,
+    0xfd,0x00,0x01,0x00,0x38,0x00,0x01,0x00,
+};
+
 #else
-#error "sokol_imgui.h: No sokol_gfx.h backend selected (SOKOL_GLCORE33, SOKOL_GLES2, SOKOL_GLES3, SOKOL_D3D11 or SOKOL_METAL)"
+#error "sokol_imgui.h: No sokol_gfx.h backend selected (SOKOL_GLCORE33, SOKOL_GLES2, SOKOL_GLES3, SOKOL_D3D11, SOKOL_METAL or SOKOL_WGPU)"
 #endif
 
 #if !defined(SOKOL_IMGUI_NO_SOKOL_APP)
@@ -865,7 +1069,7 @@ SOKOL_API_IMPL void simgui_setup(const simgui_desc_t* desc) {
     shd_desc.attrs[2].sem_name  = "COLOR";
     shd_desc.fs.images[0].name = "tex";
     shd_desc.fs.images[0].type = SG_IMAGETYPE_2D;
-    #if defined(SOKOL_D3D11)
+    #if defined(SOKOL_D3D11) || defined(SOKOL_WGPU)
         shd_desc.vs.byte_code = _simgui_vs_bin;
         shd_desc.vs.byte_code_size = sizeof(_simgui_vs_bin);
         shd_desc.fs.byte_code = _simgui_fs_bin;

Some files were not shown because too many files changed in this diff