Skip to content

fix(shader): link a table call whose V# is a slice of an s_load_dwordx8 or s_load_dwordx16 - #8070

Open
thuanquang wants to merge 2 commits into
boykopovar:mainfrom
thuanquang:fix/table-call-wide-descriptor
Open

thuanquang wants to merge 2 commits into
boykopovar:mainfrom
thuanquang:fix/table-call-wide-descriptor

Conversation

@thuanquang

@thuanquang thuanquang commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

What

Little Nightmares Enhanced Edition (PPSA10737) stops, after #7413 and a fix for #7395's GetImageResource case, in compute shader 0x200c340000 (@klosixgaming-arch on #7413):

computed/data-dependent s_swappc_b64 call target at program counter 0x000008b4 is not statically resolvable

Four of that shader's six table calls take their V# from s[88:91] and s[92:95], which one s_load_dwordx8 s[88:95], s[0:1], 0x10 loads. FindTableCalls only accepts a descriptor written by an s_load_dwordx4, so it skips them.

It now also accepts a V# that is a 4-dword-aligned slice of an s_load_dwordx8 or s_load_dwordx16: the descriptor registers must start a multiple of 4 dwords into the load's destination and lie inside it. The V# is read at the load's offset plus 16 bytes per slice before it. An s_load_dwordx4 is the one-slice case, so it behaves as before. The debt entry for table callees says so.

This links the calls at 0x0460, 0x08b4 and 0x0c7c, as @klosixgaming-arch found locally. The fourth call (0x0d2c) then stops with the table callees of the call at program counter 0x00000d2c lands out of the 16-bit branch range, because LinkCalls appends each call's chain and callee copies in call order. That is a separate change; @klosixgaming-arch proposed s_branch relay hops for it on #7413.

Tested

