diff --git a/kidlisp/PIECE-IL.md b/kidlisp/PIECE-IL.md index dbd23a7fb6..d6a97ce2bb 100644 --- a/kidlisp/PIECE-IL.md +++ b/kidlisp/PIECE-IL.md @@ -247,3 +247,26 @@ output stay in the closure compiler. Kernels take the parts that are already maps over data, which the census says is most of the arithmetic in the two big pieces: projection, star fields, the skirt's bands, the soldier's boxes. + +## 9. The frame as one buffer: drawing on the GPU + +A compiled piece that says `; @gpu` does not call the software rasterizer. +Its drawing heads record into a frame buffer (`lib/gpu-frame.mjs`): clear, +line, box, oval, tri and shape, each with its colour, one Float32Array a +frame, handed to bios in a single transferred message. bios tessellates it +to triangles with per-vertex colour and draws it with WebGPU in one pass on +its own canvas (`lib/gpu-frame-renderer.mjs`), then composites the CPU +buffer over it as a texture when the frame asks, so `write` and anything +the path does not take still show. `ink` keeps running on the CPU for its +colour parsing and the resolved colour is read back; `wipe` clears both. +The worker probes bios once; without a renderer the piece draws on the CPU +as before, same stream. + +Measured 2026-10-11, phone size / 1280×720: Fía 36 / 21 fps from 31 / 20 +on the CPU path; the shooter 25 / 24 from 22 / 22. The pictures match. The +format is the contract: a native host can consume the same buffer. + +What is left after this is evaluation and the runtime's own per-frame +work. Kernels (§8) take the data-parallel arithmetic; the whole program to +Wasm takes the rest, and a host that keeps kernel outputs on the GPU and +draws from them never pays a readback at all. diff --git a/kidlisp/reports/whistlegraph-benchmark-2026-10-10.md b/kidlisp/reports/whistlegraph-benchmark-2026-10-10.md index f9b7cd237e..50534468a6 100644 --- a/kidlisp/reports/whistlegraph-benchmark-2026-10-10.md +++ b/kidlisp/reports/whistlegraph-benchmark-2026-10-10.md @@ -21,6 +21,8 @@ into pools. | Fía | compiler v3 + the heart projection as a Wasm kernel | 26,921 | 420 | 28 | 16 | | Fía | … and no HUD colouring for the hidden label | 26,921 | 420 | 31 | 20 | | Shooter | compiler v3, no HUD colouring | 22,380 | 383 | 22 | 22 | +| Fía | … and the frame drawn by WebGPU (`; @gpu`) | 26,928 | 421 | 36 | 21 | +| Shooter | … and the frame drawn by WebGPU (`; @gpu`) | 22,387 | 384 | 25 | 24 | The compiler rows are the same sources with a `; @compile` first line (`lib/kidlisp-compile.mjs`, later the same day): the program compiled once @@ -48,6 +50,13 @@ is now skipped for a hidden label (339d671608). The star field in runtime (35 against 60 fps at phone size): a compute pass has to read its results back for a CPU rasterizer, and that costs more than the arithmetic. +The `; @gpu` rows (8754e56644, PIECE-IL.md §9): the compiled program +records its drawing into one buffer a frame (`lib/gpu-frame.mjs`) and bios +draws it with WebGPU as one vertex buffer and one draw +(`lib/gpu-frame-renderer.mjs`), the CPU buffer composited on top for text. +The frames match the CPU path's picture. What remains is evaluation and the +runtime's per-frame work around it; the rasterizer is off the clock. + ## What it says - **Size is a wash.** Prefix arithmetic costs what closures saved. A line