Skip to content

fix(agc): keep guest stores over freed storage-image memory - #6960

Draft
romainveurrier wants to merge 1 commit into
boykopovar:mainfrom
romainveurrier:fix/agc-5934-storage-writeback
Draft

romainveurrier wants to merge 1 commit into
boykopovar:mainfrom
romainveurrier:fix/agc-5934-storage-writeback

Conversation

@romainveurrier

@romainveurrier romainveurrier commented Oct 16, 2026 •

Copy link
Copy Markdown

What

SONIC SUPERSTARS crashes in its allocator after respawns: the free-list links at the start of a freed 64 KiB block hold 0x00ffffff00ffffff, the texels of a 32x32 RGBA8 R64KBX storage image at that address (#5934). The image's results stay on the GPU past the label after its dispatch and are stored later, when the title may have freed the block. Two cases lose the title's stores:

  1. Same bytes. Outside the write watch (every Windows host import, see decideImportWatch), a CPU store is found only by comparing with the bytes saved at upload. A free that writes the links the block already held reads as no store, and the results are stored over it. Deterministic.
  2. Decision to store. writeBackLayers chooses the 64 KiB blocks the CPU owns, then stores the others after a GPU round trip (CPU path) or when the recorded copy runs (import path). A CPU store landing in between is overwritten. On the CPU path the bytes the store compares against were also read after the decision.

Changes:

  • GuestMemory::WriteChangedOverOriginal[Committed]: each changed 8-byte word is stored by compare-exchange against the bytes the decision used, now read before the decision. A refused range leaves its layers stale, so they re-upload.
  • StorageTexture::StoreBeforeGuestCompletion, called from WriteLabelOnGpu and for end-of-pipe interrupts without a label: pending results over compared memory are stored in queue order before the label.
  • The recorded GPU-direct store is used only while no label or interrupt has passed since the results became pending; later results take the compare-exchange store.
  • APS5_DEFER_COMPARED_RESULTS=1 and APS5_RECORDED_WRITEBACK=1 restore the previous behaviour of each part, for comparison.

New tests, through AgcDriver::Submit (PM4 dispatch, then a RELEASE_MEM label the test waits for, then CPU stores; no hooks):

  • StorageWriteBackWindowR64Kbx: links stored at random times around a driver read that triggers the write-back, in compared and in watched memory.
  • StorageSameBytesReuseR64Kbx: the block freed with the links it held at upload.

Not addressed:

  • In watched memory an identical-byte store is still lost: unchangedSinceBaseline (dfe147f) stores over a stamped block equal to its baseline, a rule for stamps on unchanged bytes (PPSA12544). APS5_TEST_WATCHED_SAME_BYTES=1 runs that case; it fails before and after this change.
  • Results in compared memory that were never written back before are now stored at every label: a synthetic cost probe (not part of this PR; 8 GPU-only images, a label per frame) measured, in ms per frame for 4 MiB images on main -> this PR: RTX 2050 2.7 -> 18.6 (import) and 2.6 -> 32.3 (CPU path), Iris Xe 4.6 -> 21.4 (import) and 4.5 -> 33.9 (CPU path); for 256 KiB images RTX 2050 0.22 -> 1.29 (import). Watched memory is unaffected. No title measured.
  • Not yet confirmed on the title; the report asks the reporter to test this branch.

Tested

Fedora 44, Release build of main at 4986aca with and without this change, tests only (no title run).

  • StorageWriteBackWindowR64Kbx, links lost of 96 attempts per memory kind: main 4-21 per GPU, path and memory kind; this PR 0 in every case. In watched memory 16–29 attempts per run had the compare-exchange keep a store made after the decision.
  • StorageSameBytesReuseR64Kbx: main 8/8 lost; this PR 0/8.
  • Each with APS5_NO_HOST_IMPORT=1 (CPU path) and with the host import.
  • lavapipe: 0.4 s and 0.2 s.
  • AGC ctest selection, 132 tests (execution tests touching storage images, imports and labels; recorder, driver, graphics, pm4 and flip suites): main 129 passed per GPU, this PR 131. The two new tests account for the difference. The one remaining failure fails on main too: agc_driver_store_over_untracked on the RTX 2050 ("the result did not reach a block the CPU left alone") and agc_driver_sample_multisample_target on the Iris Xe.

Investigation report and logs attached.

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: PPSA06888 SONIC SUPERSTARS (PPSA06888) #5382
  • GPUs tested: NVIDIA GeForce RTX 2050 (driver 615.71.09) and Intel Iris Xe (Mesa), Fedora 44; lavapipe
  • AI-assisted: yes

@github-actions

github-actions Bot commented Oct 16, 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 862 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 1368 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 1395 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 2434 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4040 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4072 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4448 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 4472 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4847 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5021 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5431 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5441 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5499 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5609 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 5925 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6108 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6146 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6169 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6185 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6186 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6187 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6188 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6192 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6197 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6202 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6209 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6218 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6249 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6273 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6280 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6290 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6292 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6481 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6501 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketMemory.cpp
PR 6539 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6615 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6639 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6682 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6718 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6782 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6788 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6801 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6804 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6820 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6848 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6868 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6887 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6921 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6926 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6946 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6947 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6948 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6965 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6971 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6973 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6977 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6987 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6989 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6995 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7002 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7048 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7085 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7201 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7233 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7256 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7275 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7292 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7307 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7310 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7369 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7371 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7449 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
PR 7464 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7484 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7505 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 7514 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7604 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7618 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7622 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7642 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7643 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7647 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7799 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7800 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7827 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7888 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7920 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7922 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7963 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketMemory.cpp
PR 7978 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketMemory.cpp
PR 7981 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 7984 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8004 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8014 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8105 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8115 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8126 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8139 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 8180 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8212 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8246 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8261 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8267 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8278 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8336 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8380 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8432 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8484 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8489 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8612 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8642 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8658 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8707 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8735 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8740 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 8807 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8847 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8858 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8887 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8908 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8911 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8930 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 8932 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8968 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8998 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8999 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9026 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 9122 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp

@github-actions github-actions Bot added the agc libSceAgc* label Oct 16, 2026
@romainveurrier

Copy link
Copy Markdown
Author

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
Pull request Conflicting files (lines on main) Same exports Same new files
PR 6108 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp L351
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp L2056
PR 6197 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp L4682-4683
PR 6367 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp L4863-4865
PR 6820 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp L4863-4865
PR 6914 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp L89

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 1368 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 1395 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 1896 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 4040 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4048 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4072 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4448 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 4472 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4650 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4891 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5021 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5390 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 5431 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5441 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5480 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 5499 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5609 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 5761 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 5925 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5987 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6177 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6188 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6222 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6259 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6503 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6539 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6553 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6718 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp

Overlap check:

This PR is a draft until the #5934 reporter tests it in-game, so the others can go first; I'll rebase. Depends on: none.

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

The bug is real and the two tests show it (main loses 4-21 of 96 stores, this PR 0). The cost is the problem, and the PR already measures it.

"Results in compared memory that were never written back before are now stored at every label": 2.7 to 18.6 ms per frame (RTX 2050, import path) and 2.6 to 32.3 ms (CPU path) for 4 MiB images, 4.6 to 21.4 / 4.5 to 33.9 ms on the Iris Xe, 0.22 to 1.29 ms for 256 KiB images. That is a GPU-to-CPU round trip of every pending storage image at every label, on by default, for every title on every Windows host import. A title that writes a few large GPU-only render targets and has a label per frame goes from 60 fps to about 30 for this fix alone. "No title measured" does not make that acceptable, and storing at every label is the wrong approach: the SONIC SUPERSTARS case is a 32x32 RGBA8 image in a 64 KiB block, and the large images never needed this.

What I would do instead:

  • Bound the label store to the surfaces the existing small-store rule covers (StorageTexture::SmallStoreBytes, 64 KiB), which is the class that shares a block with something a title allocates over. Large render targets stay on the current path.
  • Or gate the new store on the image's results having been read back before (the image is known to be CPU-visible), so GPU-only targets are never touched.
  • Whichever is chosen, the per-frame cost on a title with several large GPU-only targets and a label per frame belongs in the test, as a bound, not in the description as a known limit.

Please also post the cost on the title this was found on (SONIC SUPERSTARS), with the summary lines of main and this PR from the same scene, no APS5_PROFILE_*. The report asks the reporter to test the branch; until they have, the PR can't show that the crash is gone or what it costs.

#6948 stores linear storage images after every dispatch for a similar reason and touches the same write-back path; the two should be reconciled so that a label does not store the same image twice.

@keravyn-ops

Copy link
Copy Markdown
Contributor

AMD / Windows run of this PR at 36df663: Radeon 780M (RDNA 3, 0x15bf), AMD driver 25.10.20.01 (32.0.21020.1007), Windows 11 Home 10.0.26100, WinLibs GCC 15.2.0 r7, Release.

  • agc_driver_storage_same_bytes_reuse_r64_kbx: pass (0.39 s)
  • agc_driver_storage_write_back_window_r64_kbx: pass (0.56 s)

AI-assisted: yes (runs made on the device above).

@hugodearaujo

hugodearaujo commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Data point from Linux, AMD Radeon RX 9070 XT, RADV (Mesa 26.2.5): EA SPORTS FC 25 (PPSA20049), main e5f18ea with #6343, #7606 and #7413.

  • Without this PR, 3 runs. One crashed in the title's own allocator 280 s after start with the signature of SONIC SUPERSTARS (PPSA06888): guest heap metadata overwritten with texel data after respawns #5934: the memory around the chunk it was splitting (0x10f4ae7e00–0x10f4ae8800) held the repeated texel 0xff1b181c where its heap headers should be, and that memory lies inside a 1920x1080 RGBA8 storage image created earlier at 0x10f4800000. Another reached Kick Off but sat on its tunnel scene with no menu and did not react to input. The third lost the GPU under gdb before that.
  • With this PR's head 36df663 merged on top, 2 runs. Both reached Kick Off's menus; one went on through team and kit selection to the pre-match cutscene, where it lost the GPU (VK_ERROR_DEVICE_LOST, amdgpu ring gfx_0.0.0 timeout). That also happened once without this PR, so I'm treating it as a separate issue.

Few runs, so this is a hint, not proof.

@MarcZX10

Copy link
Copy Markdown
Contributor

I am investigating issue #8152, where a CPU write to the right half of a resident linear target shares 64 KiB blocks with a recorded draw to the left. I added a local regression variant that seeds the left half, draws only there, writes 0x42 to the right half, and checks that both results survive. It compiles, but this host's CPU guard prevents the AGC test from running.

Does #6960's GPU-direct imported write-back path cover that partial-draw case? The current-main block selection can retain a whole touched block, preserving the CPU bytes while dropping GPU output elsewhere in that block. I want to coordinate this with your write-back changes before opening a related PR.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* needs rebase Conflicts with main, rebase needed unblocks title Names a title ID on the Unblocks line

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants