Displays, inputs and outputs
-
Frame-time p99 with the debug overlay on, any box. Plan 0030 put the three post stages behind a
PostStagetrait, so a rendered frame now costs ~4 vtable calls plus ~4TextureViewArc bumps it did not before. Expected to be unmeasurable against a render pass, but it was never measured — the check needs a live window, so it could not run at that plan’s close. Run the standalone with the overlay on, let it settle, and report whether p99 moved. (Plan 0030’s dynamic-dispatch risk bullet, extracted.) -
The display-write dither, on a second display and on the low-end box, 1080p fullscreen. Plan 0082 made the tonemap add ±1 encoded LSB of triangular noise before the 8-bit write (ADR-0096) — always on, no param, so every frame the engine draws carries it. Two things were settled on one machine and one panel and neither generalizes for free. (a) Does the grain read? The dither is a fixed pattern by design (that is what keeps every byte-equality test working), and a fixed pattern on a long-held still frame can resolve as texture. The 2026-08-12 verdict was “looks fine” on the dev box’s own display; a 6-bit + FRC panel, which runs its own temporal dither over ours, is the case that verdict cannot speak to. Load the reference frame (
RLX_PRESET_DIR=core/tests/fixtures/scratch-0082 …, the run line is in that directory’s README), go fullscreen, and hold it. If the grain reads as texture the answer is ADR-0096 Alternative F — an animated dither, one term — and it is anarchitectcall, not a constant to lower. (b) Does it cost anything? The pass gained threepowcalls per pixel (one per channel, insrgb_slope) on a fullscreen draw. Expected to be unmeasurable, never measured on weak hardware. Overlay on (F3), report the p99. (Plan 0082 Phase 5 was ahumanverdict on one display; extracted at that plan’s close.) -
A live audio input, unplugged and plugged back in — with a removable interface attached. Plan 0130 made the capture stream restartable and gave a dead input a recovery path (ADR-0142): the capture thread stores one flag when
AUDCLNT_E_DEVICE_INVALIDATEDcomes back from a packet call, and the shell reopens the mode’s default endpoint up toINPUT_RECOVERY_ATTEMPTStimes before writing alost …verdict. None of that has ever run against a real device loss — the plan’s Phase 5 ran with no removable interface on the box, so the whole path is pinned only by unit tests over a synthesized flag. With music playing into an interface (theLine (ZOOM AMS-22 Audio)endpoint the plan was designed against, or any USB interface), select it from theSmenu’s Input device row and then pull the cable. Report (a) whether the picture recovers to the default endpoint within a few frames and whatF3’saudioline then reads; (b) whether re-plugging leaves it unrecovered — it should, and confirming that is the check, because hot-plug is ADR-0142 Alternative D and deliberately unbuilt; and (c) thatconfig.toml’s[input] devicestill names the interface you chose, since a recovery deliberately does not persist its fallback. (Plan 0130 Phase 5 bullet 3, extracted at that plan’s close.)**The open question this answers is not "does the recovery work" but "does it fire at all".**The plan's own risk register names the case that would defeat every line of it: a real unplugwhose packet loop simply returns zero frames forever, which is indistinguishable from silenceand never sets the flag. If that is what happens, the honest fix is a silence-durationheuristic and that is a worse mechanism worth its own ADR — not a quiet addition. Report whichof the two you saw.**Plan 0135 Phase 5 joined this item at that plan's close (2026-08-30), for the same reason:no removable interface on the box.** It adds three questions and **changes what is undertest** — the policy is now the repaired one, so run this against a build at v0.95.0 or later:the settle window is `INPUT_RECOVERY_SETTLE_SECS = 0.36` rather than 60 frames, and anoperator-initiated swap resets the incident instead of inheriting a spent latch. Report**(d)** whether `CoCreateInstance` ever returns `REGDB_E_CLASSNOTREG` during a *real* loss, asopposed to the menu-speed churn where it was seen once; **(e)** how many of the three attemptsa real unplug consumes; and **(f)** whether the verdict that lands names the right cause —`lost …` for a gone endpoint, not a COM failure wearing the same string. **(d) is the onethat matters most**: design-backlog 0154 names three candidate fixes and says explicitly thatchoosing between them wants this evidence, so a run answering it is what unblocks that ADR.**A run that reproduces nothing is a result worth recording** — one activation in 22 is asingle sample, not a rate. _(Plan 0135 Phase 5, carried at that plan's close.)_ -
A 96 kHz interface, if one is to hand. Both analysis windows are sized in samples (
WINDOW_SIZE,LOW_WINDOW_SIZEincore/src/dsp/mod.rs), so a 96 kHz stream loses roughly a third of the band axis to one-bin resolution. This is the stated trigger of design-backlog 0032 — “worth taking the day someone runs the standalone on a 96 kHz interface and says the sub-bass reads mushy” — and Plan 0130 is what turned hitting it from a config edit into a keypress. Set the interface to 96 kHz, swap to it from theSmenu, and report whether the low end reads mushy against the same music at 48 kHz. A finding here is a backlog update on 0032, not a fix: sizing the windows in seconds re-opens ADR-0049 and is ADR territory by that entry’s own argument. (Plan 0130 Phase 5 bullet 4, extracted at that plan’s close.) -
The live video-out’s size ceiling (Plan 0115 Phase 6, item 2 — the one item that phase did not answer).
ritmolux --streamis proved steady at 1280x720 at 60 fps: 108,000 frames in 1800.00 s wall against 1799.99 s scene, +2.0 MB resident, per-stage 3.67-7.82 ms render+readback against 0.27-0.58 ms Spout send, on the RTX 3080. The largest size and rate that hold was deferred for time and is still unmeasured, which matters because ADR-0125 states its bandwidth figures (8.29 MB/frame, ~498 MB/s) at 1920x1080 and nothing has confirmed that size end to end — the receiving install is TouchDesigner Non-Commercial, which caps the TOP at 1280x1280. So this item needs either a commercial TouchDesigner licence or a different Spout receiver. Run--stream --size WxH --fps N --frames Nupward from 1280x720, read the per-stage cost line, and report the largest that holds and which GPU rendered it — the mode prints both resolved adapters at startup, and a frame-rate figure that does not name its adapter is worthless on a two-adapter box (ADR-0071, ADR-0146). Trap: a Spout receiver that loses its sender keeps presenting the last texture it received, so a still-looking picture is not evidence of a live one. Judge from motion in the frames, not from the fact that something is on screen. (Plan 0115 Phase 6 item 2, extracted at that plan’s close.) -
The operator console on two displays (Plan 0131 Phase 6).
Copens a second window on another display carrying the modals, the transport strip and a live preview of the output. Two things here are structurally invisible to CI and nothing else will answer them. (a) What the second swapchain costs the show. Record the output’s frame time console-closed and console-open, on two displays of different refresh rates, with the console on the slower one. Report it as a measurement naming the machine, both refresh rates, the GPU and which present mode the console negotiated — it is written todiagnostics.logon open as a#-prefixed note (ADR-0071). Same-refresh displays cannot answer this: that is exactly the configuration where the two pacing sources agree. “It costs the output frames” is a valid outcome and routes back to architect rather than being tuned away. (b) The dual-GPU path. On a hybrid laptop, say whether the console surface configured on the renderer’s adapter or fell to the no-preview path — the degrade exists, is logged, and has never been exercised; nothing on a single-GPU box can reach it. If no such machine is available, say so: an untested path honestly named beats a guess. Also report a legibility judgement at desk distance — the rows, the transport labels and the preview at the size the console actually opens. (Plan 0131 Phase 6, extracted at that plan’s close.)> **PART-RUN 2026-08-30 on one display; the rest is DEFERRED to ~2026-09-06, when a second> monitor is available.** What ran: two 95 s release runs differing only by `--console`.> **The console cost the output about half its frame rate — 61.7 fps against 33.1 fps,> `frame_ms_p99_steady` 18.6 ms against 47.3 ms**, with the console's present mode confirmed> as `Mailbox`. That is a finding for `architect`, not something to tune here. It was measured> **on the integrated GPU** (see below) and with **both surfaces on one display**, which is> exactly the configuration this entry says cannot separate the two pacing sources — so the> cross-refresh run is still owed and now matters more. Resident set: flat closed, +1.2 MB> across 90 s open.>> **Still owed, all of it needing the second monitor:** the two-display cross-refresh> measurement with the console on the slower panel; the cadence verdict that rides on it; and> the **dual-GPU degrade path**, which this hybrid box still cannot reach because one display> puts both windows on one adapter. Also owed and needing nobody: a legibility judgement at> desk distance.>> **A second finding came out of it and is not about the console at all.** The windowed app> renders on `AMD Radeon(TM) Graphics (Dx12, IntegratedGpu)` on this machine, which also has> an RTX 3080 — `request_adapter` with a default power preference hands a hybrid laptop the> power-saving GPU. Every windowed frame-time figure quoted on this machine before> 2026-08-30 is therefore an iGPU figure. The startup note that says which adapter is running> is what makes any of these numbers attributable.>> **`--gpu` now reaches the window** (ADR-0155), and `ritmolux --gpu 1` has been observed putting> this box's window on `NVIDIA GeForce RTX 3080 Laptop GPU (Dx12, DiscreteGpu)` with the> startup line reading `(pinned by --gpu)`. What that unblocks and nobody has yet done: **re-take> the windowed frame-time figures on the discrete adapter and compare them against the iGPU> ones already recorded.** Unflagged behaviour is unchanged by design, so the existing numbers> remain valid for the default and the comparison is a new row rather than a correction.>> **Void from 2026-09-23: the last sentence above is no longer true.** An unflagged window now> prefers the **high-performance** adapter> ([ADR-0246](adrs/0246-the-adapter-is-a-setting-and-the-window-prefers-high-performance.md)),> so a fresh unflagged run on this box resolves the RTX 3080 rather than the Radeon. The> figures in this block are not edited and stay readable as history — each names its adapter —> but none of them describes what a default launch produces now. `docs/nfr.md` carries the same> note over its own rows. What has **not** changed is the dual-GPU degrade finding above: one> display still puts both windows on one adapter, so that branch stays unexercised.
Built from 13c7582 at version 0.158.0. This site tracks main and is not versioned per release.