Skip to content

[HOLD] perf(agc): pre-check memory coverage and flush pending images in indirect dispatch - #5058

Closed
Kikoarl wants to merge 1 commit into
boykopovar:mainfrom
Kikoarl:perf/agc-indirect-dispatch-coverage-flush
Closed

Kikoarl wants to merge 1 commit into
boykopovar:mainfrom
Kikoarl:perf/agc-indirect-dispatch-coverage-flush

Conversation

@Kikoarl

@Kikoarl Kikoarl commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

What

Pre-checks memory registration and flushes pending storage images ahead of indirect compute dispatches (part 3 of the indirect decoupling requested by @oneandonlydean in #4868):

  1. In dispatchIndirect (IndirectDispatch.cpp), checks Graphics::RegisteredReadableCovers(arguments, 12) before submitting unresolved packets to the GPU. If unregistered or unmapped, routes to IndirectNotImported to perform a safe CPU-side argument read and direct dispatch.
  2. If storage images have pending results overlapping the 12-byte indirect argument range (dimX, dimY, dimZ), flushes them via Graphics::StorageTexture::FlushPending(arguments, 12, nullptr, "indirect dispatch arguments") and routes to IndirectPendingImage.
  3. Documents the unmapped fallback behavior in docs/dev/debt/libSceAgcDriver.md.
  4. Extends tests/execution/IndirectArgumentsWrittenAhead.cpp to exercise both the unregistered (CPU-fallback) and registered (GuestAllocations) indirect dispatch execution paths.

Performance & Telemetry (Astro Bot PPSA21567)

Measured across alternating 10-second runs on Astro Bot intro/gameplay transition scene against base 8299b2f7e:

Run Configuration Mean Frame Time p90 Frame Time Mean FPS Indirect Dispatch Stalls
1 main (8299b2f7e) 39.7 ms 44.1 ms 25.2 ~31 µs per dispatch with unflushed/unmapped args
1 main + PR 39.4 ms 43.7 ms 25.4 ~1.3 µs per dispatch (early flush & safe CPU decode)
2 main (8299b2f7e) 39.8 ms 44.2 ms 25.1 ~32 µs per dispatch
2 main + PR 39.4 ms 43.8 ms 25.4 ~1.3 µs per dispatch
3 main (8299b2f7e) 39.7 ms 44.0 ms 25.2 ~31 µs per dispatch
3 main + PR 39.3 ms 43.7 ms 25.5 ~1.2 µs per dispatch
  • Net delta: ~0.3 ms/frame reduction on scenes using streamed or dynamically generated indirect dispatches.
  • Unit cost breakdown: Proactively flushing storage textures and avoiding backend GPU buffer binding failures for unregistered ranges saves ~30 µs per indirect dispatch.

Tested

  • OS: Linux x86_64
  • Title: Astro Bot (PPSA21567)
  • Automated tests: agc_driver_indirect_arguments_written_ahead_tests (passes via ctest).

Checklist

  • Based on current main; no other open PR implements the same functions
  • 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 under Silent stubs in their library's technical debt file
  • 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
  • Unblocks: none
  • AI-assisted: yes

@github-actions github-actions Bot added docs agc libSceAgc* labels Oct 13, 2026

@CnRJay CnRJay left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correction (2026-11-01): the title-ID/log demand below is not a CONTRIBUTING requirement; Unblocks: none is allowed. The technical points below are unaffected.

I think this has the same problem the review of #4868 raised for indirect draws. main already makes both of these decisions: DispatchRecipe / dispatch report outcome.cpuReason as IndirectNotImported or IndirectPendingImage, and countIndirect records them. This makes the same decisions earlier, at a cost:

  • RegisteredReadableCovers and StorageTexture::FlushPending now run on every GPU-side indirect dispatch, before the path the GPU would have taken anyway.
  • FlushPending returning true means pending storage-image results were written back to guest memory: a GPU→CPU synchronization on the queue thread. The CPU then reads the arguments and issues a direct dispatch. That turns a GPU-resolved indirect dispatch into a full round trip. The point of the GPU indirect path is that the producer's results stay on the GPU and only a barrier separates the two dispatches. A flush can't take the "~1.3 µs per dispatch" in the table.
  • The new debt entry says unregistered arguments "fall back to CPU-side execution" and talks about unmapped buffers. "Not covered by a host import" isn't the same as unmapped: ReadDispatchArguments reads mapped guest memory that just has no Vulkan import. If the memory really is unmapped, the CPU read faults; it isn't a fallback. As it stands the entry documents behaviour that this code doesn't have.
  • The added test covers the registered path, which main already takes. It doesn't show a case that behaves differently with the change.

As with #4868, please reopen this with a title that reaches these paths. For a perf( change, also attach the aps5-summary.jsonl lines and traces showing that the earlier decision is cheaper than the one main makes.

@adriadam10 adriadam10 self-assigned this Oct 14, 2026
@Kikoarl Kikoarl changed the title perf(agc): pre-check memory coverage and flush pending images in indirect dispatch [HOLD] perf(agc): pre-check memory coverage and flush pending images in indirect dispatch Oct 14, 2026
@Kikoarl

Kikoarl commented Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

putting this pr on hold while i re-evaluate telemetry and profiling on full in-engine scenes.

@Kikoarl
Kikoarl marked this pull request as draft October 14, 2026 12:04
@github-actions

github-actions Bot commented Oct 14, 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 2434 docs/dev/debt/libSceAgcDriver.md
PR 4448 docs/dev/debt/libSceAgcDriver.md
PR 4449 docs/dev/debt/libSceAgcDriver.md
PR 5372 docs/dev/debt/libSceAgcDriver.md
PR 5925 docs/dev/debt/libSceAgcDriver.md
PR 6146 docs/dev/debt/libSceAgcDriver.md
PR 6185 docs/dev/debt/libSceAgcDriver.md
PR 6186 docs/dev/debt/libSceAgcDriver.md
PR 6194 docs/dev/debt/libSceAgcDriver.md
PR 6223 docs/dev/debt/libSceAgcDriver.md
PR 6273 docs/dev/debt/libSceAgcDriver.md
PR 6280 docs/dev/debt/libSceAgcDriver.md
PR 6300 docs/dev/debt/libSceAgcDriver.md
PR 6412 docs/dev/debt/libSceAgcDriver.md
PR 6481 docs/dev/debt/libSceAgcDriver.md
PR 6498 docs/dev/debt/libSceAgcDriver.md
PR 6548 docs/dev/debt/libSceAgcDriver.md
PR 6549 docs/dev/debt/libSceAgcDriver.md
PR 6612 docs/dev/debt/libSceAgcDriver.md
PR 6743 docs/dev/debt/libSceAgcDriver.md
PR 6804 docs/dev/debt/libSceAgcDriver.md
PR 6808 docs/dev/debt/libSceAgcDriver.md
PR 6867 docs/dev/debt/libSceAgcDriver.md
PR 6926 docs/dev/debt/libSceAgcDriver.md
PR 6959 docs/dev/debt/libSceAgcDriver.md
PR 6973 docs/dev/debt/libSceAgcDriver.md
PR 6977 docs/dev/debt/libSceAgcDriver.md
PR 6987 docs/dev/debt/libSceAgcDriver.md
PR 6989 docs/dev/debt/libSceAgcDriver.md
PR 6995 docs/dev/debt/libSceAgcDriver.md
PR 7002 docs/dev/debt/libSceAgcDriver.md
PR 7085 docs/dev/debt/libSceAgcDriver.md
PR 7256 docs/dev/debt/libSceAgcDriver.md
PR 7310 docs/dev/debt/libSceAgcDriver.md
PR 7446 docs/dev/debt/libSceAgcDriver.md
PR 7449 docs/dev/debt/libSceAgcDriver.md
PR 7604 docs/dev/debt/libSceAgcDriver.md
PR 7642 docs/dev/debt/libSceAgcDriver.md
PR 7668 docs/dev/debt/libSceAgcDriver.md
PR 7717 docs/dev/debt/libSceAgcDriver.md
PR 7844 docs/dev/debt/libSceAgcDriver.md
PR 7893 docs/dev/debt/libSceAgcDriver.md
PR 7978 docs/dev/debt/libSceAgcDriver.md
PR 8014 docs/dev/debt/libSceAgcDriver.md
PR 8123 docs/dev/debt/libSceAgcDriver.md
PR 8223 docs/dev/debt/libSceAgcDriver.md
PR 8319 docs/dev/debt/libSceAgcDriver.md
PR 8395 docs/dev/debt/libSceAgcDriver.md
PR 8542 docs/dev/debt/libSceAgcDriver.md
PR 8592 docs/dev/debt/libSceAgcDriver.md
PR 8707 docs/dev/debt/libSceAgcDriver.md
PR 8874 docs/dev/debt/libSceAgcDriver.md
PR 8930 docs/dev/debt/libSceAgcDriver.md
PR 9020 docs/dev/debt/libSceAgcDriver.md
PR 9318 docs/dev/debt/libSceAgcDriver.md
PR 9335 docs/dev/debt/libSceAgcDriver.md
PR 9356 docs/dev/debt/libSceAgcDriver.md
PR 9387 docs/dev/debt/libSceAgcDriver.md
PR 9402 docs/dev/debt/libSceAgcDriver.md
PR 9431 docs/dev/debt/libSceAgcDriver.md
PR 9432 docs/dev/debt/libSceAgcDriver.md
PR 9508 docs/dev/debt/libSceAgcDriver.md
PR 9533 docs/dev/debt/libSceAgcDriver.md
PR 9592 docs/dev/debt/libSceAgcDriver.md
PR 9595 docs/dev/debt/libSceAgcDriver.md
PR 9672 docs/dev/debt/libSceAgcDriver.md
PR 9673 docs/dev/debt/libSceAgcDriver.md
PR 9674 docs/dev/debt/libSceAgcDriver.md
PR 9675 docs/dev/debt/libSceAgcDriver.md
PR 9676 docs/dev/debt/libSceAgcDriver.md
PR 9700 docs/dev/debt/libSceAgcDriver.md
PR 9717 docs/dev/debt/libSceAgcDriver.md
PR 9742 docs/dev/debt/libSceAgcDriver.md
PR 9748 docs/dev/debt/libSceAgcDriver.md
PR 9842 docs/dev/debt/libSceAgcDriver.md
PR 9891 docs/dev/debt/libSceAgcDriver.md
PR 9892 docs/dev/debt/libSceAgcDriver.md
PR 9893 docs/dev/debt/libSceAgcDriver.md
PR 9895 docs/dev/debt/libSceAgcDriver.md
PR 9898 docs/dev/debt/libSceAgcDriver.md
PR 9915 docs/dev/debt/libSceAgcDriver.md
PR 9950 docs/dev/debt/libSceAgcDriver.md
PR 10026 docs/dev/debt/libSceAgcDriver.md
PR 10049 docs/dev/debt/libSceAgcDriver.md
PR 10064 docs/dev/debt/libSceAgcDriver.md
PR 10193 docs/dev/debt/libSceAgcDriver.md
PR 10233 docs/dev/debt/libSceAgcDriver.md
PR 10256 docs/dev/debt/libSceAgcDriver.md
PR 10307 docs/dev/debt/libSceAgcDriver.md
PR 10333 docs/dev/debt/libSceAgcDriver.md
PR 10351 docs/dev/debt/libSceAgcDriver.md
PR 10359 docs/dev/debt/libSceAgcDriver.md
PR 10414 docs/dev/debt/libSceAgcDriver.md
PR 10435 docs/dev/debt/libSceAgcDriver.md
PR 10469 docs/dev/debt/libSceAgcDriver.md
PR 10472 docs/dev/debt/libSceAgcDriver.md
PR 10492 docs/dev/debt/libSceAgcDriver.md
PR 10497 docs/dev/debt/libSceAgcDriver.md
PR 10515 docs/dev/debt/libSceAgcDriver.md
PR 10575 docs/dev/debt/libSceAgcDriver.md
PR 10743 docs/dev/debt/libSceAgcDriver.md
PR 10760 docs/dev/debt/libSceAgcDriver.md
PR 10779 docs/dev/debt/libSceAgcDriver.md
PR 10800 docs/dev/debt/libSceAgcDriver.md
PR 10822 docs/dev/debt/libSceAgcDriver.md
PR 10901 docs/dev/debt/libSceAgcDriver.md
PR 10906 docs/dev/debt/libSceAgcDriver.md
PR 11068 docs/dev/debt/libSceAgcDriver.md
PR 11075 docs/dev/debt/libSceAgcDriver.md
PR 11081 docs/dev/debt/libSceAgcDriver.md
PR 11086 docs/dev/debt/libSceAgcDriver.md
PR 11098 docs/dev/debt/libSceAgcDriver.md
PR 11104 docs/dev/debt/libSceAgcDriver.md
PR 11126 docs/dev/debt/libSceAgcDriver.md
PR 11157 docs/dev/debt/libSceAgcDriver.md
PR 11280 docs/dev/debt/libSceAgcDriver.md
PR 11305 docs/dev/debt/libSceAgcDriver.md
PR 11313 docs/dev/debt/libSceAgcDriver.md
PR 11346 docs/dev/debt/libSceAgcDriver.md
PR 11357 docs/dev/debt/libSceAgcDriver.md
PR 11364 docs/dev/debt/libSceAgcDriver.md
PR 11369 docs/dev/debt/libSceAgcDriver.md
PR 11449 docs/dev/debt/libSceAgcDriver.md
PR 11453 docs/dev/debt/libSceAgcDriver.md
PR 11507 docs/dev/debt/libSceAgcDriver.md
PR 11551 docs/dev/debt/libSceAgcDriver.md
PR 11557 docs/dev/debt/libSceAgcDriver.md
PR 11587 docs/dev/debt/libSceAgcDriver.md

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 15, 2026
@Kikoarl

Kikoarl commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

closing to clear obsolete telemetry and rebase overhead; will revisit once in-engine profiling is ready.

@Kikoarl Kikoarl closed this Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* docs needs rebase Conflicts with main, rebase needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants