Skip to content

feat(agc): reuse a native multisample colour target and honour guest HTILE clears - #6808

Open
KingDarkHN wants to merge 5 commits into
boykopovar:mainfrom
KingDarkHN:fix/agc-native-multisample-depth-reuse
Open

KingDarkHN wants to merge 5 commits into
boykopovar:mainfrom
KingDarkHN:fix/agc-native-multisample-depth-reuse

Conversation

@KingDarkHN

@KingDarkHN KingDarkHN commented Oct 16, 2026 •

Copy link
Copy Markdown

What

Sonic Superstars (PPSA06888) reaches the menu, but as soon as a level starts the emulator aborts
because it renders into a native multisampled colour target and then reuses that guest memory
for something else while the driver still guards it as a resident target (issue #5933). This branch
builds on #6297 and #6300 (its first three commits) and adds:

  • Drop a reused multisampled colour guard in RequireNoMultisampleTarget instead of throwing, via
    the new retireGuardForAddress (issue AGC: multisampled targets whose memory a title reuses throw on the next access (SONIC SUPERSTARS PPSA06888) #5933).
  • Honour a guest HTILE fast clear the driver has no producer note for when the whole HTILE proves
    the surface's clear value and neither the depth nor the stencil plane changed.
  • Retire a depth surface only over the bytes its plane actually stores. The tiled footprint rounds
    the plane up to whole 128x128 blocks, so a neighbouring allocation could land in the padding and
    wrongly retire a surface it never reused.
  • Accept a stencil plane whose clear state is in the raw plane when HTILE stencil metadata is
    disabled (TILE_STENCIL_DISABLE), and accept a clear-proven HTILE without ITERATE_256 or pipe
    alignment.

A guest read over a resident native multisample depth guard is not retired: it keeps
refusing (sample-preserving guest publication of native multisample depth is not implemented),
matching the contract of #6727 for an unwritten surface, until sample-preserving publication of the
depth, stencil and HTILE planes to guest memory exists. The read-site classification, whole-fill
HTILE note and exact-plane overlap work are intended to be rebased onto #6727 once it lands;
written-owner publication will be a separate change with its own regression. With this branch Sonic
Superstars aborts on a register read over a written depth owner — the documented follow-up.

Tested

  • OS: Omarchy (Arch Linux), kernel 7.2.3.
  • GPU: NVIDIA GeForce RTX 5060 Ti, driver 610.57.04.
  • Homebrew: n/a.
  • Tests: agc_driver_native_multisample_depth (a metadata-only HTILE write with no producer note
    must be served as a fast clear; a reuse read over a resident depth guard must refuse and leave the
    owner resident), agc_driver_depth_fast_clear, agc_driver_depth_fast_clear_submit,
    agc_driver_depth_surface_last_writer and agc_driver_depth_storage_reuse pass. Full
    ctest -R agc_driver is at 98% with the same pre-existing failures as the base commit; none are
    introduced (worker_failure_log also fails identically with this branch stashed).

Checklist

…HTILE fills

A 2, 4 or 8 sample D32_SFLOAT_S8_UINT target with its stencil in HTILE is
imported natively when every HTILE word proves both planes cleared: the
depth range as before, and SMem 0 for the stencil. The stencil plane joins
the watched, guarded and generation-checked ranges. A depth-only HTILE,
an unaligned stencil plane, or a word failing either proof is refused with
its own reason.

A fill covering the whole HTILE of a sampled native target is a clear
transition, proven at the next sample like the HTILE mask clear: complete
tracked stores since the fill, no CPU or queued writes, and every word
proving the depth and, with a stencil plane, the stencil clear value. A
partial fill and an HTILE mask clear of a stencil target stay refused.
…attern

A whole HTILE fill recorded on the GPU is still pending when the title
binds or samples the depth in the same frame, so the HTILE words in guest
memory are not the fill's yet and the queued write was refused as an
external GPU write. The fill's write note is kept with its pattern: while
it is still the newest queued write over the HTILE, the clear is proven
from the pattern, and the completed tracked store check is not needed for
a GPU fill. A later queued write, a CPU write or a pattern that does not
prove the clear is refused as before.

AI-assisted: yes
@KingDarkHN
KingDarkHN force-pushed the fix/agc-native-multisample-depth-reuse branch from 28a9399 to ca565ed Compare October 16, 2026 12:59
@MarcZX10

Copy link
Copy Markdown
Contributor

I compared this head with open #6727 because both replace RequireNoResidentDepthRead in DepthSurface.cpp. #6727 tracks host writes (NoteDepthSurfaceWrite, CopyAspectFrom, store-back) and only retires a guard on a guest read when hostWritten is false. In this PR’s replacement, a guest reuse read retires the owner when attachmentActive is false, but I don’t see an equivalent hostWritten check. Those conditions can differ for a native depth surface that was written by the host and is no longer the current attachment. Could you coordinate with #6727 and preserve that refusal (or explain why this reuse path proves the guest memory is current), with a regression covering a host-written inactive owner? The two heads touch the same guard/lifecycle code, so they should be reviewed together before either merges.

@MarcZX10 MarcZX10 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 updated head still has this correctness gap at RequireNoResidentDepthRead_nid_no_patch: once an overlapping guard is inactive as an attachment, it retires the owning surface without checking whether the host image contains writes that have not been published to guest memory. retire() only marks the owner inactive and erases the guards; it does not copy the host depth/HTILE contents back. An inactive owner can therefore still have newer host data, so a guest read after reuse can observe stale bytes. The related open #6727 tracks hostWritten and refuses this transition for a written owner. Please preserve the same refusal (or provide a path that publishes the written data first), and add a regression that writes the depth target on the host, makes it inactive, then attempts the guest reuse read.

@KingDarkHN

Copy link
Copy Markdown
Author

You're right about the underlying gap: retire() drops the owner without copying the host depth/stencil/HTILE image back, so a guest read that means to observe the rendered samples can see stale bytes. I tried your suggestion before replying.

I added the same hostWritten notion #6727 uses — set from draws with depth writes or stencil writes on both the plain and cached-recipe draw paths, from CopyAspectFrom, and from storage write-back, with host clears after a proven guest HTILE clear not counted — and made the overlapping owner refuse. The suite stays green, but the title then aborts on a real reuse site:

[gpu] driver failure: sample-preserving guest publication of native multisample depth is not implemented (read site=registers 0x237e06380+0x10 overlaps protected depth 0x237410000+0x10e0000 for depth 0x237410000 samples=2 attachmentActive=0 hostWritten=1)
terminate called after throwing an instance of 'std::runtime_error'

So the strict refusal can't ship on top of this head without sample-preserving publication, which is not implemented for native multisample depth (the sampling debt entry already says so). I also tried letting the retirement through only once the guest has overwritten the owner's memory, the memoryOverwritten predicate the create-time path already uses; the title still aborts, because a 17 MB owner range is not fully write-watched, so WrittenSince reports no reuse even when the guest has repurposed the memory.

What this PR does instead is bounded and explicit: it retires only when the surface is not the current attachment and the read is a reuse read (context-register, texture or vertex-buffer). It is a compatibility workaround for SONIC SUPERSTARS (PPSA06888), not a correct general fix, so I have recorded the gap as a debt entry in docs/dev/debt/libSceAgcDriver.md rather than leaving it implicit. That is also why I did not add the regression you asked for: it would pin the refusal that aborts the title.

On coordination: #6727 and this head both rewrite RequireNoResidentDepthRead_nid_no_patch and touch the same guard lifecycle, so they cannot both land as they are. I am happy to rebase on #6727 once it is in and keep only the parts that don't overlap — the read-site classification, the whole-fill HTILE note and the Overlaps used-size fix — and to split publication of a written native multisample depth owner into its own task.

Would you rather I gate the retirement further in the meantime, or land the debt-documented workaround and follow up with publication?

@MarcZX10

Copy link
Copy Markdown
Contributor

Thanks for adding the host-write tracking and documenting the limitation. I would not merge the current compatibility retirement as a general fix: it can discard newer host depth/stencil/HTILE data, and #6727’s contract is explicitly to refuse that state until sample-preserving publication exists. The measured title failure makes this a real follow-up, but it does not make the guest bytes safe to expose. Please rebase the read-site classification, whole-fill HTILE note and exact-plane overlap work onto #6727 after it lands, and keep written-owner publication as a separate change with its own regression. If you want to pursue the bounded workaround independently, please first provide evidence that the guest read is a reuse/alias event whose contents are intentionally replacing the old surface; the current “not attached” condition alone does not establish that. I’ll keep the changes-requested review in place until the unsafe retirement is removed or a publication path is added.

@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 1368 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
PR 1395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 1896 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 2434 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 4040 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 4448 docs/dev/debt/libSceAgcDriver.md
PR 4449 docs/dev/debt/libSceAgcDriver.md
PR 5021 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5058 docs/dev/debt/libSceAgcDriver.md
PR 5371 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5372 docs/dev/debt/libSceAgcDriver.md
PR 5426 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5431 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5441 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 5925 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6044 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6146 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6169 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6182 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6185 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6186 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6187 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6192 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6194 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6209 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6218 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6223 docs/dev/debt/libSceAgcDriver.md
PR 6235 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6249 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6273 docs/dev/debt/libSceAgcDriver.md
PR 6280 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6292 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
PR 6412 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6481 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6498 core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6501 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6548 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6549 docs/dev/debt/libSceAgcDriver.md
PR 6612 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6615 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
PR 6628 core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp
PR 6642 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6741 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6743 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6747 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6788 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6804 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6820 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6867 docs/dev/debt/libSceAgcDriver.md
PR 6868 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6905 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6921 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6926 docs/dev/debt/libSceAgcDriver.md
PR 6959 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6970 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6971 core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
PR 6973 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6977 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6987 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6989 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6995 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7002 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7048 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7085 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7201 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
PR 7223 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7243 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7256 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7275 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7307 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7310 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7410 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7446 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7449 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7457 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7464 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7504 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
PR 7505 docs/dev/debt/libSceAgcDriver.md
PR 7508 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7514 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7535 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7604 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7618 docs/dev/debt/libSceAgcDriver.md
PR 7642 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7644 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7647 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7659 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7668 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7677 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7705 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
PR 7717 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7800 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7803 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7817 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7833 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7844 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7886 core/libs/prx/libSceAgcDriver/tests/execution/NativeMultisampleDepth.cpp
PR 7893 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7910 docs/dev/debt/libSceAgcDriver.md
PR 7978 docs/dev/debt/libSceAgcDriver.md
PR 8014 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8070 docs/dev/debt/libSceAgcDriver.md
PR 8089 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8104 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8105 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/libs/prx/libSceAgcDriver/tests/execution/NativeMultisampleDepth.cpp
PR 8109 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
PR 8121 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 8123 core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
docs/dev/debt/libSceAgcDriver.md
PR 8139 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8145 docs/dev/debt/libSceAgcDriver.md
PR 8160 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8161 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8180 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8212 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 8213 docs/dev/debt/libSceAgcDriver.md
PR 8223 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp
docs/dev/debt/libSceAgcDriver.md
PR 8246 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 8261 docs/dev/debt/libSceAgcDriver.md
PR 8281 docs/dev/debt/libSceAgcDriver.md
PR 8283 core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 8319 docs/dev/debt/libSceAgcDriver.md
PR 8336 docs/dev/debt/libSceAgcDriver.md
PR 8365 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8372 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8395 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 8401 docs/dev/debt/libSceAgcDriver.md
PR 8412 docs/dev/debt/libSceAgcDriver.md
PR 8419 docs/dev/debt/libSceAgcDriver.md
PR 8420 docs/dev/debt/libSceAgcDriver.md
PR 8423 docs/dev/debt/libSceAgcDriver.md
PR 8424 docs/dev/debt/libSceAgcDriver.md
PR 8426 docs/dev/debt/libSceAgcDriver.md
PR 8484 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8527 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8542 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8552 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8563 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 8564 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 8592 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8608 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 8639 docs/dev/debt/libSceAgcDriver.md
PR 8658 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/libs/prx/libSceAgcDriver/tests/execution/NativeMultisampleDepth.cpp
PR 8672 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8707 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8740 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8874 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 8887 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8939 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8998 core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
PR 8999 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9007 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9013 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9017 docs/dev/debt/libSceAgcDriver.md
PR 9020 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9022 docs/dev/debt/libSceAgcDriver.md
PR 9050 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9068 docs/dev/debt/libSceAgcDriver.md
PR 9077 docs/dev/debt/libSceAgcDriver.md
PR 9098 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9159 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9176 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9185 docs/dev/debt/libSceAgcDriver.md
PR 9186 core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9193 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9243 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9248 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9260 core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
PR 9275 docs/dev/debt/libSceAgcDriver.md
PR 9287 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9289 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9305 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9317 docs/dev/debt/libSceAgcDriver.md
PR 9318 docs/dev/debt/libSceAgcDriver.md
PR 9335 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9348 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9352 docs/dev/debt/libSceAgcDriver.md
PR 9356 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9361 docs/dev/debt/libSceAgcDriver.md
PR 9387 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9393 docs/dev/debt/libSceAgcDriver.md
PR 9396 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9401 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9402 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9406 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9412 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9424 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9431 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9432 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9436 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9443 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9445 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9450 core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9457 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9489 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9495 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9508 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9514 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9521 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9533 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
core/libs/prx/libSceAgcDriver/tests/execution/NativeMultisampleDepth.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9564 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9565 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9592 docs/dev/debt/libSceAgcDriver.md
PR 9597 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9604 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9626 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9633 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9652 docs/dev/debt/libSceAgcDriver.md
PR 9670 docs/dev/debt/libSceAgcDriver.md
PR 9671 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9672 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9673 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9674 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9675 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9676 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9685 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9694 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9696 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9700 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9702 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9703 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9712 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9717 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
core/libs/prx/libSceAgcDriver/tests/execution/NativeMultisampleDepth.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9721 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9723 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9737 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9742 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
core/libs/prx/libSceAgcDriver/tests/execution/NativeMultisampleDepth.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9748 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9749 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9779 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9789 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9790 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9807 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
PR 9836 docs/dev/debt/libSceAgcDriver.md
PR 9842 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9849 core/libs/prx/libSceAgcDriver/tests/execution/NativeMultisampleDepth.cpp
PR 9852 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9856 docs/dev/debt/libSceAgcDriver.md
PR 9875 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9879 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9884 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9890 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9891 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9892 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9893 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9895 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9897 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9898 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9899 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9904 docs/dev/debt/libSceAgcDriver.md
PR 9905 docs/dev/debt/libSceAgcDriver.md
PR 9906 docs/dev/debt/libSceAgcDriver.md
PR 9907 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9913 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9915 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9940 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9941 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9950 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
core/libs/prx/libSceAgcDriver/tests/execution/NativeMultisampleDepth.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9961 docs/dev/debt/libSceAgcDriver.md
PR 9969 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9978 core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp
PR 9988 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9989 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10000 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10026 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 10043 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10044 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 10046 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 10049 core/libs/prx/libSceAgcDriver/Graphics/src/MultisampleTarget.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 10050 core/libs/prx/libSceAgcDriver/tests/execution/NativeMultisampleDepth.cpp
PR 10062 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 10064 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 10066 docs/dev/debt/libSceAgcDriver.md

…HTILE clears

Guest titles (e.g. Sonic Superstars) render into a native multisampled colour
target and then reuse that guest memory for something else while the driver
still guards it as a resident target; every such access aborted and closed the
title as soon as a level began. Drop a reused multisampled colour guard
instead of throwing (issue boykopovar#5933).

Supporting fixes that fall out of the same depth paths:

- Honour a guest HTILE fast clear the driver has no producer note for when the
  whole HTILE proves the surface's clear value and neither the depth nor the
  stencil plane changed, instead of aborting.
- Retire a depth surface only over the bytes its plane actually stores. The
  tiled footprint rounds the plane up to whole 128x128 blocks, so a
  neighbouring allocation could land in the padding and wrongly retire a
  surface it never reused.
- Accept a stencil plane whose clear state is in the raw plane when HTILE
  stencil metadata is disabled, and accept a clear-proven HTILE without
  ITERATE_256 or pipe alignment.

A guest read over a resident native multisample depth guard is not retired: it
keeps refusing ("sample-preserving guest publication of native multisample
depth is not implemented"), matching the contract of boykopovar#6727 for an unwritten
surface, until sample-preserving publication of the depth, stencil and HTILE
planes to guest memory exists. The read-site classification, whole-fill HTILE
note and exact-plane overlap work are intended to be rebased onto boykopovar#6727 once it
lands.

Tests: agc_driver_native_multisample_depth, agc_driver_depth_fast_clear and
agc_driver_depth_surface_last_writer exercise the new paths; the full
agc_driver suite stays at its pre-existing pass rate.
A guest read over the guard of a resident native multisample depth surface
refuses instead of retiring the owner, so a title that reuses written depth
memory sees stale bytes or aborts. SONIC SUPERSTARS (PPSA06888) aborts on a
register read over a written owner (measured on an RTX 5060 Ti, driver
610.57.04); publishing the samples to guest memory is the follow-up, with its
own regression. Record the gap next to the sampling debt entry.
@KingDarkHN
KingDarkHN force-pushed the fix/agc-native-multisample-depth-reuse branch from 1e8b273 to 734edb5 Compare October 16, 2026 13:55
@KingDarkHN KingDarkHN changed the title feat(agc): reuse native multisample depth by retiring its stale owners feat(agc): reuse a native multisample colour target and honour guest HTILE clears Oct 16, 2026
@KingDarkHN

Copy link
Copy Markdown
Author

Thanks for the careful review — I agree, and I've followed it. Exposing guest bytes for a written
owner is not safe, and #6727's contract is the right one until publication exists.

I've removed the unsafe retirement. A guest read over the guard of a resident native multisample
depth surface now refuses again (sample-preserving guest publication of native multisample depth is not implemented); it no longer retires the owner, so no host depth, stencil or HTILE data is
discarded on a read. RequireNoResidentDepthRead is back to a plain overlap refusal, the read-site
classification is no longer wired into a retirement path, and the hostWritten/read-site machinery
is gone.

What the branch keeps:

I updated the debt entry (docs/dev/debt/libSceAgcDriver.md): a written owner is refused, SONIC
SUPERSTARS (PPSA06888) aborts on a register read over one (measured on an RTX 5060 Ti, driver
610.57.04), and publishing the samples is the follow-up.

Plan, as you suggest:

Branch updated (head 734edb5c2); title and description reflect the narrower scope. Full
agc_driver suite at its pre-existing pass rate, and agc_driver_native_multisample_depth passes
(the reuse-read cases now assert a refusal that leaves the owner resident).

@billythemenace2

billythemenace2 commented Oct 16, 2026 •

Copy link
Copy Markdown

A Windows data point for this branch: SONIC SUPERSTARS (PPSA06888) on 734edb5c2 merged onto main 452494439. Windows 11, MinGW-w64 GCC 15, Release, AMD Radeon RX 5700 XT (driver 32.0.21045.5002). No input, no environment variables.

It now stops a few seconds after start, during the logo screens, at the depth refusal you describe:

AGC driver: SET_CONTEXT_REG_INDIRECT at DWORD 5: AGC graphics: sample-preserving guest publication of native multisample depth is not implemented

So it matches your Linux run on the RTX 5060 Ti. The native multisample stencil import requires HTILE stencil metadata stop from #6300 (eight 1920x1080 2-sample D32S8 targets with htileStencil=0, htileDepthOnly=1) did not appear before this stop. I can't tell from this run whether those targets were reached, so I'm not counting it as confirmed.

I can rerun it on this machine when the depth publication follow-up is up.

AI-assisted (Claude Code).

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

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

Source review of exact head 734edb5 while checking overlap with native color publication work. The previous depth correction is acknowledged; the remaining color retirement has the two findings below. I did not build or run this PR or its title. AI-assisted: Codex; author responsible.

for (const auto& range : guarded()) {
if (address >= range.address + range.bytes || range.address >= address + bytes) continue;
lock.unlock();
retireGuardForAddress(address, bytes);

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.

[P1] Preserve written color data before retiring its guard

This executes for every overlapping color guard. retireGuardForAddress marks the resident inactive and erases its guard without checking whether the host image has unpublished writes or copying its samples back. RequireNoMultisampleTarget then returns, allowing a guest reader to consume the old bytes. A read classified as reuse does not prove those bytes replace the rendered content; this function does not even classify the access. The same ownership concern that prompted the depth correction still applies to color. The drawn-color/guest-buffer counterexample in #6480 documents the stale-byte hazard, although I have not run that fixture against this PR. Please preserve the refusal until replacement is established or samples are published, and add a written-color/read regression.

char text[256];
std::snprintf(text, sizeof(text), "AGC graphics: %s of 0x%llx+0x%zx overlaps multisampled color target 0x%llx+0x%llx (%u samples), whose samples are only on the host: guest access to it is not implemented", access, static_cast<unsigned long long>(address), bytes, static_cast<unsigned long long>(range.address), static_cast<unsigned long long>(range.bytes), range.samples);
throw std::runtime_error(text);
std::snprintf(text, sizeof(text), "[gpu] %s of 0x%llx+0x%zx retired guard for reused multisampled color target 0x%llx+0x%llx (%u samples)", access, static_cast<unsigned long long>(address), bytes, static_cast<unsigned long long>(range.address), static_cast<unsigned long long>(range.bytes), range.samples);

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.

[P2] Copy the guard before unlocking and erasing it

range is a reference to an element of guarded(). After the shared lock is released, another writer can invalidate it; retireGuardForAddress then calls std::erase_if on that same vector and removes the overlapping entry. Reading range.address, range.bytes and range.samples afterward therefore uses an invalidated reference. Copy the needed fields while the shared lock is still held and use that copy for the diagnostic. This remains necessary if the retirement semantics are corrected separately.

@Amoenus

Amoenus commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

@KingDarkHN Updated in place: the qualified sample-preserving stack is #6973 → #6987 → #6989 → #6995 → #7002 0cdc81ae9f, retaining exact credited #6498 e15c428b4d ancestry.

#7002 has 99 focused passes (87 actual NVIDIA/AMD GPU, 12 CPU), full Windows builds, and the same nine AMD DCC assertion failures as literal main 1e774a3b22; zero VUIDs/validation errors/warnings. All writable bindings are checked before read-only publication. Historical dependency/reversed-order controls retain their original pins, without a new rerun claim. Current scope and stack evidence are maintained in #6480 and #7002.

This is our adapted composition, not validation of unchanged #6808 or SONIC SUPERSTARS. For PPSA06888 reuse in #5933, format, tile/sample count, DCC/CMASK state and the next consumer still matter; I have not tested that title. #7260 retains Sonic's ordinary-run boundary and historical gameplay; no new title/FPS claim. AI-assisted: Codex; author responsible.

@MarcZX10

Copy link
Copy Markdown
Contributor

I checked the linked #5933 report for the format/reuse details. It records a 4x, 64 KiB native target overlapping a 512x512 texture view (format 173, tile mode 2, 10 mips, size 0x56000); the view starts 0x51000 before the target. The report also has separate storage-image and CPU-read overlaps. It does not record DCC/CMASK state or establish whether the aliased texture is meant to consume the old rendered samples versus data written after reuse, so I cannot say the #7002 buffer-publication path applies. Its stated scope is read-only shader-buffer consumers; this #5933 example is a texture read and needs its own publication evidence/coverage.

@hugodearaujo

Copy link
Copy Markdown
Contributor

Another title that stops on this refusal: Assassin's Creed Mirage (PPSA13960, 01.007.000), on main with #6343, #7532 and #7533:

AGC graphics: a storage image access of 0x10e0720000+0x870000 overlaps multisampled color target 0x10e0720000+0x870000 (4 samples), whose samples are only on the host: guest access to it is not implemented

With a local change equivalent to this PR's RequireNoMultisampleTarget (retire the guard instead of throwing), it passes that point and runs about two more minutes through its start-up screens, then stops at an unrelated guest memory is not readable error. Unlike Sonic Superstars, Mirage does not reuse the memory later: every frame it renders two 960x540 4x MSAA targets (R11G11B10F and R16F) and then accesses the same memory as 1920x1080 single-sample images (a compute storage write in SW_64KB_S and a texture read). With the guard retired, those views do not see the samples drawn on the host.

@github-actions github-actions Bot added the unblocks title Names a title ID on the Unblocks line label Oct 18, 2026
@oneandonlydean oneandonlydean self-assigned this Oct 20, 2026
@oneandonlydean

Copy link
Copy Markdown
Collaborator

Thanks. This branch is far behind main and conflicts in DepthSurface.cpp, MultisampleTarget.cpp, both multisample execution tests and the debt file. main has since changed the same paths (retired multisample colour targets are reclaimed, HTILE clears of later slices, the ITERATE_256 depth import). Could you rebase onto current main? It would also help to say how this relates to the sample-preserving stack in #6973 to #7002, which covers part of the same ground, so it's clear which parts are still needed here.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

@KingDarkHN a follow-up to my rebase ask: we're going to take the native multisample colour work forward through Amoenus's stack (#6973 → #6987 → #6989 → #6995 → #7002), which adapts this approach and is kept up to date with main.

Two questions, so nothing in this PR gets lost:

  1. Is there anything in the colour-target part of this PR that the stack doesn't cover? If so, could you point to it (a file and function is enough), and we'll make sure it's carried over.
  2. The guest HTILE clear / depth half is a separate change from the colour reuse, and it overlaps work in progress on HTILE depth clears (fix(agc): separate possible writes from complete coverage #7233). Would you be willing to split it into its own PR, rebased onto current main? On its own it's much easier to review and test.

Thanks for the original work. The stack builds on it.

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* build docs 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.

7 participants