Skip to content

perf(agc): a DMA_DATA prefetch keeps the draw pipeline - #6538

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
TheAggie:perf/agc-dma-prefetch-keeps-pipeline
Oct 19, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
TheAggie:perf/agc-dma-prefetch-keeps-pipeline

Conversation

@TheAggie

Copy link
Copy Markdown
Contributor

What

With pipelined draws, every packet that is not known to be safe drains the draw pipeline before it runs. DMA_DATA with its destination set to nowhere (DST_SEL 2) is a cache prefetch: it writes no memory, so there is nothing for the draws ahead of it to order against. RADV issues one per draw for its descriptor and push-constant rings (about 12,000 a second in a PS2 title under RetroArch's PCSX2 core, every one a drain), and each drain idles the queue worker until the committer catches up.

  • keepsDrawPipeline keeps the pipeline for a DMA_DATA whose destination is nowhere. Copies, fills and GDS transfers drain as before.
  • DrawPipeline::Drains(reason) reads a drain count under the pipeline's lock, for the test.

Overlaps with #6208, which pipelines every DMA_DATA and covers this case among others; that PR is being reworked, and this one is the one-line subset that needs no snapshotting, with its own test and numbers. If #6208 lands first this PR is void.

Tested

Windows 11, NVIDIA GeForce RTX 5070 Ti, MinGW-w64 GCC 15.2.0, on main 92e50418f.

  • ctest: 1276 of 1295 pass, 14 skipped. guest_call_trace_abort and windows_backtrace_report fail, and fail the same way on plain main here; agc_driver_prepared_graphics_prebuild_0/_1 and undeliverable_host_exception fail under my test runner because it skips their environment changes and pass pattern, and pass run with those.
  • New test agc_driver_pipelined_prefetch: a commit holds the draw pipeline busy, and a DMA_DATA is submitted with a label write behind it. For a prefetch the queue worker passes it and the label queues behind the held commit, with no packet drain; for a copy the worker is held in the copy's drain until the commit is released, one drain, and the copy's bytes land. Without the change the prefetch case fails the same way the copy case passes: the worker is held.
  • RetroArch (PPSA99169) with its PCSX2 core running Ratchet & Clank's intro, pipelined draws, immediate present, audio muted, same build otherwise with the local draw-cache changes that let its draws hit: the heavy intro scenes went from 24-25% of real time to 37-43% over three runs, and the [draw] pipelined line's packet drains per 10 s from about 120,000 (all opcode 0x50) to under 1,000 (none 0x50). The lighter scenes reach real time.

Checklist

  • Based on current main; no other open PR implements the same functions (perf(agc): pipeline DMA_DATA when APS5_PIPELINE_DMA=1 #6208 overlaps, see above)
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes. Written with Claude Code under my direction.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 4448 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
PR 5115 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
PR 5925 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
PR 6188 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
PR 6292 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
PR 6501 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
PR 6615 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
PR 6946 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
PR 6947 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
PR 6963 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
PR 7008 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
PR 7340 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
PR 7642 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp

@blawesom

Copy link
Copy Markdown
Contributor

Rebase handoff — rebased onto current main (authorship unchanged). One conflict in DrawPipeline.cpp: two drain-metrics functions landed at the same spot — main's DrainRequestsByOpcode (used by the pipelined dispatch tests) and this PR's Drains(DrainReason) (used by the prefetch test); both kept.

Verified on Linux (CachyOS, kernel 7.2.9, GCC 16.2.1, Ninja, Release, BUILD_TESTING=ON, AMD RX 9070 XT / RADV):

To pick it up:

git fetch https://github.com/blawesom/AnyPS5 rebase/6538
git checkout <your branch>
git merge --ff-only FETCH_HEAD

Head is d7f2311bd.

@blawesom

Copy link
Copy Markdown
Contributor

Re-anchored rebase handoff — main moved since the earlier handoff, so the branch is rebased onto current main again (authorship unchanged; the same two drain-metrics functions kept, main's DrainRequestsByOpcode alongside yours).

Verified on Linux (CachyOS, kernel 7.2.9, GCC 16.2.1, Ninja, Release, BUILD_TESTING=ON, AMD RX 9070 XT / RADV):

To pick it up:

git fetch https://github.com/blawesom/AnyPS5 rebase/6538
git checkout <your branch>
git merge --ff-only FETCH_HEAD

Head is 7e55f5b93.

@github-actions github-actions Bot added perf Performance change perf numbers missing perf pull request without a before and after summary line labels Oct 18, 2026
@adriadam10 adriadam10 self-assigned this Oct 19, 2026
A DMA_DATA whose destination is nowhere writes no memory, so the draws ahead of it have nothing to order against. RADV issues one per draw, and each drained the pipeline and idled the queue worker until the committer caught up.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@adriadam10
adriadam10 force-pushed the perf/agc-dma-prefetch-keeps-pipeline branch from 8071044 to e8377c9 Compare October 19, 2026 05:51
@github-actions

Copy link
Copy Markdown

This pull request is labeled perf, so it needs the summary line of a capture on main and one with the change, from the same title, scene and machine, as the Performance report form asks. Please paste both aps5-summary.jsonl lines, attach the two traces and add the output of tools/trace_digest.py.

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 19, 2026
@adriadam10
adriadam10 merged commit 63e4a63 into boykopovar:main Oct 19, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* perf numbers missing perf pull request without a before and after summary line perf Performance change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants