Skip to content

fix(agc): return 0 for out-of-range sceAgcInit without table lookup - #5163

Merged
adriadam10 merged 3 commits into
boykopovar:mainfrom
mazen320:fix/agc-init-fallback-out-of-range
Oct 14, 2026
Merged

adriadam10 merged 3 commits into
boykopovar:mainfrom
mazen320:fix/agc-init-fallback-out-of-range

Conversation

@mazen320

@mazen320 mazen320 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

What

Pointer-shaped / out-of-range sceAgcInit values (>=14) return 0 without a register-default lookup. Versions 0–13 still select their tables. sceAgcInit_0090 checks the state pointer and then calls sceAgcInit, as OpenAGC does.

#4808 console probe (firmware 13.60): sceAgcInit(&buf, 8) (NID kW3GLb7QfPg) returns 0 and writes nothing. The probe does not establish that table 13 is selected. Scalar versions 2–13 return 0x8A6C0004 on that console but still return 0 here (documented in debt; not changed by this PR).

Tested

  • Windows 11, WinLibs MinGW-w64 GCC 15.2.0 r7, Release, BUILD_TESTING=ON
  • ctest --test-dir build-win -R 'agc_initialization|agc_commands' --output-on-failure — 2/2 passed
  • python -I tools/check_conventions.py --base upstream/main --head HEAD — passed
  • Titles not rerun on this revision; earlier Windows/AMD title evidence on this PR still applies to returning 0 for the pointer-shaped call

Checklist

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked the call path and the GetRegisterDefaults results are used only to initialize the cached table objects; sceAgcInit does not store a selected version or return that table. The two reported firmware runs therefore support returning success for these pointer-shaped calls, while they do not establish which table firmware selects. The PR description and debt entry preserve that distinction, so I found no blocking issue in this diff.

@coltken95

Copy link
Copy Markdown

Tested on Linux x86-64 (Release build), with 0cc5102 merged into main 9d0a41d:

  • With the PR: agc_initialization and agc_commands pass.
  • With main's sources and the PR's tests: both fail.

AI-assisted: yes (Claude Code)

@LeandroLP23

Copy link
Copy Markdown
Contributor

Title runs on Windows with AMD, since the description says the titles were not rerun. Setup: Windows 11 (26300), Radeon 860M (RDNA 3.5, driver 32.0.13058.8001), WinLibs GCC 15.2.0, Release. 0cc51023b merged onto main a0f5916a2. Catalog builds, 40 s runs. PPSA99011 was relinked with --trap-sdk-syscall-stubs.

agc_initialization and agc_commands pass.

Title main main + this PR (3 runs)
PS5 FSR4 Showcase (PPSA99011 01.000.010) Exits after 4 s. Its log: FSR4_SHOWCASE_ERROR vkCreateDevice(physical, &di, NULL, &device) = -3, result=FAIL Creates the device and its pipelines, then logs FSR4_SHOWCASE_READY version=01.000.010 display=1920x1080. Stops 7-10 s in at the next, unrelated limit (below)
Prospero Win (PPSA99995 0.2.0) Alive at 40 s, but its log reports launcher video=state and no window appears Logs launcher video=ok and presents: window Prospero Win | FPS: 1.02 at 40 s, 3 of 3 runs

The next stop of PPSA99011 with this PR is AGC driver: COPY_DATA at DWORD 69: COPY_DATA register, GDS or reference-clock source is not implemented. These are three COPY_DATA packets (control 0x00100200) that copy the SH registers 0x2e0c, 0x2e07 and 0x2e00 (COMPUTE_PGM_LO, COMPUTE_NUM_THREAD_X, COMPUTE_DISPATCH_INITIATOR) to memory, next to a DISPATCH_DIRECT.

AI-assisted: yes (Claude Code)

@MarcZX10

Copy link
Copy Markdown
Contributor

Thanks for the Windows/AMD follow-up. This adds useful title-level evidence: PPSA99011 gets past device creation and reaches the later COPY_DATA stop, while Prospero Win opens and presents in all three runs. The next FSR4 stop is now covered separately by #5477, which implements the register-to-memory copies and tests the dispatch register values. The table-selection behavior above version 13 remains unverified, as the PR description states.

RINNECODER added a commit to RINNECODER/AnyPS5 that referenced this pull request Oct 13, 2026
* perf(agc): fast-skip pure PM4 NOP packets during queue execution

(cherry picked from commit 139bf04)

Ported from upstream PR boykopovar#5481

* fix(agc): copy a shader, context or user config register to memory with COPY_DATA

A dispatch now leaves its initiator and, for DISPATCH_DIRECT, its group
counts in the shader registers, where the CP puts them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 5e36c08)

Ported from upstream PR boykopovar#5477

* fix(agc): accept reported vertex stage state

(cherry picked from commit 632331d)

Ported from upstream PR boykopovar#4341

* fix(agc): initialize stencil control and reference masks

(cherry picked from commit 85e0d98bba896002539365bb29a7a39a8e43f501)
(cherry picked from commit 13dca48)

Ported from upstream PR boykopovar#5347

* fix(agc): accept inactive vertex point size on non-point draws

