Commit Graph
86 Commits
Author SHA1 Message Date
Dean e3d03fbae6 Merge pull request #7930 from AnthonyClemens/perf/agc-skip-empty-indirect
perf(agc): skip CPU-path indirect draws that draw nothing before buil…
2026-10-23 23:45:49 +13:00
Adrià e5d9c923db Merge pull request #6951 from alfalfa-star/perf/agc-span-mirror
perf(agc): memoize host import run bounds per lease snapshot
2026-10-23 11:52:55 +02:00
Adrià a7d342efc9 Merge pull request #6948 from alfalfa-star/fix/agc-linear-readback-store
fix(agc): store linear compute writes behind their dispatch
2026-10-23 11:12:44 +02:00
Dean Galvin 8199835b02 Merge main into perf/agc-skip-empty-indirect 2026-10-23 21:43:40 +13:00
Dean 72fe76ff89 Merge pull request #7920 from hugodearaujo/feat/agc-amd-buffer-marker-checkpoints
feat(agc): record GPU checkpoints through VK_AMD_buffer_marker
2026-10-23 21:20:57 +13:00
alfalfa-starandClaude Opus 5.5 5d3c0d741a perf(agc): memoize host import run bounds per lease snapshot
Every import lookup walked the lease out from the containing range to find
the run of continuing registry ranges, which is linear in the run length.
That walk depends only on the lease snapshot, the containing range and the
import window block, so its first and last index are now memoized per
thread under a weak reference to the snapshot, the range index, the window
and the window's low end. APS5_NO_RUN_MEMO walks every time.

Everything that depends on other state runs on each call as before: the
largest size, the budget, the failed blocks, the remembered refusals and
the halving block search. importRunBounds returns the chosen indices, so
sameRange, runCovers and the whole-run lookup in importAllocation compare
against the lease without copying the run's range pointers.