Windows 11 26200, AMD Radeon RX 6700 XT (gfx1031), driver 32.0.21045.5002, WinLibs GCC 15.2.0 r7, Release, BUILD_TESTING=ON, rebased onto main 1edbe4b5e, which has #7413. Rebased again onto main 4ec064d29b on 2026-10-22 (head 73c9c2a762; the only conflict was the debt entry's neighbouring line): scalar_call and agc_driver_compute_table_calls pass 3 of 3 on it. The runs below use VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation (Vulkan-ValidationLayers vulkan-sdk-1.4.363.0, built locally), ANYPS5_NO_SHADER_CACHE=1, ANYPS5_REQUIRE_VULKAN=1 and ctest -V, with the implicit overlay layers on this PC switched off (VK_LOADER_LAYERS_DISABLE=~implicit~). No log reports the layer as not found, and a run with VK_LOADER_DEBUG=layer shows the loader inserting it as an instance and a device layer.

  • scalar_call: FindTableCalls on the table caller with its s_load_dwordx4 swapped for an s_load_dwordx8 or s_load_dwordx16 into s[24:…]:
    • slices 0 and 1 of the x8, and slices 2 and 3 of the x16, link with descriptor offsets 0x270, 0x280, 0x290 and 0x2a0;
    • a buffer load through registers past the x8, and one through a misaligned register range, link nothing.
  • agc_driver_compute_table_calls: a caller whose V# is the second half of an s_load_dwordx8 at offset 0x10. The first half is a zero V#, so reading the wrong slice would fail. The first record's callee runs with SCC 0 and the second record's with SCC 1, in wave32 and wave64.
  • With this change, scalar_call, agc_driver_compute_table_calls, agc_driver_compute_fs_table_calls and agc_driver_compute_user_data_calls pass 3 of 3. Eight other tests of s_swappc_b64 calls and control flow also pass 3 of 3: scalar_swappc, agc_driver_scalar_swappc, agc_driver_scalar_swappc_fetch, agc_driver_scalar_static_call, agc_driver_compute_user_data_calls_registered, agc_shader_control_flow, agc_shader_control_flow_iteration_selection_off and agc_shader_control_flow_forced_fallback.
  • With GraphBuilder.cpp from main, scalar_call fails (scalar call regression) and agc_driver_compute_table_calls fails with the first record's callee through the second half of an s_load_dwordx8 (wave64): lane 0 is 3405691582, expected 16. The other two pass.
  • main 1edbe4b5e with its own versions of the tests: all four pass.
  • scalar_call also checks three V#s that an s_load_dwordx8 writes only in part, or not on a 4-dword boundary from its first register; none links: the load into s[26:33] with the V# at s[28:31], the same load with the V# at s[24:27], and a load into s[22:29] with the V# at s[28:31]. With the (descriptor - loaded) % 4u clause deleted, the first links at descriptor offset 0x278 and scalar_call fails (scalar call regression).
  • Deleting descriptor < loaded, the dataDwordCount bound, or both changes nothing: scalar_call passes, and a temporary sweep of s_load_dwordx4/x8/x16 destinations from s0 to vcc_hi against V# bases from s0 to s104 (17172 programs) accepts the same 148 calls. The writer search only returns a load that writes part of the V#, so a V# that starts before the load or runs past its end is never 4-dword aligned to it, and the alignment clause rejects it first. The two bounds stay as the statement that the slice lies inside the load.
  • No log has a VUID- error: not the runs with this change, the run with GraphBuilder.cpp from main, or the run on main.
  • @wachi35676 ran the earlier head b521b3eb5 (the same fix commit, before the test commit with the three slice-guard ScalarCall cases was added), merged into main 9127ea36d, on an NVIDIA RTX 5070 Ti (driver 617.42) and an AMD Radeon iGPU (RDNA2, 1002:13c0, AMD proprietary driver 2026.04.17), Windows 11 Home 26300, ANYPS5_REQUIRE_VULKAN=1: scalar_call, agc_driver_compute_table_calls, agc_driver_compute_fs_table_calls and control_flow_graph pass on both. With GraphBuilder.cpp back to main, scalar_call fails, and agc_driver_compute_table_calls fails on both with the message above. On WSL Ubuntu 24.04 with llvmpipe (Mesa 25.2.8), with this and six other PRs merged, 61 of the 62 related tests pass, these four included; the other fails on a WSL write-watch limit.
  • python tools/check_conventions.py --base origin/main with this title and body reports no errors and one warning: the table callees debt entry is over 1000 characters (2981 here, 2908 on main).
  • python tools/pr_overlap.py --branch fix/table-call-wide-descriptor (on 4ec064d29b, 2026-10-22): feat: macOS host support (Apple Silicon via Rosetta 2, Vulkan on MoltenVK) #8658 (macOS host support) adds Apple-only lines right after the calls.push_back this PR changes, and fix(shader): link table callees that together exceed s_call_b64 range #9068 rewrites the same Table callees debt entry; neither does what this PR does, and whichever merges second needs a rebase. Among the open PRs it could not compare (they conflict with main), feat: run PS4 games on the AGC driver — Limbo (CUSA01664) plays at 60 fps #6977 also changes GraphBuilder.cpp outside FindTableCalls, and test: organize library tests and label CTest suites #6044 moves ScalarCall.cpp to core/libs/tests/graphics/.
  • Not run: the full suite on this head.
  • Not tested: the title (its next stop is the branch range above).

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
  • Fixes: none
  • Unblocks: PPSA10737 Little Nightmares Enhanced Edition (PPSA10737) #6275 (the 0x08b4 stop on compute shader 0x200c340000; the title then stops on the 16-bit branch range at 0x0d2c, a separate change)
  • GPUs tested: AMD Radeon RX 6700 XT (gfx1031), driver 32.0.21045.5002, Windows 11 26200; by @wachi35676: NVIDIA RTX 5070 Ti, driver 617.42, and AMD Radeon iGPU (RDNA2, 1002:13c0), AMD proprietary driver 2026.04.17, Windows 11 Home 26300; llvmpipe (Mesa 25.2.8), WSL Ubuntu 24.04
  • AI-assisted: yes (Claude Code)

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Oct 19, 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
PR 8658 core/shader/recompiler/ControlFlow/src/GraphBuilder.cpp L1551
PR 9068 docs/dev/debt/libSceAgcDriver.md L203

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 2434 docs/dev/debt/libSceAgcDriver.md
PR 4448 docs/dev/debt/libSceAgcDriver.md
PR 4449 docs/dev/debt/libSceAgcDriver.md
PR 5058 docs/dev/debt/libSceAgcDriver.md
PR 5372 docs/dev/debt/libSceAgcDriver.md
PR 5499 docs/dev/debt/libSceAgcDriver.md
PR 5925 docs/dev/debt/libSceAgcDriver.md
PR 6044 core/libs/tests/ScalarCall.cpp
PR 6194 docs/dev/debt/libSceAgcDriver.md
PR 6223 docs/dev/debt/libSceAgcDriver.md
PR 6280 docs/dev/debt/libSceAgcDriver.md
PR 6300 docs/dev/debt/libSceAgcDriver.md
PR 6412 docs/dev/debt/libSceAgcDriver.md
PR 6481 docs/dev/debt/libSceAgcDriver.md
PR 6548 docs/dev/debt/libSceAgcDriver.md
PR 6549 docs/dev/debt/libSceAgcDriver.md
PR 6741 docs/dev/debt/libSceAgcDriver.md
PR 6808 docs/dev/debt/libSceAgcDriver.md
PR 6867 docs/dev/debt/libSceAgcDriver.md
PR 6868 docs/dev/debt/libSceAgcDriver.md
PR 6946 docs/dev/debt/libSceAgcDriver.md
PR 6947 docs/dev/debt/libSceAgcDriver.md
PR 7256 docs/dev/debt/libSceAgcDriver.md
PR 7310 docs/dev/debt/libSceAgcDriver.md
PR 7449 docs/dev/debt/libSceAgcDriver.md
PR 7505 docs/dev/debt/libSceAgcDriver.md
PR 7604 docs/dev/debt/libSceAgcDriver.md
PR 7642 docs/dev/debt/libSceAgcDriver.md
PR 7800 docs/dev/debt/libSceAgcDriver.md
PR 7910 docs/dev/debt/libSceAgcDriver.md
PR 8014 docs/dev/debt/libSceAgcDriver.md
PR 8083 docs/dev/debt/libSceAgcDriver.md
PR 8395 docs/dev/debt/libSceAgcDriver.md
PR 8527 docs/dev/debt/libSceAgcDriver.md
PR 8538 docs/dev/debt/libSceAgcDriver.md
PR 8564 docs/dev/debt/libSceAgcDriver.md
PR 8592 docs/dev/debt/libSceAgcDriver.md
PR 8672 docs/dev/debt/libSceAgcDriver.md
PR 9020 docs/dev/debt/libSceAgcDriver.md
PR 9084 docs/dev/debt/libSceAgcDriver.md

