Skip to content

fix(agc): normalize unused viewport depth ranges - #6535

Merged
adriadam10 merged 2 commits into
boykopovar:mainfrom
gguerra26:fix/agc-unused-viewport-depth
Oct 19, 2026
Merged

adriadam10 merged 2 commits into
boykopovar:mainfrom
gguerra26:fix/agc-unused-viewport-depth

Conversation

@gguerra26

@gguerra26 gguerra26 commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

What

Balatro (PPSA21402) uses a viewport depth range of [-1, 1] for color-only draws. On Apple M1 with MoltenVK these stop at viewport depth outside [0, 1] requires VK_EXT_depth_range_unrestricted, even when there is no depth attachment and the pixel shader does not read PositionZ.

Normalize the viewport endpoints only for those draws. Preserve XY coordinates, clip-space mode and depth clamping. Depth attachments, PositionZ inputs and non-finite ranges keep their existing behavior and validation. The adjustment is part of the decoded draw state, so cached draws receive the same state.

This is independent of #4650, which emulates observable depth transforms, and does not include the broader Mac changes in #6222.

Tested

  • macOS 15.3.1, Apple M1, MoltenVK 1.4.2 (Vulkan 1.4.357), x86-64 runtime under Rosetta.
  • agc_driver_unused_viewport_depth passes. It also runs the existing depth-clip checks and covers PositionZ reads, attached depth, reversed ranges, in-range values, non-finite rejection and preserved XY/clipping state.
  • Full local Mac runtime build passes. Balatro gets past the viewport-depth stop and runs repeated frames. With this fix alone it next encounters separate rectangle-tessellation and barycentric fallback failures. Integrating the corresponding fixes from Macos m4 #6222 locally renders the Balatro main menu, and the user confirmed on 2026-10-15 that gameplay also works on this M1 setup. One earlier run rejected a corrupted command packet; the intermittent failure remains unresolved and long-session stability is not established. Those additional changes are outside this PR.
  • Title testing used the local macOS port rebased onto upstream, plus the existing CPU instruction fixes. This PR contains only the five files for unused viewport depth, based on upstream main.
  • git diff --check and python3 tools/check_conventions.py --base origin/main --head fix/agc-unused-viewport-depth pass.

The reasoning follows Vulkan's viewport transform and fragment operations: the changed depth value has no consumer when neither the fragment shader nor a depth attachment observes it.

