Skip to content

perf(agc): take a storage image's generation baseline only when its guest bytes are settled - #2791

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
alfalfa-star:perf/agc-storage-baseline-settled
Oct 10, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
alfalfa-star:perf/agc-storage-baseline-settled

Conversation

@alfalfa-star

@alfalfa-star alfalfa-star commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

What

#1599 keeps a baseline of a storage image's guest bytes (images up to 1 MiB) when its layers get their generation, so a write-back can store the GPU results over CPU-stamped blocks whose bytes didn't change. The upload takes it with GuestMemory::ReadCommitted, also on the host-import path, where the upload itself runs on the GPU.

That read goes through the flush hook. When a unit shadow, another image's pending results or a recorded GPU store covers the surface, the hook publishes the shadow and the worker waits for the GPU on every such upload. Stack from PPSA14632, sampled at those waits: Driver::dispatch → ShaderResources::buildComplete / Revalidate → lookupStorageTexture → StorageTexture::Refresh → upload → (generation stamp) → ReadCommitted → FlushForAccess.

The baseline is now taken only when nothing of that kind overlaps the surface (StorageTexture::guestBytesSettled: AnyShadowedOverlaps, AnyPendingOverlaps, Recorder::PendingWriteOverlaps). Otherwise the image has no baseline, and its write-back keeps the CPU's bytes for stamped blocks, the rule before #1599. The TechnicalDebt entry from #1599 now names the condition.

New ctest agc_storage_baseline_settled (agc_driver_recorder_tests --settled-baseline-only): it creates a storage image over a watched host import while a recorded store is pending over part of it, and checks that the upload did not submit the open batch. Without this change it fails ("an upload over a pending recorded store submitted the open batch to read its generation baseline"). agc_unchanged_cpu_stamps (#1599) still passes, so settled surfaces keep the baseline.

Tested

Linux (Arch), RX 9070 XT, RADV, Release:

flush-hook recorded-store syncs waited queue 0 direct dispatch, device call
without ~3,400 ~4.0 s 356 us
with this PR ~630 ~0.3 s 107 us

On its own this barely moves presents (~100 → ~104 per 10 s): the GPU wait moves to DMA_DATA copies, which #2792 addresses.

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 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

🤖 Generated with Claude Code

…uest bytes are settled

An upload of a storage image up to 1 MiB reads the surface's guest bytes
into a baseline (boykopovar#1599), which a later write-back compares against for
blocks the CPU stamped. When a unit shadow, another image's pending
results or a recorded GPU store covers the surface, that read goes
through the flush hook: the shadow is published and the worker waits for
the GPU, although the upload itself runs on the GPU from the import.

The baseline is now taken only when nothing of that kind overlaps the
surface. Otherwise the image has none, and its write-back keeps the CPU's
bytes for stamped blocks, the rule before boykopovar#1599. TechnicalDebt's entry
names the condition.

agc_storage_baseline_settled creates a storage image over a watched host
import with a recorded store pending over part of it and checks that the
upload did not submit the open batch; without the change the baseline
read syncs on that store. agc_unchanged_cpu_stamps (boykopovar#1599) still passes.

PPSA14632 (LEGO Horizon Adventures) refreshes such images about 870
times per 10 s from queue 0 dispatches: the hook's recorded-store syncs
go from about 3400 waiting 4.0 s to about 630 waiting 0.3 s per 10 s,
and a direct dispatch's device call from 356 to 107 us.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@popcoder565

Copy link
Copy Markdown
Contributor

Native Windows run, since no Windows results were posted. Setup: Windows 10 (19045), RTX 3060 Laptop (NVIDIA 616.92), MinGW-w64 GCC 15.2.0 (WinLibs r7), Release. Head 75b540c2, merged onto main 57f96fd in one build with 4 other new PRs.

  • agc_driver_recorder_tests (not in ctest), which holds this PR's test change, passes 10 of 10, built explicitly.
  • Full ctest in that build: 711 of 711.

No title was run.

🤖 Addressed by Claude Code

@orbz22

orbz22 commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

Checked on Windows with Hollow Knight: Silksong (PPSA12544), the title whose boxed menu letters #1599 fixed.

Setup: Windows 11 Pro (26300), i7-11800H, RTX 3060 Laptop (driver 617.42), WinLibs GCC 15.2.0 r7, Release. main de5e541 + #846 (for the plugins), with and without this PR. Each run used the same scripted input for 250 s (title menu, profile select, New Game, the opening, into Moss Grotto) with APS5_PROFILE_DRAW=1.

🤖 Generated with Claude Code

MichalSy added a commit to MichalSy/AnyPS5 that referenced this pull request Oct 10, 2026
Adapt upstream PRs boykopovar#1315, boykopovar#2791 and boykopovar#2792 to the current descriptor ABI and synchronization paths. Bound immutable binding plans to 1024 entries while retaining live resource addresses and specialization identity.

Keep real CPU writebacks and fault completion active. Capture generation baselines only over settled guest bytes. Add focused cache, texture baseline and copy synchronization regressions.
@oneandonlydean
oneandonlydean merged commit 9206c3e into boykopovar:main Oct 10, 2026
16 checks passed
@alfalfa-star
alfalfa-star deleted the perf/agc-storage-baseline-settled branch October 11, 2026 09:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants