Files
psxrecomp/docs/GPU_INTERLACED_RASTER.md
T
2026-09-06 14:16:53 +03:00

3.0 KiB

Interlaced primitive drawing

The GPU preserves one row parity while drawing in 480-line interlaced mode when GP0(E1h) prohibits drawing to the display area. The display origin and current field select that parity. Progressive modes and the draw-to-display override draw both parities. Fills, copies and VRAM transfers keep both fields.

gpu_raster_skipped_row() reads current GPU state for each primitive. The renderer facade applies the field mask with native-row clip rectangles and restores the original clip. This also preserves the corresponding rows in scaled surfaces. Each clipped triangle retains its precision and perspective metadata, which hardware backends otherwise consume on the first submission. The facade counts each original perspective triangle once; repeated backend metadata setup does not add diagnostic hits. No title address or title detection selects this behavior.

Pro Pinball: Timeshock! USA SLUS-00639 repeatedly draws and reads a test pixel at (1020,511) during startup. Frozen source 63446a28 always returned the drawn pixel and stayed black. This correction lets the guest's existing field test finish. The same disc, BIOS and settings then reach the table.

The field latch uses the runtime's existing vertical-blank model. This change does not claim scanline-accurate timing. Row clipping can increase submissions for large interlaced primitives; no general performance claim is made.

Verification

Configure runtime/ with BUILD_TESTING=ON, then run ctest --test-dir <build> -R gpu_interlace_render_test --output-on-failure. The fixture covers the mode predicate, origin/field parity, all nine primitive families, clip restoration, transfers, mode changes, scaled output and triangle metadata consumed by a backend. The original renderer fails the same row-preservation assertions.

Prior art

These sources supplied behavioral evidence. The implementation and regression fixture were written independently. Exact title run receipts and route limits are maintained by the Timeshock correction project.

Precise vertices use signed 16.16 positions. Row dispatch covers the union of integer fallback bounds and precise vertex bounds, with one row for rounding. Tests compare native and enhanced masked pixels with unmasked images when precise positions cross the integer bounds, including negative coordinates. A tiny precise triangle must submit three row clips rather than 256.

Flat overlay rectangles also submit one-row geometry while field masking is active. This keeps the mask when a wide backend intentionally replaces its scissor. Non-interlaced overlays retain the original geometry and policy. A backend fixture that ignores the scissor tests both field parities, original progressive behavior, and clip restoration. This is not Vulkan driver testing.