@wachi35676

Copy link
Copy Markdown
Contributor

NVIDIA and AMD iGPU runs, plus Linux, of b521b3eb5.

#7413 has since merged, and this head merges onto current main without conflicts. On top of the merged #7413, what is left is the 6-line FindTableCalls change and its tests, so "Depends on" can be cleared.

Windows 11 Home 26300, WinLibs GCC 15.2.0, Release, BUILD_TESTING=ON, main 9127ea36d with this head merged. GPUs: RTX 5070 Ti (NVIDIA 617.42) and the AMD Radeon iGPU (RDNA2, 1002:13c0, AMD proprietary driver 2026.04.17, ANYPS5_GPU=AMD). Run with ANYPS5_REQUIRE_VULKAN=1.

AI-assisted: yes (Claude Code); results above were run on this machine.

@thuanquang

Copy link
Copy Markdown
Contributor Author

Thanks @wachi35676 for the NVIDIA, AMD iGPU and Linux runs and the hand decode. #7413 has merged, so I'll rebase this onto main, clear Depends on, and add your runs to the description.

@klosixgaming-arch, on #7413 you suggested s_branch relay hops for the stop that comes after this one on shader 0x200c340000:

the table callees of the call at program counter 0x00000d2c lands out of the 16-bit branch range

Are you opening that change? If you aren't, I'll pick it up after this PR. I'm asking first so we don't both write it.

@thuanquang
thuanquang force-pushed the fix/table-call-wide-descriptor branch from b521b3e to 10832cd Compare October 20, 2026 08:01
@github-actions github-actions Bot added the unblocks title Names a title ID on the Unblocks line label Oct 20, 2026
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 21, 2026
thuanquang and others added 2 commits October 22, 2026 00:13
…x8 or s_load_dwordx16

Co-Authored-By: Claude <noreply@anthropic.com>
…'s s_load_dwordx8

Co-Authored-By: Claude <noreply@anthropic.com>
@thuanquang
thuanquang force-pushed the fix/table-call-wide-descriptor branch from eaf9943 to 73c9c2a Compare October 21, 2026 17:23
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 21, 2026

This branch has not been deployed

No deployments
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 unblocks title Names a title ID on the Unblocks line

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants