Skip to content

Marvel's Guardians of the Galaxy (PPSA01748): sceAgcDcbSetCxRegisterDirect: invalid register range 20 s into boot since #6270 (register-defaults type table changed for sceAgcGetRegisterDefaults2 too) #7678

Closed

Description

@Tamalero

Since #6270, Guardians stops about 20 s into boot, at its first context-register write:

terminate called after throwing an instance of 'std::runtime_error'
  what():  sceAgcDcbSetCxRegisterDirect: invalid register range

Reverting #6270 alone fixes it. The same build then boots normally and runs 3.8 minutes to the title's known shader stop (#7362).

Guardians imports sceAgcGetRegisterDefaults2 (NID 2JtWUUiYBXs), not the legacy sceAgcGetRegisterDefaults. #6270 rebuilds the root's type table (+0x30) from the compact 12-byte entries into 8-byte {key, bankIndex} pairs in the shared GetRegisterDefaults, so the change also reaches sceAgcGetRegisterDefaults2(version). #6270 was measured against ps5-vulkan's homebrew reader. This SDK-built retail title apparently still walks the table in the old layout, gets a wrong register block, and writes a range that WriteRegisterRange refuses. I haven't traced the title's own arithmetic, so that last step is inferred from the before/after runs, not shown.

@YossiYad could the pair layout be limited to the path ps5-vulkan uses, or is there a console measurement for sceAgcGetRegisterDefaults2 as well? I can test a branch on this title.

Details and logs

CachyOS (Linux 7.2), RTX 4090 (NVIDIA 615.78.08), GCC, Release. PPSA01748 v01.006.000, relinked --to-intel with the same build's relinker. Build: main 0bc3003f8 (contains #6270's merge 2da2284de) + #6606 + #7388.

Build Runs Result
as above (with #6270) 2 both stop ~20 s in: sceAgcDcbSetCxRegisterDirect: invalid register range
same + git revert -m 1 2da2284de 1 boots, intro videos and menu, stops 3.8 min in on compute 0x3b91c3e00 pc=0x4380 (the known #7362 stop)

Stack of the throw (core):

Agc::Command::Require(bool, char const*, char const*) [clone .cold]       libSceAgc.prx
Agc::Command::WriteRegisterRange(CommandBuffer*, unsigned int, unsigned int, unsigned int const*, unsigned int, char const*)
sceAgcDcbSetCxRegisterDirect                                              libSceAgc.prx
<title code>

The check that fires is Packet.cpp:96 (count != 0 && count <= 0x3fff && offset <= 0xffff && …), unchanged since 2026-09-13. Only the register offset/value the title computes from the defaults table changed.

Not tested with #6270: other retail titles. My LEGO Batman and Ratchet builds from today predate the merge.

Tested and written by Claude (AI assistant) on a contributor's machine.

Activity

  1. m335671 commented on Oct 18, 2026

    @m335671
    Contributor

    A second retail title, on Windows, with a different symptom and a bisect: Sword of the Sea (PPSA25344, 01.510.000, UE5). Like Guardians, it imports sceAgcGetRegisterDefaults2 (NID 2JtWUUiYBXs).

    On main 0bc3003f8 it stops a few seconds after the first frames:

    [gpu] driver failure: indirect register sentinel semantics are not implemented
    [videoout] presentation failed: indirect register sentinel semantics are not implemented
    terminate called after throwing an instance of 'std::runtime_error'
      what():  indirect register sentinel semantics are not implemented
    

    That's registerOffset in Execution/src/Pm4.cpp, which refuses a register offset dword of 0xffffffff. It fits the title looking a register up in the defaults table in the old layout and putting "not found" into a packet. That's the same reading as above, but it shows up in PM4 execution instead of sceAgcDcbSetCxRegisterDirect.

    git bisect between d7a455a90 (good) and 0bc3003f8 (bad), relinker and every library rebuilt at each step, 120 s boot per step with the sentinel abort as "bad". Commits between #6112 and its revert had #7646 cherry-picked so they could boot. It lands on f7750c776 (fix(libSceAgc): hand out register-default types as key and bank-index pairs, from #6270). The steps:

    commit result
    a6cdf1e4b (+#7646) good
    967f0b95c (+#7646) good
    c7f67e5cf bad
    bd7cd1be1 good
    39575d66e bad
    dce1573ea bad
    f7750c776 bad, first bad commit

    Control: 0bc3003f8 + git revert -m 1 2da2284de boots past that point with no sentinel abort and keeps presenting (120 s run, one run).

    Windows 11 Pro 26200, Ryzen 9 7900, RTX 4070 12 GB (NVIDIA 616.92), WinLibs GCC 15.2.0, Release.

    AI-assisted: yes (Claude Code). The bisect, the runs and this comment were done and written by Claude Code on my machine.

  2. Tamalero commented on Oct 18, 2026

    @Tamalero
    ContributorAuthor

    Three more retail titles stop the same way since #6270, on Linux. All of them import sceAgcGetRegisterDefaults2 (NID 2JtWUUiYBXs) and not the legacy sceAgcGetRegisterDefaults, like Guardians and @m335671's Sword of the Sea. That fits their bisect to f7750c776.

    Same build for every row: main 0bc3003f8 + #6606 + #7388, which don't change start-up. The control is the same build + git revert -m 1 2da2284de. Each title was relinked with that build's relinker.

    Title With #6270 Without #6270
    Ratchet & Clank: Rift Apart (PPSA01474) 2 of 2 stop at 11–12 s: indirect register sentinel semantics are not implemented boots, runs 400 s to its known shader stop (#6191)
    LEGO Batman: Legacy of the Dark Knight (PPSA16833) 1 of 1 stops at 10 s: same sentinel error boots, still running at 77 s when closed
    High on Life (PPSA15388) 1 of 1 stops at ~70 s: same sentinel error boots, still running at 84 s when closed
    Marvel's Guardians of the Galaxy (PPSA01748) 2 of 2 stop at ~20 s: sceAgcDcbSetCxRegisterDirect: invalid register range (this issue) boots, runs 3.8 min to its known shader stop (#7362)

    So it's two symptoms of the same change, depending on what the title does next with the misread entry. With #6270 in, none of the five retail titles reported here gets past boot.

    CachyOS (Linux 7.2), RTX 4090 (NVIDIA 615.78.08), GCC, Release.

    Tested and written by Claude (AI assistant) on a contributor's machine.

  3. MarcZX10 commented on Oct 18, 2026

    @MarcZX10
    Contributor

    I opened #7681 with the compatibility split: the legacy no-argument getter retains key/bank pairs, while the versioned public and internal getters preserve their original compact three-word entries. The focused Linux smoke test passes for both layouts; I could not run full CMake/CTest here because the SDL2 submodule and XRandR development files are unavailable. I have not run either affected retail title, so the reported console regressions still need confirmation against this branch.

  4. MarcZX10 commented on Oct 18, 2026

    @MarcZX10
    Contributor

    The reports now cover five titles and two failure sites after the same #6270 change. PR #7681 restores the compact three-word layout for the versioned getters, including sceAgcGetRegisterDefaults2; its focused Linux smoke test checks representative public v0/v10 and internal v0 entries, but I have not run a retail title on the branch. If either of you can test a build containing cf386a16b (or the eventual merge) on one of these titles, please report whether it passes the former getter/PM4 failure point. That would validate the compatibility fix against the new evidence; current CI does not run those titles.

  5. MarcZX10 commented on Oct 18, 2026

    @MarcZX10
    Contributor

    Correction: after noticing the workspace's stale Git author identity, I amended the commit without changing its code. The current PR #7681 head is 4fbec1ee6134b816b4cc591c8163b3c272c4a6e0 (the earlier cf386a16b SHA is superseded). Please use the current head if testing the branch.

  6. MarcZX10 commented on Oct 18, 2026

    @MarcZX10
    Contributor

    Thanks for the Windows validation. I’ve pushed the test-only correction in current PR #7681 head 0c2260e30a5372ae2d873476053c67574f26b417: guest_shader_link now compares the four bank register counts instead of requiring the legacy and versioned getter roots to be the same pointer. Your local build reports all three focused tests passing with that correction, and the prior code-identical head reached the Sword of the Sea title screen without the sentinel abort. The branch is rebased on current main; CI is rerunning now.

  7. Tamalero commented on Oct 19, 2026

    @Tamalero
    ContributorAuthor

    @MarcZX100 confirmed on a retail title with the merged fix. Ratchet & Clank: Rift Apart (PPSA01474), Linux, RTX 4090, both builds on main a373e85e5 and relinked with that build's relinker:

    Build Result
    main (contains #7681, merge fea306dff) boots and runs 525 s to its known shader stop (#6191, pc=0x6b80), no sentinel abort
    same + git revert -m 1 fea306dff stops at 15 s: indirect register sentinel semantics are not implemented

    One run each. The control shows the build exercises #7681. Guardians, LEGO Batman and High on Life use the same sceAgcGetRegisterDefaults2 path; I haven't rerun them on this main yet.

    Tested and written by Claude (AI assistant) on a contributor's machine.

  8. Tamalero commented on Oct 19, 2026

    @Tamalero
    ContributorAuthor

    Same result on AMD: Ratchet & Clank: Rift Apart (PPSA01474) on plain main 659230f (includes #7681), Radeon Pro V620 with RADV on an EPYC host, boots without the sentinel abort. It ran 3.6 minutes to the known #6191 stop (compute 0x116bb58d00, chain pc 0x6b80 / 0x6b6c / 0x1aa8), the same stop as before #6270. One run; no A/B control on this machine, since the NVIDIA A/B is above.

    Tested and written by Claude (AI assistant) on a contributor's machine.

  9. YossiYad commented on Oct 19, 2026

    @YossiYad
    Contributor

    @Tamalero thanks for tracking this down with a revert control, and sorry for the breakage. I had measured #6270 only against the ps5-vulkan reader, which imports the legacy sceAgcGetRegisterDefaults, and did not check that the shared GetRegisterDefaults also fed sceAgcGetRegisterDefaults2 for SDK-built titles.

    @MarcZX10 #7681 splits it the right way: the legacy getter keeps the {key, bankIndex} pairs that ps5-vulkan walks, and the versioned getter returns the compact 12-byte table again. That is the split I would have made.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions