Skip to content

WebGPU: "Error: Invalid Surface Status" triggered randomly #23407

Open
@chirsz-ever

Description

Environment:

  • x86_64 ArchLinux
  • Plasma 6.0.3 wayland
  • Deno 1.42.1

Repuroducable code:

// https://deno.com/blog/v1.40#webgpu-windowing--bring-your-own-window

import {
    EventType,
    WindowBuilder,
} from "jsr:@divy/[email protected]";

const width = 800;
const height = 600;

const win = new WindowBuilder("Hello, World!", width, height).build();

const adapter = await navigator.gpu.requestAdapter();
if (!adapter) {
    console.error("WebGPU not supported!");
    Deno.exit(1);
}
const device = await adapter.requestDevice();

/* Returns a Deno.UnsafeWindowSurface */
const surface = win.windowSurface();
/* Returns a WebGPU GPUCanvasContext */
const context = surface.getContext("webgpu");

context.configure({
    device,
    format: navigator.gpu.getPreferredCanvasFormat(),
    width,
    height,
});

for await (const event of win.events()) {
    if (event.type === EventType.Quit) break;
    if (event.type !== EventType.Draw) continue;

    // Sine wave
    const r = Math.sin(Date.now() / 1000) / 2 + 0.5;
    const g = Math.sin(Date.now() / 1000 + 2) / 2 + 0.5;
    const b = Math.sin(Date.now() / 1000 + 4) / 2 + 0.5;

    const textureView = context.getCurrentTexture().createView();

    const commandEncoder = device.createCommandEncoder();
    const passEncoder = commandEncoder.beginRenderPass({
        colorAttachments: [
            {
                view: textureView,
                clearValue: { r, g, b, a: 1.0 },
                loadOp: "clear",
                storeOp: "store",
            },
        ],
    });
    passEncoder.end();

    device.queue.submit([commandEncoder.finish()]);
    surface.present();
}

Save it as "example.ts" and run (SDL needs to be installed in advance):

deno run --unstable-webgpu --unstable-ffi -A example.ts

Got:

picture

Only one success.

If replacing deno_sdl2 with dwm, the same error would occur:

// https://deno.com/blog/v1.40#webgpu-windowing--bring-your-own-window

import {
    createWindow,
    mainloop,
} from "https://deno.land/x/[email protected]/mod.ts";

const width = 800;
const height = 600;

const adapter = await navigator.gpu.requestAdapter();
if (!adapter) {
    console.error("WebGPU not supported!");
    Deno.exit(1);
}
const device = await adapter.requestDevice();

const win = createWindow({
    title: "Deno Dwm WebGL",
    width,
    height,
});

/* Returns a Deno.UnsafeWindowSurface */
const surface = win.windowSurface();
/* Returns a WebGPU GPUCanvasContext */
const context = surface.getContext("webgpu");

context.configure({
    device,
    format: navigator.gpu.getPreferredCanvasFormat(),
    width,
    height,
});

function frame() {
    // Sine wave
    console.log("Draw!");
    const r = Math.sin(Date.now() / 1000) / 2 + 0.5;
    const g = Math.sin(Date.now() / 1000 + 2) / 2 + 0.5;
    const b = Math.sin(Date.now() / 1000 + 4) / 2 + 0.5;

    const textureView = context.getCurrentTexture().createView();

    const commandEncoder = device.createCommandEncoder();
    const passEncoder = commandEncoder.beginRenderPass({
        colorAttachments: [
            {
                view: textureView,
                clearValue: { r, g, b, a: 1.0 },
                loadOp: "clear",
                storeOp: "store",
            },
        ],
    });
    passEncoder.end();

    device.queue.submit([commandEncoder.finish()]);
    surface.present();
}

mainloop(frame);

Maybe this is a wgpu bug on Xwayland? When I start my desktop environment with X11, this problem disappears.

By the way, I think it worthy of adding a "wayland" backend for Deno.UnsafeWindowSurface

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions