The port pre-registered a test and ran it: against live-splash-publisher.png a cropped render scores RMSE 558.1 (0.85%) and a scaled one 10118.8 (15.4%). Cropping is 18x better. Confirmed here independently, from a different observable: the committed captures are 1279x675, 1280x690 and 1252x754. VARYING heights. A fixed presenter resample produces one size; crops of differently-sized windows produce exactly that spread. And ui-render-tone-curve.md had already recorded every capture aligning at dy=0 dx=0 with correlation 0.9466, which a 0.9375 vertical scale cannot produce -- the evidence was in the corpus before I wrote the claim. So the captures are crops of a 1:1 surface, and every RMSE, glyph count and surface mean against them is pixels to pixels with no filter to caveat. The blanket "everything measured off a PNG carries the resample" is withdrawn. Not refuted: the cvar reading. Canary does letterbox by default. What is refuted is my inference that the corpus's capture path went through it. Whether the presenter is bypassed, the window is 1:1, or the tool crops before saving is open and unestablished. The error is the one this session keeps paying for: I read a configuration and inferred a consequence FOR THE DATA without testing it against the data. The test costs one render and one RMSE and I had every capture needed to run it. Also downgrades my refutation of the corpus's oracle principle from "survives with a qualifier" to "survives, and my qualifier was wrong", kept rather than deleted because the failure is the instructive part. Section 1 (gamma: VdGetCurrentDisplayGamma is kStub, the splash shader has no pow/ramp/lookup) and the two-path distinction stand unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jc4pciRArGHfxGGhEbwp5t
6.9 KiB
What Canary does between the guest's draw and a captured pixel
🔴 CORRECTION 2026-09-02, same day — §2's CONSEQUENCE is REFUTED
I wrote that the presenter's letterbox-and-scale is in the capture path, that it explains the 1279×675 surface, and that "everything measured off a PNG carries the resample." The port pre-registered a test and ran it: against
live-splash-publisher.png, a cropped render scores RMSE 558.1 (0.85 %) and a scaled one 10 118.8 (15.4 %). Cropping is 18× better.✅ Confirmed independently here, from a different observable. The committed captures are 1279×675, 1280×690, 1252×754 — varying heights. A fixed presenter resample produces one size; crops of differently-sized windows produce exactly this spread. And
ui-render-tone-curve.mdalready recorded every capture aligning atdy=0 dx=0, correlation 0.9466, which a 0.9375 vertical scale cannot produce. The evidence was in the corpus before I wrote the claim.So the captures are CROPS of a 1:1 surface, not resamples, and every RMSE, glyph count and surface mean against them is pixels to pixels with no filter to caveat.
⚠️ What is NOT refuted: the cvar reading itself. Canary does letterbox by default. What is refuted is my inference that the corpus's capture path went through it. Whether the presenter is bypassed, the window is 1:1, or the tool crops the letterbox before saving is open and unestablished.
🔴 The error is the one this session keeps paying for. I read a configuration and inferred a consequence for the data without testing it against the data — the same shape as reading a base-address change as a decode. The test that refutes it costs one render and one RMSE, and I had every capture needed to run it.
§1 (gamma) and the two-paths distinction in §3 stand; §3's blanket caveat does not. Corrected in place below.
Status: ✅ decoded from Canary's own source. Instrument: ⟨canary-source⟩, with ⟨capture⟩ for the dumped guest shader. 2026-09-02.
Answers question 3 of ../agents/PLAYTEST-2026-09-02.md
— "present cadence, and any resolve, scale or gamma between the guest's draw and
a capture's pixels."
1 — gamma: Canary applies none
VdGetCurrentDisplayGamma is the export the play-test warns about. Reading it:
void VdGetCurrentDisplayGamma_entry(lpdword_t type_ptr, lpfloat_t power_ptr) {
*type_ptr = cvars::kernel_display_gamma_type; // default 2 = TV (BT.709)
*power_ptr = float(cvars::kernel_display_gamma_power);
}
DECLARE_XBOXKRNL_EXPORT1(VdGetCurrentDisplayGamma, kVideo, kStub);
It is declared kStub and it transforms nothing. It reports a gamma type to
the guest, which D3D would use to build a ramp. So the question becomes whether
the guest applies one — and for the splash it demonstrably does not. The
splash pixel shader, dumped from the running game, is four ALU ops:
tfetch2D r2, r1.xy, tf0
mul r1.___w, r2.wwww, r0.wwww
mul r0.xyz_, r2.xyzz, r0.xyzz
mul r1.xyz_, r0.xyzz, r1.wwww
max oC0, r1, r1
No pow, no ramp, no lookup. Nothing in the splash path applies gamma —
neither side of the emulation boundary.
2 — geometry: ⚠️ the presenter CAN resample, but the corpus's captures are CROPS
presenter.cc defaults:
| cvar | default | effect |
|---|---|---|
present_letterbox |
true | aspect preserved, bars added rather than stretching |
present_safe_area_x / _y |
100 | nothing cropped |
So Canary would scale the guest's 1280×720 to fit the host window and letterbox it. 🔴 But the committed captures did not go through that, per the correction above — they are crops. The 1279×675 surface is a cropped window grab, not a scaled one, which the varying capture sizes (1279×675, 1280×690, 1252×754) show directly.
⚠️ The wait_title.sh single-pixel failure is still real and still explained:
a coordinate valid at 1280×720 lands outside a 1279×675 crop just as surely as
outside a scaled one. The failure was the fixed coordinate, not the transform.
3 — 🔴 So there are TWO measurement paths, and only one has Canary in it
| path | route | Canary processing |
|---|---|---|
| pixels | guest draw → EDRAM → resolve → front buffer → presenter (scale + letterbox) → X11 → screenshot → PNG |
a resample, plus whatever the window system does |
| vertex stream | guest CPU writes a vertex buffer → the draw logger reads guest memory directly | none |
📌 The per-frame alpha series is the second path. The k_8_8_8_8 colour is
read out of the guest's own vertex buffer before it reaches a shader, a render
target, a resolve or the presenter. There is no Canary processing between the
guest's intent and that number — which is why
splash-interpolates-every-frame.md can
state per-frame alphas as the game's values rather than as pixels we measured.
🔴 The blanket caveat I attached here is WITHDRAWN. I claimed everything measured off a PNG carries a resample. It does not: the captures are crops, and pixel-exact comparison against them is pixels to pixels. The two-path distinction stands — the vertex stream still has strictly less between the guest and the number — but the practical gap is far smaller than I said, and a large body of shared evidence needs no qualifier.
Refutation attempt, recorded per the adversarial duty
Target: this corpus's own founding principle, stated at the top of three documents — "the oracle is the real game running in Xenia Canary, captured."
Result: it SURVIVES, and my proposed qualifier was WRONG. I claimed a PNG capture is "the oracle plus a resample". The port tested it and it is not — the captures are crops, and the principle needs no amendment. Recorded as a failed refutation rather than deleted, because the failure is instructive: I tried to attach a caveat to a large body of evidence on the strength of a config file, and the check that would have stopped me was one render and one RMSE.
The vertex stream is still the cleaner instrument — strictly less sits between the guest and the number — but that is now a statement about robustness, not a correction to anything measured.
Reach
⟨canary-source⟩ for the gamma stub and the presenter defaults — these are facts
about this build, and a different --present_* or kernel_display_gamma_type
would change them. ⟨capture⟩ for the shader, which is the splash's; other
screens' shaders have not been checked for gamma and the negative in §1 covers
the splash only.
❔ Not measured here: the resample's actual filter. I read the cvars that say scaling happens, not the kernel that does it. What a 1280×720 → 1279×675 resample does to a thin glyph is unquantified, and that is the number anyone doing pixel-exact work against a PNG would need.