From 0c6173f1bd7d62c4e3b2e63f719b95ce32423cae Mon Sep 17 00:00:00 2001 From: James Dansereau <106631954+jkdansereau@users.noreply.github.com> Date: Tue, 8 Sep 2026 20:43:15 -0400 Subject: [PATCH] diag(D172): replace weak tri probe with a decisive TEXEL1-bind dump The old 'cyc2 combine at cycletype=1CYC' probe over-fired on trivial passthrough cyc2 terms. Replace with one that fires only when a 2-cycle triangle actually consumes TEXEL1 (the G_CC_INTERFERENCE particle case) and dumps both texunits' tile/tmem/fmt/siz. One Silo capture then shows whether TEXEL1 resolves to the fire tile (tmem 392, RGBA16) or something wrong. Build clean; bunker1 verify PASS. --- docs/dev/D172-PARTICLE-COLOR-RESEARCH.md | 15 ++++++--- port/fast3d/gfx_pc.cpp | 42 +++++++++++++----------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/docs/dev/D172-PARTICLE-COLOR-RESEARCH.md b/docs/dev/D172-PARTICLE-COLOR-RESEARCH.md index 3b8c7087..508b8e3a 100644 --- a/docs/dev/D172-PARTICLE-COLOR-RESEARCH.md +++ b/docs/dev/D172-PARTICLE-COLOR-RESEARCH.md @@ -104,10 +104,17 @@ render-iterate pass (headless can't see particle colour) — see §6. ### Probes shipped (M-82, `#ifdef PORT`, `GE_D172=1`, inert when unset) - `gfx_pc.cpp` G_SETCOMBINE case — logs each distinct combine + active - cycletype (dedup, 64 max). -- `gfx_pc.cpp` `gfx_sp_tri1` — flags tris with a non-trivial cyc2 combine - drawn while cycletype != 2CYC (over-fires on trivial passthrough cyc2 — - read `combine_mode` values, don't trust the count). + cycletype (dedup, 64 max). Confirmed the particle combine `fc26a004` runs + at `cycletype=2CYC`. +- `gfx_pc.cpp` `gfx_sp_tri1` (after the texunit loop) — whenever a **2-cycle + triangle actually consumes TEXEL1**, dumps `combine_mode` + both texunits' + `tile / tmem / fmt / siz`. This is the decisive probe: a Silo close-range + guard kill with `GE_D172=1` should log + `T0[... fmt=3(IA) siz=1(8b)] T1[tmem=392 fmt=0(RGBA) siz=2(16b)]`. + If `T1.tmem != 392`, or `T1.fmt/siz` are wrong, the TEXEL1 bind is the bug. + If they're all correct, the fault is in `import_texture_rgba16` for the + second texunit or the `G_CC_INTERFERENCE` CC generation — pair with + `GE_DTEX=1` / `GE_TEXRAW=1` to dump the fire tile's bytes. ## 6. Fix path (next session — needs a display) diff --git a/port/fast3d/gfx_pc.cpp b/port/fast3d/gfx_pc.cpp index b2e48e45..e46f0133 100644 --- a/port/fast3d/gfx_pc.cpp +++ b/port/fast3d/gfx_pc.cpp @@ -1529,25 +1529,6 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo use_alpha = true; } -#ifdef PORT - /* D172 probe (env-gated, inert): flag triangles whose combine carries - * non-trivial cycle-2 terms while fast3d is NOT in 2-cycle mode - the - * suspected particle-colour bug (records set a 2-cyc combine but never - * set cycletype). rgb_cyc2 sits at bits 28..43 of combine_mode. */ - if (getenv("GE_D172")) { - uint32_t rgb_cyc2 = (uint32_t)((rdp.combine_mode >> 28) & 0xffff); - if (!use_2cyc && rgb_cyc2 != 0) { - static int d172t = 0; - if (d172t < 12) { - d172t++; - sysLogPrintf(LOG_NOTE, - "D172: tri with 2cyc combine but cycletype=1CYC combine_mode=%llx", - (unsigned long long)rdp.combine_mode); - } - } - } -#endif - if (use_alpha) { cc_options |= (uint64_t)SHADER_OPT_ALPHA; } @@ -1710,6 +1691,29 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo } } +#ifdef PORT + /* D172 probe (env-gated, inert): the magenta/cyan blood/spark bug. The + * particle records (assets/oddtextures.c globalDL_0x078..) draw a 2-cycle + * G_CC_INTERFERENCE combine (TEXEL0*TEXEL1) binding two tiles of two + * formats - tile 0 IA8 smoke, tile 1 RGBA16 fire @ tmem 0x188. Dump both + * texunits' tile state whenever a 2-cycle tri actually consumes TEXEL1, so + * one Silo capture pins whether TEXEL1 resolves to the right tmem/format. */ + if (getenv("GE_D172") && use_2cyc && comb->used_textures[1]) { + static int d172x = 0; + if (d172x < 16) { + d172x++; + const uint32_t t0 = rdp.first_tile_index + gfx_lod_tile_offset(0); + const uint32_t t1 = rdp.first_tile_index + gfx_lod_tile_offset(1); + sysLogPrintf(LOG_NOTE, + "D172: 2cyc+TEXEL1 tri combine=%llx " + "T0[tile=%u tmem=%u fmt=%u siz=%u] T1[tile=%u tmem=%u fmt=%u siz=%u]", + (unsigned long long)rdp.combine_mode, + t0, rdp.texture_tile[t0].tmem, rdp.texture_tile[t0].fmt, rdp.texture_tile[t0].siz, + t1, rdp.texture_tile[t1].tmem, rdp.texture_tile[t1].fmt, rdp.texture_tile[t1].siz); + } + } +#endif + struct ShaderProgram* prg = comb->prg[tm]; if (prg == NULL) { comb->prg[tm] = prg =