test(texdump): contract-freeze golden list + inertness/engine gates in make test

One binary (test/tools/test_texdump, in make test via the in-tree
test/roms/yarc.j64 so it never skips) runs five sessions and asserts:

- contract_freeze: manifest hash set equals the committed golden list
  (test/expected/texdump_yarc.txt, 28 hashes) — the CI tripwire that
  makes the day-one identity contract real
- determinism: two consecutive dump-on runs, identical sets
- engine_independence: fast vs accurate blitter, identical sets
- inertness_on: per-frame framebuffer hashes AND savestate digests at
  frames 300/600 identical dump-on vs dump-off
- png_validity: signature, IHDR dims vs manifest, every chunk CRC-32
  via src/core/crc32.c — no external decoder
- palette_not_identity: a CLUT-change re-blit of known bytes mints no
  new hash and appends exactly one sighting row

No in-tree public ROM blits more than its two boot-time code copies
with SRCEN (yarc and jagniccc both render via the OP — measured), so
instead of the spec's second-ROM fallback the tool drives a synthetic
blit battery through the real bus/launch path (JaguarWriteLong ->
BlitterWriteWord -> TexDumpLaunch, TEST_EXPORTS ABI): 26 scripted
tiles across 1/2/4/8/16/32bpp and both source channels.

The fast-blitter session runs LAST: a fast->accurate engine flip
leaves cross-load static residue that moves the next session's
savestate digest even with texture dump never enabled (pre-existing
leak, reproduced independently; see the run-order note in the tool).

test_blitter_mmio gains the texdump stubs its standalone link now
needs; test_option_visibility asserts the 16bpp knob is hidden while
the dump option sits at its disabled default.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Joseph MattielloandClaude Opus 5 committed 2026-08-17 20:59:54 -04:00
1 parent aaeb3a03d6
commit 448deafa5e
5 files changed
+1082 -2

No files matched your search

