Skip to content

fix(agc): start DB_Z_INFO and DB_STENCIL_INFO at their clear-state value - #7659

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
thuanquang:fix/db-plane-clear-state
Oct 23, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
thuanquang:fix/db-plane-clear-state

Conversation

@thuanquang

@thuanquang thuanquang commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

What

METAL GEAR SOLID: MASTER COLLECTION Vol.2 BONUS CONTENT (PPSA24040) stops 4.25 s after launch on unmodified main (#7621):

[gpu] driver failure: depth, stencil or conditional color writes is unsupported (register 0x200 = 0x00000777)

Its draw enables the depth and stencil tests (DB_DEPTH_CONTROL 0x777: Z and stencil on, Z writes on, both functions ALWAYS) in a context that never wrote DB_Z_INFO or DB_STENCIL_INFO (context 0x010 and 0x011). Those two registers were not in the initial context, so depthSurfaceBound, planeTests and depthPlanesAbsent saw neither a bound plane nor an absent one, and both DecodeState and the draw precheck refused the draw.

The two registers now start at 0, both initially and after CLEAR_STATE, the way #4949, #2128 and #5347 added other registers a title may leave unwritten. 0 is FORMAT INVALID in both, so an unwritten pair now decodes like a pair written as INVALID: the tests pass and nothing is written (the path from 48ebf31 and 77373c0). The draw precheck already read the two registers as 0 when they were missing (DrawPrecheck.cpp), so it now agrees with DecodeState.

The value:

  • Linux's GFX10 clear state, clearstate_gfx10.h (gfx10_SECT_CONTEXT_def_1 from 0xa000): DB_Z_INFO and DB_STENCIL_INFO are 0.
  • The GC 10.3 register reset values, gc_10_3_0_default.h: mmDB_Z_INFO_DEFAULT and mmDB_STENCIL_INFO_DEFAULT are 0.
  • libSceAgc's public register-default tables (RegisterDefaultsData.hpp, the context table of V0, V4, V5 and V7-V11) write 0x80000180 and 0x20000180. Those are also INVALID formats, with a swizzle mode, ZRANGE_PRECISION and TILE_STENCIL_DISABLE set. Of these other bits, only TILE_STENCIL_DISABLE changes a result in the driver: the HTILE layout of a multisampled depth plane whose DB_STENCIL_INFO was never written. A debt entry records the difference and that the console's reset values are not measured.

The same gap stopped two more cases, now covered by the test: a depth plane in a context that never wrote DB_STENCIL_INFO, and a stencil plane in a context that never wrote DB_Z_INFO. decodeDepth read the unwritten register and threw AGC graphics: missing register in context bank at DWORD 0x11 (17) and ... DWORD 0x10 (16). They now decode as a depth-only and a stencil-only target.

Two more effects of the unwritten pair now reading as absent planes:

  • A CB metadata pass in such a context no longer refuses with depth or stencil work because of a set DB_DEPTH_CONTROL, as it already did not when both planes are written as INVALID (d9fbaf7).
  • A stencil clear in a context that wrote only DB_Z_INFO used to stop with missing register ... DWORD 0x11 and now stops with stencil clear requires a writable stencil plane. Both are refusals.
  • A read-only depth resummarize (DB_RENDER_CONTROL 0x10, a passing depth test, no color writes) on a depth plane whose DB_STENCIL_INFO was never written now draws nothing, as it already did when that register is written INVALID (fix(agc): handle Demon's Souls read-only depth resummarize #4049). It used to refuse with DB_RENDER_CONTROL depth copy, resummarize or decompress. (Found by @wachi35676.)

Tested

Windows 11 26200, AMD Radeon RX 6700 XT (gfx1031), driver 32.0.21045.5002, WinLibs GCC 15.2.0 r7, Release, BUILD_TESTING=ON, ANYPS5_REQUIRE_VULKAN=1.

  • agc_driver_graphics, new UnwrittenDepthPlaneTests. A fresh queue (initial context) gets the draw registers of makeState() on top, and never writes DB_Z_INFO or DB_STENCIL_INFO:
    • DB_DEPTH_CONTROL 0x777 decodes with no depth target and no depth or stencil test or write, and the precheck accepts it;
    • the same with depth bounds (0x77f);
    • a Z_32_FLOAT depth plane beside an unwritten DB_STENCIL_INFO decodes as a 32x2 depth-only target;
    • a stencil plane beside an unwritten DB_Z_INFO keeps its stencil test and drops the depth test;
    • CLEAR_STATE (ClearContext) resets both registers to 0.
  • agc_driver_pm4: the CLEAR_STATE packet check from fix(agc): initialize stencil control and reference masks #5347 now also writes 0x010 and 0x011 first and requires 0 after.
  • Red on main 505767380 (this change without the QueueState.hpp line): agc_driver_graphics fails with the title's message, depth, stencil or conditional color writes is unsupported (register 0x200 = 0x00000777), and agc_driver_pm4 with register is not set. Run case by case on that build, the precheck refuses 0x777 and 0x77f with the same message, and DecodeState throws missing register in context bank at DWORD 0x11 (17) for the depth plane and ... DWORD 0x10 (16) for the stencil plane.
  • Green: both tests pass with the change, on 505767380 and after rebasing onto main 48d61f53b.
  • Full ctest --parallel 4 --timeout 120 on this change rebased onto main 48d61f53b: 1513 tests, 5 fail, the same 5 as on unchanged main 505767380 on this machine: agc_driver_lds_mixed_width_atomics (fix(shader): release the LDS lock with an exchange and drop fences inside it #6976), agc_driver_lds_lock_budget (AGC: AMD device-backed LDS lock-budget case returns half of expected sum #7344), agc_driver_layered_volume_vertex_no_gpl (AMD Windows: alpha-to-coverage still fails at the original executable path after #6436 #4768), and log_macros and log_macros_timestamps, which fail only in this local build because ccache's base directory turns __FILE__ into a relative path with backslashes.
  • Other machines, on the same red/green: @wachi35676 (Windows 11 with an RTX 5070 Ti and an AMD RDNA2 iGPU, and Linux), @MaxLikesCode (RTX 4090, 975 selected tests, no new failures) and @savvaniss (Intel UHD 770 and AMD RX 9070 XT); see their comments below.
  • Rebased onto main d0852defa. fix(agc): reread an invalid indirect register list where its packet executes #7683's new testInvalidRegisterListEntries checks that a rejected register list leaves 0x10 and 0x11 unwritten by testing that they are absent from a fresh QueueState. With this change, both start present at their clear-state value 0. The check now compares the whole context with its initial state, which still catches any partial write. agc_driver_graphics and agc_driver_pm4 pass 2 of 2 on the rebased head.
  • Rebased onto main 47fa6eecf (head 9ab433f25). The only conflicts were next to this change: main added sampleOrderTests() beside this PR's UnwrittenDepthPlaneTests() call in tests/Graphics.cpp, and the Multisampled DCC comp-to-single clears entry beside this PR's debt entry; both are kept. agc_driver_graphics and agc_driver_pm4 pass 2 of 2 on the rebased head (same machine).
  • Khronos validation layer (vulkan-sdk-1.4.363.0), VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, ANYPS5_NO_SHADER_CACHE=1, ANYPS5_REQUIRE_VULKAN=1, ctest -V, same RX 6700 XT. The 22 depth and stencil execution tests (ctest -R "^agc_driver_(depth|stencil)_"), which record depth/stencil draws on a Vulkan device, pass on main d0852defa and on this head. Neither log reports was not found but was requested or any VUID- error.
  • python tools/check_conventions.py --base origin/main with this title and body passes.
  • The title, run by @THEMANnt on METAL GEAR SOLID: MASTER COLLECTION Vol.2 BONUS CONTENT (PPSA24040) #7621 (Windows 11 26200, RTX 5070 Ti, driver 616.92), with this commit on the report's main aff1f7190: PPSA24040 v01.200.001 now logs always-pass depth/stencil state is rendered without a depth target (DB_DEPTH_CONTROL=0x00000777) and shows its main menu and bonus-content selection at about 60 FPS. Audio and save reload work, and a 468 s run ended normally with no new stop.
  • Not tested by me: the title (I don't have it) and Linux. The new checks decode state on the CPU.

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
  • Fixes: none
  • Unblocks: PPSA24040 METAL GEAR SOLID: MASTER COLLECTION Vol.2 BONUS CONTENT (PPSA24040) #7621
  • GPUs tested: AMD Radeon RX 6700 XT (gfx1031), driver 32.0.21045.5002, Windows 11 26200; from reviewers: NVIDIA GeForce RTX 5070 Ti and an AMD RDNA2 iGPU (Windows 11), NVIDIA GeForce RTX 4090 (driver 617.42, Windows 11 26200), Intel UHD Graphics 770 (32.0.101.7088) and AMD Radeon RX 9070 XT (32.0.31041.1004, Windows 11 26300)
  • AI-assisted: yes (Claude Code)

🤖 Generated with Claude Code

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

github-actions Bot commented Oct 18, 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
PR 7910 docs/dev/debt/libSceAgcDriver.md L77-78

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 1395 core/libs/prx/libSceAgcDriver/Execution/include/QueueState.hpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 2434 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 5058 docs/dev/debt/libSceAgcDriver.md
PR 5441 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 5925 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6186 core/libs/prx/libSceAgcDriver/tests/Pm4.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6194 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6223 docs/dev/debt/libSceAgcDriver.md
PR 6235 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6273 docs/dev/debt/libSceAgcDriver.md
PR 6280 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6300 docs/dev/debt/libSceAgcDriver.md
PR 6412 docs/dev/debt/libSceAgcDriver.md
PR 6481 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6548 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6549 core/libs/prx/libSceAgcDriver/tests/Pm4.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6741 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6804 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6808 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6867 docs/dev/debt/libSceAgcDriver.md
PR 6868 docs/dev/debt/libSceAgcDriver.md
PR 6970 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6977 docs/dev/debt/libSceAgcDriver.md
PR 7256 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7410 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7449 docs/dev/debt/libSceAgcDriver.md
PR 7604 docs/dev/debt/libSceAgcDriver.md
PR 7642 docs/dev/debt/libSceAgcDriver.md
PR 7800 docs/dev/debt/libSceAgcDriver.md
PR 8014 docs/dev/debt/libSceAgcDriver.md
PR 8246 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 8365 docs/dev/debt/libSceAgcDriver.md
PR 8395 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 8527 docs/dev/debt/libSceAgcDriver.md
PR 8542 docs/dev/debt/libSceAgcDriver.md
PR 8592 docs/dev/debt/libSceAgcDriver.md
PR 8608 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 8658 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 8672 docs/dev/debt/libSceAgcDriver.md
PR 8874 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 8999 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9020 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9335 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9356 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9387 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9412 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9431 docs/dev/debt/libSceAgcDriver.md
PR 9432 docs/dev/debt/libSceAgcDriver.md
PR 9489 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9508 docs/dev/debt/libSceAgcDriver.md
PR 9592 docs/dev/debt/libSceAgcDriver.md
PR 9670 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 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9676 docs/dev/debt/libSceAgcDriver.md
PR 9748 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9891 docs/dev/debt/libSceAgcDriver.md
PR 9892 docs/dev/debt/libSceAgcDriver.md
PR 9893 core/libs/prx/libSceAgcDriver/tests/Pm4.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9895 docs/dev/debt/libSceAgcDriver.md
PR 9897 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9898 docs/dev/debt/libSceAgcDriver.md
PR 10026 docs/dev/debt/libSceAgcDriver.md

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

Copy link
Copy Markdown
Contributor

Tested on Windows 11 (RTX 5070 Ti and AMD RDNA2 iGPU) and on Linux (gcc 13.3), base a373e85e5.

  • With only this PR's test hunk on main, agc_driver_graphics fails with ... register 0x200 = 0x00000777, and agc_driver_pm4 fails with register is not set.
  • Both pass with the change, and the 791-test agc/shader/video subset has no new failures on either GPU.
  • The sources check out: Linux v6.12 clearstate_gfx10.h:41-42 and gc_10_3_0_default.h:2723-2724 give both registers as 0.

One side effect the description doesn't list, from reading the code rather than a run: DepthResummarizeDrawsNothing (State.cpp:975) used to require both registers to be present. It now also applies when DB_STENCIL_INFO was never written, so such a context takes the "draws nothing" path instead of DepthMaintenanceRejection.

AI-assisted: yes (Claude Code); results above were run on this machine.

@MaxLikesCode

Copy link
Copy Markdown
Contributor

Tested on NVIDIA: GeForce RTX 4090, driver 617.42, Windows 11 Pro 26200, WinLibs GCC 15.2.0 r7, Release, BUILD_TESTING=ON with every execution test built. This head (05b1428) merged into main ad502d7.

Not tested: the title.

AI-assisted: yes (Claude Code)

@savvaniss

Copy link
Copy Markdown
Contributor

Intel and AMD Windows data: agc_driver_pm4 and agc_driver_graphics fail on main and pass with this PR, on an Intel UHD 770 and an AMD RX 9070 XT.

Windows 11 Pro 26300, WinLibs GCC 15.2.0 r7, Release, every execution test built, ANYPS5_NO_SHADER_CACHE=1, serial CTest. Intel UHD Graphics 770 (8086:a780), driver 32.0.101.7088. AMD Radeon RX 9070 XT (1002:7550), driver 32.0.31041.1004, with VkCache emptied first. This head 05b1428ec merged into main 07377573f. "Without" means this PR's test files on main 07377573f, with none of its other changes.

Tests, ×3 UHD 770 RX 9070 XT
This head: the 31 tests built from tests/Graphics.cpp and tests/Pm4.cpp 31 of 31 pass 31 of 31 pass
Without agc_driver_pm4 and agc_driver_graphics fail same

I also ran full CTest with this PR and the 13 other open AGC and shader PRs I tested in the same batch merged together (#7668, #7504, #7432, #7426, #7413, #7480, #7465, #7466, #7464, #7449, #7489, #7673, #7560). Neither GPU showed a failure beyond main's own: the five image-table tests (#6647) and agc_driver_sample_multisample_target (#6957) on the UHD 770, and agc_driver_layered_volume_vertex_no_gpl (#4768) on the RX 9070 XT.

AI-assisted: yes (Claude Code)

@thuanquang

Copy link
Copy Markdown
Contributor Author

@wachi35676 thanks for the runs and the source check. You're right about DepthResummarizeDrawsNothing: a read-only resummarize of a depth plane whose DB_STENCIL_INFO was never written used to fall through to the DB_RENDER_CONTROL depth copy, resummarize or decompress refusal, and now takes the draws-nothing path #4049 added for a plane written as INVALID. That matches reading the unwritten register as its clear-state 0, so I've added it to the description, along with your runs and those of @MaxLikesCode and @savvaniss.

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 19, 2026
@adriadam10 adriadam10 self-assigned this Oct 19, 2026
@adriadam10
adriadam10 force-pushed the fix/db-plane-clear-state branch from 05b1428 to b30f616 Compare October 19, 2026 17:53
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 19, 2026
@thuanquang
thuanquang force-pushed the fix/db-plane-clear-state branch 2 times, most recently from 8ef2cd5 to 51c1690 Compare October 20, 2026 17:22
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 21, 2026
A context that never wrote DB_Z_INFO or DB_STENCIL_INFO had neither
register, so a draw testing depth or stencil without a depth target was
refused (PPSA24040, DB_DEPTH_CONTROL 0x777), and a depth or stencil plane
whose other register was never written stopped on a missing register.
Both now start at 0, FORMAT INVALID, initially and after CLEAR_STATE.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@thuanquang
thuanquang force-pushed the fix/db-plane-clear-state branch from 51c1690 to 9ab433f Compare October 21, 2026 12:13
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 21, 2026
@adriadam10
adriadam10 merged commit 0a5d810 into boykopovar:main Oct 23, 2026
11 of 12 checks passed
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the 0 value against Linux's GFX10 clear state and the GC 10.3 defaults, the debt entry, and that both new tests fail without the QueueState.hpp line (confirmed by @wachi35676, @MaxLikesCode and @savvaniss on NVIDIA, AMD and Intel); merged.

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

Labels

agc libSceAgc* docs 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