No description
- Shell 32.2%
- JavaScript 26.7%
- C 22.4%
- C++ 9.3%
- HTML 5.4%
- Other 4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| guest | ||
| qemu-wasm | ||
| scripts | ||
| tests | ||
| web | ||
| .gitignore | ||
| README.md | ||
rv100-web
QEMU in the browser (x86_64, wasm JIT) with rv100, the emulated ATI Radeon 7000 / RV100, as its only display, booting Arch Linux into Xorg. On the emulated card:
glxgears, hardware-rendered through Mesa Amber's classic R100 driver (radeon_dri.so) and the stockradeonkernel driver;- an xterm that runs
glxinfo | grep -i opengl,lspci -kandfastfetch.
Live: https://apps.wizardhat.info/rv100-web/
The page shows the card's scanout on a canvas, a boot checklist, glxgears' FPS, and a root shell on the serial console. It is slow: the x86 guest runs roughly 15-20x slower than native QEMU TCG. Measured in headless Chrome on a Ryzen 7 3700X: kernel at ~90 s, radeon bound at ~165 s, X at ~240 s, the xterm's three commands done at ~520 s, glxgears drawing at ~560 s, at 0.3-2.5 FPS. (Native TCG: gears at 18.6 s and 29 FPS; KVM: 63-65 FPS, vsync.)
Layout
guest/ the Arch guest: build-guest.sh (kernel + initramfs from Arch packages,
fetched with pacman -Sp and unpacked, never installed),
build-mesa-amber.sh (Mesa 21.3.9 Amber, r100 only), rootfs/ (init, X config,
the demo terminal script), build-qemu.sh + run-native.py (native QEMU proof),
evidence/ (native screenshots and serial log)
qemu-wasm/ QEMU for the browser: build.sh builds ktock/qemu-wasm (pinned, QEMU 8.2 base)
with the rv100 device in rootless podman; device/ is rv100's QEMU device
ported to 8.2 plus a frame-grab export; web/rv100web.js is the JS API;
test/ is the emulator-only smoke test
web/ the page: index.html, app.js, coi-sw.js (adds COOP/COEP, see below)
scripts/build-site.sh assembles build/site from build/qemu-wasm, build/guest and web/
tests/site_smoke.mjs the whole site in headless Chromium, served WITHOUT COOP/COEP
Build
guest/build-guest.sh # -> build/guest/{vmlinuz,initramfs.cpio.gz}
qemu-wasm/build.sh # -> build/qemu-wasm/ (podman; first run builds the toolchain image)
scripts/build-site.sh # -> build/site
PLAYWRIGHT_CORE=<dir with node_modules/playwright-core> node tests/site_smoke.mjs
Notes
- Cross-origin isolation. qemu-wasm runs QEMU's threads as Web Workers
sharing one memory, which needs SharedArrayBuffer, which needs the page to
be served with COOP
same-originand COEPrequire-corp. The host serves every app through one nginx config without them, soweb/coi-sw.js, a service worker, adds them; the page installs it and reloads once. - The X cursor is not drawn: neither the model nor the frame grab composites the hardware cursor, and the page does not forward mouse or keyboard to the guest's X server. Typing goes to the serial console.
- Memory. The QEMU build has a fixed 2300 MB wasm memory; the guest gets
512 MB (it uses about 220 MB with X and glxgears running).
-m 1536does not fit alongside the 500 MB translation cache. - The rv100 repo's
frontend/qemu/qemu-v11.1.0.patchhas a wrong hunk count in its last hunk;guest/build-qemu.shcorrects it on the fly.