Describe the WSL2 runner and its browser mode (#283)

CI moved from stein2 to a runner in a WSL2 distro on melektaus-atx.

- Development: ci.yml asks for game-maker-wsl, the stein2 runner keeps
  game-maker-ci as the way back.
- The GPU per runner: the render node on stein2, /dev/dxg with Xvfb
  and ANGLE/GL under WSL2 (GAME_MAKER_BROWSER=wsl).
- The renderer check that stops a run on software rendering.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adminandClaude Opus 5.5 committed 2026-09-29 21:00:44 +02:00
1 parent d345d9960d
commit 02ac5dac84
1 file changed
+28 -9
+28 -9
@@ -39,8 +39,10 @@ in software that is ruinous: measured here on an idle page over 20 s, software W
a core at 8 fps**, the same page on the Intel HD 630 via ANGLE/Vulkan costs **69% at 56 fps**. The
full suite takes about four minutes that way. `tools/lib/browser.mjs` therefore always asks for the GPU and has
**no software fallback** — on a host without one, chromium should fail loudly rather than melt the
machine down. (`--use-angle=gl` and `--use-gl=egl` measure cheaper still, but get no WebGL context at
all, so the app never renders.)
machine down. (`--use-angle=gl` and `--use-gl=egl` measure cheaper still, but a headless chromium
gets no WebGL context with them at all, so the app never renders.) Every run also names its renderer
in the log (`renderer: …`) and stops if that is a software one such as llvmpipe or SwiftShader:
under WSL2 a missing GPU driver does not fail by itself, llvmpipe still offers WebGL 2 there.
**Leave the full run to CI.** Every push runs the whole proof on the runner (see *Continuous
integration*), so locally take only what the change needs: the gate, plus the step that covers it —
@@ -284,10 +286,27 @@ Every push runs the whole proof on the Gitea runner: `.gitea/workflows/ci.yml` i
seeders need (`PUT` does not create a project, `POST` hands out a random id). Every tool takes its
server from `GAME_MAKER_BASE_URL`.
The job runs in the image from `tools/ci/Dockerfile` under the label `game-maker-ci`: chromium
with the Vulkan drivers, `php-cli`, and the host's font packages, because the checks measure text
widths to find click points. The **render device is not in this repo** — `/dev/dri/renderD128`
and a 1 GB `/dev/shm` come from `container.options` in the runner's own `config.yaml`, which
applies to every job on that runner. Without them chromium falls back to llvmpipe, which gets
WebGL 1.0 only. Measured in the job container: `ANGLE (Intel, Vulkan 1.3.230, HD Graphics 630)`,
WebGL 2.0, and the same 1027 checks as here.
The jobs run in the image from `tools/ci/Dockerfile`: chromium with the Vulkan drivers and
`xvfb`, `php-cli`, and the host's font packages, because the checks measure text widths to find
click points. `ci.yml` asks for the label **`game-maker-wsl`** (#283): a runner in a WSL2 distro
on a Windows machine with an RTX 4070, so this host no longer carries the suite. The runner on
this host is still registered with the label `game-maker-ci` and the same image; pointing both
`runs-on` back at that label moves the runs here again.
The **GPU is not in this repo**. It comes from `container.options` in each runner's own
`config.yaml`, which applies to every job on that runner:
- **Here:** `/dev/dri/renderD128` and a 1 GB `/dev/shm`. Measured in the job container:
`ANGLE (Intel, Vulkan 1.3.230, HD Graphics 630)`, WebGL 2.0.
- **Under WSL2:** `/dev/dxg`, the Windows driver libraries from `/usr/lib/wsl` and the same
`/dev/shm`, plus `GAME_MAKER_BROWSER=wsl` from the runner's `envs`. There is no DRM render node
and no Vulkan there, and a headless chromium gets no WebGL at all. In this mode
`tools/lib/browser.mjs` starts an invisible Xvfb and an X11 chromium on ANGLE/GL, which reaches
the GPU through Mesa's d3d12 driver: `ANGLE (Microsoft Corporation, D3D12 (NVIDIA GeForce RTX
4070), OpenGL 4.2)`, WebGL 2.0, 60 frames a second. A Wayland chromium reached the GPU as well,
but let the editor's clock stall in long runs.
The suite takes about 40% longer there than here, almost all of it in the modules that read
back many pixels (drawing, tilemaps, shaders).
Without these options chromium falls back to software rendering, and the harness stops at the
renderer check.