Charge read-only GPU-copy input snapshots and depth-copy linear scratch for their requested bytes while the batch retains them. Exercise both production paths with CPU Vulkan mocks, including the budget boundary and fence-governed resource retention.
Co-Authored-By: Codex <[email protected]>
Resolves the shader debt file bullet by bullet: main's EmitSetAttribute entry, and this branch's PERSP_SAMPLE/LINEAR_SAMPLE and pixel-position entries.
fopen resolved the random device paths to a host file that does not
exist and failed with ENOENT, while open and sceKernelOpen already serve
them from host entropy. A read-only fopen of either path now returns a
stream whose fread fills the buffer with host entropy. setvbuf, feof,
ferror, clearerr, the stream locks and fclose work on it, fflush returns
0 as on a FreeBSD stream that is not writing, other stream functions
throw, and opening the paths for writing throws as in libkernel.
ProsperoTV (PPSA99003) reads its phone pairing code this way and showed
"Code expired or unavailable".
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Queue 0 skips partial and cache flush EVENT_WRITE packets and ACQUIRE_MEM, and nothing ends the
open render pass on them, so the pass hazard tracker is all that orders two draws inside one
pass. A write-only store, a flush and a second write-only store to the same bytes stayed in one
pass with no barrier between them, although the flush orders them on the guest GPU.
At such a packet, the write-only ranges of the open pass now count as written, so a later
write-only store to them is a WriteAfterWrite and begins a new pass. The seal is queued behind
the draws in the draw pipeline (or made at once when it is idle), once per run of flushes after
a draw.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
A guest buffer the recompiler classifies as only stored to (bufferWritten, not bufferRead, not
bufferAtomic), which no other allocation of the draw overlaps, is a write-only range of the draw.
It conflicts with every read and every other write of the open render pass, but not with the
write-only stores of other draws to the same range: the guest GPU leaves stores of different draws
unordered as well, since no barrier separates them. Before, such a buffer counted as both read
and written, so consecutive draws storing to it each began a new pass with two full barriers.
APS5_NO_WRITE_ONLY_PASSES=1 restores that.
Unreal Engine 4 stores virtual texture feedback from every base pass material that samples a
virtual texture into one buffer per frame: in Stray (PPSA02100) about 90 % of the pass restarts.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
vkGetPipelineCacheData is not stable in size on a driver that keeps
pipelines: RADV grows a loaded cache by 8 bytes on the first create and
shrinks it by 8 on a later hit, so an exact size match reports a hit as a
miss and agc_pipeline_cache_file fails on hardware. lavapipe keeps
nothing, so every size stays equal, the probe reads that as a device that
does not store pipelines and the test skips, which is why CI never saw
this.
Size each pipeline in an empty cache first and treat a change below half
that as a hit, and skip on a device where a pipeline adds nothing.
Co-Authored-By: Claude Opus 5 <[email protected]>
The initial import of a native multisampled depth target only proceeds
when every HTILE word proves the same clear value, so no compressed Z
planes are read from guest memory. ITERATE_256 only changes how the DB
and the texture unit walk compressed MSAA Z planes (Mesa
ac_descriptors.c: "TC-compatible MSAA HTILE requires ITERATE_256").
The HTILE footprint (Addrlib) and the HTILE clear words (Mesa
radv_get_htile_fast_clear_value) do not depend on it. The import no
longer requires it; the texture's ITERATE_256 must still match the
target's.
Unblocks PPSA27836 (Onimusha: Way of the Sword), which samples a
four-sample D32 target with pipe-aligned HTILE and ITERATE_256 off.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The constant folder now knows which bits a value can hold (masks, merges,
shifts, field extracts, 16- and 8-bit widenings, selects) and which bits a
user reads:
- a mask that clears no bit the value can hold is dropped, and so is a
merged part with no bit under the mask;
- And(And(x, a), m) becomes And(x, m) when m keeps no bit outside a, and a
mask rewrite is folded again;
- a field extract, shift, mask or 16-bit truncation reads through masks
that keep the bits it reads and through merged parts that hold none;
- a right shift of a left shift by the same amount becomes a mask;
- BitFieldUExtract(x, 0, n) is x when x has no bit at or above n;
- Or of two masked parts of one word becomes the word under the union of
the masks (the word itself when they cover it);
- a field extract of a left shift reads the unshifted word.
These patterns come from 16-bit halves of 32-bit registers (f16 and packed
math), which the translator splits and merges per instruction.
Test: agc_constant_bit_test gets six cases (repeated, narrower and wider
masks, a mask under a merge, half extractions, halves that rejoin); all six
fail on main.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01XBXM4pgkMHYEtqN1EQni2P