Skip to content

fix(agc): preserve hand-built user VGPR offsets - #3496

Merged
adriadam10 merged 4 commits into
boykopovar:mainfrom
MarcZX10:codex/primstate-normalize-disabled-vgpr-3457
Oct 11, 2026
Merged

adriadam10 merged 4 commits into
boykopovar:mainfrom
MarcZX10:codex/primstate-normalize-disabled-vgpr-3457

Conversation

@MarcZX10

@MarcZX10 MarcZX10 commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

What

Issue #3457 reports four titles with hand-built shader headers (PPSA99039, PPSA99505, PPSA99515 and PPSA99997) stopping in sceAgcCreatePrimState: their ge_user_vgpr_en special is stored at GE_USER_VGPR1 (0x25c) with value 0. This change passes that special through at the offset recorded by the shader header instead of rejecting or relocating it.

This follows OpenAGC's clean-room reconstruction of the FW 5.50 SPRX, which copies the special register pairs verbatim. GE_CNTL, VGT_SHADER_STAGES_EN and a used VGT_GS_OUT_PRIM_TYPE remain checked at the offsets the driver reads. Offset errors now identify the special and the offset found.

The implementation adopts screamm's commit aeaa5080, shared on #3457 after the intake check prevented them from opening a PR. The regression test covers the 0x25c pass-through and the GE_CNTL diagnostic.

Tested

Linux, GCC 12.2, Release: built agc_shader_helpers_tests; agc_shader_helpers passed three consecutive runs. python3 tools/check_conventions.py --base upstream/main and git diff --check passed. The issue contributor reports all four titles get past sceAgcCreatePrimState with this pass-through change; the title then encounters the separately reported GetImageResource shader-recompiler error. Windows and console behavior have not been independently retested on this PR head.

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 in TechnicalDebt
  • No notes, investigation .md files or images added to the repository
  • New third-party code is a submodule built from source
  • Generic behavior, not specific to one title
  • Depends on: none
  • AI-assisted: yes

@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the change against main merged: agc_shader_helpers passes, and without the change the new test case doesn't build/fail. Only {0x25c, 0} is normalized to GE_USER_VGPR_EN; a non-zero value still throws, which is covered by the test.

Added by us (pushed to your branch):

  • TechnicalDebt line under "Unknown function info" for sceAgcCreatePrimState: the normalization is inferred from the title's headers and the console's behaviour is unknown.

Rebased on current main, scoped build and ctest green; merging once CI is green.

@adriadam10
adriadam10 force-pushed the codex/primstate-normalize-disabled-vgpr-3457 branch from fb37dae to 8351f30 Compare October 11, 2026 12:00
@adriadam10

Copy link
Copy Markdown
Collaborator

CI on this head failed in actions/checkout on all jobs (No url found for submodule path '3rdparty/imgui' in .gitmodules), which comes from main (gitlink without a .gitmodules entry), not from this diff. Verdict unchanged; merging once main is fixed and CI is green.

@LeandroLP23

Copy link
Copy Markdown
Contributor

Ran it on Windows: Radeon 860M (RDNA 3.5), Windows 11 (26300), WinLibs GCC 15.2.0 r7, Release, driver and shader caches emptied. agc_shader_helpers passes 3/3. EVO Player (PPSA99039), freshly relinked with this branch's .prx files, gets past sceAgcCreatePrimState and stops at the next blocker reported in #3457: ShaderRecompiler::Recompile: GetImageResource dword 3 is not a valid runtime value.

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Thanks for the native Windows run and trace. Getting past sceAgcCreatePrimState confirms the normalization on the reported title; the later GetImageResource failure is the separate next blocker already tracked in #3457. The PR checks remain blocked at checkout by the main imgui mapping issue in #3511.

@github-actions github-actions Bot added docs agc libSceAgc* labels Oct 11, 2026
@MarcZX10
MarcZX10 force-pushed the codex/primstate-normalize-disabled-vgpr-3457 branch from 8351f30 to b33d2e3 Compare October 11, 2026 12:49
@MarcZX10

Copy link
Copy Markdown
Contributor Author

Update after #3511 merged: I rebased this PR onto current main (a11c8f7f). The patch still only normalizes {GE_USER_VGPR1, 0} to GE_USER_VGPR_EN; the existing helper test and Windows title validation remain the relevant behavior checks. git diff --check and the conventions check pass on the rebased diff, and CI has restarted. The prior checkout failure from the orphan 3rdparty/imgui gitlink should no longer apply.

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Update: the rerun on rebased head b33d2e37 is fully green, including conventions and all three relinker jobs. The full Linux/Windows jobs are skipped by the contributor workflow. The previously reported Windows Radeon 860M validation remains the available native title evidence.

David and others added 2 commits October 11, 2026 13:19
…ceAgcCreatePrimState

EVO Player (PPSA99039), Jelly5 (PPSA99505), Emby5 (PPSA99515) and
Nuvio PS5 (PPSA99997) stop on main 0f863c1 with

  what():  sceAgcCreatePrimState: invalid user configuration register offsets