Checklist

  • Based on current main; no other open PR implements the same function (related feat(agc): remap a viewport depth range the device cannot express into the vertex shader #4650 and Macos m4 #6222 reviewed)
  • One topic per PR; follow-ups go in a new PR
  • No comments added in code
  • Unimplemented paths still throw; no silent stubs added
  • No investigation notes, images or logs added to the repository
  • No new third-party code
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Unblocks: PPSA21402 Game bring-up #1142, viewport-depth stop only
  • GPUs tested: Apple M1, MoltenVK 1.4.2, macOS 15.3.1; Balatro title launch. State regression uses CPU validation.
  • AI-assisted: yes (Codex)

@github-actions

github-actions Bot commented Oct 15, 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 6804 core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp L165
PR 7627 core/libs/prx/libSceAgcDriver/CMakeLists.txt L1783-1785, L1803

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 1191 core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
PR 1341 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1368 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp
PR 1395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 2434 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 4040 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 5021 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5371 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5426 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5441 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 5480 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5499 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 5500 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 5656 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5925 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6044 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6146 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6185 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6186 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6192 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6194 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6235 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6249 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6300 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6501 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6548 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6611 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6612 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6636 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6683 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6701 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6747 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6762 core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6763 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6788 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6808 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6868 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6887 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6937 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6941 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6946 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6947 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6963 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6965 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6970 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6972 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6973 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6977 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
PR 6987 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6989 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6995 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7002 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7048 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7085 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7201 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7223 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7254 core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7256 core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7332 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7505 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7514 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7604 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7615 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7642 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7800 core/libs/prx/libSceAgcDriver/CMakeLists.txt

@milescoviello

Copy link
Copy Markdown
Contributor

A Linux data point from a device without VK_EXT_depth_range_unrestricted: an Intel Arrow Lake iGPU on Mesa 26.1 ANV (Ubuntu VM), release build, 40 s runs. On main 44df216, 22 catalog homebrew apps stop 0–1 s in with viewport depth outside [0, 1] requires VK_EXT_depth_range_unrestricted. With this PR merged (head 3782121):

Result with this PR Apps
Reach the 40 s limit Stremio Plus (PPSA74126), PokeMMO Prospero (PPSA98001), ProsperoStore (PPSA99000), ProsperoEden (PPSA99008), OpenNOW PS5 (PPSA99082), Nuvio Max'd (PPSA99288), Régie5 (PPSA99520), Cloud Play (PPSA99600)
Get past the check, then exit with code 1 at 3–4 s without a message (not looked at) Homebrew UI Lab (PPSA99050), Surround Sound Studio (PPSA99051)
Still stop at the same check PPSA17641, PPSA28319, PPSA39410, PPSA69421, PPSA99001, PPSA99002, PPSA99003, PPSA99005, PPSA99006, PPSA99009, PPSA99773, PPSA99930

I didn't check why the last 12 still stop. I'd expect their draws to have a depth target or read PositionZ, which this PR leaves alone. One run per app and build.

AI-assisted: yes

@DavidSamir

Copy link
Copy Markdown
Contributor

A second title this clears on macOS: ProsperoLichess (PPSA99009, homebrew catalog), on Apple M2.

macOS 26.7.1, Apple M2, x86-64 under Rosetta, MoltenVK from the LunarG Vulkan SDK 1.4.363, Release. A local tree of main ce991f1 with #4627, #4630, #6124, the four macOS relinker PRs and mugurc's macOS port branches merged; this PR's head 378212176 applied on top, nothing else changed between the runs.

  • Without this PR, 2 runs of 2 stop 4 to 12 s in:
    libc++abi: terminating due to uncaught exception of type std::runtime_error: AGC graphics: viewport depth outside [0, 1] requires VK_EXT_depth_range_unrestricted
    
  • With it, 3 runs of 3 log no viewport-depth refusal and get further, then stop 2 to 21 s in on a different refusal, which is outside this PR:
    libc++abi: terminating due to uncaught exception of type std::runtime_error: AGC graphics: last provoking vertex requires VK_EXT_provoking_vertex with provokingVertexLast enabled
    
  • agc_driver_unused_viewport_depth passes in this tree.

I didn't test #4650.

AI-assisted: yes

@milescoviello

milescoviello commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

A check on a device without VK_EXT_depth_range_unrestricted: Intel Arrow Lake iGPU (ANV, Mesa 26.1.6), Debian 13, kernel 6.12. I ran this PR's head (3782121769) as-is against its base (44df216321), same relinker, 60 s, no pad input. Two catalog titles that stop on the depth range there:

Title base 44df216321 this PR
ProsperoEden 1.004.000 (PPSA99008) stops at 3 s: viewport depth outside [0, 1] requires VK_EXT_depth_range_unrestricted runs to the 60 s limit
Signal Companion 00.001.000 (PPSA69426) stops at 0 s, same message stops at 8 s, same message

So ProsperoEden's out-of-range viewports are all the unused kind this PR normalizes. Signal Companion gets 8 s further and then reaches a draw whose depth range is in use, which this PR leaves alone (that one needs #4650). On NVIDIA, which has the extension, neither stops on the depth range.

AI-assisted: yes (Claude Code)

@blawesom

Copy link
Copy Markdown
Contributor

Rebase handoff — rebased onto current main (authorship unchanged). One conflict in the test registration: your agc_driver_unused_viewport_depth entry sits alongside main's newer agc_driver_msaa_dcc_state, both kept.

Verified on Linux (CachyOS, kernel 7.2.9, GCC 16.2.1, Ninja, Release, BUILD_TESTING=ON, AMD RX 9070 XT / RADV):

To pick it up:

git fetch https://github.com/blawesom/AnyPS5 rebase/6535
git checkout <your branch>
git merge --ff-only FETCH_HEAD

Head is be25cb2eb.

@github-actions github-actions Bot added the unblocks title Names a title ID on the Unblocks line label Oct 18, 2026
@adriadam10 adriadam10 self-assigned this Oct 19, 2026
@adriadam10
adriadam10 force-pushed the fix/agc-unused-viewport-depth branch from 3782121 to 4af72dc Compare October 19, 2026 06:13
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 19, 2026
gguerra26 and others added 2 commits October 19, 2026 09:02
Use representable viewport endpoints only when the draw has no depth attachment and its pixel shader does not read PositionZ. Preserve XY coverage, clip-space mode, depth clamping, and validation of non-finite inputs.

Balatro (PPSA21402) reaches rendering on Apple M1 with MoltenVK after this change instead of stopping at VK_EXT_depth_range_unrestricted. Depth-dependent draws retain their original behavior.
@adriadam10
adriadam10 force-pushed the fix/agc-unused-viewport-depth branch from 4af72dc to e1e6ae0 Compare October 19, 2026 07:33
@adriadam10
adriadam10 merged commit a8c934d into boykopovar:main Oct 19, 2026
10 checks passed
@adriadam10

Copy link
Copy Markdown
Collaborator

Thanks. main moved again, so I rebased onto it and added one commit on your branch:

  • CMakeLists.txt: agc_driver_unused_viewport_depth was missing the Windows PATH prepend for libc, so the Windows job failed with 0xc0000135 (DLL not found). It is now in the same WIN32 block as the other agc_driver_graphics_tests cases.

Merging once the full Build is green.

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

Labels

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