Skip to content

fix(agc): accept a CB metadata pass beside depth state without depth or stencil planes - #4076

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
Nesyth:fix/agc-cb-metadata-pass-without-depth-planes
Oct 12, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
Nesyth:fix/agc-cb-metadata-pass-without-depth-planes

Conversation

@Nesyth

@Nesyth Nesyth commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

What

DecodeColorMetadataPass refuses a CB fast-clear eliminate or DCC decompress pass while DB_DEPTH_CONTROL or DB_RENDER_CONTROL enables depth or stencil work ("CB metadata pass with depth or stencil work"). Vampire Survivors (PPSA21703) runs a DCC decompress pass on its results screen with DB_DEPTH_CONTROL = 0x700763 left over from earlier draws, while DB_Z_INFO and DB_STENCIL_INFO both have format 0. No depth or stencil plane is bound, so the pass does no depth or stencil work, but the driver threw and the title aborted when the player pressed "Done".

The pass is now accepted when no depth or stencil plane is bound (depthPlanesAbsent) and still refused when one is. Without a plane the pass does not read DB_DEPTH_CONTROL or DB_RENDER_CONTROL, since they cannot change the outcome. metadataPassTests adds the title's register values, the refusal once a Z or a stencil format is set, and a pass without planes that never wrote either control register.

Bring-up notes: #3745 (comment)

Tested

Windows 11 Pro 10.0.22631, AMD Ryzen 7 7800X3D, AMD Radeon RX 7900 XTX, WinLibs GCC 15.2.0, Release.

  • Vampire Survivors (PPSA21703, v01.016.107), with this change on an earlier main: "Done" on the results screen aborted with the error above. With the change the title returns to the stage map and keeps running.
  • ctest -R agc_driver_graphics on 7a84b22: passes, and fails without the change.

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

@Dextroid17

Copy link
Copy Markdown
Contributor

The change is one predicate, and it is the one this file already applies:

  • depthPlanesAbsent() already exists here and is already the rule the draw path uses for exactly this reasoning — a depth or stencil test with no plane bound cannot do depth or stencil work (State.cpp:629, State.cpp:1091). The old Require asked whether depth work was enabled, not whether it could happen.
  • With a plane bound the new disjunct is false, so the Require reduces to the old one exactly; acceptance widens only where both planes read format 0, and the added case pins both directions (DB_Z_INFO format 0 accepted, format 3 refused).

The helper's name reads wider than it behaves: it returns false when DB_Z_INFO/DB_STENCIL_INFO are absent from the register block, not only when a plane is bound, so the new disjunct only applies when both registers were written with format 0 — conservative, and the same reading planeTests() directly above it gives an unwritten register, though that helper treats the two registers independently where this one requires both present.

One more thing worth flagging, since it's a second acceptance path this diff opens without a test for it: the || short-circuits, so read(0x200)/read(0x0) are skipped whenever depthPlanesAbsent() is true. Before this change, a pass with DB_DEPTH_CONTROL/DB_RENDER_CONTROL never written threw "missing register" (read() throws on an absent register); now it decodes instead, on the strength of the two DB_*_INFO formats alone. Harmless today — nothing downstream of this Require reads depth/stencil state for a color-only pass — but it's a path the added test doesn't exercise, since the test only varies the Z-format axis; the stencil half of the predicate is never decisive either.

The title's leftover DB_DEPTH_CONTROL = 0x700763 with both planes at format 0 is exactly the state the old Require refused, which makes the added case the right regression.

Written with AI assistance.

@Nesyth
Nesyth force-pushed the fix/agc-cb-metadata-pass-without-depth-planes branch from b5bcf88 to d9fbaf7 Compare October 12, 2026 01:19
@Nesyth

Nesyth commented Oct 12, 2026

Copy link
Copy Markdown
Contributor Author

Thanks. I added two cases to metadataPassTests:

  • Z format 0 with a stencil plane bound (DB_STENCIL_INFO format 1) is refused, so the stencil half of depthPlanesAbsent now decides a case on its own.
  • Both planes at format 0 with DB_DEPTH_CONTROL and DB_RENDER_CONTROL never written decodes.

The second one is intended: with neither plane bound those two registers cannot change the outcome, so the decode should not require them. Reading them first would bring back missing register for values that cannot matter.

#2121 changes the line after this one (the resolve sample count), so whichever merges second needs a one-line rebase; neither depends on the other.

@JAB-dev

JAB-dev commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Hit the same abort on Windows with NVIDIA (RTX 4070 SUPER). The draw that threw was a non-indexed rect list, 4 vertices, VGT_PRIMITIVE_TYPE 7, with DB_DEPTH_CONTROL=0x700763 and DB_RENDER_CONTROL=32, on the results screen "Done" flow. Checking that no depth or stencil plane is bound is cleaner than what I tried (matching the draw shape), and with a shape-based version "Done" stopped aborting on my side, so the cause lines up with yours.

@oneandonlydean oneandonlydean self-assigned this Oct 12, 2026
@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

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
#2121 core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp L1090-1091

@oneandonlydean
oneandonlydean merged commit 52973f8 into boykopovar:main Oct 12, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc*

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants