floooh / sokol

minimal cross-platform standalone C headers
https://floooh.github.io/sokol-html5
zlib License
6.93k stars 487 forks source link

WebGPU TextureView validation error #1073

Closed FaultyPine closed 3 months ago

FaultyPine commented 3 months ago

I'm getting this error message loads of times in the chrome console (and a black canvas) when trying to run a webgpu sokol app. Reduced the code down to the bare minimum example code from sokol-samples.

ERROR: [TextureView of Texture (unlabeled 300x150 px, TextureFormat::BGRA8Unorm)] is associated with [Device], and cannot be used with [Device].
app.js:3245  - While validating colorAttachments[0].
app.js:3245  - While encoding [CommandEncoder (unlabeled)].BeginRenderPass([null]).

Chrome version: 126.0.6478.127

Code ```cpp //------------------------------------------------------------------------------ // clear-wgpu.c // Simple draw loop, clear default framebuffer. //------------------------------------------------------------------------------ #ifdef TARGET_WEB #define SOKOL_WGPU #elif defined(TARGET_DESKTOP) #define SOKOL_GLCORE #else #error "Unsupported target right now..." #endif #define SOKOL_IMPL #include "sokol/sokol_gfx.h" #include "sokol/sokol_log.h" #include "sokol/sokol_app.h" #ifdef TARGET_WEB #include "wgpu/wgpu_entry.h" #include #include "wgpu/wgpu_entry.c" //#include "wgpu/wgpu_entry_dawn.cc" #include "wgpu/wgpu_entry_emsc.c" #include "wgpu/wgpu_entry_swapchain.c" #endif // emcc src/main.cpp -o app.html -I. -s USE_WEBGPU=1 -DTARGET_WEB -Iexternal -g -s USE_WEBGPU=1 --shell-file=configs/index.html static sg_pass_action pass_action; static void init(void) { sg_desc desc = { .logger.func = slog_func, .environment = wgpu_environment(), }; sg_setup(&desc); pass_action = (sg_pass_action) { .colors[0] = { .load_action = SG_LOADACTION_CLEAR, .clear_value = { 1.0f, 0.0f, 0.0f, 1.0f } } }; } static void frame(void) { float g = pass_action.colors[0].clear_value.g + 0.01f; pass_action.colors[0].clear_value.g = (g > 1.0f) ? 0.0f : g; sg_pass pass = { .action = pass_action, .swapchain = wgpu_swapchain() }; sg_begin_pass(&pass); sg_end_pass(); sg_commit(); } static void shutdown(void) { sg_shutdown(); } sapp_desc sokol_main(int argc, char* argv[]) { wgpu_desc_t desc = { .width = 640, .height = 480, .title = "clear-wgpu", .init_cb = init, .frame_cb = frame, .shutdown_cb = shutdown, }; wgpu_start(&desc); return {}; } ```

compiled with

emcc src/main.cpp -o app.html -I. -s USE_WEBGPU=1 -DTARGET_WEB -Iexternal -g -s USE_WEBGPU=1 --shell-file=index.html

where index.html looks like

index.html ```html {{{ SCRIPT }}} ```

repro.zip

Running the compilation command in this repro folder and then doing emrun app.html reproduced the issue for me.

floooh commented 3 months ago

Must be something about the swapchain setup. Does the same problem happen with the samples here: https://floooh.github.io/sokol-html5/?

A couple of questions:

floooh commented 3 months ago

Nvm, I can reproduce the problem, but only with your repro.zip, not from the code in sokol-samples. I'll check how the code differs.

floooh commented 3 months ago

Hmm, no differences at first glance except for a couple of minor C vs C++ changes.

I'll need to dive a bit deeper later today.

Can you check if the original code in sokol-samples works?

Basically:

./fips emsdk install latest
./fips set config wgpu-wasm-ninja-release
./fips build
./fips run clear-wgpu

...this works here, but your example doesn't.

floooh commented 3 months ago

Erm, wait a second... the code somehow combines sokol_app.h with the bare wgpu-init code, that definitely won't work...

The idea is that you either use sokolapp.h (which has its own webgpu setup code) or the wgpu setup code, but not both (since both sokolapp.h and wgpu will do the WebGPU device and swapchain setup.

Let me check something...

floooh commented 3 months ago

...ok, the easiest way to make it work is to ignore all the stuff under wgpu/, and change main.cpp like this (ignoring the C++20 warnings):

//------------------------------------------------------------------------------
//  clear-wgpu.c
//  Simple draw loop, clear default framebuffer.
//------------------------------------------------------------------------------
#ifdef TARGET_WEB
#elif defined(TARGET_DESKTOP)
#define SOKOL_GLCORE
#else
#error "Unsupported target right now..."
#endif

#define SOKOL_IMPL
#define SOKOL_WGPU
#include "sokol/sokol_gfx.h"
#include "sokol/sokol_log.h"
#include "sokol/sokol_app.h"
#include "sokol/sokol_glue.h"

// emcc src/main.cpp -o app.html -I. -s USE_WEBGPU=1 -DTARGET_WEB -Iexternal -g -s USE_WEBGPU=1 --shell-file=configs/index.html

static sg_pass_action pass_action;

static void init(void) {
    sg_desc desc =
    {
        .logger.func = slog_func,
        .environment = sglue_environment(),
    };
    sg_setup(&desc);
    pass_action = (sg_pass_action) {
        .colors[0] = {
            .load_action = SG_LOADACTION_CLEAR,
            .clear_value = { 1.0f, 0.0f, 0.0f, 1.0f }
        }
    };
}

static void frame(void) {
    float g = pass_action.colors[0].clear_value.g + 0.01f;
    pass_action.colors[0].clear_value.g = (g > 1.0f) ? 0.0f : g;
    sg_pass pass = { .action = pass_action, .swapchain = sglue_swapchain() };
    sg_begin_pass(&pass);
    sg_end_pass();
    sg_commit();
}

static void shutdown(void) {
    sg_shutdown();
}

sapp_desc sokol_main(int argc, char* argv[])
{
    return {
        .width = 640,
        .height = 480,
        .init_cb = init,
        .frame_cb = frame,
        .cleanup_cb = shutdown,
        .window_title = "clear-wgpu",
    };
}

...otherwise if you don't want to to use sokolapp.h, use the wgpu* files from there, but in that case do not use sokol_app.h: https://github.com/floooh/sokol-samples/tree/master/wgpu

Just be aware that the current version of libdawn isn't supported, so that code won't help you getting a native WebGPU executable.

FaultyPine commented 3 months ago

Ahhh that makes sense. Fixed! Thank you for the quick response! It's really appreciated <3