(cherry picked from commit d4b59ce)

Ported from upstream PR boykopovar#4715

* fix(agc): treat type-0 texture descriptors as null

(cherry picked from commit 7e1e1ce)

Ported from upstream PR boykopovar#4779

* fix(agc): fall back out-of-range sceAgcInit versions to table 13

Pointer-shaped NID kW3GLb7QfPg calls from public homebrew succeed on console; returning an error left those titles failing init after boykopovar#4835.

(cherry picked from commit 939f784)

Ported from upstream PR boykopovar#5163 (debt-doc hunk dropped: file absent on main)

* fix(agc): clamp sceAgcInit versions above 13 inline

(cherry picked from commit 0cc5102)

Ported from upstream PR boykopovar#5163 (second commit)

* metal: adapt the shared AGC driver slice to the Metal execution loop

- skip pure PM4 NOP packets in the Metal packet loop (upstream PR boykopovar#5481)
- note the dispatch registers after direct and indirect Metal dispatch so
  COPY_DATA from a shader register works there (upstream PR boykopovar#5477)
- NullImageDescriptor delegates to IsNullTextureResource (upstream PR boykopovar#4779)
- tests: pm4 compute replay reads the dispatch initiator and group counts
  back through COPY_DATA; metal utility tests cover a type-0 image descriptor

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj

---------

Co-authored-by: Kikoarl <7354010+Kikoarl@users.noreply.github.com>
Co-authored-by: LeandroLP23 <leandroplacidi@gmail.com>
Co-authored-by: MarcZX100 <marczxrr@gmail.com>
Co-authored-by: MathiasDevelopes <25400788+MathiasDevelopes@users.noreply.github.com>
Co-authored-by: lorkydey <57268822+Lorkydey@users.noreply.github.com>
Co-authored-by: mazen <mazenshaar@hotmail.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
@oneandonlydean

Copy link
Copy Markdown
Collaborator

The console measurement is in #4808 now (#4808 (comment)): sceAgcInit(&buf, 8) returns 0 and writes nothing. So return 0 for these calls without picking table 13 for a stack address; choosing a table the firmware is not shown to use is a fallback. Please cite the measurement in the debt entry and the description, and note there that scalar values 2 to 13 return 0x8A6C0004 on the console but 0 on main and here.

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PS5 probe linked from #4808 changes the evidence for this fallback: sceAgcInit(&buf, 8) returns 0 and leaves the buffer unchanged, while every tested scalar value >=2 returns 0x8A6C0004. Selecting table 13 for a pointer-shaped argument is therefore unsupported. Please make the pointer-shaped path return success without a register-default lookup, cite the probe in this PR and the debt entry, and document that scalar 2–13 still differ from the current AnyPS5 behavior. The probe does not establish that table 13 is selected or that scalar 2–13 should use those tables.

@xXPBSXx

xXPBSXx commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

Windows test of #5163: Windows 10 (19045), MinGW-w64 GCC 15.2, Release, ninja -j 4, ctest called directly. Tree: main feddf7f4c + merge of PR head 0cc51023b130ddb251198b05c4a8d6eee4044b71 (local merge 6429dab37).
agc_commands (built from libSceAgc/tests/Commands.cpp): exit code 0 in 3 of 3 runs (0.05 s each). The test selects no GPU.
Not tested: that the new test case fails without the change (no baseline run), other ctest targets, Linux, a title run (PPSA99011 not available here). The PR state was UNSTABLE when I looked (CI not finished); I did not look at which check.

AI-assisted (Claude Code).

@MarcZX10

Copy link
Copy Markdown
Contributor

Thanks for the controlled Windows run: agc_commands passes 3/3 on the merged PR head, which confirms the suite is stable on that setup. The new report does not cover the console-observed pointer-shaped sceAgcInit(&buf, 8) behavior, and the current diff still maps that value to table 13. The firmware evidence in #4808 remains the unresolved point in my review; please update the pointer-shaped path and cite the measurement before I can approve this revision.

Pointer-shaped NID kW3GLb7QfPg calls from public homebrew succeed on console; returning an error left those titles failing init after boykopovar#4835.
Pointer-shaped calls match the boykopovar#4808 console probe (success, no writes); selecting table 13 for those values was unsupported.
@mazen320
mazen320 force-pushed the fix/agc-init-fallback-out-of-range branch from 0cc5102 to eb1b9ec Compare October 14, 2026 07:39
@mazen320 mazen320 changed the title fix(agc): fall back out-of-range sceAgcInit versions to table 13 fix(agc): return 0 for out-of-range sceAgcInit without table lookup Oct 14, 2026
@mazen320

Copy link
Copy Markdown
Contributor Author

Linux x86-64 (WSL2 Ubuntu 24.04, GCC 13.3.0), Release, BUILD_TESTING=ON, PR head eb1b9eca9:

  • ctest --test-dir build-linux -R 'agc_initialization|agc_commands' --output-on-failure — 2/2 passed
  • python3 -I tools/check_conventions.py --base upstream/main --head HEAD — passed (also on Windows WinLibs 15.2.0 r7 for the same head)

AI-assisted: yes

@mazen320

Copy link
Copy Markdown
Contributor Author

Closing temporarily to free the first-contributor open-PR slot so I can open a RetroArch Windows bring-up fix (select on regular files + AGC 8_8 UINT). Will reopen this AGC init fallback PR after that one merges (or sooner if preferred).

@mazen320 mazen320 closed this Oct 14, 2026
@mazen320 mazen320 reopened this Oct 14, 2026
@mazen320

Copy link
Copy Markdown
Contributor Author

Reopened — keeping this PR open to wait for merge. The RetroArch select + 8_8 UINT fix is parked on mazen320:fix/retroarch-windows-select-and-8_8-uint / #5795 and will be reopened after this lands.

@mazen320

Copy link
Copy Markdown
Contributor Author

Re the overlap bot vs #5845: Depends on: none.

  • This PR only changes sceAgcInit / sceAgcInit_0090 behavior + its debt bullet + tests.
  • feat(libSceAgc): implement sceAgcGetDefaultCxStateFlat #5845 adds sceAgcGetDefaultCxStateFlat and inserts a new debt bullet above the sceAgcInit line; it does not implement the same export.
  • The shared file is only docs/dev/debt/libSceAgc.md (adjacent lines). Whoever merges second rebases and keeps both bullets — no functional dependency either way.

@mazen320

Copy link
Copy Markdown
Contributor Author

Triple-check follow-up (trial merges on current upstream/main 066b58fa1):

Order Commands.cpp Init.cpp docs/dev/debt/libSceAgc.md
#5163 then #5845 clean auto-merge only #5163 content conflict (adjacent bullets)
#5845 then #5163 clean auto-merge only #5163 content conflict (adjacent bullets)
  • Same exports: none (this PR: sceAgcInit / sceAgcInit_0090; feat(libSceAgc): implement sceAgcGetDefaultCxStateFlat #5845: sceAgcGetDefaultCxStateFlat).
  • Not a functional dependency either way → Depends on: none still correct.
  • Second merger must rebase the debt file and keep both bullets (new CxStateFlat line + updated sceAgcInit line). That is the whole overlap the bot reported.

@babyhuey

Copy link
Copy Markdown
Contributor

Windows 10 evidence for this PR: merge 0d69a9e (this branch onto main 066b58f), MinGW-w64, 0 build warnings.

  • agc_initialization and agc_commands: 5/5 each.
  • Prospero Win (PPSA99995), 2 runs each. Main: launcher video=state, no window. Merge: launcher video=ok, a window presenting at "FPS: 1.01 (55)" and "1.02 (55)", still running at 60 s with no throws.
  • PS5 FSR4 Showcase (PPSA99011, relinked with --trap-sdk-syscall-stubs and --registry). Main: FSR4_SHOWCASE_ERROR vkCreateDevice(...) = -3, then FSR4_SHOWCASE_END result=FAIL, no window. Merge: window opens, passes PIPELINES and OUTPUT, prints FSR4_SHOWCASE_READY version=01.000.010 display=1920x1080, then stops with AGC driver: COPY_DATA at DWORD 69: COPY_DATA register, GDS or reference-clock source is not implemented. That next stop is the one fix(agc): copy a shader, context or user config register to memory with COPY_DATA #5477 addresses.

@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
#5889 core/libs/prx/libSceAgc/DcbState/src/Init.cpp L14-23
core/libs/prx/libSceAgc/tests/Commands.cpp L627-632
docs/dev/debt/libSceAgc.md L10

@mazen320

Copy link
Copy Markdown
Contributor Author

Re the overlap bot vs #5889: Depends on: none — this is a competing change to the same exports, not a base we build on.

This PR (#5163) #5889
sceAgcInit ABI kept as uint32_t yes changes to (void*, uint32_t)
Out-of-range / pointer-shaped >=14 return 0, no GetRegisterDefaults still GetRegisterDefaults + 0x80890001 above 13
Matches MarcZX100 / #4808 probe guidance (pointer-shaped success without table lookup) yes no
babyhuey Windows evidence on this PR (PPSA99995 window + PPSA99011 READY) yes n/a

Same files because both touch Init.cpp / tests / the sceAgcInit debt bullet. Same exports: sceAgcInit / sceAgcInit_0090. Merging one supersedes the other for those lines — second merger rebases or closes as duplicate.

Prefer this PR for the out-of-range path reviewers already asked for; #5889 can close or retarget if maintainers want the two-arg signature separately (still needs the >=14 → 0 without lookup to unblock the same titles).

@mazen320
mazen320 requested a review from MarcZX10 October 14, 2026 17:44
@adriadam10 adriadam10 self-assigned this Oct 14, 2026
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the diff against the #4808 console measurement (sceAgcInit(&buf, 8) returns 0, writes nothing): values >=14 return 0 with no register-default lookup, sceAgcInit_0090 checks the pointer and delegates, and the debt entry cites the probe and the scalar 2–13 difference. agc_commands builds and passes with the PR (libSceAgc scope, 22/22) and fails without the change; the Windows/AMD title runs in the thread cover the rest. Merging once CI is green.

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.

8 participants