Commit Graph
420 Commits
Author SHA1 Message Date
Dean b52e86f043 Merge pull request #9898 from savvaniss/perf/agc-stores-without-drains
perf(agc): keep constant RAM dumps and unregistered labels on the GPU without draining
2026-11-04 08:10:45 +13:00
Dean 1e658521a0 Merge pull request #12120 from meh7an/perf/agc-depth-transfer-passes
perf(agc): read depth planes into storage images in a compute pass
2026-11-04 05:43:40 +13:00
Savvanis SpyrosandClaude Opus 5.5 f160886325 Merge main into perf/agc-stores-without-drains
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-03 17:37:34 +02:00
Dean 81605d59ec Merge pull request #12132 from mrfelek/fix/descriptor-web-lane-index
fix(shader): fold descriptor web paths that hold the lane index or texels
2026-11-03 21:10:04 +13:00
Dean fe69769167 Merge pull request #8963 from EagleBearerYS/perf/agc-shared-bda-fault-buffers
perf(agc): share BDA fault buffers in a per-device arena, with 32-byte slots for report-only programs
2026-11-03 21:07:29 +13:00
Dean 1d922bd0b1 Merge pull request #6185 from ee6aba54/fix/agc-changed-copy-back
fix(agc): copy only the dwords a shader changed back from a GPU-copied buffer
2026-11-03 21:07:12 +13:00
Savvanis SpyrosandClaude Opus 5.5 f070b16201 Merge main into perf/agc-stores-without-drains
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-03 09:18:32 +02:00
Dean bd620b35b5 Merge pull request #15004 from JJenkx/fix/trace-unlabeled-imports-20261102
fix(libc): infer missing call trace library labels
2026-11-03 18:13:10 +13:00
Dean Galvin d6e038b9a2 Merge commit 'f6232fcfda70644495273f6b8dd88cf0603463d6' into HEAD
# Conflicts:
#	core/libs/prx/libSceAgcDriver/CMakeLists.txt
2026-11-03 17:57:56 +13:00
felek b5f1d6b44d docs(debt): say which image results a descriptor web fold takes
The descriptor web entry and APS5_STRICT_DESCRIPTOR_WEBS said "texels";
the fold takes image loads and samples only. A path through an image
gather or an image atomic's returned value still throws.

AI-assisted.
2026-11-02 23:58:12 +01:00
Dean a5c53e975c Merge pull request #12980 from Gonic0/fix/agc-min-lod-pinned-level
fix(agc): bind a T# minimum LOD through an S# that holds the LOD at 0
2026-11-03 11:35:28 +13:00
Dean 1f272537eb Merge pull request #12764 from Pipodi/perf/flat-private-aperture-1028
perf(recompiler): back compute scratch with a device buffer slot pool
2026-11-03 11:35:12 +13:00
Dean Galvin 972242f204 Merge commit 'a4eca2a056bf3bbbec98ab42e9d28163e4ea9cb8' into HEAD
# Conflicts:
#	docs/dev/ENVIRONMENT.md
2026-11-03 06:36:10 +13:00
Dean 94653ac192 Merge pull request #13169 from Rengundom/feat/preparation-input-capture
feat(diagnostics): capture shader inputs before preparation
2026-11-03 06:27:35 +13:00
Dean 8009be68d7 Merge pull request #13159 from Gonic0/perf/agc-gds-on-gpu
perf(agc): back the GDS with anonymous shared memory on integrated GPUs and keep its DMA_DATA on the GPU
2026-11-03 06:27:29 +13:00
Nicolas GonzalezandClaude Opus 5.5 fe18496c95 feat(agc): apply a T#'s MIN_LOD clamp in the shader without VK_EXT_image_view_min_lod
MoltenVK has no VK_EXT_image_view_min_lod, so since #130 the first T#
with a MIN_LOD clamp above its base level threw. ASTRO BOT (PPSA21564
01.007.000) hits it on the title screen, about four minutes after boot.
MoltenVK does offer shaderResourceMinLod, which maps the SPIR-V MinLod
operand to Metal's min_lod_clamp.

On a device with shaderResourceMinLod, without the extension and
without graphics pipeline libraries, the new target flag
shaderImageMinLod moves the clamp into the shader:

- DescriptorBindingBuilder writes each direct image's clamp, relative
  to the view's base level and bounded by its last level and MAX_MIP,
  as a float specialization constant at MinLodBase + image.
- Samples of direct images take it as the MinLod operand, or as an FMax
  on an explicit LOD when the clamp is above 0, combined with an
  instruction's _cl clamp.
- The image view no longer chains the clamp there; image table entries
  with a clamp are still rejected, and devices with the extension are
  unaffected. APS5_NO_IMAGE_VIEW_MIN_LOD forces the shader lane.
- It throws when the clamp sits above a paired S#'s MAX_LOD or has no
  mip filter, follows an explicit LOD or gradient with a nonzero S# LOD
  bias, pairs with a run-time S# or different min and mag filters, or
  meets image_get_lod, gathers at a clamp of a level or more, or the
  emulated depth-compare or 11:11:10 sample.
- ValidateShaders accepts CapabilityMinLod when the device enables
  shaderResourceMinLod.
- The flag is written after hostInterpolationFirst as request
  serialization version 53; older versions read it as false.

The gaps, including llvmpipe applying the S# bias after the clamp, are
recorded in docs/dev/debt/shader.md.

Tested on an M-series Mac (MoltenVK 1.4.2, x86_64 under Rosetta):
image_sample_lod_clamp samples a T# with fractional and level clamps
over BASE_LEVEL 0 and 1 in both lanes, and fails without the shader
clamp or with an absolute one; graphics, shader disk cache, shader
memory and request serializer tests pass. PPSA21564 renders the title
and reaches the warp sequence after it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-02 11:58:37 -03:00
Dean 46622fff7c Merge pull request #12752 from MarcZX10/feat/language-auto
feat(libSceSystemService): take the console language from the host with ANYPS5_LANGUAGE=auto
2026-11-03 02:39:32 +13:00
Dean aab20786cd Merge pull request #12616 from Raghav314/perf/capture-pending-branches
perf(agc): leave a capture's branch over a pending GPU write unpruned instead of waiting
2026-11-03 02:38:59 +13:00
Dean 25797f0fab Merge pull request #12500 from StoneDC/feat/b20-autorun-noninteractive
feat(relinker): optionally skip the autorun exit prompt
2026-11-03 02:38:19 +13:00
Nicolas GonzalezandClaude Opus 5.5 d4cf5cbeec perf(agc): back the GDS with anonymous shared memory on integrated GPUs and keep its DMA_DATA on the GPU
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-02 09:57:34 -03:00
Dean a2583610de Merge pull request #11899 from edubox/feat/playgo-unlisted-chunk-list
feat(playgo): accept a chunk id list for dumps without metadata
2026-11-03 01:28:11 +13:00
Dean 79eb4afea7 Merge pull request #10547 from mrfelek/claude/project-thread-umbqjy
fix(agc): prefer host interpolation on RADV to avoid the quad seam
2026-11-03 01:25:37 +13:00
Dean Galvin e9d8998d58 Merge main 3c3b3cda73 into #12764 (fee187ee67)
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.
2026-11-02 23:39:24 +13:00
Dean 5a2174a6fb Merge pull request #10750 from EagleBearerYS/fix/agc-queued-index-read-idle-store
test(agc): keep queued_index_read_order's image results pending past the idle store
2026-11-02 23:24:08 +13:00
Dean cb958150bb Merge pull request #10382 from Celegans12/perf/agc-read-only-lease-skip
perf(agc): stop counting the lease of a build that never stores through BDA as a writer
2026-11-02 23:22:45 +13:00
Dean 18bb046f69 Merge pull request #7922 from ThatsLeo/feat/shader-spanned-uniformity
perf(shader): span single-wave wave64 compute by default after a uniformity check
2026-11-02 23:22:27 +13:00
JJenkx 851525c96b fix(libc): infer missing call trace library labels 2026-11-02 04:12:56 -05:00
mrfelek b6ed7fa781 fix(agc): prefer host interpolation on RADV to avoid the quad seam
RADV gives the second triangle of a full-screen quad PerVertexKHR values
in an order that does not match gl_BaryCoordKHR, so passes whose pixel
shader uses plain v_interp_p1/p2 show a diagonal seam (Silksong final
pass on a Radeon 780M). On RADV, pixel shaders are now first translated
with host interpolation; only shaders the host interpolation checker
rejects keep native VK_KHR_fragment_shader_barycentric.
APS5_NO_HOST_INTERPOLATION_FIRST=1 restores the old behaviour.