+21 -2
View File
@@ -893,6 +893,10 @@ endif
# libchdr is C99; the rest of the core is gnu89. A dedicated rule so
# the generic %.o: %.c line cannot compile unity.c as C89. Must sit
# AFTER `all:` so it is not the default goal.
#
# MINIZ_DEFLATE_APIS (texture dump's PNG encoder, issue #369) rides in
# LIBCHDR_CFLAGS -- see the comment in Makefile.common -- so the
# theos_ios path, which compiles unity.c without this rule, gets it too.
$(LIBCHDR_DIR)/unity.o: $(LIBCHDR_DIR)/unity.c
$(CC) -c $(OBJOUT)$@ $< $(CFLAGS) $(LIBCHDR_CFLAGS) $(LIBCHDR_WARNFLAGS)
@@ -921,7 +925,7 @@ clean:
test/tools/test_memory_map test/tools/test_option_visibility test/test_memtrack test/test_nvmbios test/tools/test_dsp_audio_diag \
test/tools/test_frame_timing test/tools/test_runahead_determinism test/tools/test_pertitle_db \
test/test_titledb test/test_titlehook test/tools/test_hook_gate \
test/tools/test_wedge_spin test/tools/i2s_lag_probe \
test/tools/test_wedge_spin test/tools/test_texdump test/tools/i2s_lag_probe \
test/tools/joymatrix_identity test/tools/mouse_decode_test \
test/tools/rotary_decode_test \
test/test_quadrature \
@@ -971,7 +975,7 @@ test: test/test_dram_timing test/test_cheat test/test_event_queue test/test_jlin
test/test_blitter_mmio test/test_blitter_cmd test/test_eeprom_lifecycle test/test_eeprom_read_race test/test_tom_visible_window \
test/test_framebuffer_integrity test/test_state_compat \
test/test_frontend_pacing test/test_jgd \
test/tools/test_runahead_determinism test/tools/test_wedge_spin \
test/tools/test_runahead_determinism test/tools/test_wedge_spin test/tools/test_texdump \
test/test_butch_cd test/test_bios_config test/test_boot_config \
test/test_cart_format test/test_cart_needs_bios \
test/test_cd_boot test/test_cd_hle_boot test/test_cd_bios_boot test/test_cd_toc_contract test/test_cd_fifo_stream test/test_cd_ssi_stream test/test_cd_second_transfer test/test_cd_hle_idempotent test/test_cd_lost_wakeup test/test_cd_pregap test/test_cd_chd test/test_chd_unit test/test_cd_synth_read test/test_cd_synth_butch test/test_cd_synth_cdda test/test_cd_synth_subq \
@@ -1177,6 +1181,14 @@ test: test/test_dram_timing test/test_cheat test/test_event_queue test/test_jlin
@# every STATE_SAVE_BUF; yarc.j64 is in-tree so this never skips, and
@# a real music-on title is used when the private corpus is present.
./test/tools/test_runahead_determinism ./$(TARGET) test/roms/yarc.j64 --quiet
@# Texture dump mode (issue #369): identity-contract freeze vs the
@# committed golden list, determinism, fast/accurate engine
@# independence, machine inertness (fb hashes + savestate digests
@# on vs off), PNG validity, and the bytes-only-identity palette
@# check. yarc.j64 is in-tree so this never skips; the synthetic
@# blit battery inside the tool covers every bpp (see the tool
@# header for why a ROM run alone is a 2-hash tripwire).
./test/tools/test_texdump ./$(TARGET) test/roms/yarc.j64 --quiet
@rom=$$(bash scripts/find-rom.sh 'Iron Soldier (1994).jag' 'Iron Soldier (World)*.j64' 'Iron Soldier.jag'); \
if [ -n "$$rom" ]; then \
./test/tools/test_runahead_determinism ./$(TARGET) "$$rom" --quiet; \
@@ -1701,6 +1713,13 @@ test/tools/test_runahead_determinism: test/tools/test_runahead_determinism.c \
test/harness/harness.c \
$(if $(filter Linux,$(shell uname -s)),-ldl -lrt) -lm
test/tools/test_texdump: test/tools/test_texdump.c \
test/harness/harness.c test/harness/harness.h src/core/crc32.c
$(CC) -O2 -Wall -std=c99 $(INCFLAGS) \
-o $@ test/tools/test_texdump.c \
test/harness/harness.c src/core/crc32.c \
$(if $(filter Linux,$(shell uname -s)),-ldl -lrt) -lm
test/tools/test_wedge_spin: test/tools/test_wedge_spin.c \
test/harness/harness.c test/harness/harness.h
$(CC) -O2 -Wall -std=c99 $(INCFLAGS) \
+31
View File
@@ -0,0 +1,31 @@
# texdump v1 golden hash list -- see docs/texture-dump.md.
# Regenerate ONLY for a deliberate contract bump:
# ./test/tools/test_texdump <core> <rom> --update-golden
0e4ae2eb24870790
0f772bb6bc839bd8
16e8fa46e9f385ac
21cf0c079984ecac
2a5e050ac9b17bd0
2bde3a05ce2964bc
421d8b30f71200cc
61988d68f3fa4c16
6a7d968113200e58
7c9d3d7e79ca5e0c
814cea49cca6aac8
844b45fe86eb8fd6
9d9387421c646610
b1f77f2d3bbfef90
b88041c0ba7e58d0
bdec3fb0c6ee6a98
be036a03e848b290
c2f123c336896a6c
c8e69a047a2827e8
cfae851286a0f848
d45afa75267ac058
d646a02c367010d0
d81ecf4097997450
d921299d59d81428
db1330dddf747173
dcc886748f68a513
f7d9939f2e53e450
fbe56a8d86973510
+2
View File
@@ -28,6 +28,8 @@ void BlitterRunComparison(void) {}
void blitter_blit(uint32_t cmd) { (void)cmd; }
void BlitterMidsummer2(void) {}
int BlitMemoLaunch(void) { return 0; } /* memo off: dispatch as before */
int texDumpEnabled = 0; /* texture dump off */
void TexDumpLaunch(void) {}
/* Blitter bus-time model dependencies (vjs.blitterTiming stays 0 in the
* stub settings above, so the timing path short-circuits; these only
+3
View File
@@ -240,6 +240,9 @@ int main(int argc, char **argv)
expect("(cart)", "virtualjaguar_cd_trace", false);
expect("(cart)", "virtualjaguar_bios", true);
expect("(cart)", "virtualjaguar_bios_type", true);
/* Texture dump (#369): the 16bpp preview knob is hidden while the
* dump option sits at its disabled default. */
expect("(cart)", "virtualjaguar_texdump_16bpp", false);
p_unload();
/* --- CD: CD options shown, cartridge BIOS option hidden --- */
File diff suppressed because it is too large. Load diff