You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
sceAgcInit throws for an out-of-range version; PS5 FSR4 Showcase calls it with a pointer and expects an error result #4808
PS5 FSR4 Showcase (PPSA99011) passes its imports on main43e3a70 (relinked with --trap-sdk-syscall-stubs, #3804) and then stops in sceAgcInit:
[libc] unhandled exception 'St13runtime_error' thrown from ...
what(): sceAgcInit: unsupported register defaults version
The title's platform layer calls sceAgcInit (kW3GLb7QfPg) with a pointer and a size, not a version. At app.elf + 0x431e4:
lea rdi,[rbp-0x18] ; &local, zeroed just before
mov esi,0x8
call [sceAgcInit]
mov r14d,eax
call log ; log("INFO", "PS5VK_PLATFORM_INIT rc=%d", rc)
test r14d,r14d
je ok
mov edi,0x80000094
call [sceSysmoduleUnloadModuleInternal] ; vXZhrtJxkGc, then "init-rollback-unload"
sceAgcInit(std::uint32_t version) in DcbState/src/Init.cpp therefore receives the low half of a stack address as the version. In gdb that's 4294951544 (0xFFFFC278), and GetRegisterDefaults throws because it's not below 14.
The title handles a non-zero result: it logs the rc, unloads the module and rolls back. So what it needs is the result the console returns for a version it doesn't know, not a throw. OpenAGC's notes on the firmware wrapper (game_compat.c, sceAgcInit) say the common initializer checks the SDK version, and its reimplementation returns AGC_ERROR_INVALID_ARGUMENT (0x80890001, agc_error.h) for a version above 12.
AnyPS5 accepts versions 0 to 13 and throws for anything above, which also covers versions newer than its tables. Whether an out-of-range version should return the console's error, and from which version up, needs someone who knows which versions the firmware accepts, so I haven't opened a PR.
Linux (GCC 13) and Windows 11 (WinLibs GCC 15.2) stop the same way. On Windows the run log is [debug:0] FSR4_SHOWCASE_BEGIN heap=0 and then the throw above. The title's own PS5VK_PLATFORM_* log lines don't show up on either system, so the call sequence above is from the disassembly.
I opened PR #4835 to make sceAgcInit return 0x80890001 for versions outside AnyPS5's defaults table, while preserving version 13 support. The regression includes the pointer-valued argument seen in PPSA99011.
Validation on Debian 12 / GCC 12.2: agc_command_tests built and agc_initialization passed (1/1). The changed C++ files also pass Linux and MinGW GCC 12 syntax checks with -Wall -Wextra -Werror. I did not rerun the title. The retail upper version remains unverified: OpenAGC accepts 0–12, while AnyPS5 currently has a version 13 table.
A second title stops here, Prospero Win (PPSA99995). With #4690 merged it gets past its /data set-up on mainc13dc7e (no --trap-sdk-syscall-stubs needed) and throws the same error on Linux (GCC 13) and Windows 11 (WinLibs GCC 15.2):
terminate called after throwing an instance of 'std::runtime_error'
what(): sceAgcInit: unsupported register defaults version
In gdb the version GetRegisterDefaults receives is 4294950264 (0xffffbd78), another stack address. Prospero Win is also by the author of ps5-vulkan (mpereiraesaa/prospero-win), so it most likely makes the same sceAgcInit(&state, sizeof(state)) call. Before the throw, its session log shows its data mount and launcher mode set up (REC 3 data_mount ... root=/data/prospero-win, REC 5 args argc=1 mode=launcher).
Second title with the same pattern: PPSA99995 (prospero-win) stopped on sceAgcInit: unsupported register defaults version in my fifth catalog run (mainc2565f01, before #4835 merged). Its only call site is lea rdi,[rbp-0x18]; mov esi,0x8; call [sceAgcInit], matching prospero-win native/pw_agc_ps5.c:37,78 (sceAgcInit(&state, sizeof(state))), so the runtime receives the low 32 bits of a stack address as the version, exactly as here. The bundled RADV libvulkan.prx calls sceAgcInit(8) correctly.
On what the console answers for that call, three public records say it succeeds rather than erroring: mpereiraesaa/ps5-vulkan (e6d3c3f8, native/platform_ps5.c makes the same call and fails init on non-zero; its tools/verify_runtime.py requires agc_init=0 and VALIDATION.md records GPU runs on a PS5 on firmware 12.02), ps5-agc-gears (docs/CAPABILITY_MATRIX.md, sceAgcInit exercised on 12.02 with the (void*, uint32_t) declaration), and mihawk-99/PS5_Vulkan (docs/HARDWARE_FINDINGS.md). So 0x80890001 for versions of 14 and above (#4835) probably differs from the console; what register defaults the firmware applies for such a value is not settled by any public source (OpenAGC notes sceAgcGetRegisterDefaults2 falls back to the v11 table above 12), which is the part that would need a measurement before changing the return. Traced with Claude Code assistance.
Thanks for adding the second title and the PS5-run references. This is an important ABI follow-up to merged #4835: that change keeps sceAgcInit(version) scalar and returns 0x80890001 when a pointer-shaped argument is interpreted as an unsupported version. The call shape you traced (sceAgcInit(&state, sizeof(state))) may instead be the separate pointer-and-version ABI already represented by sceAgcInit_0090(state, version) in the source. Can you confirm the import NID for these title call sites and whether it maps to the scalar sceAgcInit export or _0090? If the same NID is being called with both signatures, #4835's behavior needs revisiting; if not, this points to an import mapping issue. I have not changed code based on the call shape alone.
Prospero Win (PPSA99995) v0.2.0, sha256 7585efc6…26ca, relinked with --to-intel --registry on main7e181fc (includes #4690): aborts at sceAgcInit (exit 134).
gdb at the call site:
lea rdi,[rbp-0x18]; mov esi,8; movq $0,-0x18(%rbp)
call *sceAgcInit ; kW3GLb7QfPg
test eax,eax; je ok
<cleanup>; mov eax,0xfffffff6
kW3GLb7QfPg is distinct from sceAgcInit_0090 (23LRUSvYu1M). A non-zero result makes the title clean up and return -10. v0.1.1 stops at the same call.
The "exits 1 with no output" in the Linux catalog run on 1c5e628 is the missing /data from before #4690. strace with that directory absent ends in stat(data)=ENOENT … socket … exit_group(1) with no writes to fd 1 or 2.
No change proposed: what the console returns for this call is unmeasured, so 0x80890001 would stay a guess. The measurement that would settle it is the return value of sceAgcInit(&buf, 8) on a console.
Measured on my PS5 (firmware 13.60) from a homebrew payload: dlopen("libSceAgc.sprx"), sceAgcInit resolved by NID kW3GLb7QfPg (23LRUSvYu1M resolves to a different address), called with two integer arguments. The buffer is 64 bytes inside a canary-filled area with guard pages on both sides.
sceAgcInit(&buf, 8) returns 0 and writes nothing, before and after the other calls below (4 of 4). sceAgcInit(&buf, 0) also returns 0.
A scalar version is refused. With the second argument 0, the first argument 0 or 1 returns 0, and every other value tried returns 0x8A6C0004: 2, 7–16, 20, 0x100, 0x10000, 0x7fffffff, 0xffffc278, 0xfffffffe and 0xffffffff. With the second argument 8, only 1 returns 0. 0 and 2–20 return 0x8A6C0004.
So on the console sceAgcInit takes the two titles' call shape: a pointer to their state and 8 return 0. A small scalar like sceAgcInit(8) fails with 0x8A6C0004, not 0x80890001, whether esi is 0 or 8. The values that fail are also addresses that are not mapped in the payload, so this does not tell an invalid version from an invalid pointer. Why 1 is accepted is unclear. For these two titles, returning 0 matches the console (#5163); what the export does for the small versions AnyPS5 maps to register-default tables is not settled by this.
Prospero Win (PPSA99995 v0.2.0) still stops at this call on main23be5a02, but now without a throw, so title sweeps report it as running.
Since #4835, sceAgcInit (kW3GLb7QfPg) takes (&state, 8) as a version, gets an address of 14 or more, and returns SCE_AGC_ERROR_INVALID_ARGUMENT. The title's pw_agc_ps5_open (native/pw_agc_ps5.c) treats any non-zero return as PW_ERR_STATE. pw_videoout_ps5_open then fails before sceVideoOutOpen, and the launcher never draws. Its session log (/data/prospero-win/logs/session-0.log) shows:
After that it idles in its input loop with no window. I saw the same on Linux (headless, 20 s) and on Windows (RTX 3080, 60 s). Returning 0 for this call, as the console does per the measurement above and as #5163 did, is what this title needs.
#5163 is merged: sceAgcInit now returns 0 for a pointer-shaped version, as the console probe showed. Closing; reopen if the FSR4 Showcase or Prospero Win still stops at this call on current main.
Activity
MarcZX10 commentedon Oct 12, 2026
I opened PR #4835 to make
sceAgcInitreturn0x80890001for versions outside AnyPS5's defaults table, while preserving version 13 support. The regression includes the pointer-valued argument seen in PPSA99011.Validation on Debian 12 / GCC 12.2:
agc_command_testsbuilt andagc_initializationpassed (1/1). The changed C++ files also pass Linux and MinGW GCC 12 syntax checks with-Wall -Wextra -Werror. I did not rerun the title. The retail upper version remains unverified: OpenAGC accepts 0–12, while AnyPS5 currently has a version 13 table.babyhuey commentedon Oct 13, 2026
A second title stops here, Prospero Win (PPSA99995). With #4690 merged it gets past its
/dataset-up onmainc13dc7e (no--trap-sdk-syscall-stubsneeded) and throws the same error on Linux (GCC 13) and Windows 11 (WinLibs GCC 15.2):In gdb the version
GetRegisterDefaultsreceives is 4294950264 (0xffffbd78), another stack address. Prospero Win is also by the author of ps5-vulkan (mpereiraesaa/prospero-win), so it most likely makes the samesceAgcInit(&state, sizeof(state))call. Before the throw, its session log shows its data mount and launcher mode set up (REC 3 data_mount ... root=/data/prospero-win,REC 5 args argc=1 mode=launcher).screamm commentedon Oct 13, 2026
Second title with the same pattern: PPSA99995 (prospero-win) stopped on
sceAgcInit: unsupported register defaults versionin my fifth catalog run (mainc2565f01, before #4835 merged). Its only call site islea rdi,[rbp-0x18]; mov esi,0x8; call [sceAgcInit], matching prospero-winnative/pw_agc_ps5.c:37,78(sceAgcInit(&state, sizeof(state))), so the runtime receives the low 32 bits of a stack address as the version, exactly as here. The bundled RADVlibvulkan.prxcallssceAgcInit(8)correctly.On what the console answers for that call, three public records say it succeeds rather than erroring: mpereiraesaa/ps5-vulkan (
e6d3c3f8,native/platform_ps5.cmakes the same call and fails init on non-zero; itstools/verify_runtime.pyrequiresagc_init=0andVALIDATION.mdrecords GPU runs on a PS5 on firmware 12.02), ps5-agc-gears (docs/CAPABILITY_MATRIX.md,sceAgcInitexercised on 12.02 with the(void*, uint32_t)declaration), and mihawk-99/PS5_Vulkan (docs/HARDWARE_FINDINGS.md). So0x80890001for versions of 14 and above (#4835) probably differs from the console; what register defaults the firmware applies for such a value is not settled by any public source (OpenAGC notessceAgcGetRegisterDefaults2falls back to the v11 table above 12), which is the part that would need a measurement before changing the return. Traced with Claude Code assistance.MarcZX10 commentedon Oct 13, 2026
Thanks for adding the second title and the PS5-run references. This is an important ABI follow-up to merged #4835: that change keeps
sceAgcInit(version)scalar and returns0x80890001when a pointer-shaped argument is interpreted as an unsupported version. The call shape you traced (sceAgcInit(&state, sizeof(state))) may instead be the separate pointer-and-version ABI already represented bysceAgcInit_0090(state, version)in the source. Can you confirm the import NID for these title call sites and whether it maps to the scalarsceAgcInitexport or_0090? If the same NID is being called with both signatures, #4835's behavior needs revisiting; if not, this points to an import mapping issue. I have not changed code based on the call shape alone.semirkabir commentedon Oct 13, 2026
Prospero Win (PPSA99995) v0.2.0, sha256
7585efc6…26ca, relinked with--to-intel --registryonmain7e181fc (includes #4690): aborts atsceAgcInit(exit 134).gdb at the call site:
kW3GLb7QfPgis distinct fromsceAgcInit_0090(23LRUSvYu1M). A non-zero result makes the title clean up and return -10. v0.1.1 stops at the same call.The "exits 1 with no output" in the Linux catalog run on 1c5e628 is the missing
/datafrom before #4690. strace with that directory absent ends instat(data)=ENOENT … socket … exit_group(1)with no writes to fd 1 or 2.No change proposed: what the console returns for this call is unmeasured, so
0x80890001would stay a guess. The measurement that would settle it is the return value ofsceAgcInit(&buf, 8)on a console.AI-assisted: yes
hugodearaujo commentedon Oct 13, 2026
Measured on my PS5 (firmware 13.60) from a homebrew payload:
dlopen("libSceAgc.sprx"),sceAgcInitresolved by NIDkW3GLb7QfPg(23LRUSvYu1Mresolves to a different address), called with two integer arguments. The buffer is 64 bytes inside a canary-filled area with guard pages on both sides.sceAgcInit(&buf, 8)returns 0 and writes nothing, before and after the other calls below (4 of 4).sceAgcInit(&buf, 0)also returns 0.0x8A6C0004: 2, 7–16, 20, 0x100, 0x10000, 0x7fffffff, 0xffffc278, 0xfffffffe and 0xffffffff. With the second argument 8, only 1 returns 0. 0 and 2–20 return0x8A6C0004.So on the console
sceAgcInittakes the two titles' call shape: a pointer to their state and 8 return 0. A small scalar likesceAgcInit(8)fails with0x8A6C0004, not0x80890001, whetheresiis 0 or 8. The values that fail are also addresses that are not mapped in the payload, so this does not tell an invalid version from an invalid pointer. Why 1 is accepted is unclear. For these two titles, returning 0 matches the console (#5163); what the export does for the small versions AnyPS5 maps to register-default tables is not settled by this.Probe output
[AgcDriver] Info - Initialized, submit.mode= 1.was printed on the console when the library loaded.AI-assisted: yes
fix(agc): return 0 for out-of-range sceAgcInit without table lookup
babyhuey commentedon Oct 14, 2026
Prospero Win (PPSA99995 v0.2.0) still stops at this call on
main23be5a02, but now without a throw, so title sweeps report it as running.Since #4835,
sceAgcInit(kW3GLb7QfPg) takes(&state, 8)as a version, gets an address of 14 or more, and returnsSCE_AGC_ERROR_INVALID_ARGUMENT. The title'spw_agc_ps5_open(native/pw_agc_ps5.c) treats any non-zero return asPW_ERR_STATE.pw_videoout_ps5_openthen fails beforesceVideoOutOpen, and the launcher never draws. Its session log (/data/prospero-win/logs/session-0.log) shows:After that it idles in its input loop with no window. I saw the same on Linux (headless, 20 s) and on Windows (RTX 3080, 60 s). Returning 0 for this call, as the console does per the measurement above and as #5163 did, is what this title needs.
AI-assisted: yes
oneandonlydean commentedon Oct 14, 2026
#5163 is merged:
sceAgcInitnow returns 0 for a pointer-shaped version, as the console probe showed. Closing; reopen if the FSR4 Showcase or Prospero Win still stops at this call on current main.fix(agc): return 0 for out-of-range sceAgcInit without table lookup
fix(agc): return 0 for out-of-range sceAgcInit without table lookup
Upstream sync 11E: AGC driver onto Metal (29 commits) (#512)