AI-assisted. Tested by me on my own machine.
2026-11-02 10:12:24 +01:00
Dean Galvin fee187ee67 Merge commit '88e804b0a7df1f1ac373a9e2f72fb378d925fdd4' into HEAD
# Conflicts:
#	core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
#	docs/dev/debt/libSceAgcDriver.md
#	docs/dev/debt/shader.md
2026-11-02 21:17:34 +13:00
Dean Galvin 38f1f885ed Merge commit '88e804b0a7df1f1ac373a9e2f72fb378d925fdd4' into HEAD
# Conflicts:
#	core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
2026-11-02 21:06:53 +13:00
Dean Galvin f0a15aeb5e Merge commit '88e804b0a7df1f1ac373a9e2f72fb378d925fdd4' into HEAD
# Conflicts:
#	core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
#	core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_recorder_tests.cmake
2026-11-02 21:06:52 +13:00
Dean 2403a74f49 Merge pull request #10026 from winstrex/fix/agc-unwatch-baseline
fix(agc): hash an idle unit when its range leaves the write watch instead of at every upload
2026-11-02 20:59:45 +13:00
Dean bfd8b8cc7d Merge pull request #9287 from Celegans12/perf/agc-dispatch-overlap-staged
perf(agc): keep staged buffer copies inside a dispatch run
2026-11-02 20:57:24 +13:00
Dean 77bd452035 Merge pull request #8887 from SleglJan/pr/flush-wait-stored-layers
perf(agc): wait on a flush only for writers over the image layers it stores
2026-11-02 20:57:08 +13:00
Dean 8c96e69367 Merge pull request #8542 from milescoviello/fix/journal-replay-limit-per-kind
fix(agc): bound a journal replay's graphics and compute pipelines apart
2026-11-02 20:56:51 +13:00
Alex ColliniandClaude Opus 5.5 ce38162aa1 fix(agc): hold one compute scratch pool under 2 GiB and the total budget
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]>
2026-11-02 04:35:35 +01:00
Alex ColliniandClaude Opus 5.5 cc61c3ae31 perf(agc): hold all compute scratch pools under one memory budget
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]>
2026-11-02 04:35:35 +01:00
Alex ColliniandClaude Opus 5.5 a46f050af8 perf(recompiler): back compute scratch with a device buffer slot pool
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]>
2026-11-02 04:35:35 +01:00
Jan ŠléglandClaude Fable 5.1 f142188caf fix(agc): wait on a flush for writers over the shadowed units it publishes
A flush that publishes unit shadows waited only for writers over the
layers its images store and for heap leases over the range. A shadowed
unit elsewhere in the range is dropped by the publish when a newer
import write has stamped its block, which most writers do when they are
recorded; a small label or packet store deferred to a completion and a
CPU write-back of a copied buffer stamp only when their batch is reaped,
so such a unit, retiled after them by a flush that waits for no writer,
could be published over their bytes. The flush now also asks for
writers over the live units the publish would select, as whole units,
hulled beyond eight runs like the stored layers: a registry lookup when
there are none, and a conservative wait when there are, since a writer
whose stamp would make the publish drop the unit is waited for too.

