Skip to content

feat(agc): link calls through the AGC FS table - #6160

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
fma-rc:feat/agc-fs-table-calls
Oct 18, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
fma-rc:feat/agc-fs-table-calls

Conversation

@fma-rc

@fma-rc fma-rc commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

What

1348 Ex Voto (PPSA24249) stops on current main 2559e96 when a compute shader calls through libSceAgc's FS table:

[videoout] presentation failed: compute shader 0x16800e3000: shader 0x16800e3000 stage 0: ShaderRecompiler::Recompile: computed/data-dependent s_swappc_b64 call target at program counter 0x00000130 is not statically resolvable

The shader builds the constant address 0xF_E0040000 with two s_mov_b32, loads slot 0 there as a V#, reads a call target at +0x20 and skips the s_swappc_b64 when it is zero. Issue #6117 reports the same shape in MXGP 26 and asks what a console keeps at that address.

On the PS5 12.00 modules, libSceAgc's init gets a block from libSceAgcDriver, aborts unless the table lands at 0xF_E0040000, zeroes six 16-byte slots, and makes slot 0 a V# (stride 16, eight records) over a buffer of eight {routine address, 0} records. This PR:

  • maps 2 MiB at 0xF_E0000000 once per process when the driver is created (MAP_FIXED_NOREPLACE on Linux, a commit inside the guest arena on Windows), fills the table that way and registers the block with GuestAllocations;
  • points every record at one routine that only returns (s_setpc_b64 s[14:15]); Sony's routines are not modeled (TechnicalDebt);
  • extends the table-callee path from feat(shader): link callees of calls whose target is loaded from a table #4706 to a V# pointer set by two s_mov_b32 of constants, and lets the writer search cross a conditional branch that jumps past the call (the null check).

Refs #6117 (same call; its unaligned atomic stays open).

Tested

Linux, current main 2559e96 plus this PR:

Run main this PR
Ex Voto, warm shader cache, 300 s limit stops at 57.1 s (frame 30) with the line above no stop, frame 566 at 300 s
Ex Voto, cold shader cache, 300 s limit frame 32 at 300 s no stop, frame 472 at 300 s

Rebased onto main 4524944 (2026-10-16): agc_driver_compute_fs_table_calls passes on RTX 5080 (NVIDIA 615.78.08), Radeon 610M (RADV) and lavapipe. Ex Voto, warm cache, 300 s: main stops at 53.1 s with the same s_swappc_b64 line; with this PR no stop, frame 851 at 300 s, on the title screen.

With the PR and a warm cache, pressing Cross at the title screen reaches the main menu (Play / Options / Credits) with no stop in 390 s.

MXGP 26 (PPSA30839), tested by milescoviello on Linux (RTX 4070 Ti, main d92a8da merged with d1a68c4, comment): main stops at 135 s with the issue's s_swappc_b64 line; with this PR 2 of 2 runs reach the 180 s limit without it.

Silent Hill: Townfall (PPSA33286), tested by tv7 on Windows (RTX 3070, main ff23657 merged with d1a68c4, comment): main stops on the s_swappc_b64 line in 3 of 3 runs after about 2.5 min; with this PR it appears in none of 5 runs and 4 of 5 reach the 900 s limit (the fifth hits a render-thread timeout tv7 has seen before without this PR).

Hot Wheels Infinite Rush (PPSA22408), tested by mrfelek on Linux (RTX 3080 Ti, main 5d9dcc4 merged with d1a68c4, comment): main aborts on the same s_swappc_b64 line at PC 0x134 after the boot screens; with this PR none of 3 runs shows it (one reaches the loading screen, one stops on a storage-image write-watch error also seen once without it, one runs out of device memory while storage images grow).

