Repository navigation
fix(agc): prepare the null pixel program at draw when its variant was not prepared - #1902
Conversation
|
Hit this exact crash in Hades II (PPSA36082) and dug into why the null program misses in the first place. Two things:
With insert_or_assign there and a user count of 0, the draw matches the variant from registration and nothing needs compiling at draw. That's enough for Hades. The leftover wave32 bit would still need handling the same way, which your PR already covers. I've got this on a branch with a test that goes through the real registration path. Happy to share it if you want to use any of it here. Your call how you want to handle it. |
|
Astro Bot (PPSA21567) hits the case this PR fixes, and the next stop is a rect-list draw with the same null pixel program. Setup: RX 9070 XT (RADV / Mesa 26.2.4), Linux. Without this PR: the run stops about 3 min in on With it: the log prints I added a local log in So the draw is a rect list that uses the null pixel program variant prepared at draw ( Tested and written by Claude (AI assistant) on a contributor's machine. |
|
Uncharted: Legacy of Thieves Collection (PPSA05684) hits the same miss for the null pixel program on The title also misses for its own registered shaders, which this PR does not cover: It links libSceAgc statically, so the driver's ABI-resolution hooks never see its state and registration cannot predict the variant (here the push-constant layout). Locally I prepare a registered shader's missing variant at the draw and keep it with the snapshot (with an error log line), which gets the title to its main menu. In terms of this PR, that is |
|
Astro's Playroom (PPSA01325) hits this on Windows with NVIDIA. Setup:
Windows 11, RTX 3060 Laptop (NVIDIA 616.92), WinLibs GCC 15.2. 🤖 Generated with Claude Code |
|
Tested with Sonic Origins (PPSA05324) on Linux, R9 380 (RADV). Its depth/stencil clear draws have no pixel program, and the title uses three null pixel variants: wave 64 with 0, 4 and 16 user SGPRs. Without this PR the first one stops at Bring-up thread: #2021 |
|
Thanks, all. @Raghav314, that was the root cause. Since #1178 the two Fixed in d83e608. Registration now uses I couldn't find your branch, so the test is mine. If you push yours, I'm happy to add it here with a Co-authored-by line. @XairRrR, preparing registered shaders at draw is a bigger change than this PR. It decides when registered shaders compile, which oneandonlydean has asked boykopovar to rule on in #1836. I'd keep it as its own PR on top of this one. @EdouardSence, once #1836 is in I'll rebase and return AI-assisted: yes |
|
Another title hitting #1901: Marvel's Wolverine (PPSA03671) on Windows. Setup: Windows 11 Pro (10.0.26200), RTX 3070, GCC 15.2.0 UCRT (WinLibs), Release. This PR (d83e608) merged onto main 54f28f2 with #1836, #1893, #1709, #1837, #1940, #2022, #2219, and a local change that lets Without this PR: the first presentation fails with With this PR: the null pixel draws pass. The next stop is Merge note: with #1836 also applied, Limits: one title, one run each way. |
d83e608 to
1140f63
Compare
|
Rebased onto main 0011248 as planned. New head: 1140f63. The only conflict was Tested on an RTX 5070 Ti (NVIDIA 595.91.07), built with AI-assisted: yes |
…PRs its draws use Since boykopovar#1178 the SPI_PS_INPUT_ENA/ADDR emplace calls did nothing, so the registered variant had no pixel inputs, and null pixel draws took the last pixel shader's user SGPR count and the bound targets' export mapping. Registration now overwrites those registers, the draw gives the null program no user SGPRs and an empty export mapping, and the at-draw preparation is left for wave32 only. Root cause found by @Raghav314.
|
Rebased onto current Checked on the rebased head: build + ctest of libSceAgcDriver/libkernel scope, 380/380 passed ( |
1140f63 to
e2664be
Compare
|
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.
|
|
CI re-run: the only red job was |
…-on-demand fix(agc): prepare the null pixel program at draw when its variant was not prepared
Closes #1901
What
The driver's null pixel program is prepared only in its registration variants (0 user SGPRs). A draw without a pixel program uses the queue's
SPI_SHADER_PGM_RSRC2_PSuser count andSPI_PS_IN_CONTROLwave bit for it. When those differ from the registration variant,SourceHandleForandInvocationForthrowprepared shader artifact is missing for the requested static ABI.The root cause, found by @Raghav314: since #1178 the two
emplacecalls at registration did nothing, so the null program was registered with the wrong inputs, and a null pixel draw took the last bound pixel shader's user SGPR count.PrepareNullPixelProgram(device), which usesinsert_or_assignfor the program address,SPI_PS_INPUT_ENA/ADDRand RSRC2 (no user SGPRs).PreparedAtUse. For the null program it prepares a variant at the draw only for wave32, which registration doesn't prepare. Every other miss still throws as before.PreparedAtUsereturnssnapshot.prepared->deferredfor a registered shader, so a shader whose preparation fix(agc): defer shaders that cannot be prepared at registration to their first use #1836 deferred is still prepared at use.Tested
Linux (Nobara 44, GCC), RTX 5070 Ti, NVIDIA 595.91.07.
d83e608 adds
NullPixelMatchesRegistrationtoagc_driver_prepared_graphics: a null pixel draw with a previous shader's leftover state (4 user SGPRs, other inputs, a bound export mapping) must use the artifact prepared at registration. It fails without the fix and still fails with only part of it; it passes with all of it.ctest -R agc_: 248/248 on the RTX 5070 Ti and on RADV (Mesa 26.2.1).tools/check_conventions.pypasses.After the rebase onto
main0011248 (with #1836), built withANYPS5_ENABLE_SPIRV_TOOLS=ON:agc_driver_prepared_graphicsandagc_driver_prepared_shaderspass, andctest -R agc_ -j1passes 278 of 279 on the RTX 5070 Ti. The one failure,agc_driver_dcc_keys_first_write, also fails on plainmain0011248 on this GPU.The earlier at-draw check and its results:
New check
NullPixelAtDraw()intests/execution/PreparedShaders.cpp. It prepares the registration variant of the null pixel program, then requests a wave32, 4 user SGPR fragment variant at push offset 20 / capacity 108.ctest -R agc_driver_prepared_shadersmain1be6f9f + the test onlyprepared shader artifact is missing for the requested static ABI: ... stage=5 wave=32 pushOffset=20 pushCapacity=108 preparedLayouts= [0,128]._debug_failurepasses, as it expects a failure.agc_driver_prepared_graphicspasses tooStray: without this change it aborts on the first such draw (above). With it, the log shows
The null pixel program has no artifact for this draw (wave 64, 4 user SGPRs); preparing it at drawand the run continues to a later, unrelated error.Checklist
main; no other open PR implements the same functions.mdfiles or images added to the repository