Skip to content

feat(shader): read domain inputs at a control-point index computed from data - #8144

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
TheSovietWaffle:fix/recompiler-domain-computed-control-point
Oct 20, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
TheSovietWaffle:fix/recompiler-domain-computed-control-point

Conversation

@TheSovietWaffle

Copy link
Copy Markdown
Contributor

What

Tessellation lowering accepted a computed control-point index only for hull LDS reads (#4727, extended to selects and phis by 9f429e65a). Two gaps, reported in #8051:

  1. Domain reads were refused. Onimusha: Way of the Sword (PPSA27836) picks one of its patch's three control points from data in its first scene (v_cmp results feed v_cndmask/v_add_co_ci, then v_lshl_add_u32 scales the index by the 32-byte stride before a buffer_load from the off-chip ring), and main stops with tessellation lowering: the tessellation ring or LDS address is not affine in the control point and relative patch at pc 0x354.
  2. A computed hull read left its patch when the relative patch index is also data. The read keeps the program's own address, which contains relative * inputs * localStride; when the program also uses its relative patch index as data, the bases are replaced by the grouped patch instead of 0, so that term stayed and the read landed in another patch's slots.

Changes:

  • Off-chip EvaluationInput reads get the same dynamic term as hull LDS reads. It must be a whole number of control points, and the backend clamps the domain gl_in index to the last output control point, as it already does for hull reads (the hull input control points entry in docs/dev/debt/shader.md now covers both).
  • A value read from the patch's own ring or LDS no longer counts as depending on the relative patch index: the lowered read takes its patch implicitly.
  • When the relative patch index is used as data, computed reads (hull and domain) subtract their relative patch term before the bases are replaced. Programs that do not use it as data keep the program's own address, as 9f429e65a's tests require.

Tested

Windows 10 Pro 22H2 (19045), WinLibs GCC 15.2.0 r7, Release, on main 3aa35dc01.

Checklist

🤖 Generated with Claude Code

…om data

A domain program that picks one of its patch's control points from data
(Onimusha: Way of the Sword, PPSA27836, selects a corner with v_cmp and
v_cndmask before a buffer_load from the off-chip ring) was refused with
"the tessellation ring or LDS address is not affine in the control point
and relative patch". Computed indices were accepted only for hull LDS
reads.

- The address evaluator gives off-chip EvaluationInput reads the same
  dynamic term as hull LDS reads, and a value read from the patch's own
  ring or LDS no longer counts as depending on the relative patch index,
  since the lowered read takes the patch implicitly.
- When the program also uses its relative patch index as data, the
  index is replaced by the grouped patch instead of 0, which left a
  computed read's address pointing into another patch. Such reads now
  subtract their relative patch term, for hull and domain reads alike;
  reads in programs that do not use the index as data keep their address.
- The computed offset must be a whole number of control points, and the
  backend clamps the domain gl_in index to the last output control point
  as it already does for hull reads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@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 commented Oct 20, 2026 •

Copy link
Copy Markdown

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 5021 docs/dev/debt/shader.md
PR 5371 docs/dev/debt/shader.md
PR 5941 docs/dev/debt/shader.md
PR 6009 docs/dev/debt/shader.md
PR 6235 core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
docs/dev/debt/shader.md
PR 6280 docs/dev/debt/shader.md
PR 6412 docs/dev/debt/shader.md
PR 6488 docs/dev/debt/shader.md
PR 6657 core/libs/prx/libSceAgcDriver/tests/execution/Tessellation.cpp
core/shader/recompiler/Optimization/src/TessellationLowering.cpp
PR 6683 core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
PR 6879 docs/dev/debt/shader.md
PR 6924 docs/dev/debt/shader.md
PR 6947 core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
PR 6977 docs/dev/debt/shader.md
PR 7085 docs/dev/debt/shader.md
PR 7201 core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
PR 7395 docs/dev/debt/shader.md
PR 7484 docs/dev/debt/shader.md
PR 7642 core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
PR 7684 docs/dev/debt/shader.md
PR 7888 core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
docs/dev/debt/shader.md
PR 7922 docs/dev/debt/shader.md
PR 8004 docs/dev/debt/shader.md
PR 8077 docs/dev/debt/shader.md

@github-actions github-actions Bot added shader core/shader docs agc libSceAgc* fix error Closes an issue (Fixes #N) labels Oct 20, 2026
@oneandonlydean oneandonlydean self-assigned this Oct 20, 2026
@wachi35676

Copy link
Copy Markdown
Contributor

Results on current main (02fb1ce53, 395 commits after this PR's base) with f95471ec6 merged (clean). Tested on an RTX 5070 Ti (NVIDIA 617.42) and an AMD Radeon iGPU (AMD proprietary 2.0.353). Windows 11 (26300), WinLibs GCC 15.2.0, Release, ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1.

  • agc_tessellation_lowering, agc_tessellation_factor_ring and agc_driver_tessellation pass 3 of 3 on each GPU.
  • Negative control: this PR's two test files alone on main fail on both GPUs. agc_tessellation_lowering fails with a hull read at a computed control-point index stays in its patch when the relative patch is also data, and agc_driver_tessellation fails with tessellation lowering: the tessellation ring or LDS address is not affine in the control point and relative patch at pc 0x34.
  • The 9 spirv tests pass on each GPU.
  • Related set of 98 tests (tessellation, lds, subgroup, shader, stencil, msaa, multisample, label, write_tracking, resident and so on, plus agc_driver_graphics): 98 of 98 pass on each GPU. agc_driver_stencil_ref_export skips on NVIDIA because the GPU has no stencil export.

Not run: the validation layer and a title.

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

@DavidAmsellem

Copy link
Copy Markdown
Contributor

First Linux run of this PR, on AMD with RADV. Head f95471ec6 merged onto main 2fee39f1b (clean merge), built in full and compared with the same main, on the same machine.

AMD Radeon RX 7900 XT (RADV NAVI31, gfx1100), Mesa 25.2.8, Linux Mint 22.3 (Ubuntu 24.04 base), kernel 7.0.0-38, GCC 13.3, Release.

Full suite (ANYPS5_REQUIRE_VULKAN=1 ctest -j8) at 46d1d2db3: 1715/1716 with this PR, against 1715/1716 on main. The one failure is the same on both, so this PR adds none: agc_driver_guest_memory_lifetime (#7784, which #7849 addresses).

Comparing the JUnit output with main: this PR adds no ctest entry, and none is skipped or removed. The tests it extends, agc_tessellation_lowering and agc_driver_tessellation, run and pass.

GPUs tested: AMD Radeon RX 7900 XT (RADV NAVI31, gfx1100), Mesa 25.2.8, Linux Mint 22.3 / kernel 7.0.0-38

AI-assisted: yes

@oneandonlydean
oneandonlydean merged commit 2674007 into boykopovar:main Oct 20, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* docs fix error Closes an issue (Fixes #N) shader core/shader unblocks title Names a title ID on the Unblocks line

Projects

None yet

4 participants