All four build their shader headers by hand (EVO-PLAYER-PS5
evo_agc_shader_header.c, ported from ps5-xash3d-halflife) and store the
ge_user_vgpr_en special at 0x25c (GE_USER_VGPR1, value 0) instead of
0x262 (GE_USER_VGPR_EN), as analysed in boykopovar#3457. They run on the console.

OpenAGC's reconstruction of the FW 5.50 sceAgcCreatePrimState
(src/game_compat.c at 3c7e8072) copies the four special register pairs
verbatim without checking their offsets; KytyPS5's offset checks
(src/libs/agc.cpp at 16a7fe68) are EXIT_NOT_IMPLEMENTED guards. The
special is now copied at the offset the header stores, not moved to
0x262; the driver reads neither register. GE_CNTL, VGT_SHADER_STAGES_EN
and a used VGT_GS_OUT_PRIM_TYPE are still required at their own
offsets because the driver reads them there, and the error now names
the special and the offset found.

With the change all four titles get past sceAgcCreatePrimState and stop
in the shader recompiler (GetImageResource dword 3 is not a valid
runtime value), as boykopovar#3457 reported for EVO Player.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit aeaa508)
@MarcZX10 MarcZX10 changed the title fix(agc): normalize disabled user VGPR special offset fix(agc): preserve hand-built user VGPR offsets Oct 11, 2026
@MarcZX10

Copy link
Copy Markdown
Contributor Author

Update on the revised implementation:

  • The code now passes ge_user_vgpr_en through at the offset recorded by hand-built shader headers, following the SPRX behavior documented by screamm. The earlier zero-value normalization has been removed.
  • The new agc_shader_helpers regression checks the GE_USER_VGPR1 pass-through and the register-specific GE_CNTL diagnostic. Linux/GCC 12.2 Release build succeeded; the focused CTest passed three consecutive runs. Conventions and git diff --check pass.
  • All applicable hosted checks on head afcaf910 are green. Full Linux and Windows jobs are skipped by the contributor workflow.
  • screamm's issue report reports the four affected titles get past this call with the pass-through change. Windows and console behavior have not been independently retested on this PR head.

The PR description now reflects the pass-through behavior and credits the implementation. Please review the revised diff when convenient.

@github-actions

github-actions Bot commented Oct 11, 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
#3670 docs/dev/TechnicalDebt.md L603
#3700 docs/dev/TechnicalDebt.md L603
#3781 docs/dev/TechnicalDebt.md L603
#3789 docs/dev/TechnicalDebt.md L603
#3791 docs/dev/TechnicalDebt.md L603
#3800 docs/dev/TechnicalDebt.md L603
#3829 docs/dev/TechnicalDebt.md L603

@reyani-dev

Copy link
Copy Markdown
Contributor

Windows check of head afcaf9101 with the five catalog titles that stop on this throw on main a11c8f7 (Windows 11, RTX 4070, WinLibs GCC 15.2.0 r7, catalog builds with eboot.bin and sce_module/libc.prx unwrapped, 60 s each).

All five get past sceAgcCreatePrimState: EVO Player (PPSA99039), PS5VR (PPSA99177), Jelly5 (PPSA99505), Emby5 (PPSA99515) and Nuvio PS5 (PPSA99997). All five then stop on the same shader at their first draw:

  what():  ShaderRecompiler::Recompile: GetImageResource dword 3 is not a valid runtime value; chain: SelectU32(SLessThan32(ReadConst(GetSrtResource, Immediate), Immediate), ReadConst(GetSrtResource, Immediate), BitwiseAnd32(ReadConst(GetSrtResource, Immediate), Immediate))

That one is separate from this PR. The SRT evaluator handles SLessThan32 since #2072, but IsRuntimeUniformOp leaves it out, so the runtime validator rejects the chain first. I have a one-line fix with a test ready (AchrafReyani:fix/shader-srt-signed-less-than-uniform) and will open it once this PR is in, since that's when it becomes the titles' stop on main. With both changes:

  • PS5VR runs the full 60 s without an error and compiles 150 shaders.
  • The other four stop at AGC graphics: guest 2D texture descriptor has a nonzero depth or base array.

@reyani-dev

Copy link
Copy Markdown
Contributor

Follow-up: with this PR plus #3807 (signed compare in SRT values) and a branch that reads a linear 2D T#'s DEPTH as its default pitch (to be opened after #3807), all five titles run the full 60 s on Windows with no error. EVO Player, Jelly5 and Nuvio PS5 present 600 frames. PS5VR compiles 150 shaders. Emby5 sits in its library scan.

@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the revised pass-through against OpenAGC's sceAgcCreatePrimState (copies the special pairs verbatim), build + libSceAgc ctest (20/20) and the new agc_shader_helpers case (it fails to build without the change). CI is green on this head, and the Windows runs above cover the titles. Merging.

@adriadam10
adriadam10 merged commit 59559c3 into boykopovar:main Oct 11, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants