Skip to content

fix(shader): count vertex clip distances in the rect-list tessellation limits - #12228

Merged
oneandonlydean merged 2 commits into
boykopovar:mainfrom
MarcZX10:fix/rectlist-tessellation-clip-distance-components
Oct 28, 2026
Merged

oneandonlydean merged 2 commits into
boykopovar:mainfrom
MarcZX10:fix/rectlist-tessellation-clip-distance-components

Conversation

@MarcZX10

Copy link
Copy Markdown
Contributor

What

BuildRectListShaders sized the per-vertex tessellation interface from the position and the exported parameters only. The generated control and evaluation shaders also declare the vertex shader's ClipDistance array (up to eight scalars) as input and output builtins, so for a vertex shader that writes clip distances the real interface was up to eight components larger than the checked size. The check could pass and emit shaders that exceed maxTessellationControlPerVertexInputComponents, its output counterpart and the evaluation limits, which makes the pipeline invalid. The sibling BarycentricGeometryShader.cpp already counts clip distances (4 + clipDistances + 4 * sources).

The clip distance count is now read before the check, and both the parameter capacity and the component total include it: parameters are trimmed to what fits, and an interface that cannot fit is rejected.

Two commits: the fix, then the test (RectListPositionInvariant.cpp: with eight per-vertex components, a ClipDistance[2] vertex shader still builds and a ClipDistance[8] one is rejected as exceeding the device limits).

Tested

Linux x86-64, a throwaway archive build with the host CPU gate patched. agc_rect_list_position_invariant passes. On main the ClipDistance[8] case is accepted (the checked size was 4 against a limit of 8), so the new assertion fails there; I reasoned that from the code rather than running the old build. tools/check_conventions.py --base upstream/main and git diff --check pass.

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: none
  • GPUs tested: n/a (SPIR-V generation and limit arithmetic only; no GPU work in the test)
  • AI-assisted: yes

…n limits

BuildRectListShaders sized the per-vertex tessellation interface from the
position and the exported parameters only. The generated control and evaluation
shaders also carry the vertex shader's ClipDistance array (up to eight scalars)
as input and output builtins, so for a vertex shader that writes clip distances
the interface was up to eight components larger than the checked size and could
exceed maxTessellationControlPerVertexInputComponents and its siblings. The
sibling barycentric geometry shader already counts them.

The clip distance count is now read before the check, and both the parameter
capacity and the component total include it, so parameters are trimmed to what
fits and an interface that cannot fit is rejected.
…istances

With eight per-vertex components, a ClipDistance[2] vertex shader still builds
and a ClipDistance[8] one is rejected as exceeding the device limits.
@maskym

maskym commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

Windows + NVIDIA result for head 06cc9022b2, merged into main 3b979d42a9 (the PR's GPUs tested line names no NVIDIA run on Windows).

This PR's own tests: agc_rect_list_position_invariant (0.07 s), agc_driver_rect_list_indirect and agc_driver_rect_list_corner, all passed.

Host: Windows 11 26300, Intel i7-12700K, NVIDIA GeForce RTX 2070 SUPER (vendor 0x10de, device 0x1e84; Vulkan loader 1.4.357 from the NVIDIA driver 621.01), Khronos Validation Layers nightly 1.4.366 (b2b44c0d37) through VK_ADD_LAYER_PATH, WinLibs GCC 15.2.0 (x86_64-ucrt-posix-seh, r6), Release, BUILD_TESTING=ON, Ninja. Build clean.

Same focused run on main 3b979d42a9 and on this tree, same machine and GPU: VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, ANYPS5_NO_SHADER_CACHE=1, ANYPS5_REQUIRE_VULKAN=1, VK_LOADER_DEBUG=error,warn,layer, ctest --test-dir build -R '^(agc|guest_video_out|video_out)' --parallel 4 -V.

The tree also carried the open PRs #12298, #12272, #12262, #12256, #12250, #12234, #12211, #12210, #12209, #12208, #12207, all merged cleanly, so the run is a joint one. Not run on a PS5.

AI-assisted: yes (Claude Code), the runs and the numbers above are from this machine.

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