importRunFailureShrinkTests records a failed 8 MiB block between two
lookups on an unchanged registry and requires the run to shrink to its
4 MiB blocks. importRunGrowthTests and importRunReplacedTests check that a
run grows and shrinks when its ranges are registered or replaced.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-23 10:04:37 +02:00
raghav314andClaude Opus 5.5 c0dbd1871c perf(agc): draw finisher pipeline (APS5_DRAW_PIPELINE)
The second half of a pipelined draw (stage materialization, cache insert,
enqueue) runs on a finisher thread, overlapping the next draw's packet
work; draws whose stages could write memory are held back. Commits skip
work whose inputs did not change since the last commit, color metadata
passes are ordered through the pipeline, resource and storage-image proofs
are reused within one collect epoch until a write breaks them, and a shape
entry is refreshed in place at the second sight of the same read user words.
APS5_VERIFY_DRAW_PIPELINE checks reused proofs against a full check.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-23 03:46:57 +05:30
milescovielloandClaude Opus 5.5 f57bbc936a perf(agc): store only the depth plane units a flush overlaps
A read of memory inside a stale D32 Z_X depth plane (FlushDepthPlanes) stored
the whole plane: a copy of the depth image into the mirror, MarkWholeWritten
and a write-back of every byte. In Super Meat Boy 3D (#8840) a read-only
buffer ending about 3 KiB inside a stale 3840x2160 plane makes
ShaderResources::Revalidate flush ~1000 times per 5 s, each one moving
31.9 MiB, bound by transfer bandwidth.

A depth surface now tracks its plane as 64 KiB units, each one 128x128 tile
of the mirror's block units: a stale bit and a write generation per unit
replace memoryStale and the plane-wide syncedGeneration.

- FlushDepthPlanes stores only the stale units the range overlaps: the depth
  to mirror copy takes one region per unit rectangle (UnitRects, from the
  mirror's slice windows), the mirror marks just those units written
  (MarkUnitsWritten) and the write-back covers their hull. The other units
  stay stale and the plane stays registered. Stale bits are cleared only
  after the copy was recorded, and the stored units' generations advance
  only when FlushPending stored them. A depth fast clear still pending at
  the store rewrites the whole image, so it makes every unit stale first.
- SyncFromMemory copies from the mirror only the units the guest wrote since
  their own generation (one ChangedBlocks scan; untracked memory counts as
  unwritten, as WrittenSince did), so a guest write into one unit no longer
  replaces GPU depth that is still unstored in the others.
- Flushes followed by a retire keep the whole-plane store: the color target
  flush in Draw and a written storage view (DepthPlaneScope::Whole). The
  retire of an overwritten surface in DepthSurfaceTexture first stores its
  remaining stale units the guest did not write.
- A mirror without block units (APS5_NO_BLOCK_TRACKING, unaligned base)
  falls back to the whole-plane copy, and APS5_DEPTH_PLANE_WHOLE_STORE=1
  tracks the plane as one unit, the previous behaviour.
- DepthPlaneStoreCounts reports stores, units and bytes stored.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 10:03:00 +00:00
Dean e6ebe8a8b7 Merge pull request #8857 from Dripl1x/perf/direct-memory-section-pool
perf(libkernel): reuse released direct-memory sections that never held data
2026-10-21 22:20:39 +13:00
Celegans12 952ddb7844 feat(agc): skip draws whose graphics stage the recompiler refuses behind APS5_SKIP_REFUSED_DRAWS
When a draw's stage fails to prepare, capture or recompile, the packet
worker fails the queue and the next Submit or WaitIdle rethrows the
error, which ends the title. With APS5_SKIP_REFUSED_DRAWS set,
materializeDrawStage rethrows that error as a RefusedDraw; the packet
loop skips the draw, counts it as a thrown skip, logs the shader once
per address and runs the rest of the submission. The frame then lacks
that draw. Compute refusals and errors outside the stage build fail as
before, and without the switch nothing changes.

agc_driver_draw_unsupported_buffer_type_skip_refused submits a draw
whose pixel shader is refused twice with the switch: the WRITE_DATA
after it lands both times and the color target stays untouched.

AI-assisted: yes
2026-10-21 08:17:59 +02:00
Evgeniy KazarinandClaude Opus 5.5 69f843c910 perf(libkernel): reuse released direct-memory sections that never held data
The title allocates, maps and releases about 48 direct-memory blocks per frame.
Each allocation created a pagefile-backed section and each release closed it.
A released section whose pages were never stored to (resident pages keep their
data in private memory and saved buffers, not in the section) is still blank,
so up to 256 such sections of at most 16 MiB, 256 MiB in total, are kept by
size and handed to the next allocation of that size instead of a new
CreateFileMappingW. APS5_NO_DIRECT_MEMORY_SECTION_POOL keeps the old behaviour.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 10:32:44 +08:00
Dean 3b5a24c0d6 Merge pull request #8075 from johandavidcm/feat/agc-sample-committer
feat(agc): sample the draw committer with APS5_SAMPLE_COMMITTER
2026-10-21 14:12:36 +13:00
Dean 57fdffd915 Merge pull request #8697 from oneandonlydean/feat/f32-denorm-preserve
feat(shader): request DenormPreserve 32 where the device preserves f32 denormals
2026-10-21 13:29:41 +13:00
Dean 926ed2eda1 Merge pull request #7480 from Scramblrrrr/codex/videoout-force-sdr-main
feat(videoout): allow forcing SDR output
2026-10-21 12:28:40 +13:00
Dean 7e95bde794 Merge pull request #7427 from parl0v/perf/clear-keys-hand-over
perf(agc): hand pending results over to an image whose DCC keys are a clear code
2026-10-21 11:53:16 +13:00
Dean Galvin 3117837b35 docs(dev): list APS5_NO_HW_F32_PRESERVE in ENVIRONMENT.md 2026-10-21 10:45:24 +13:00
Adrià 73b6a4cc71 Merge pull request #8066 from HQasper/perf/gpu-thread-dimensions
perf(agc): resolve DISPATCH_INDIRECT thread dimensions on the GPU
2026-10-20 23:06:48 +02:00
Adrià be1ce988d4 Merge pull request #7870 from ionut27001/perf/image-memory-pool
perf(agc): keep released image memory in the buffer pool for reuse by type and size
2026-10-20 23:05:43 +02:00
Dean 29e4c46b4d Merge pull request #7417 from IshmamDC217/feat/relinker-trace-imports-linux
feat(relinker): support --trace-imports for Linux output
2026-10-21 09:03:29 +13:00
Dean Galvin 143ed02750 Merge branch 'main' into #7417
Resolve docs/dev/debt/libc.md: keep main's _Throw_Cpp_error entry and this branch's call tracing entry.
2026-10-21 06:33:59 +13:00
Nicolas Abosch f857616caa Merge remote-tracking branch 'origin/main' into perf/gpu-wake-sleeps
# Conflicts:
#	core/libs/prx/libSceAgcDriver/Execution/src/Driver/EntryPoints.cpp
#	core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
2026-10-20 14:29:10 -03:00
Dean GalvinandJoey Fisher 1cb64823ef Merge main into fix/template-texture-audit
Co-authored-by: Joey Fisher <[email protected]>
2026-10-21 03:35:29 +13:00
Dean 5f7e30233e Merge pull request #7340 from teepean/perf/write-only-pass-continuation
perf(agc): draws that only store to a buffer continue one render pass
2026-10-21 03:23:29 +13:00
Adrià 277671f838 Merge pull request #7683 from Longziip/fix/agc-indirect-register-reread
fix(agc): reread an invalid indirect register list where its packet executes
2026-10-20 15:18:56 +02:00
Adrià 7faab0aea9 Merge pull request #4891 from dantdmdarealguy/feat/screenshot-hotkey
feat(agc,videoout): save the displayed frame as a PNG with a screenshot key
2026-10-20 10:40:02 +02:00
Ethan Barcus a8e06fb008 Merge branch 'main' into feat/trace-bench-fields 2026-10-20 02:57:23 -05:00
dantdmdarealguy e3125e43af feat(agc,videoout): save the displayed frame as a PNG with a screenshot key
F12 (the new Screenshot input action) requests a capture of the next
presented display buffer. The presenter records it with the existing
APS5_DUMP_FRAMES GPU readback at full resolution, and the frame dump
writer thread encodes it with decoder_png into anyps5-screenshots/
beside the executable, or ANYPS5_SCREENSHOTS.
2026-10-20 00:28:39 -05:00
Dean c9c7e6cfaf Merge pull request #7964 from emirplus/docs/env-cpu-flip-in-order
docs(env): list APS5_CPU_FLIP_IN_ORDER in the environment reference
2026-10-20 17:08:23 +13:00
Dean db9fe52310 Merge pull request #7828 from savvaniss/fix/gpl-off-keep-library-extensions
fix(agc): keep the pipeline library extensions enabled under APS5_NO_GPL
2026-10-20 15:52:17 +13:00
Joey Fisher b4cd843324 fix(agc): fail a template's proof on a released texture and audit it with the full walk
The fast proof of a cached ShaderResources proves each sampled texture
from write stamps, keys and the pending registry. It never asks whether
the sampled lookup would still return the bound Texture, so a template
whose surface memory is unchanged keeps binding an old object:

- After the sampled cache drops or replaces the entry (#6492 marks the
  texture released), Find keeps serving the template until the next
  Insert, and its fast proof passes.
- When the lookup's answer changes without any lookup running (a
  snapshot whose surface became host-imported is viewed through its
  storage image from then on), nothing replaces the entry and the
  template keeps the snapshot until it leaves the resource cache.

The fast proof now fails with 'replaced texture' when a bound texture
is released. A template whose last full walk is older than
APS5_TEMPLATE_AUDIT_MS (default 1000, 0 turns it off) takes the full
walk instead of the fast proof ('audit'), so a different lookup answer
fails the proof and the template is rebuilt.
2026-10-19 16:13:56 -06:00
Ishmam Ahmed d128ce7bb8 feat(libc): record traced system library calls on Linux
Build the call tracer for Linux as well as Windows. The thunk area is a
memfd mapped twice, writable and executable, and threads are named by
gettid. Linux has no crash report, so the first traced import installs a
SIGABRT handler that prints the last calls and the most called imports,
then passes the signal on to the previous handler.

guest_call_trace and guest_call_trace_abort now run on Linux too.
2026-10-19 22:55:07 +01:00
Johan David e4898783b6 feat(agc): sample the draw committer with APS5_SAMPLE_COMMITTER
Queue 0's draw committer records the draws the packet worker hands
over. When the worker's APS5_SAMPLE_WORKER stacks wait in
DrawPipeline::Enqueue, the committer is the thread that bounds the
frame, and only APS5_SAMPLE_THREADS sees it: 40 addresses, 12 frames
deep, without whole stacks.

APS5_SAMPLE_COMMITTER=<file> attaches the worker's sampler to the
committer when its thread starts and writes the same two files. Both
use one start function, and StopWorkerSampler stops both.
2026-10-19 14:45:14 -05:00
Adrià 965dc2d78c Merge pull request #7298 from eliyarson/feat/videoout-telemetry
feat(videoout): write pad and present telemetry to APS5_VIDEOOUT_TELEMETRY_DIR
2026-10-19 20:40:04 +02:00
ionut27001 4513d47104 perf(agc): keep released image memory in the buffer pool for reuse by type and size
An image's own VkDeviceMemory was allocated and freed one at a time, and in a scene that re-creates its storage images at every dynamic-resolution step the dispatching queue worker spent half of its image-table resolution freeing evicted images and most of the rest allocating new ones. The pool now keeps the device memory of a released storage or sampled image under its own budget (APS5_IMAGE_POOL_MIB, a quarter of the device tier's budget by default) and hands it to the next image of the same memory type and size.
2026-10-19 21:30:25 +03:00
HQasperandClaude Opus 5.5 612b41e4f3 perf(agc): resolve DISPATCH_INDIRECT thread dimensions on the GPU
An indirect dispatch with USE_THREAD_DIMENSIONS read its thread counts on the
CPU, which waits for the recorded work that stores them. The argument kernel now
turns them into group counts on the GPU and copies the counts into the
ShaderData thread limit, so the dispatch stays on the GPU path.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 19:36:01 +02:00
Adrià e6a3cf0079 Merge pull request #7808 from parl0v/docs/host-import-budget-default
docs(env): describe the default host import budget as HostImportBudget computes it
2026-10-19 19:35:47 +02:00
Nicolas Abosch 4bc91c9fbb Merge remote-tracking branch 'origin/main' into perf/gpu-wake-sleeps 2026-10-19 13:47:53 -03:00
alfalfa-starandClaude Opus 5.5 14fd9853db fix(agc): also store small tiled images before a label
The Smurfs - Dreams (PPSA21607) reads a 1x1 RGBA16F R64KBX storage image
on the CPU after a label. The label-time store took only linear images, so
the image stayed pending and the sky light read 0. Tiled images up to
SmallStoreBytes are stored before the label as well.

Reported and tested by Pacuka.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 18:44:06 +02:00
Longziip ae67e2b7f9 fix(agc): write the reread indirect register list when skipping its invalid entries
When the list read at submission is invalid, the worker now always
executes the copy read again where the packet runs. With
APS5_SKIP_INVALID_INDIRECT_REGISTERS=1 only that copy's invalid entries
are skipped, so the valid entries of a partly updated list are written
instead of the stale ones from submission.

testPartlyUpdatedRegisterListSkipsOnlyItsInvalidEntries submits a list
that is invalid at submission, updates it to a valid entry plus an
invalid one before its packet runs, and reads the register back with
COPY_DATA.
2026-10-19 17:29:53 +01:00
Longziip 557ae22bd1 fix(agc): reread an invalid indirect register list where its packet executes
SET_*_REG_INDIRECT lists are read when the command buffer is submitted.
When that copy holds an offset dword that is no register offset, the
queue worker now reads the list again where the packet executes (as the
console PFP does) and uses that copy if it is valid.

PPSA23566 (UFC 6) intermittently submits a SET_CONTEXT_REG_INDIRECT
whose first entry is 0x038f038f or 0x03900390 in both copies, followed by
180 valid pairs, and the title stopped with "extended register semantics
are not implemented". With APS5_SKIP_INVALID_INDIRECT_REGISTERS=1 the
invalid entries are skipped and the other registers are written; without
it the packet throws as before.
2026-10-19 17:29:53 +01:00
emirplus 854570694f docs(env): list APS5_CPU_FLIP_IN_ORDER in the environment reference 2026-10-19 19:19:38 +03:00
Adrià 5638146d6a Merge pull request #7526 from Amoenus/codex/docs-trace-summary-seconds-main3e3e
docs(dev): correct periodic trace summary interval units
2026-10-19 18:18:10 +02:00
Nicolas Abosch 843084a9d1 Merge remote-tracking branch 'origin/main' into perf/gpu-wake-sleeps 2026-10-19 12:44:46 -03:00
Adrià c017549dc1 Merge pull request #6955 from alfalfa-star/perf/agc-space-page-reuse
perf(agc): reuse a cached address space's committed pages on a hit
2026-10-19 17:33:02 +02:00
Dean Galvin 064a6f98ab Merge main into pr-7427
# Conflicts:
#	core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
2026-10-20 04:25:03 +13:00
Nicolas Abosch b131d2db5d Merge remote-tracking branch 'origin/main' into perf/gpu-wake-sleeps 2026-10-19 11:58:20 -03:00
Adrià c92eb8da1e Merge pull request #6931 from AnthonyClemens/perf/agc-pipelined-indirect-draws
perf(agc): queue CPU-path indirect draws on the draw pipeline
2026-10-19 16:48:13 +02:00
billybobpicklioandClaude Opus 5.5 1ee2996829 perf(agc): skip CPU-path indirect draws that draw nothing before building their stages
An indirect draw read its count and records only after every stage had been captured and
compiled, so a draw whose records all have no vertices or no instances (what GPU-side culling
leaves for most draws in a culled scene) cost a full stage build to draw nothing.

When the front program's last indirect draw took the CPU path, the draw now reads its count and
records first, through the same flush hook, and returns before the stage build when no record
draws. APS5_NO_EMPTY_INDIRECT_SKIP=1 builds them as before. The [draws] profile line counts the
skipped draws. agc_driver_empty_indirect_skip_tests draws one record, two empty ones and one
more, and checks that the empty ones were skipped and the last one draws as the first.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 10:26:35 -04:00
Adrià 3efab5ed86 Merge pull request #6914 from moong15/pr/queued-index-read-order
fix(agc): order deferred write-backs after queued draws' index reads
2026-10-19 15:39:49 +02:00
Adrià Franch 6ff980cc2e docs(env): document APS5_VIDEOOUT_TELEMETRY_DIR 2026-10-19 15:27:59 +02:00