Repository navigation
fix(shader): link a table call whose V# is a slice of an s_load_dwordx8 or s_load_dwordx16 - #8070
Conversation
|
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.
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.
|
|
NVIDIA and AMD iGPU runs, plus Linux, of #7413 has since merged, and this head merges onto current Windows 11 Home 26300, WinLibs GCC 15.2.0, Release,
AI-assisted: yes (Claude Code); results above were run on this machine. |
|
Thanks @wachi35676 for the NVIDIA, AMD iGPU and Linux runs and the hand decode. #7413 has merged, so I'll rebase this onto @klosixgaming-arch, on #7413 you suggested 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. |
b521b3e to
10832cd
Compare
…x8 or s_load_dwordx16 Co-Authored-By: Claude <noreply@anthropic.com>
…'s s_load_dwordx8 Co-Authored-By: Claude <noreply@anthropic.com>
eaf9943 to
73c9c2a
Compare
|
Ghostrunner data with this PR and #9068 together (data only). Setup: Ghostrunner (PPSA03685 01.000.005, Unreal Engine 4) on an RTX 4090 (NVIDIA 616.92) and a Ryzen 7 5800X, Windows 11, WinLibs GCC 15.2, Release, Linking: with #9068 alone, the shader links its calls at 0x434 and 0xc84 and stops at the third: What follows: that preparation takes minutes, and it runs on the thread that processes queue 0. The cinematic plays at about 60 FPS. When it ends, about two minutes in, the screen goes black and presentation stops. Two to six minutes later Unreal aborts with A local trace that names each shader prepared at use shows 0x200c520000 starting its preparation and never finishing. The six other shaders prepared at use in that run took 13 to 25 ms each. Offline: I replayed the request the driver dumped for that preparation with
So with both PRs, the title's next two stops are both outside them: the structurizer's time on this 4,750-block graph, which is longer than Unreal's 120 s watchdog, and then #7459. Runs: five runs past the cinematic all end the same way.
@thuanquang, on the relay change you asked @klosixgaming-arch about above: #9068 has it since e5a02bd. Before the first of an earlier call's callee copies, and after each one, AI-assisted: yes (Claude Code) |
|
A second Unreal Engine title this fixes: Severed Steel (PPSA05106) 01.000.000. Linux 7.2.9, Radeon RX 6650 XT, RADV Mesa 26.2.4, GCC Release. Setup
Result
With I haven't checked that the shader is the AI-assisted testing and report: yes, Claude Code. |
|
A title where this pattern stops a real scene: Persona 3 Reload (PPSA10872), thread #9692. Compute shader 0x2014960000, entering the Iwatodai Station strip mall. Windows 11, RTX 5090 (NVIDIA 617.42), The call at |
|
Checked |
What
Little Nightmares Enhanced Edition (PPSA10737) stops, after #7413 and a fix for #7395's
GetImageResourcecase, in compute shader 0x200c340000 (@klosixgaming-arch on #7413):Four of that shader's six table calls take their V# from
s[88:91]ands[92:95], which ones_load_dwordx8 s[88:95], s[0:1], 0x10loads.FindTableCallsonly accepts a descriptor written by ans_load_dwordx4, so it skips them.It now also accepts a V# that is a 4-dword-aligned slice of an
s_load_dwordx8ors_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. Ans_load_dwordx4is 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, becauseLinkCallsappends each call's chain and callee copies in call order. That is a separate change; @klosixgaming-arch proposeds_branchrelay 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 ontomain1edbe4b5e, which has #7413. Rebased again ontomain4ec064d29bon 2026-10-22 (head73c9c2a762; the only conflict was the debt entry's neighbouring line):scalar_callandagc_driver_compute_table_callspass 3 of 3 on it. The runs below useVK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation(Vulkan-ValidationLayersvulkan-sdk-1.4.363.0, built locally),ANYPS5_NO_SHADER_CACHE=1,ANYPS5_REQUIRE_VULKAN=1andctest -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 withVK_LOADER_DEBUG=layershows the loader inserting it as an instance and a device layer.scalar_call:FindTableCallson the table caller with itss_load_dwordx4swapped for ans_load_dwordx8ors_load_dwordx16intos[24:…]:agc_driver_compute_table_calls: a caller whose V# is the second half of ans_load_dwordx8at 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.scalar_call,agc_driver_compute_table_calls,agc_driver_compute_fs_table_callsandagc_driver_compute_user_data_callspass 3 of 3. Eight other tests ofs_swappc_b64calls 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_offandagc_shader_control_flow_forced_fallback.GraphBuilder.cppfrommain,scalar_callfails (scalar call regression) andagc_driver_compute_table_callsfails withthe first record's callee through the second half of an s_load_dwordx8 (wave64): lane 0 is 3405691582, expected 16. The other two pass.main1edbe4b5ewith its own versions of the tests: all four pass.scalar_callalso checks three V#s that ans_load_dwordx8writes only in part, or not on a 4-dword boundary from its first register; none links: the load intos[26:33]with the V# ats[28:31], the same load with the V# ats[24:27], and a load intos[22:29]with the V# ats[28:31]. With the(descriptor - loaded) % 4uclause deleted, the first links at descriptor offset 0x278 andscalar_callfails (scalar call regression).descriptor < loaded, thedataDwordCountbound, or both changes nothing:scalar_callpasses, and a temporary sweep ofs_load_dwordx4/x8/x16destinations froms0tovcc_hiagainst V# bases froms0tos104(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.VUID-error: not the runs with this change, the run withGraphBuilder.cppfrommain, or the run onmain.b521b3eb5(the same fix commit, before the test commit with the three slice-guardScalarCallcases was added), merged intomain9127ea36d, 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_callsandcontrol_flow_graphpass on both. WithGraphBuilder.cppback tomain,scalar_callfails, andagc_driver_compute_table_callsfails 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/mainwith this title and body reports no errors and one warning: the table callees debt entry is over 1000 characters (2981 here, 2908 onmain).python tools/pr_overlap.py --branch fix/table-call-wide-descriptor(on4ec064d29b, 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 thecalls.push_backthis 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 withmain), feat: run PS4 games on the AGC driver — Limbo (CUSA01664) in game (integration branch) #6977 also changesGraphBuilder.cppoutsideFindTableCalls, and test: organize library tests and label CTest suites #6044 movesScalarCall.cpptocore/libs/tests/graphics/.Titles, from testers:
main38d3c0858a+ fix(agc): resolve and render a multisampled target through its sRGB twin format #8847 stops 24 s in on compute shader 0x2007910000:computed/data-dependent s_swappc_b64 call target at program counter 0x74 is not statically resolvable. With onlylibSceAgcDriver.prxfrom thatmainwith this PR merged, there is no recompiler stop, and withAPS5_PLAYGO_UNLISTED_CHUNKS=installedit reaches the campaign New Game menu. JJenkx did not check that this shader is thes_load_dwordx8slice case.s_load_dwordx8 s[88:95], s[0:1]. With fix(shader): link table callees that together exceed s_call_b64 range #9068 alone it stops there; with this PR on top, the shader links. The title's next stops are outside this PR: the structurizer's time on the 4,750-block graph, which is longer than Unreal's 120 s watchdog, and then Shader recompiler: non-invariant descriptor Phi causes GetImageResource validation abort #7459.0x854through the V#s[88:91]from ans_load_dwordx8 s[88:95]at0x46c. Onmainb27924d85+ fix(agc): save the guest bytes of results that become pending over a surface that is no longer fully write-watched #7048 + fix(shader): link table callees that together exceed s_call_b64 range #9068 it stops there (computed/data-dependent s_swappc_b64 call target at program counter 0x00000854 is not statically resolvable); with this PR's head73c9c2a76applied, the call links. The next stop is a table callee longer thanReadUserDataCallee's 64 KiB limit (on fix(shader): link table callees that together exceed s_call_b64 range #9068).Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)0x08b4stop on compute shader0x200c340000; the title then stops on the 16-bit branch range at0x0d2c, a separate change); PPSA05106 Severed Steel (PPSA05106) #9594 (the start-up stop at0x74, @JJenkx); PPSA03685 Ghostrunner (PPSA03685) #7320 together with fix(shader): link table callees that together exceed s_call_b64 range #9068 (the call at0x89c, @frankea); PPSA10872 Persona 3 Reload (PPSA10872) #9692 together with fix(agc): save the guest bytes of results that become pending over a surface that is no longer fully write-watched #7048 and fix(shader): link table callees that together exceed s_call_b64 range #9068 (the call at0x854, @zaidhawk)1002:13c0), AMD proprietary driver 2026.04.17, Windows 11 Home 26300; llvmpipe (Mesa 25.2.8), WSL Ubuntu 24.04; title runs by @JJenkx: AMD Radeon RX 6650 XT, RADV Mesa 26.2.4, Linux 7.2.9; by @frankea: NVIDIA RTX 4090, driver 616.92, Windows 11; by @zaidhawk: NVIDIA RTX 5090, driver 617.42, Windows 11🤖 Generated with Claude Code