The label read trap skipped every image sharing a page with another
pending image. Large tiled images are never stored at a label, so an
image inside one no longer counts as sharing. A store of an image over a
trapped one now stores the trapped one in the same flush, and an
eviction or explicit write-back stores the trapped images inside it
first.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The trap was released when FlushPending took the image out of the pending
registry, before it waited for GpuMutex, so a read in between saw the old
bytes; cache eviction and explicit write-backs did not release it at all.
Every store now releases it in writeBackLayers: after recording the GPU copy
into the import, or before the first CPU access on the CPU path, which also
releases the traps of other images on the same pages. A trapped image is
stored whole, and direct memory mapped at a second address is not trapped.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Before a label, a pending linear or small storage image that shares no page
with another pending or storing image now gets a write-watch read trap
instead of its store. The first access to its pages stores it through the
host-read hook; any other store releases the trap first.
APS5_NO_LABEL_READ_TRAP=1 keeps the store at the label.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
GuestWriteWatchTrapReads takes all access to the pages of a range until
the resolver set with GuestWriteWatchSetReadTrapResolver has run for it.
A fault on a trapped page waits while the resolver runs on the watch's
own thread; host writes and GuestWriteWatchProtect run it first on the
calling thread. Collections keep trapped pages inaccessible, and
registering or unregistering memory drops its traps.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Waveform adds now follow the PS5 module in cases main threw or answered with
the wrong code: flag bits 0x8, 0x20 and 0x40 and up are ignored in the values
PS5 ran, an add of no blocks with APPEND or RESET|APPEND returns 0 (or the
closed code on a closed waveform), one APPEND block on a mono PCM voice with
nothing queued is queued as a block of no frames (unsigned 8-bit, 16, 24 and
32-bit integer, 32 and 64-bit float), and any add to a never-set-up voice whose
waveform an add of no blocks closed returns the closed code.
The PS4 library shares the sources and returns its own code for a closed
waveform and a full queue, 0x804A0151, as PS4 11.00 does.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
sceFontGraphicsAppendGradientSegment decodes from the 4.03 libSceFont
body at 0x20500: sorted-inserts a 0x18-byte color-stop node into the +8
chain of linear (0x20) and radial (0x30) gradient records while
node->+4 == record->+4 and position >= node->+0x10. Stop records live in
a unit byte stream built from the per-object segment arena at
object->+0x10 (+0xc0 descriptor, mutex at +0x40, stats +0x48/+0x4c),
allocated by the span allocator at 0x1b5e0 (12-byte nodes: count(22b),
chain index(21b), span end(21b); index 0 is the sentinel). Units chain
through frame->+0x18/+0x20 with byte position in frame->+0x10/+0x14;
sub-0x18 tails get a 0xff pad record plus a zeroed tail. Validation
order, error codes (0x80460020/0x80460086/0x80460002/0x804600a0), NaN
acceptance, stats updates skipped on alloc failure, and the pad loop's
abandon-on-failure all follow the disassembly; guest_font_graphics
covers insert order, epoch stop, pads, unit boundaries and exhaustion.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>