Files
TeslaRel410/emulator/firmware-decomp/GPU-RETARGET.md
T
CydandClaude Opus 4.8 5d29442ecb Golden-model conformance suite (C1-C4 CONFORMANT) + GPU-compute retarget plan
igc_conformance.py pins the reference behaviour any port (RTL/GPU/C) must
reproduce: the DUMP packet parse, a synthetic raster, the bars pipeline
(texu==x+2 from the real cap7 tile programs), and the fxtest effect
primitives (coverage + z pinned) -- fixtures committed under conformance/.
GPU-RETARGET.md maps the DOSBox-renderer path: EMC tile as compute shader
(pixel=thread), 4 milestones, conformance-gated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 10:21:47 -05:00

3.3 KiB
Raw Blame History

GPU-compute retarget — the DOSBox-renderer path (2026-07-19)

Companion to FPGA-RECONSTRUCTION.md. This is the plan for shipping the decoded IGC/EMC model as a real-time renderer behind the existing DOSBox seam — the practical answer to "use this as the renderer for the pod."

Why GPU compute

The EMC array is 8,192 bit-serial PEs per 64×128 tile. On a GPU that is one thread per pixel executing the same decoded op stream — a literal 1:1 mapping, no hardware, ships as software next to the renderer we already deploy. The original array ran ~40 MHz bit-serial; any integrated GPU exceeds the whole frame's work by orders of magnitude.

Architecture

DOSBox (game, unmodified)
   │ wire protocol (known)          ── existing seam: render-bridge/live_bridge
   ▼
emu860 geometry stage               ── the i860 firmware, C/JIT port for realtime
   │ per-draw DMA stream + payloads (the coefficient programs)
   ▼
IGC translator (host)               ── igc_exec.parse -> flat op records
   │ SSBO: op stream + payload floats + tile list
   ▼
compute shader "EMC tile"           ── pixel = thread; fields in registers/LDS:
   │ texz/texu/texv/zbuf as uint20, r/g/b as uint8, enable as bool;
   │ ops = a switch over the named table (TREE*, MEM*, CPY, sweeps, SCA*)
   ▼
readout pass                        ── ramp(texu) / rgb24 -> RGBA8 frame texture
   ▼
present (the existing renderer window / vr_readpixels reply)

What ports 1:1 from the golden model

  • The op table (data) and parser — host-side, unchanged.
  • Tile semantics — each Tile.run branch becomes a shader case; the pixel memory bit-fields become packed uints (no bit-serial emulation needed: field-level semantics are already proven equivalent by the conformance suite).
  • Readout — ramp LUT as a small texture.

Conformance gate

igc_conformance.py (C1-C4, committed fixtures) is the acceptance bar: the shader path must reproduce C2-C4 outputs exactly (C1 is host-side parse). Add a C5 full-frame image hash (bars + fxtest frames) once texel sampling lands.

Realtime budget (per frame)

  • 52 tiles × ~100-3000 op-steps × 8,192 px ≈ 1-10 G pixel-ops worst case — a compute-shader trifle at 60 fps on integrated graphics.
  • Geometry stage: the real wall. emu860 in Python ≈ 600K steps/s; a frame is ~10-50M steps → need the C/JIT step-core (planned; the i860 ISA semantics are fully pinned by emu860 + MAME cross-validation). Interim: pre-captured streams replay at full speed for validation.

Milestones

  1. M1 shader tile: WGPU/GL compute kernel executing the named ops; passes C2-C4. (small)
  2. M2 frame loop: DMA-stream walker + tile dispatch + readout; renders the bars + fxtest fixtures. (small-medium)
  3. M3 texel path: TXDN stream -> texture sampling (needs the remaining spec work — the io-port fetch protocol). (medium, spec-gated)
  4. M4 live seam: behind live_bridge in place of / beside the GL renderer; real-time gate = the C step-core for emu860. (the big one, independent)

Open spec items feeding this (tracked in IGC-ENCODING-DERIVATION.md)

  • op-0x2c edge exact semantics (winding rule) — affects M1 fidelity.
  • TXDN io-port texel stream — gates M3.
  • The texz coordinate-seed op + the real ramp tables — purity for M2 images.