Skip to content

feat(shader): link raw fragment epilogs through user data - #4840

Merged
adriadam10 merged 3 commits into
boykopovar:mainfrom
Lorkydey:feat/shader-fragment-user-data-tail
Oct 14, 2026
Merged

adriadam10 merged 3 commits into
boykopovar:mainfrom
Lorkydey:feat/shader-fragment-user-data-tail

Conversation

@Lorkydey

@Lorkydey Lorkydey commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

What

XashPS5 (PPSA19111, v1.3 / content 01.030.000, bring-up #4711) uses a separate RADV fragment epilog. On the main baseline 43e3a70f8, it first stops at the point-size check addressed by #4715. With #4715 and #4821, the next stop is:

shader 0x200290800 stage 5: ShaderRecompiler::Recompile: unsupported dynamic s_setpc_b64 at program counter 0x00000100

The captured fragment body preserves s4 from user data, uses the original s5 as flags, then writes s5 = 2 before s_setpc_b64 s[4:5]. Its epilog at 0x200290a00 packs and exports the computed colors. Reading the original user-data pair would produce the wrong address.

Extend the bounded tail proof to accept an unchanged user-data low half with a high half whose last writer is an unconditional immediate s_mov_b32. Keep all preceding instructions and register state, including SCC and EXEC, and link raw fragment tails through the same mechanism as vertex tails. Track the epilog snapshot in draw-cache validation so a changed address or rewritten epilog cannot reuse stale pixels. The high half does not require a second user-data word.

Unknown/computed target halves, branching bodies, registered shader tails, mesh tails and continuations reading their relocated PC remain unsupported. This adds no shader bypass or title-specific address.

Semantics follow AMD RDNA2 ISA sections 12.3 (S_MOV_B32, S_SETPC_B64) and 12.5 (S_BRANCH). The convention is explicit in XashPS5's pinned Mesa: fragment epilog jump, 32-to-64-bit pointer conversion, and lowering to s_setpc_b64. Console hardware has not been measured; shader debt records that limitation.

Tested

  • Windows: Windows 11 Pro 26100, WinLibs MinGW-w64 GCC 15.2.0 r7, Ninja, Release, BUILD_TESTING=ON, GTX 1660 SUPER (driver 32.0.15.5585). Full libs, relinker and focused targets build at e229262449157afcc1544448c9724a80bdb2636d, based on main dacd78525e537a779682032c0ace7f7af120af05. Local ANYPS5_ENABLE_SPIRV_TOOLS=OFF. All 19 selected tests pass with Vulkan required: graphics, continuation clip/cull exports, layered rendering, shader memory/control flow, driver, scalar set-PC, compute user-data calls and prepared graphics.

  • Portable vertex state regression, following review: both SCC outcomes export a valid position and a defined vertex color. The EXEC cases save the active mask, perform a masked color write across the tail boundary, and restore the mask before exporting color and position. Full-image comparisons check linked versus monolithic shaders, identical triangle coverage and white versus black pixels. No assertion relies on vertices that omit a position export. The parent feat(shader): link raw vertex prologs through user-data tails #4821 validation separately corrupts only the linked SCC or EXEC and confirms each fails the pixel comparison on Windows NVIDIA and Linux lavapipe; restoring that source passes. AMD RADV hardware has not been retested here.

  • Fragment regression (wave64): full-image comparison with a monolithic reference, five versus six user SGPRs, changed epilog addresses, rewritten/restored code and carried SGPR/VGPR/SCC/EXEC state. The supplied high user-data word is flags, not the pointer high half. The fragment test fails at unsupported dynamic s_setpc_b64 against both main and the updated feat(shader): link raw vertex prologs through user-data tails #4821 alone (7092b01b0daab6afc52ce67d79f5d0f2537b7279), on Windows and Linux. The vertex fault-injection checks are documented in feat(shader): link raw vertex prologs through user-data tails #4821's validation.

  • Linux: exact-source validation passes on Ubuntu 24.04, GCC, Release, default ANYPS5_ENABLE_SPIRV_TOOLS=OFF and lavapipe, with Vulkan required. Full libs/relinker and focused targets build. Of 19 selected tests, 18 pass and agc_driver_vertex_clip_cull_distances skips; zero failures. That test passes on the Windows GPU. The workflow verifies the negative controls, restores the exact source, rebuilds and retests. Conventions, test registration and patch whitespace pass. These are focused checks, not the full suite. The validation workflow is kept off the PR source branch.

  • Title, Windows: with fix(agc): accept inactive vertex point size on non-point draws #4715 and feat(shader): link raw vertex prologs through user-data tails #4821, local integration 82b64a3da stops at the fragment error above. Adding this change passes it. Retesting exact head e2069019e plus fix(agc): accept inactive vertex point size on non-point draws #4715 on the earlier main baseline 90c683946 (clean local integration 1de643a65) with shader/frame capture enabled stops after 5.61 s at:

    shader 0x200220200 stage 7: ShaderRecompiler::Recompile: unsupported dynamic s_setpc_b64 at program counter 0x0000003c
    

    The captured request is now a mesh-stage draw with a different continuation (0x200291300), which is outside this change's supported stages. GDB independently reaches the same stop. An earlier uncaptured run exited with 0x20474343 and no diagnostic; its cause is not established. No presented frame, menu, gameplay or performance improvement is claimed.

  • Conventions, test registration and patch whitespace checks pass. This is focused validation, not the full test suite.

Reproduction uses the public XashPS5 v1.3 release, relinker --windows --windows-diagnostics --registry input/eboot.elf run/app.exe, bundled guest libc, matching host libraries in run/libs, release resources and owned Half-Life 1 valve data in run/app0/valve, then run/app.exe from run. Captures use only the existing APS5_DUMP_SHADERS / APS5_DUMP_FRAMES diagnostics. No game assets are included.

Dependencies and overlap

Restacked on #4821 7092b01b0daab6afc52ce67d79f5d0f2537b7279, including its portable SCC/EXEC pixel-test revision, then fragment-tail commit e229262449157afcc1544448c9724a80bdb2636d. Main dacd78525 includes merged #3763 and #4271. The inherited shader-debt conflict is resolved, retaining main's cached-IR entry and both tail entries, as well as continuation-aware clip/cull layouts with routed layer bits.

Merge #4821 first, then this follow-up. #4715 remains the title prerequisite; its commits are not included. Inherited open overlaps #1313 and #4943 are tracked in #4821's description and coordination thread. Their proposed orders are not claimed as agreed. Preserve all draw-cache fields and export-layout behavior during integration, then rerun the relevant tests. Those open implementations are not carried here and have not been tested together with this branch. #4706's compute calls are a different operation.

Additional overlap: #494 and its stacked follow-ups #1191, #1193, #1201 and #1202 share draw-cache changes. Coordination proposes #494, then #4821, then #4840 for this overlap, subject to the existing prerequisites. Agreement is pending; the direct Depends on entry will be updated once the order is agreed. Pairwise merge simulations at #494 5fe165d37 and #1202 fda7dbf04 conflict in DrawCache.hpp and DrawDecode.cpp. Integration must preserve continuation snapshots and their validation, refresh the continuation after data-only user-word reloads, and retain clip/cull layouts. Combined build/runtime validation remains outstanding; the standalone results above do not cover this stack.

The revised SCC/EXEC test is also covered by the RADV retest request; AMD hardware validation is still pending.

The title evidence above is from the pinned earlier runs, not a fresh title run on this rebase. No presented frame, menu, gameplay or performance improvement is claimed.

Checklist

@Lorkydey

Copy link
Copy Markdown
Contributor Author

The overlaps with #1313 and #4271 are inherited from #4821. I have opened one coordination thread on the prerequisite to keep the order and resolution in one place.

The proposal is #1313 and #4271 first, then #4821, then this PR; #4715 remains required for the title bring-up. #4821 now records the two proposed merge-order dependencies. This PR continues to depend on #4821 and #4715.

At the checked heads, the conflicts are the adjacent DrawProgram field additions and the shader debt entries. The rebase must preserve both fields and all relevant debt entries, including this PR's fragment-tail entry. The order still awaits the other authors' agreement; the merge simulations do not establish combined runtime compatibility.

AI-assisted: yes (Codex).

@github-actions github-actions Bot added build shader core/shader docs agc libSceAgc* labels Oct 13, 2026
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 13, 2026
@Lorkydey
Lorkydey force-pushed the feat/shader-fragment-user-data-tail branch from e206901 to 7ba0462 Compare October 13, 2026 09:57
@github-actions github-actions Bot added needs rebase Conflicts with main, rebase needed and removed needs rebase Conflicts with main, rebase needed labels Oct 13, 2026
@Lorkydey
Lorkydey force-pushed the feat/shader-fragment-user-data-tail branch from 7ba0462 to 5d1d434 Compare October 13, 2026 11:19
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 13, 2026
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 13, 2026
@blawesom

Copy link
Copy Markdown
Contributor

Rebase handoff — rebased onto current main, authorship unchanged. (Rebased cleanly apart from the docs entry — this branch carries the same fix family as its sibling #4821.)

One finding — independent of the rebase: agc_driver_vertex_user_data_tail fails deterministically on this machine with AGC graphics: SCC was not preserved across the tail jump. It fails identically on this PR's original branch at its own base, so it is not rebase-induced — likely driver/timing-sensitive (RADV GFX1201 here). Worth a look before merge; the same test fails the same way on the sibling PR #4840.

Verified on Linux (CachyOS, kernel 7.2.9, GCC 16.2.1, Ninja, Release, BUILD_TESTING=ON, AMD RX 9070 XT / RADV):

To pick it up:

git fetch https://github.com/blawesom/AnyPS5 rebase/4840
git checkout <your branch>
git merge --ff-only FETCH_HEAD

@adriadam10

Copy link
Copy Markdown
Collaborator

Checked on lavapipe: control_flow, fragment_user_data_tail, vertex_user_data_tail and submit pass; the ControlFlow test does not compile without the change. Measured on gfx1035: s_setpc_b64 through an unchanged low half plus an immediate s_mov_b32 high half jumps correctly and keeps SCC and the other SGPRs. Merging.

@adriadam10
adriadam10 merged commit 131171e into boykopovar:main Oct 14, 2026
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* build docs shader core/shader

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants