#13474 implemented sceAgcDriverUserDataWritePacket,
sceAgcDriverUserDataWritePushMarker, sceAgcDriverUserDataWriteSetMarker
and sceAgcDriverUserDataWritePopMarker in Submit/src/Dcb.cpp, with their
firmware signatures, and removed their stubs from Export.cpp. The
pending export list still named them as no-parameter stubs, so
UnsupportedDiagnostics.cpp stopped compiling once merged with main.
The list drops them, and the debt entry counts the 24 exports that are
still pending. The other listed exports are still stubs on main.
A title can render a tiled image by compute and read it on the CPU after a label. StoreReadbackBeforeLabel took only linear images and those up to 64 KiB, so the CPU read the old bytes at that address. PPSA06866 renders its save thumbnail into a 768 KiB image this way and stored noise as every save's PNG. An image up to 1 MiB on its first write or not written in the last 8 flips now takes one store before a label. The label clears the flag when it chooses the image, so with no flips it cannot store the image at every label. Images written on consecutive flips stay on the GPU.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
SpirvEmitter.cpp: main now calls Finalize() before filling info and checks
spanned-wave barriers on the words; keep that and run this branch's
VerifyScratchPoolReturns(state, words) on the same words before returning.
On an RTX 4090 (driver 617.42) a scratch pool buffer of 2049 MiB returned wrong scratch values in the scratch dispatch bench, while 2047 MiB was correct, though maxStorageBufferRange is larger. One pool is now held under 2 GiB, under APS5_SCRATCH_POOL_MIB and under APS5_SCRATCH_POOL_TOTAL_MIB, so a large APS5_SCRATCH_POOL_MIB no longer creates a pool over the total budget or over 2 GiB.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Each compute program that uses scratch kept its own pool of up to APS5_SCRATCH_POOL_MIB (64 MiB) until device teardown, so the pools of many such programs added up without bound.
All pools together are now held under APS5_SCRATCH_POOL_TOTAL_MIB (default 256 MiB). A new or enlarged pool first drops the least recently used pools until it fits; the newest pool is always kept. A dropped pool stays alive until the batches that recorded it complete, since the recorder keeps a reference, and the program gets a new pool with a zeroed header when it dispatches again.
The test dispatches two scratch programs over a 1 MiB budget and checks that the second evicts the first, and that the first then runs correctly in a recreated pool.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The slot-lock header of a compute scratch pool was cleared by a fill recorded
into the first dispatch batch that used the pool, and a flag set at record time
said it was done. A batch that Recorder::Submit discarded unsubmitted (for
example a vkEndCommandBuffer failure) left the pool cached with the flag set,
so later dispatches skipped the clear and slot acquisition read uninitialized
ownership words and could spin; a second dispatch recorded against the same
pool before the first batch submitted trusted the same flag.
The header is now zeroed by a one-off command batch that is submitted and
waited on when the pool is created, before the dispatch's own batch opens, so
discards and recording order no longer matter. The zeroed flag and the
in-batch fill are gone. A new test discards the first batch that uses a pool
(two dispatches against it) on top of dirtied pool memory and checks that the
header reads zero and the retried dispatch completes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
NVIDIA's front end spends tens of seconds per large compute program on the
dynamically indexed Function arrays that held the per-lane scratch. A compute
program that uses scratch (scratch_* or a FLAT access that the aperture split
routes to the private aperture) now keeps it in a storage buffer instead, so
no Function array is declared or indexed. FLAT routing is unchanged.
The driver allocates one buffer per compute pipeline on its first dispatch,
capped by APS5_SCRATCH_POOL_MIB (default 64), holding a lock word and an
invocation counter per slot followed by the slots, and binds it in descriptor
set 2 (the layout of the device-memory LDS buffer). The shader takes the slot
count from the array length. Invocation 0 of each workgroup claims a slot with
a compare-exchange scan that starts at its linear workgroup id and spins until
it wins one; a barrier publishes the slot. Every invocation decrements the
slot's counter on every compute exit and the last one frees the lock, so
divergent exits and concurrent dispatches of one pipeline share the buffer
safely. The emitter fails the compile if a compute return lacks the release.
Programs without scratch keep their SPIR-V and pipeline layout.
The buffer is decorated Coherent: without it NVIDIA lost earlier byte stores
of a sequence of byte read-modify-writes to one dword. Lane-private
read-modify-writes no longer use atomics.
Tests: a new execution test covers the private aperture reached through a
table load, a literal and a computed address (store, atomic, and both ways
through scratch_*), a callee reached through s_swappc_b64, isolation of 64
workgroups over one or two slots, divergent wave exits with a second dispatch
reusing the slots, and the module shape (no Function array, no binding in a
program without scratch). The guarded memory load fixture skips the slot
acquisition.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
With alpha-to-coverage and DB_SHADER_CONTROL.MASK_EXPORT_ENABLE the pixel shader now writes SampleMask as the AND of its MRT0 alpha coverage and its MRTZ mask export instead of throwing, as Vulkan multisample coverage ANDs the shader sample mask with the alpha-to-coverage mask. Adds eight- and two-sample GPU tests and a shader debt entry for the rule, which is not measured on hardware.