The storage flush ordering test gains the case: an image stored into the
shadow without a publish, a fill over its first unit, a second image
flushed over the range with the default scope. The flush waits for the
fill, the fill's bytes stay, the untouched unit is published and the
second image's texel is stored. Skipped where the unit shadow is off or
the write-back did not retile into it.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-11-01 22:38:13 +01:00
Jan ŠléglandClaude Fable 5.1 0b003a7999 test(agc): skip the mip-chain flush wait on an unsupported alignment
The dedicated runner returned 0 when the helper refused a nonzero host
import alignment that does not divide 64 KiB, so CTest reported a run
that tested nothing as passed. The helper now reports whether it ran and
names the alignment it refused, and the runner turns a refusal into exit
code 77, which the test's SKIP_RETURN_CODE maps to Skipped. The recorder
tests take ANYPS5_TEST_HOST_IMPORT_ALIGNMENT in place of the device's
alignment, so both skips and the run itself can be exercised on one
device; a value that is not a number or not a multiple of the device's
alignment fails the run instead of skipping it.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-11-01 22:38:13 +01:00
Jan ŠléglandClaude Opus 5.5 035377127a perf(agc): wait on a flush only for writers over the image layers it stores
FlushPending waited for the newest unfinished batch that writes anywhere in the flushed range (#6364),
but its write-backs store only the pending layers the range overlaps, or every pending layer when the
image stores whole (DCC keys not uncompressed) or may widen a partial store. A writer elsewhere in the
range cannot be overwritten by those stores, yet each such wait submitted the open batch or finished the
in-flight ones under the GPU mutex. The flush now asks for writers over the 64 KiB blocks of the layers
it stores, the granularity of the write-back's own unit publishes; an image with many separate pending
runs is checked over their hull. For an image that stores whole, that includes its pending layers
outside the range, which the range check left out. A DCC image with more than one mip is checked over
all of its pending layers too: more than today's write-back stores for it, so the check stays sufficient
if the write-back stores such an image whole, as #8707 proposes. When the flush publishes unit shadows,
an address-based dispatch's heap lease over the range is still waited for: such a dispatch stamps its
pages only at completion, so the publish could not tell its writes from fresh shadow units otherwise.
APS5_FLUSH_WAIT_WHOLE_RANGE=1 checks the whole range as before.

The storage flush ordering test gains two cases, each with a GPU fill noted in the open batch: a fill
inside the flushed range but past the image's pending layer, which the flush no longer submits or waits
for while both the image's texel and the fill land; and a fill inside the pending layer, which it still
waits for, so that the fill's block keeps its bytes and a texel in another block is stored. A recorder
test pins the DCC clause: a three-mip image with uncompressed keys, flushed over its first unit,
completes the batch of a writer over its last pending unit.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-01 22:37:47 +01:00
Dean Galvin d6f1eccfe2 revert(agc): keep driver pipeline caches and costly compute pipeline binaries across updates (#13931)
This reverts commit d8b60b46ed, reversing
changes made to d94fad17de.
2026-11-02 08:24:24 +13:00
Savvanis SpyrosandClaude Opus 5.5 a814af06ee Merge main into perf/agc-stores-without-drains
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-01 21:06:53 +02:00
Celegans12 c3768e3488 perf(agc): stop counting the lease of a build that never stores through BDA as a writer
PendingWriterSerial counts an address-based build's lease as a writer of
every leased range, because such a build marks the pages it stored to
through BDA only when its batch completes. A build whose shaders never
store through BDA marks nothing at completion; its descriptor writes are
already noted as pending writes when it is recorded. Its lease is now
noted as ReadKind::AddressBasedReadOnly, which PendingWriterSerial skips
and every other read check treats like any pending read.

A texture refresh flush over a range such a build leased no longer waits
for its batch. APS5_NO_READ_ONLY_LEASE_SKIP=1 notes the lease as
AddressBased, as before. LinearTargetDrawBindings runs its scenario
after a storing and after a read-only address-based draw: the drawn
target's store syncs the batch after the first and is recorded into it
after the second, unless the switch is set.

AI-assisted: yes
2026-11-01 13:45:23 +01:00
winstrexandClaude Opus 5.5 42f9605c6c Merge remote-tracking branch 'upstream/main' into fix/agc-unwatch-baseline
- ImportMappedRanges: main's `replacing` structure, with UnwatchHookLocksGpu in place of AnyPendingOverlaps.
- markLayersPending: main's `!layerPending.AllIn(first, count)` block around this branch's pendingMiss bookkeeping and captureGuestBytes(&unsaved, true). With every unit already pending, that bookkeeping changed nothing, so skipping it keeps the behaviour.
- writeBackWindows: no unit shadow destination when the stored span is not watched or the image is at most SmallStoreBytes.
- Tests: agc_storage_pending_after_unwatch and agc_unwatch_hook_lock_order move to tests/cmake/agc_driver_recorder_tests.cmake.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-01 08:07:36 -03:00
liskeeeandClaude Opus 5.5 0c572f1c25 feat(agc): persist costly compute pipeline binaries
Capture costly compute builds and restore matching recipes after checking
full recipes, driver fingerprints and Vulkan compatibility keys. Add size
and time thresholds, opt-out, atomic persistence and corruption/rejection
fallback.

Remember below-threshold recipes in separate files so competing decisions
cannot overwrite captured binaries. Prefer saved binaries and retry
capture when the time threshold is lowered.

Cover compatibility, fallback, deterministic competing writers and
cross-process capture, restore and corruption.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-01 11:56:06 +01:00
Dean Galvin a68458936e Merge main into feat/shader-spanned-uniformity
# Conflicts:
#	docs/dev/ENVIRONMENT.md
#	docs/dev/debt/shader.md
2026-11-01 20:59:37 +13:00
Celegans12 80ff4017ee perf(agc): run the dispatches a compute ring leaves unordered side by side
Every dispatch records a barrier before and after itself, and on NVIDIA
any barrier between two dispatches drains the GPU.

A dispatch of a compute ring (queue != 0) with only SET_SH_REG and plain
NOPs between it and the ring's previous dispatch in the same submission
may join that dispatch's run: it records no leading barrier, and the
run's trailing barrier is deferred until any other command records it.
It joins only when its buffer ranges and storage images are disjoint
from the run's (reads against writes, writes against writes); an
address-based or BDA build counts as accessing everything, and a run
never takes the same resources object twice. A dispatch that records
GPU checkpoints (NV checkpoints or AMD buffer markers) never joins.
APS5_NO_DISPATCH_OVERLAP=1 turns it off.

AI-assisted: yes
2026-11-01 08:30:16 +01:00
Savvanis SpyrosandClaude Opus 5.5 87e6918b69 Merge main into perf/agc-stores-without-drains
Recorder keeps both this branch's LookupStoredBytes and main's UnlandedOwnLabel, with both test groups in --completion-labels-only and the full recorder run.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-01 09:16:31 +02:00
milescovielloandClaude Opus 5.5 ee0d52b98f fix(agc): bound a journal replay's graphics and compute pipelines apart
The replay kept the newest APS5_PIPELINE_JOURNAL_ENTRIES entries of
either kind, so compute pipelines used up the bound meant for the
graphics pipeline store, and the entries left out were not reported.
Graphics entries now count against that bound alone, compute entries
against APS5_PIPELINE_JOURNAL_COMPUTE_ENTRIES (1024); each kind keeps
its newest entries in record order, and a line says how many of each a
replay leaves out.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-01 06:47:31 +00:00