Files
psxrecomp/runtime/tests/test_depth24_present_hold_vblank.py
T
Shokunin 0d096e2858 GPU: carry the depth24 held-VBlank flag in the snap; executable hold regression
Review follow-up on #661 (#636):
- test_depth24_present_hold_vblank.py reads sources as UTF-8 (cp1252 on
  native Windows Python raised UnicodeDecodeError).
- The present skip is now guest state: set at guest VBlank, read (not
  consumed) by the present and packed into the GPU snap's hold word (bit 8;
  older snaps derive it from the count). The executable test showed the
  host-side latch made the present of a restored tick differ from live on
  the last held VBlank (hold 0, skip 1), exposing stale trailing FMV
  columns after a rollback load.
- Depth24 scanout staging and trailing-column blanking move from main.cpp
  into gpu_depth24_stage_scanout (gpu.c), so the test renders through the
  same code every CPU depth24 present runs.
- New depth24_present_hold_exec_test: drives real gpu.c through a 15-bit to
  24-bit FMV, GP1(07h) retargets and mode transitions; compares hold, skip,
  upload span and snapshot bytes across windowed/headless/deferred presents,
  rollback replay from every tick and disk loads, and checks staged frames
  never show stale movie pixels while the new movie stays visible.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 10:53:21 -07:00

33 lines
1.3 KiB
Python

#!/usr/bin/env python3
"""The depth24 present hold is guest state, counted down at guest VBlank.
GP1(07h) arms s_d24_present_hold (skip a few Swaps after a depth24 band
retarget). It is in the GPU snap. It used to count down only at host present,
so a headless run never moved it, and a rollback snap load zeroed it: the
replayed save of a tick differed from the live save in the GPU section
(psxrecomp #636). Guards: gpu_vblank_tick counts it down, the present-side
query never touches it, and a rollback snap load keeps the restored value.
"""
from pathlib import Path
from test_netplay_load_apply_flow import function_body
SRC = Path(__file__).resolve().parents[1] / "src"
def main():
gpu = (SRC / "gpu.c").read_text(encoding="utf-8")
vblank = function_body(gpu, "void gpu_vblank_tick(void)")
assert "s_d24_present_hold--" in vblank
tick = function_body(gpu, "int gpu_depth24_present_hold_tick(void)")
assert "s_d24_present_hold" not in tick, "the hold must not move at host present"
main_cpp = (SRC / "main.cpp").read_text(encoding="utf-8")
rb_loaded = function_body(main_cpp, 'extern "C" void psx_frontend_on_rb_snap_loaded(void)')
assert "gpu_depth24_on_savestate_loaded" not in rb_loaded
print("depth24 present hold: ok")
if __name__ == "__main__":
main()