Commit Graph
1604 Commits
Author SHA1 Message Date
Dean 3fea2a937b Merge pull request #11685 from oneandonlydean/port/direct-depth-layer-copy-v2
feat(agc): copy depth planes to and from color storage images directly where maintenance8 allows
2026-10-27 23:03:00 +13:00
Dean a636927e5f Merge pull request #8161 from Celegans12/feat/tools-ab-split
feat(tools): split the periodic reports of an APS5_AB run by phase
2026-10-27 21:34:47 +13:00
Adrià d768fb5df3 Merge pull request #10513 from thuanquang/perf/frame-dump-writer-cpu
perf(agc): write CPU-path frame dumps through the frame dump writer
2026-10-27 09:21:55 +01:00
Dean e07c21ce68 Merge pull request #11157 from janzezno/feat/agc-frame-capture-linux
feat(agc): capture and replay frames on Linux
2026-10-27 21:20:55 +13:00
Dean 26c451905c Merge pull request #10973 from MarcZX10/marc/fix-asan-copy-guest-bytes-alignment
fix(agc): read unaligned guest words through a one-byte-aligned type in the ASan copy
2026-10-27 18:29:32 +13:00
Adrià 6856adae6e Merge pull request #10655 from thuanquang/perf/import-watched-parallel-hash
perf(agc): hash the pages of an import window on several threads
2026-10-27 05:44:55 +01:00
Adrià 5caff281bd Merge pull request #10540 from maximilianfv/fix/agc-macos-build-frame-recorder
fix(agc): build the frame recorder and the resident heap mirror test on macOS
2026-10-27 04:52:21 +01:00
Adrià 4c486ca322 Merge pull request #10515 from JJenkx/fix/agc-two-sample-dithered-a2c
fix(agc): emulate two-sample DB_ALPHA_TO_MASK 0xe701 dithered alpha-to-coverage
2026-10-27 04:52:02 +01:00
Dean abed035468 Merge pull request #11313 from frankea/fix/agc-draw-index-multi-instanced
fix(agc): write the console's DRAW_INDEX_MULTI_INST packet for sceAgcDcbDrawIndexMultiInstanced
2026-10-27 15:02:15 +13:00
Dean 0fba400ce4 Merge pull request #11171 from Amoenus/codex/fix-cpu-write-mapping-lifetime-20261025
fix(agc): retain registered mappings during CPU stores
2026-10-27 15:01:15 +13:00
Dean c72ed0b7c8 Merge pull request #10388 from Tamalero/perf/prebuild-pool-threads
perf(agc): prebuild registration libraries on half the hardware threads by default
2026-10-27 14:59:11 +13:00
Dean d1de04f943 Merge pull request #7484 from AlxcBTW/pr/robust-loads
perf(recompiler): leave the descriptor-range comparison out of direct buffer loads when the device zeroes past the range
2026-10-27 14:56:32 +13:00
Dean 630211a866 Merge pull request #6612 from milescoviello/feat/tess-geometry
feat(agc): draw tessellation followed by an NGG geometry stage
2026-10-27 14:56:18 +13:00
Dean 8b2ae8a578 Merge pull request #6249 from Ondra97/codex/fix-copy-alias-byte-coverage
fix(agc): preserve all bytes in image-backed buffer copies
2026-10-27 14:56:03 +13:00
Dean a83ebf95ea Merge pull request #11306 from frankea/fix/agc-tag-marker-headers
fix(agc): write libSceAgc's tag markers with the console's header flags
2026-10-27 14:27:49 +13:00
Dean 74acfad65b Merge pull request #11365 from oneandonlydean/sa/per-draw-gpu-timing
feat(agc): opt-in per-draw GPU timing and dump-by-address diagnostics
2026-10-27 11:08:24 +13:00
Yunus Shaikh b1889783be feat(agc): fill the overlay's second page from the driver's counters
Page 2 now samples its sources once a second, in NotePresent, while it
shows; nothing of it runs while the overlay is hidden or on page 1.

- Busy share per queue worker, the top 5 phases in ms per frame and queue
  0's waits (memory, lock, GPU) come from the trace's per-thread totals.
  Showing page 2 turns recording on with buffering off, so a timed scope
  only adds to its thread's totals; leaving it turns recording off again.
  Toggle switches it under a mutex, and ANYPS5_OVERLAY=2 switches it on at
  start. An APS5_TRACE_* run keeps its own recording untouched, and page 2
  then shows these lines only while that trace records. A driver thread
  names itself when it starts (BindThread without APS5_TRACE_* stores the
  name only) and binds on its first timed scope while page 2 shows;
  unnamed threads are not bound.
- Render passes per frame: the draw path counts a begun pass in the trace
  totals while page 2's totals are on (PerformanceTrace::Count).
