Skip to content

fix(agc): poison unreadable direct user-data SRT roots - #5384

Closed
MarcZX10 wants to merge 1 commit into
boykopovar:mainfrom
MarcZX10:marc/srt-user-data-unmapped-5099
Closed

MarcZX10 wants to merge 1 commit into
boykopovar:mainfrom
MarcZX10:marc/srt-user-data-unmapped-5099

Conversation

@MarcZX10

@MarcZX10 MarcZX10 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

What

Fixes the direct user-data root case in #5099. Live AGC capture now treats an inaccessible LoadAddressU32 rooted at GetAddressResource(GetUserData, GetUserData) as a poisonable SRT read, records its address, and avoids the later throwing dereference. Guard-slot planning includes that direct root so the generated fault path can report it.

This is opt-in for live AGC capture. Snapshot-backed evaluation remains strict and still errors when the supplied snapshot lacks required memory. Runtime runs below show that capture gets past the original host-side unreadable-memory abort; they do not show the shader's later GPU access is repaired or that rendered output is correct.

Tested

  • Linux GCC 12.2, Ninja Release: built agc_shader_memory_tests; ctest -R '^agc_shader_memory$' passed (1/1). The regression uses user-data words 0x7 and 0x0004dfac, verifies the resulting aligned address is recorded as poison, and verifies the inaccessible read callback is not invoked.
  • Linux, RTX 5080, title follow-up on this head: Stray ran 12 times for 120 seconds without ending on the original unreadable-memory abort; the reported baseline run on main stopped there. Kena no longer hit that read, then ended on later variable stops, including its render-thread watchdog and shader/descriptor errors. The follow-up logs still contain a deferred write-back failure at 0xdfac00000004, so the GPU access remains unresolved.
  • The 28 tests matching agc_shader_memory|shader|srt passed in the title-run environment.
  • tools/check_conventions.py and git diff --check pass. Rendered output was not compared, and these title results do not establish gameplay correctness.

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; no new unimplemented path
  • No notes, investigation .md files or images added to the repository
  • New third-party code is a submodule built from source; no third-party code added
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Unblocks: none confirmed
  • GPUs tested: RTX 5080 (runtime report by fma-rc)
  • AI-assisted: yes; reviewed and tested by MarcZX100

@likecrank-dotcom

Copy link
Copy Markdown

Independent Windows validation by OpenAI Codex (AI-assisted; report authored by an AI):

  • Verified PR head 368c123ac7174892f0f5c9c19820c6b183db1b13.
  • Built agc_shader_memory_tests on Windows 11 Pro (WinLibs GCC 15.2.0, Ninja, CMake 4.4.4).
  • CTest agc_shader_memory passed five consecutive runs (5/5; 9.87 seconds total).
  • tools/check_conventions.py and git diff --check passed.

This is focused Windows test validation only; I did not test on a GPU or run a commercial title. No changes were made to the PR branch.

@github-actions github-actions Bot added shader core/shader agc libSceAgc* labels Oct 13, 2026
@fma-rc

fma-rc commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

I ran this head on the two titles from #5099 (Linux, RTX 5080).

Stray: 12 runs of 120 s on 368c123 (on main 18c438b), none ends on guest memory is not readable. Without the PR, the first run on main dacd785 stops at AGC driver: guest memory is not readable at 0xdfac00000008 (range 0xdfac00000008+0x4), and an earlier series on 60fb618 stopped that way in 8 of 22 runs.

Kena no longer hits the read either. It then ends on its own watchdog at 273 s (GameThread timed out waiting for RenderThread after 120.00 secs), which I have not looked into yet.

The 28 tests matching agc_shader_memory|shader|srt pass here. I did not compare the picture.

One detail from the stops, in case it helps: the handle's two registers are user-data words 14 and 15, and words 8-11 and 12-15 look like two inline 16-byte buffer descriptors, so 14 and 15 would be the upper half of the descriptor whose address is in 12 and 13.

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Thanks for the two-title A/B. This gives the direct-root poison handling runtime evidence: Stray no longer reaches the unreadable-memory stop in 12 runs, and Kena clears the same read before reaching its separate render-thread watchdog. I also note the 28 matching AGC/SRT tests passed. I will update the validation note to distinguish that runtime result from the still-unverified image output.

@fma-rc

fma-rc commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

A follow-up from the logs of those same runs, since it bears on whether the read is dead: with this head the shader still performs it on the GPU. The line is

[gpu] deferred write-back failed: BDA access failed: address=0xdfac00000004 instruction=0x18 bytes=4 stage=5 reason=1

always with that address, instruction and stage. Stray logs it in 4 of the 12 runs (13,982 lines in total) and keeps running. Kena logs it in 5 of 6 runs (17 lines), and all six runs then end between 96 and 273 s on different stops: its own render-thread watchdog once, shader buffer exceeds descriptor range limit twice, and once each buffer descriptor uses an unsupported type, shader buffer aliases the render target and image descriptor is incompatible with the static runtime image interface.

So the load at pc 0x18 of that pixel shader does execute with the pointer built from user-data words 14 and 15. I have not shown that Kena's later stops come from it, only that they vary from run to run.

@ThatsLeo

Copy link
Copy Markdown
Contributor

Stray (PPSA02101 v01.002, EU) on Intel Arc (Meteor Lake, Mesa 26.2.3 ANV), Fedora 44, Release: 368c123ac merged into main 0aa4cb1c, with #5181 and a local SPIR-V mapping change on top to fit 14 GB.

No abort on the read here either. But in this run the failed write-back @fma-rc describes came right after the brightness calibration screen was accepted (two lines, same address, instruction and stage). From then on no frame was presented while the audio kept playing, and about 170 s later the title stopped on the same watchdog as Kena: GameThread timed out waiting for RenderThread after 120.00 secs. On the same stack without this PR, presents went on past that screen until the read threw at about 335 s.

One run, so I can't say whether the hang follows from the failed access or only happened alongside it.

AI-assisted: yes.

@fma-rc

fma-rc commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

@ThatsLeo on the RTX 5080 Stray keeps presenting after it. One run on this head that waited for the first BDA access failed line and then read the frame counter every 15 s: fault at 28 s on frame 759, then 1003, 1359, 1702 and 2009 at 88 s, with 2,504 of those lines logged meanwhile. Three other runs went 200 s without the line at all.

So here the failed access alone does not stop presents; your hang may need something else on top, or differ by driver.

@github-actions

github-actions Bot commented Oct 14, 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
#757 core/libs/prx/libSceAgcDriver/Execution/src/ShaderMemory.cpp L258
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp L726-792, L812-862, L888-893, L896-900, L903-917, L919-938
core/shader/recompiler/Optimization/include/Optimization/SrtWalker.hpp L34
#758 core/libs/prx/libSceAgcDriver/Execution/src/ShaderMemory.cpp L258
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp L726-792, L817-862, L888-893, L896-900, L903-917, L919-938
core/shader/recompiler/Optimization/include/Optimization/SrtWalker.hpp L34

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Thanks for the Intel Arc run. I’ll record this as a driver-specific observation: one run stopped presenting after the failed write-back and later hit the render-thread watchdog, while the RTX 5080 runs continued presenting after the same logged failure. That makes the failure worth investigating, but does not yet establish that it caused the stall. The PR's current validation supports the unreadable-read behavior, not that the failed write-back is harmless across drivers.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Thanks for this and for the follow-up runs. #5573 removes the cause: the fused geometry program no longer lives in memory the title reuses, so the SRT walk never reads through 0xdfac00000008, and the later BDA access failed ... 0xdfac00000004 is gone with it. Recording the root as poison would now only hide a read that should not happen, so closing this as covered by #5573. If a title still reaches an unreadable direct user-data root on current main, please reopen with its ID and log.

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

Labels

agc libSceAgc* shader core/shader

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants