Track an open GP0(A0) upload in the renderer whatever the HD state
(facade gr_vram_upload_begin/commit/set_open): HD activation mid-A0
waits for the commit instead of reading the FBO over received words,
and a full-VRAM load no longer ends the hold; gpu.c restores it from
gp0_state on load and ends it on GP1(01h). Sync the render thread
before flushing dumps or reading HD diagnostics, suppress dumps from
generated frames, use _putenv on MinGW, drop a stale log. Adversarial
fixtures for both cases in full-VRAM and high-resolution-window modes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Generated frames are presentation only: their replayed draws skip the CPU
raster and the pack flush, and textured draws resolve the same HD
replacements as the real frame. Drop the HD gate on frame generation. The
HD fixture runs a 30 Hz game with generation off and forced on: real frames
and native VRAM are identical, and every generated frame shows the HD HUD.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A GP0(A0) under HD authority takes the context at its header and keeps it
until the payload commits, so gpu.c's array holds every earlier native draw:
unwritten words keep queued draws and mask checks see the prior native mask.
Publication copies the whole private VRAM (no A0 can be open then), and
render_thread_stop publishes the final private draws before freeing them.
HD replacements and dumping no longer refuse startup or park the thread;
Smooth motion stays off under HD. Adds the review reproduction and #570's
HD safety cases with the render thread running.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With an HD texture pack the CPU raster is native VRAM's authority, and on
the render thread it writes the private copy: gpu.c's array never saw those
draws, so guest readbacks, mask checks and savestates read stale VRAM. Each
acquire now copies the private result into gpu.c's array (the analogue of
ensure_cpu's FBO readback), leaving the words of a GP0(A0) payload that is
still streaming. Fixture: a recorded fill/draw is visible to a readback.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HD texture packs matched draws on the render thread but tracked uploads and
invalidations on the emulation thread, hashing gpu.c's array: a data race
(crash seen in hd_texture_pack_match) and wrong identities whenever the
emulation thread had already recorded a later upload.
The facade now sends residency changes through an optional backend hook
(hd_texture_note). The render-thread backend records them as RTH_HD_NOTE
after the upload/draw they follow; the replay hashes the render thread's own
VRAM copy, which the HD module now follows with the SW rasterizer
(gpu_hd_textures_bind_vram). Pack (re)configuration and HD mode changes are
sync points. Other backends apply the change immediately as before.
The HD GL fixture gains a render-thread case (fails without this change)
and links again: the scale fixture's facade stubs no longer collide with
the real gpu_render.c it includes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The .hdres sidecar (version 2) carries the pack's identity, a hash of its
sorted replacement keys (hd_texture_pack_identity); a load with another
pack is refused, as the docs say.
- The learned upload rectangles are bounded by area as well as count: a
restage (load, rewind) re-hashes at most one VRAM's worth of words.
- gl_hd_texture_pack_test: residency is refused with a different pack;
before the load a textured draw shows native artwork, after it the same
draw shows the HD replacement and counts as an applied draw.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rewind and in-session savestate loads have no sidecar. Each Beetle-keyed
upload rectangle seen in the session is remembered (at most 256); after a
restage it becomes resident again only if the restored words still hash to
a replacement key, so the HUD keeps its replacement across loads.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A savestate restage cleared every upload identity, so a texture uploaded
once (a race HUD) lost its replacement after any load until the game
uploaded it again. Saving a slot now also writes the Beetle-format residency
beside it (*.hdres: host metadata, never in the .pst), bound to a CRC of
the whole native VRAM. A load restores it only over exactly that VRAM, so
no identity is fabricated; anything else falls back as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Load modern texpage/texupload PNG replacements independently of DuckStation source. Integrate pack folders and options with mods, preserve native VRAM, and validate GL rendering, format matching, dump safety, and upload invalidation.