- Flips/s and the draw cache's hit rate come from the driver through a
  source it registers at start (the draw cache's lock is only tried); the
  pipeline store's hit rate from PipelineStoreTotals; the compile backlog
  from the shader preparation and library prebuild pools (tried locks).
- Dropped frames per second are the presents that found no free swapchain
  image; repeated ones are presents of the display buffer shown just before.
  The device passes the buffer's address, its present mode and the drops.
- Commit charge against the commit limit: GetPerformanceInfo on Windows,
  Committed_AS and CommitLimit from /proc/meminfo on Linux; page faults per
  second from PageFaultCount or getrusage.
- Host imports: their count and bytes against the budget, on devices that
  import host memory.
- CPU copies: address-based builds count the bytes they copy in a
  per-thread counter (a relaxed load and store, folded once a second) with
  the largest build of each second against the address-copy cap.
- Unimplemented-function calls: libc counts NotImplemented_nid_no_patch
  calls; refused shaders are the APS5_SKIP_REFUSED_DRAWS set's size.
- Title ID (when the title has a param.json) and present mode.

The tests cover the trace deltas, hit rates, present-mode names, the
/proc/meminfo parser and the OS reads, the per-thread copy counter's fold,
the counted unimplemented call, the trace switch with page 2 and lazy
binding without buffering, and on lavapipe the sampler end to end with a
fake driver source, its reset when page 2 is left, and the cost of a
present hidden, on page 1 and on page 2.
2026-10-26 20:42:29 +01:00
Yunus Shaikh b6d3ae0dd6 feat(agc): add a detailed second page to the performance overlay
F10 now cycles through three states: off, the existing overlay (page 1)
and a detailed page (page 2), then off again. ANYPS5_OVERLAY=2 starts on
page 2; 1 and 0 or unset keep their meaning, and any other value still
throws, now naming 0, 1 and 2. OverlayPageAfter is the cycle, the
starting page plus the F10 presses modulo 3. Toggle stores the page it
gives under a mutex and PerformanceOverlay::Page loads it, so Visible,
which every present calls, stays one load as before. Each change of
page resets the statistics, as a toggle did.

Page 2 has its own composer, ComposeOverlayDetails, a pure function of
one OverlayDetailSample. It fills a 46-column panel without the graph.
Every value is optional, and a line whose sources are all missing is
left out; a line with some missing shows only the values it has. Each
line names its unit. Names from elsewhere (threads, trace phases, the
title, the present mode) go through OverlayText, which upper-cases
them and turns characters the font has no glyph for into spaces;
phase names are cut to fit the line. Page 1 is unchanged, line for
line.

On page 2, NotePresent keeps the frame statistics and fills the sample
with the frame rate, the last frame's time, presents per second and
the pipelines created in the last second. It reads nothing else, and
it skips page 1's memory reads and packet sums. The next commit adds
the driver and system counters. NotePresent latches the page, so
Record draws the page NotePresent sampled.

Tests: ANYPS5_OVERLAY 2 and 3, 02 and -1; the cycle from each starting
page through three presses and past 2^64 presses; page 2 of a full
sample, line for line, of an empty sample, and of a sample with
missing sources; every character either composer can emit has a
glyph; page 2 laid out at 1280x720, 1920x1080, 3840x2160 and 640x360,
every line drawn, no graph, and a 60-line page shrunk to scale 3 at
3840x2160. On lavapipe, under the Khronos validation layer with no
message: page 2 drawn at 1280x720 bit for bit, and F10 through a real
overlay: page 1, page 2 drawn from its own composer, then hidden, with
the statistics reset at each change.
2026-10-26 20:42:15 +01:00
Yunus Shaikh e11fb2a288 refactor(agc): take the performance overlay panel's width from its content
The panel was fixed at OverlayMetrics::Columns, 27 columns, and always
kept rows for the frame-time graph. OverlayContent now carries its
column count and whether it has a graph, and the panel's width, height,
fit test and scale come from them. ComposeOverlay still fills 27
columns with a graph, so the existing panel is drawn as before, line
for line.

LayOutOverlay refuses a panel with no columns, a graph on a panel
narrower than its 120 frames, and frame times on a panel without a
graph.

The 5x7 font gains %, +, -, _, J, Q, Y and Z, from the same HD44780
character set as its other glyphs, and OverlayFontCharacters lists
every character it can draw.

Tests: every listed character has a glyph no wider than 5 pixels,
non-empty unless it is the space, and unlike any other; characters
outside the list are refused; a 48-column panel without a graph is
laid out and scaled at 1280x720, 1920x1080, 3840x2160 and 320x180; a
140-column panel at 3840x2160 shrinks from scale 5 to 4; a too-long
line, a 20-column graph and frame times without a graph are refused.
2026-10-26 20:42:15 +01:00
Dean Galvin 9b31471555 feat(agc): copy depth planes to and from color storage images directly where maintenance8 allows
A depth plane and the color storage image that holds or receives its texels were copied image to buffer, then buffer to image. With VK_KHR_maintenance8, which the device already enables, vkCmdCopyImage copies the depth aspect directly to and from a single-component color format of its size (D32 with R32, D16 with R16), so those copies record one image copy and two barriers in place of the staging buffer round trip and three barriers. TakeStorage keeps its discard of the new depth surface before the copy. 24-bit depth, the stencil plane and every other format pair keep the buffer path, as does APS5_NO_DIRECT_DEPTH_COPY=1. The graphics Context now carries the maintenance8 flag. No performance claim is made.
2026-10-27 08:40:41 +13:00
Dean Galvin 09334e1ac5 Merge remote-tracking branch 'up/main' into sa/per-draw-gpu-timing 2026-10-27 08:24:46 +13:00
Adrià afc780e681 Merge pull request #10507 from orezraey/feat/videoout-composite-overlay
feat(videoout): composite the overlay bus over the main output
2026-10-26 20:00:54 +01:00
Dean 48c160c58b Merge pull request #10930 from ahmadmuj/fix/anyps5-agc-wait-unmasked
fix(agc): mask the WAIT_REG_MEM address before keepsDrawPipeline checks it
2026-10-27 05:54:44 +13:00
frankea 49ce12ad0a Merge remote-tracking branch 'origin/main' into fix/agc-tag-marker-headers 2026-10-26 12:32:50 -04:00
frankea 72f663c64c Merge remote-tracking branch 'origin/main' into fix/agc-draw-index-multi-instanced 2026-10-26 12:32:50 -04:00
janzezno c867473002 feat(agc): capture and replay frames on Linux 2026-10-26 16:11:45 +01:00
Celegans12 3cf8170ff8 feat(agc): toggle runtime switches in alternating phases of one run
Two runs of the same scene drift apart by more than many effects worth
measuring. APS5_AB=<seconds>:<switch>[+...] alternates phase A (switches
as the environment sets them) and phase B (the listed switches toggled)
at flip packets, under the GPU mutex after the draw pipeline drained,
and prints "[ab] phase A|B <k> begins/settled at present <n> (t <s> s)".
APS5_AB_START (a flip count, or <n>s) delays the first phase and
APS5_AB_SETTLE (default 2 s) marks when a phase's reports are clean.
Switches live in a registry (RuntimeSwitches) of relaxed atomics that
start as the environment sets them; APS5_NO_BARRIER_BATCH is the first,
since every elision it gates is decided per barrier. Any other name
fails the first flip. Without APS5_AB nothing changes.

AI-assisted: yes
2026-10-26 12:26:04 +01:00
thuanquang d1564becdb Merge remote-tracking branch 'origin/main' into perf/import-watched-parallel-hash
# Conflicts:
#	core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
2026-10-26 17:49:50 +07:00
Romans Pokrovskis 4ac4a00801 Merge commit '5b5d24cb223ede690fe5eab1fe2f7a1736b801a5' into codex/fix-cpu-write-mapping-lifetime-20261025 2026-10-26 12:17:15 +02:00
Dean Galvin e0bd61fae2 Merge branch 'main' into pr/robust-loads 2026-10-26 23:10:10 +13:00
Dean Galvin 8c45681cc3 fix(agc): join gputime keys to drawvariant ids and name queued draws
The [gputime] line printed a draw's range key with the draw flag still set, so an ordinary variant id 0x2 appeared as 0x8000000000000002 next to [drawvariant] 0x2. A draw's key now comes from Recorder::DrawTimingKey and the line prints it through Recorder::TimingKeyLabel as "draw 0x2", the id [drawvariant] names.

The [drawvariant] line was only printed when a draw was recorded inline, so a queued draw's first-seen variant had a timing range with no address line. It is now printed before the draw is handed to the pipeline.

The APS5_PROFILE_GPU_DRAWS row states the label, the shared per-batch query cap and that draws using a recipe are not timed.
2026-10-26 22:33:53 +13:00
Dean Galvin 809914084f Merge main into sa/per-draw-gpu-timing 2026-10-26 22:33:43 +13:00
Dean b27cc8416f Merge pull request #7505 from AlxcBTW/pr/unwatch-hook-exits-v2
fix(agc): run the unwatch hook before an import whose range leaves the write watch whatever the import does
2026-10-26 21:31:22 +13:00
Dean 204c6747d0 Merge pull request #11197 from LeandroLP23/fix/agc-frame-recorder-settle-before-delta
fix(agc): read a frame capture's memory delta once the accepted submissions completed
2026-10-26 20:48:54 +13:00
SP4C3B4R-8 3cd49f9b9b chore(agc): dump a draw's programs by code address
APS5_DUMP_DRAW_SHADERS also matches a program's code address, so a program
named by [drawvariant] or [gputime] can be dumped directly.
2026-10-26 20:10:08 +13:00
SP4C3B4R-8 631f77e696 perf(agc): time each recorded draw on the GPU by its fragment program
Opt-in with APS5_PROFILE_GPU_DRAWS=1 together with APS5_PROFILE_GPU=1: a [gputime] range around each recorded draw command keyed by the fragment program's variant id, and a [drawvariant] line naming the code address behind each variant id once.
2026-10-26 20:10:08 +13:00
orezraeyandClaude Opus 5.5 f34c280578 Merge main into feat/videoout-composite-overlay
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 03:06:04 -03:00
Dean 426e1dbf2d Merge pull request #10174 from ntamas94/fix/agc-raw-shader-cache-eviction
fix(agc): keep hundreds of raw shader snapshots cached
2026-10-26 18:26:35 +13:00
Dean 3fcef220ca Merge pull request #10160 from EagleBearerYS/port/fable-fix-present-key-wait
perf(agc): wait for the display keys' writer before a present takes the device lock's time
2026-10-26 18:26:31 +13:00
frankea 37857ceb29 fix(agc): write the console's DRAW_INDEX_MULTI_INST packet for sceAgcDcbDrawIndexMultiInstanced
On a PS5 the builder writes 15 dwords: a tag write of 0xc6000006, opcode 0x3a with its arguments, initiator 0x80 whatever the modifier, and a closing tag write; GetSize returns 60. AnyPS5 wrote NUM_INSTANCES and DRAW_INDEX_2 under argument meanings nothing confirms. The driver refuses 0x3a, whose field meanings are not known, and names it DRAW_INDEX_MULTI_INST as Linux's nvd.h does.
2026-10-25 23:14:39 -04:00
Dean 27905e1dfc Merge pull request #9888 from m335671/fix/dispatch-ahead-adopt-check
fix(agc): re-check a dispatch resolved ahead against memory before adopting it
2026-10-26 15:31:28 +13:00
frankea be69f66349 fix(agc): write tag markers with the console's header flags
sceAgcDcbWaitRegMem and sceAgcDcbDrawIndirectMulti now write their 0x342 tag writes with header flag bit 2 and sceAgcAcbWaitRegMem with no flags, as libSceAgc on a PS5 does, instead of the predicate bit. ValidateWait accepts both forms and Pm4::IsTagMarker no longer depends on the header flags.
2026-10-25 21:58:54 -04:00
Dean Galvin d84ce7c11c fix(agc): suspend the tracker lock around the unwatch hook 2026-10-26 14:36:49 +13:00
Dean Galvin 72598e34c8 Merge branch 'main' into pr/unwatch-hook-exits-v2 2026-10-26 14:36:49 +13:00
Dean d31f372e33 Merge pull request #10062 from imellag/fix/agc-moltenvk-destroy-at-idle
fix(agc): destroy buffers and memory on MoltenVK only while the graphics queue is idle
2026-10-26 14:28:45 +13:00
orezraeyandClaude Opus 5.5 655d0f3f32 Merge main into feat/videoout-composite-overlay
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 21:51:50 -03:00
Romans Pokrovskis 7dde90dc9c chore: refresh CPU store pins on main 5b85225ef3 2026-10-26 02:42:22 +02:00
Dean 73a5dc0886 Merge pull request #10807 from milescoviello/fix/presentation-source-host-fallback
fix(agc): place the presentation source in host memory when device memory runs out
2026-10-26 13:34:02 +13:00
Adrià acb900c194 Merge pull request #9737 from imellag/feat/agc-depth-bounds-emulation
feat(agc): emulate a one-sided depth bounds test without the depthBounds feature
2026-10-26 00:35:49 +01:00
LeandroLP23andClaude Opus 5.5 a69872e516 fix(agc): hand a recorded submission to the driver before the recorder takes its next call
The recorder released its lock between recording a submission, flip or
suspend point and the driver accepting it. Another thread's delta could
then wait for the accepted work, read its blocks, and record itself
after a call whose work the driver had not accepted yet, so the replay
submitted that work before applying stale bytes over its result. The
entry points now pass the driver call to the recorder, which runs it
under the same lock right after recording the call.

agc_driver_frame_replay_concurrent submits copies from a second thread
during the capture and checks that every memory delta was read after
the submissions recorded before it had completed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 23:20:21 +01:00