Files
xenia-rs/crates
MechaCat02 f6f3aac673 [iterate-3Z] Fix logo color (yellow->white): k_8_8_8_8 vfetch + vfetch field/stride/saturate
Defect 2 of the three render-fidelity defects vs the canary oracle (the
publisher "SQUARE ENIX" logo rendered YELLOW instead of WHITE). Root,
measured by readback (env-gated probes, removed): the logo PS multiplies
the sampled texture by the interpolated vertex COLOR; the K8888 texture
itself decodes correctly (67,667 white texels + 2,087 red — the red dots —
zero yellow), so the yellow came from the vertex-color attribute decode.

Four coupled, canary-faithful fixes (all UI-translator/capture only — the
deterministic headless core is untouched; n50m --gpu-inline --stable-digest
golden byte-identical, exit 0):

- GPUBUG-112 (translator vfetch): VertexFormat 6 = k_8_8_8_8 (4x u8
  normalized, 1 dword), NOT k_16_16 (which is 25) per canary xenos.h:643.
  The logo color stream is k_8_8_8_8; decoding it as k_16_16 read only 2 of
  4 channels and forced BLUE = 0 -> white texture x (R,G,0) = yellow. Now
  unpacks all four 8-bit channels (canary spirv_shader_translator_fetch.cc
  k_8_8_8_8 packed_offsets 0/8/16/24); added k_16_16 (format 25) too.

- GPUBUG-113 (ucode/fetch): vfetch is_signed / is_normalized / is_mini_fetch
  bit positions were wrong (read bits 24/25, which sit inside exp_adjust).
  Per canary ucode.h:757-758,764: signed=fomat_comp_all (w1 bit12),
  normalized=(num_format_all==0) (w1 bit13), mini_fetch (w1 bit30).

- GPUBUG-114 (translator vfetch): a vfetch_mini reuses the address AND
  STRIDE of the preceding full vfetch of the same stream (canary
  ucode.h:733); its own stride field is 0. Track the last full stride per
  fetch-const and inherit it so a mini color/UV attribute indexes by the
  real vertex stride, not its tight dword count.

- GPUBUG-115 (translator PS export): saturate the color export to [0,1]
  before the UNORM render-target write, mirroring canary
  spirv_shader_translator.cc:3607 ("Saturate, flushing NaN to 0"). Without
  it an out-of-range guest color writes garbage to the sRGB target.

Verified by env-gated frontbuffer readback (copy_texture_to_buffer, removed
before commit): the logo now renders WHITE text + RED dots (bbox centered
~y322-389), zero yellow anywhere. Workspace tests green (added 4: k_8_8_8_8
4-channel unpack, mini-fetch stride inheritance, vfetch bit decode, PS
saturate). Determinism: golden byte-identical.

Remaining (defects 1 & 3, see memory iterate-3Z): logo orientation and the
ed732b5a fullscreen background fill (renders ~white, canary shows black) —
both localized but not yet cleanly resolved; plan in the memory file.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 20:58:21 +02:00
..