agc_driver_compute_fs_table_calls (the Ex Voto shape: the marker store runs only after the call returns) and scalar_call fail with GraphBuilder.cpp and Lifecycle.cpp from main (FS table at 0xfe0040000 is not mapped, scalar call regression; NVIDIA) and pass with the PR on NVIDIA RTX 5080 (615.78.08), RADV (Ryzen 7 7800X3D iGPU) and lavapipe. Windows (WinLibs GCC 15.2, VM): the full suite passes except guest_kernel_stack_protect and guest_kqueue, which fail the same way on main there.

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 under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Unblocks: PPSA24249 (1348 Ex Voto), PPSA30839 (MXGP 26, with fix(shader): act on the containing dword for unaligned 32-bit buffer atomics #6094 for its atomics), PPSA33286 (Silent Hill: Townfall), PPSA22408 (Hot Wheels Infinite Rush)
  • GPUs tested: NVIDIA RTX 5080 (615.78.08, Arch Linux), AMD Ryzen 7 7800X3D iGPU (RADV, Arch Linux), lavapipe
  • AI-assisted: yes

@milescoviello

Copy link
Copy Markdown
Contributor

MXGP 26 (PPSA30839), the title in #6117, with this PR on Linux.

Setup: Ubuntu 24.04, GCC 13.3, Release, RTX 4070 Ti (NVIDIA 595.99), main d92a8da merged with this head d1a68c4ae (clean merge), relinked with --to-intel, 180 s runs with pad input (a button every 1.5 s from 8 s).

Not checked on Windows.

AI-assisted: yes

This was referenced Oct 15, 2026
@ps54all

ps54all commented Oct 18, 2026

Copy link
Copy Markdown

Tested on God of War Ragnarök (PPSA08330, 06.006.000): the computed s_swappc_b64 stop is gone.

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


Generated by Claude Code

@ps54all ps54all mentioned this pull request Oct 18, 2026
11 tasks done
@adriadam10 adriadam10 self-assigned this Oct 18, 2026
@adriadam10
adriadam10 merged commit c34e9d8 into boykopovar:main Oct 18, 2026
8 checks passed
@JJenkx JJenkx mentioned this pull request Oct 18, 2026
12 tasks done
ycarogabriel-lgtm added a commit to ycarogabriel-lgtm/AnyPS5 that referenced this pull request Oct 18, 2026
…tta holds it

Upstream's FS table calls (boykopovar#6160) map 2 MiB of AGC driver memory at 0xfe0000000 with MAP_FIXED_NOREPLACE, which macOS does not define, so libSceAgcDriver stopped building. The address cannot be mapped under Rosetta either: the translator reserves 0xfc0000000-0x1000000000 with a maximum protection of none, so a hinted mmap lands elsewhere and a fixed one fails with EACCES. On macOS the driver now maps the memory with the address as a hint, and when it does not get that address it says so once and starts without the table instead of failing every device; agc_driver_compute_fs_table_calls skips with the reason on such hosts. The limit is in the AGC debt file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ycarogabriel-lgtm added a commit to ycarogabriel-lgtm/AnyPS5 that referenced this pull request Oct 18, 2026
…tta holds it

Upstream's FS table calls (boykopovar#6160) map 2 MiB of AGC driver memory at 0xfe0000000 with MAP_FIXED_NOREPLACE, which macOS does not define, so libSceAgcDriver stopped building. The address cannot be mapped under Rosetta either: the translator reserves 0xfc0000000-0x1000000000 with a maximum protection of none, so a hinted mmap lands elsewhere and a fixed one fails with EACCES. On macOS the driver now maps the memory with the address as a hint, and when it does not get that address it says so once and starts without the table instead of failing every device; agc_driver_compute_fs_table_calls skips with the reason on such hosts. The limit is in the AGC debt file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 605298a)
@mugurc mugurc mentioned this pull request Oct 18, 2026
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 19, 2026
An ANYPS5_ENABLE_ASAN build moves the guest arena up by 0x100000000000,
past AddressSanitizer's shadow gap, but the AGC driver memory that holds
the FS table (boykopovar#6160) is still mapped at the fixed 0xfe0000000. That
address is in the shadow gap, so the mapping fails with EEXIST and no
test that initializes the driver runs under ASan.

The offset is now GuestArena::GuestAddressOffset in GuestArena.hpp, and
the driver memory and the FS table move by it like the arena. Builds
without ASan keep 0xfe0000000. agc_driver_compute_fs_table_calls skips
in an ASan build: its shader builds the PS5's fixed table address from
literals, as titles' shaders do, and that address can't be mapped there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ycarogabriel-lgtm added a commit to ycarogabriel-lgtm/AnyPS5 that referenced this pull request Oct 25, 2026
…tta holds it

Upstream's FS table calls (boykopovar#6160) map 2 MiB of AGC driver memory at 0xfe0000000 with MAP_FIXED_NOREPLACE, which macOS does not define, so libSceAgcDriver stopped building. The address cannot be mapped under Rosetta either: the translator reserves 0xfc0000000-0x1000000000 with a maximum protection of none, so a hinted mmap lands elsewhere and a fixed one fails with EACCES. On macOS the driver now maps the memory with the address as a hint, and when it does not get that address it says so once and starts without the table instead of failing every device; agc_driver_compute_fs_table_calls skips with the reason on such hosts. The limit is in the AGC debt file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 605298a)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* docs shader core/shader

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants