Skip to content

fix(shader): pass clip distances through the rect-list stages as the vertex shader writes them - #7334

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
milescoviello:fix/rect-list-clip-distances
Oct 18, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
milescoviello:fix/rect-list-clip-distances

Conversation

@milescoviello

Copy link
Copy Markdown
Contributor

What

A recompiled vertex shader writes gl_ClipDistance through an output variable of its own (OpDecorate %var BuiltIn ClipDistance) next to its position block. VertexClipDistanceCount reads it that way.

The rect-list control and evaluation stages, which forward clip distances since #7124, declared it as a second member of their per-vertex block instead. So the vertex shader's output block (Position) and the rect-list control stage's input block (Position, ClipDistance) did not match, and the Khronos layer reports VUID-RuntimeSpirv-OpVariable-08746 for each rect-list pipeline whose vertex shader has clip distances. It is the mismatch #7328 reports for the barycentric tessellation stages (#7330 changes those); this PR changes only the rect-list ones.

RectListShaders.cpp now keeps Position alone in the block and passes the clip distances through BuiltIn ClipDistance variables of their own:

  • control stage: an input array of 3 per-vertex float[N] and an output array of 4;
  • evaluation stage: an input array of 4 and a float[N] output.

The values are the same as before: the control stage still interpolates the fourth corner's distances, and the evaluation stage still copies the selected corner's. ShaderValidation already strips the per-vertex dimension of such variables and checks its length (3 in, 4 out), so it accepts them as it accepted the block members.

Tested

Linux (Ubuntu 24.04, GCC 13.3, Release), RTX 4070 Ti, NVIDIA 595.99.02; main f1af6c5.

  • agc_driver_graphics, new rect-list case: a vertex shader with two clip distances. The control, last-vertex control and evaluation stages must each declare two ClipDistance variables (input and output) and no ClipDistance block member. The four stages must then validate as a rect-list pipeline.

    With main's RectListShaders.cpp it fails 3 of 3 with a rect-list stage does not take and forward the vertex clip distances through variables of their own, as the vertex shader writes them. With this change it passes 3 of 3, and so do agc_driver_rect_list_indirect and agc_rect_list_position_invariant.

  • agc_driver_rect_list_indirect under the Khronos validation layer (Ubuntu's 1.3.275), on NVIDIA: 2 VUID-RuntimeSpirv-OpVariable-08746 errors on main, none with this change. The test passes its own checks either way. The layer reports two other errors on both builds, an unknown device pNext structure (this layer is older than the device's extensions) and VUID-VkGraphicsPipelineCreateInfo-pLibraries-06681; neither is about these stages.

  • ctest ^agc_ (684 tests): all pass.

  • check_conventions.py passes. pr_overlap.py lists Macos port #7201 and Macos m4 #6222 in RectListShaders.cpp, and the many PRs that add cases to Graphics.cpp. This PR's test case and helpers sit in rectListTests and just above it, away from the barycentric case fix(shader): match barycentric tessellation clip interfaces #7330 edits; the two merge cleanly.

Not checked on Windows, macOS, AMD or Intel.

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: none (Vulkan validity of the generated rect-list stages)
  • GPUs tested: NVIDIA GeForce RTX 4070 Ti (595.99.02, Linux)
  • AI-assisted: yes

🤖 Generated with Claude Code

…vertex shader writes them

The recompiled vertex shader writes gl_ClipDistance through a variable of
its own beside its position block, but the rect-list control and
evaluation stages read and wrote it as a second member of their
per-vertex block, so the stage interfaces did not match
(VUID-RuntimeSpirv-OpVariable-08746). They now take and forward the clip
distances through ClipDistance variables of their own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added shader core/shader agc libSceAgc* labels Oct 18, 2026
@github-actions

github-actions Bot commented Oct 18, 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 1395 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 4040 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 4650 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 5441 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 5499 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 5500 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 5925 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6188 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6194 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6222 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/shader/recompiler/SpirvBackend/src/RectListShaders.cpp
PR 6235 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6297 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6320 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6481 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6535 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6548 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6563 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6647 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6741 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6783 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6804 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6808 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6973 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6987 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6989 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6995 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7002 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7089 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7175 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7201 core/shader/recompiler/SpirvBackend/src/RectListShaders.cpp
PR 7332 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp

@Amoenus

Amoenus commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Sonic Unleashed Recompiled PPSA99902, #4443/#7260, also reaches this interface mismatch. Its completed ordinary RTX5080 replay at integration38faf/mainf663, without this PR, emits9 VUID08746 errors. The first two directly follow rect-list preparation of vertex0x201320e00 with fragments0x201321000/0x201321200 and show Position-only VS output versus Position+ClipDistance TCS input. Corrected #7330 is already present. I have not attributed every one of the nine messages to a specific draw.

Your exact6c47 change is now included in our composed integration027bc (main0bb plus retained bring-up fixes). Full Windows/Linux relinker/library builds pass. agc_driver_rect_list_indirect passes3/3 on RTX5080 and AMD Radeon Graphics with Khronos1.4.363 confirmed loaded, no observed VUID/errors, and3/3 on llvmpipe. CPU graphics (including your added rect-list checks) also passes3/3 on each OS:15 passing invocations for this selection, no selected whole skip/timeout. Existing volume-barrier advisories in other groups are not called clean. SPIRV-Tools OFF; shader cache/pipeline journal disabled; driver caches uncontrolled.

GPUs: RTX5080 (10de:2c02),610.62/32.0.16.1062; AMD Radeon(TM) Graphics (1002:13c0),32.0.21036.18; Windows11 Enterprise26200/GCC15.2r7. Linux: llvmpipe LLVM20.1.2/Mesa25.2.8, Ubuntu24.04 WSL2/GCC13.3, no validation layer.

This is composition validation, not a run of an unchanged standalone PR head. The follow-up ordinary RTX5080 replay at 10a1b28e4a completed its1800s bound with107 spaced captures and zero logged VUID/validation errors, including zero08746. Earlier frame007 confirms the CONTINUE menu; final frame106 remains the opening cinematic, with no interactive-gameplay claim. This composition also adds queued-native-clear consumer settlement and reviewed#7310, so it is not an isolated rect-list A/B. Maintenance9 advisories and11 guest-runtime vkWaitForFences failures remain. Current title report keeps the combined outcome and limits. #7334 is now included in current main; this evidence stays pinned to the tested composition.

ctest --test-dir build -V -j1 --repeat until-fail:3 --timeout 30 -R '^agc_driver_(graphics|rect_list_indirect)$'

AI-assisted validation/report: Codex; author responsible.

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

Labels

agc libSceAgc* shader core/shader

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants