Skip to content

feat(shader): emulate barycentrics and per-vertex parameters on the mesh path - #6941

Merged
adriadam10 merged 5 commits into
boykopovar:mainfrom
kq62:fix/mesh-barycentric-emulation
Oct 19, 2026
Merged

adriadam10 merged 5 commits into
boykopovar:mainfrom
kq62:fix/mesh-barycentric-emulation

Conversation

@kq62

@kq62 kq62 commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

What

Fixes #5079. On a device without VK_KHR_fragment_shader_barycentric, a pixel shader that reads barycentrics after an NGG program on the mesh path stopped in Draw.cpp ("needs a vertex shader before it"): the vertex-path emulation inserts a generated geometry stage, which a mesh pipeline cannot have. This blocks ccleste (PPSA59322) on Intel Arc on Windows, and #5079 reports the same stop in about a dozen catalog homebrew on other devices.

  • The mesh program is compiled a second time with the layout its pixel shader needs (MeshBarycentricLayout, taken from the pixel compile result). It writes its clip position as a varying and the three corner clip positions of each primitive as per-primitive outputs. The pixel shader solves a 3x3 system for the weights, for smooth and linear interpolation.
  • Per-vertex parameters (v_interp_mov P10/P20) are staged in workgroup memory and written per primitive, in the order of the triangle indices.
  • The emulated interface comes from DescribeEmulatedInterface, split out of feat(shader): emulate barycentrics through tessellation on devices without geometry shaders #7308's CollectEmulatedInterface, so the geometry, tessellation and mesh routes share one description of it. The mesh path is handled first in Draw.cpp; the vertex path falls through to the geometry and tessellation builders.
  • The layout is part of the mesh cache key, the disk artifact (FormatVersion 38) and the captured request (serializer 33). ShaderValidation accepts a per-primitive interface only at the locations the layout reserves, and only for mesh outputs and pixel inputs; guest per-primitive user outputs still throw.
  • It throws when the provoking vertex is not the first, when the workgroup staging exceeds the device's mesh shared memory, when the output components or output memory exceed the device's limits, and on a device with neither the extension nor mesh shaders (new message and technical-debt entry). The output estimate follows the spec formula in "Mesh Shader Output" (4 scalars per location, granularity, every declared built-in except primitive indices) and is tested in agc_mesh_output_budget.
  • On devices with the extension the layout is never set, so nothing changes there. On devices without it, a mesh program that feeds an emulating pixel shader is compiled twice (registration, then paired).

Not measured on PS5: the weights match the analytic values within the existing test tolerance, not hardware I/J bit for bit, and the vertex order of per-vertex parameters follows the triangle indices with the first provoking vertex.

lavapipe exposes VK_EXT_mesh_shader, but 1d6968225 records that mesh pipeline draws die with an LLVM error on Mesa 25.2.8 / LLVM 20.1.2. The new test skips on llvmpipe like the existing mesh test, and lavapipe titles may move from the clean error to that crash. There is no llvmpipe-specific handling.

Related: #7308 adds the tessellation route for the vertex path on devices without geometry shaders and shares the interface helper with this PR. #6523 adds a general mesh-shader check in ValidateShaders, which complements the barycentric-specific message here. #6612 touches the same files and versions, so whichever lands second rebases. #6470 is nearby.

Tested

Checklist

ccleste (PPSA59322) on the Intel Arc 140T with this PR:

image

@kq62 kq62 changed the title Fix/mesh barycentric emulation feat(shader): emulate barycentrics and per-vertex parameters on the mesh path Oct 16, 2026
@kq62 kq62 changed the title feat(shader): emulate barycentrics and per-vertex parameters on the mesh path feat(shader): emulate barycentrics and per-vertex parameters on the mesh path Oct 16, 2026
@milescoviello

Copy link
Copy Markdown
Contributor

On Linux this head (b7cc861, merged onto main 1b1f848, Ubuntu 24.04, GCC 13.3, Release) doesn't build. Two of the libstdc++-only size checks in ShaderDiskCache.cpp fail:

ShaderDiskCache.cpp:87: static_assert(sizeof(CompiledShaderArtifact) == 240 ...)  the comparison reduces to '(280 == 240)'
ShaderDiskCache.cpp:89: static_assert(sizeof(RecompileResult) == 472 ...)         the comparison reduces to '(512 == 472)'

The new std::optional<MeshBarycentricLayout> meshBarycentrics adds the 40 bytes. encodeArtifact/decodeArtifact already write and read it, and EncodeResult goes through encodeArtifact, so only the two expected sizes need updating (280 and 512). These checks only exist under __linux__ && __x86_64__ && __GLIBCXX__, which is probably why your build passed. I'll run the before/after lists with those two numbers changed locally and post the results here.

AI-assisted: yes

@kq62
kq62 force-pushed the fix/mesh-barycentric-emulation branch from b7cc861 to 042bb42 Compare October 16, 2026 20:43
@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

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.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 4891 core/libs/prx/libSceAgcDriver/CMakeLists.txt L2022
PR 6612 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp L473-474
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp L26-27
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp L345, L621-622, L658-659
core/shader/recompiler/CacheKey.hpp L104-105, L109
core/shader/recompiler/tests/RequestSerializerTests.cpp L210, L249, L274, L397-400, L411, L431, L433
PR 6639 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp L53
core/shader/recompiler/tests/RequestSerializerTests.cpp L210, L249, L274, L398, L411, L431, L433
PR 6679 core/shader/recompiler/tests/RequestSerializerTests.cpp L210, L249, L274, L397-400, L411, L431, L433
PR 6801 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp L53
PR 6959 core/shader/recompiler/Recompiler.cpp L593
PR 7410 core/shader/recompiler/tests/RequestSerializerTests.cpp L210, L249, L274, L398, L411, L431, L433
PR 7677 core/libs/prx/libSceAgcDriver/CMakeLists.txt L2022
PR 7831 core/shader/recompiler/Recompiler.hpp L477-492, L496
core/shader/recompiler/ShaderDiskCache.cpp L506, L553
core/shader/recompiler/SpirvBackend/src/BarycentricGeometryShader.cpp L398
core/shader/recompiler/SpirvBackend/src/SpirvMemory/SpirvEmitterHelpers.cpp L221
PR 7888 core/shader/recompiler/Recompiler.cpp L573
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp L31
core/shader/recompiler/tests/RequestSerializerTests.cpp L210, L249, L274, L398, L411, L431, L433
PR 7933 core/shader/recompiler/CMakeLists.txt L238
PR 8004 core/shader/recompiler/tests/RequestSerializerTests.cpp L210, L249, L274, L398, L411, L431, L433

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 1368 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1896 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
PR 2434 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 4072 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp
core/shader/recompiler/Recompiler.cpp
PR 5021 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
PR 5058 docs/dev/debt/libSceAgcDriver.md
PR 5371 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
PR 5404 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
PR 5426 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5431 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
PR 5441 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
PR 5499 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 5500 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
PR 5609 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 5656 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 5925 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/shader/recompiler/CMakeLists.txt
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6044 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6146 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6177 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
PR 6185 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6186 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6187 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/shader/recompiler/Recompiler.hpp
PR 6192 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6194 docs/dev/debt/libSceAgcDriver.md
PR 6209 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6223 docs/dev/debt/libSceAgcDriver.md
PR 6235 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvMemory/SpirvEmitterHelpers.cpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
PR 6273 docs/dev/debt/libSceAgcDriver.md
PR 6280 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6290 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
PR 6292 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 6300 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6412 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6481 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6488 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/ShaderDiskCache.cpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
PR 6501 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 6539 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6548 docs/dev/debt/libSceAgcDriver.md
PR 6549 docs/dev/debt/libSceAgcDriver.md
PR 6604 core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
PR 6611 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/Recompiler.cpp
PR 6615 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 6636 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6645 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
PR 6682 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6683 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6718 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6727 docs/dev/debt/libSceAgcDriver.md
PR 6730 docs/dev/debt/libSceAgcDriver.md
PR 6747 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6759 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6788 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6808 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6820 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6867 docs/dev/debt/libSceAgcDriver.md
PR 6868 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6879 core/shader/recompiler/CMakeLists.txt
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6924 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6926 docs/dev/debt/libSceAgcDriver.md
PR 6946 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/CMakeLists.txt
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6947 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CMakeLists.txt
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
core/shader/recompiler/SpirvBackend/src/SpirvMemory/SpirvEmitterHelpers.cpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6970 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6977 core/shader/recompiler/CMakeLists.txt
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/ShaderDiskCache.cpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
docs/dev/debt/libSceAgcDriver.md
PR 7048 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7201 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/shader/recompiler/CMakeLists.txt
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvMemory/SpirvEmitterHelpers.cpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
PR 7223 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7256 docs/dev/debt/libSceAgcDriver.md
PR 7332 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CMakeLists.txt
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/BarycentricGeometryShader.cpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
core/shader/recompiler/SpirvBackend/src/SpirvMemory/SpirvEmitterHelpers.cpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7369 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
PR 7392 core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
PR 7395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7427 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7446 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7449 docs/dev/debt/libSceAgcDriver.md
PR 7457 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7484 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
PR 7505 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7514 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7533 docs/dev/debt/libSceAgcDriver.md
PR 7550 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7604 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7615 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7642 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CMakeLists.txt
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
core/shader/recompiler/SpirvBackend/src/SpirvMemory/SpirvEmitterHelpers.cpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7684 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7689 core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7800 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7844 docs/dev/debt/libSceAgcDriver.md
PR 7927 docs/dev/debt/libSceAgcDriver.md
PR 7978 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
docs/dev/debt/libSceAgcDriver.md
PR 8014 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8099 docs/dev/debt/libSceAgcDriver.md

@kq62

kq62 commented Oct 16, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, good catch. Both values are fixed (280 and 512) and folded into the first commit, so each commit has them. I syntax-checked ShaderDiskCache.cpp on Linux with GCC 13.3 at the first and the last commit, and both asserts hold; I haven't done a full Linux build. Those checks are behind __linux__ && __x86_64__ && __GLIBCXX__, so my MinGW build never compiled them. The new head is 042bb42. Looking forward to the before/after runs.

@milescoviello

Copy link
Copy Markdown
Contributor

Before/after on the Intel VM from my #5079 list: Arrow Lake iGPU, Mesa 26.1.6 ANV, Debian. main 1b1f848 vs that main + this head b7cc861, with the two Linux size checks set to 280/512 locally. Release build, 40 s with pad input, one run each.

That device does expose VK_EXT_mesh_shader; my note on #5079 was wrong. It has no VK_KHR_fragment_shader_barycentric, and maxMeshOutputMemorySize is 32768. So it is the combination this PR targets.

App main with this PR
VLC (PPSA85300) barycentrics stop, 0 s reaches 40 s
PSXS5 (PPSA97510) barycentrics stop, 1 s reaches 45 s
SwanStationPS5 (PPSA98510) barycentrics stop, 1 s reaches 45 s
Porpoise (PPSA99764) barycentrics stop, 10 s reaches 41 s
Mario 64 (PPSA99310) barycentrics stop, 4 s exits on its own at 8 s (status 0), as on NVIDIA
ccleste (PPSA59322) barycentrics stop, 4 s barycentric emulation on the mesh path needs 34304 bytes of mesh output memory, the device allows 32768, 3 s
RommPS (PPSA76677) barycentrics stop, 6 s the same 34304 > 32768 refusal, 6 s
ProsperoAI (PPSA99004) barycentrics stop, 8 s the same refusal, 9 s
Mortalfin (PPSA99141) barycentrics stop, 7 s the same refusal, 6 s
Ruffle (PPSA68091) barycentrics stop, 0 s still a pixel shader that reads barycentrics without VK_KHR_fragment_shader_barycentric needs a vertex shader before it, 1 s
Dusklight (PPSA99305) barycentrics stop, 15 s still the same message, 15 s

So 5 of the 11 get past the stop, and 4 are refused because the emulation would need 1,536 bytes more mesh output memory than ANV allows. Ruffle and Dusklight still hit the old message, which may be a draw this PR doesn't route. On the RTX 4070 Ti, which has both extensions, all 11 ran to the limit on main except Dusklight (posix_spawnp, unrelated) and Mario 64 (its own exit). The run with this PR there is still going, and I'll add it.

AI-assisted: yes

@kq62

kq62 commented Oct 16, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, this is exactly the device this PR targets, and very useful.

On the four refusals: the shortfall is exactly 1536 bytes, which is 3 components x 128 primitives x 4 bytes. The per-primitive corner positions are stored as full vec4s, but the solve only needs x, y and w, so dropping z may bring these titles to exactly 32768. I'm checking the estimate against the spec's output memory formula before changing it, since it has to match how the driver counts.

Ruffle and Dusklight hit the vertex-path branch, so that's a different draw that this PR doesn't route. If you still have those logs, the shader preparation lines just before the stop would help for a separate issue.

AI-assisted: yes (Claude).

@milescoviello

Copy link
Copy Markdown
Contributor

The RTX 4070 Ti run with this head (same setup, NVIDIA 595.99.02, which has both extensions) matches main on all 11: the same nine reach 40–45 s, Mario 64 exits on its own at 8 s, and Dusklight stops on the unrelated posix_spawnp call (#6233). No new messages either way.

AI-assisted: yes

@kq62

kq62 commented Oct 16, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, that confirms devices with the extension are unchanged, which I couldn't test myself. I've added both of your runs to the description.

@kq62
kq62 force-pushed the fix/mesh-barycentric-emulation branch from 042bb42 to 2d52296 Compare October 16, 2026 21:00
@kq62

kq62 commented Oct 16, 2026

Copy link
Copy Markdown
Contributor Author

Follow-up on the four refusals: dropping z doesn't help. The spec's "Mesh Shader Output" formula counts whole locations (4 scalars each), so a vec3 costs the same as a vec4. Checking it also showed our estimate undercounted (vec3 varying as 3 scalars, CullPrimitiveEXT left out), so it now follows the formula exactly, with granularity and every declared built-in except primitive indices. For ccleste's configuration that is 36864 bytes, so those four apps stay refused on ANV's 32768, now with the correct number.

Fitting them needs packing several values into shared locations, which depends on which channels the pixel shader actually reads. I'll do that as a follow-up PR after this one, to keep this one reviewable. New head: 2d52296a8.

AI-assisted: yes (Claude).

@github-actions github-actions Bot added build shader core/shader docs agc libSceAgc* fix error Closes an issue (Fixes #N) labels Oct 16, 2026
@keravyn-ops

Copy link
Copy Markdown
Contributor

AMD / Windows run of this PR at 2d52296: Radeon 780M (RDNA 3, 0x15bf), AMD driver 25.10.20.01 (32.0.21020.1007), Windows 11 Home 10.0.26100, WinLibs GCC 15.2.0 r7, Release.

  • agc_driver_mesh_barycentric_emulation: pass (932 perspective and 932 linear I/J pixels, 932 raw vertex value pixels, 0.59 s)
  • agc_mesh_output_budget: pass (0.17 s)
  • agc_shader_disk_cache: pass (2.07 s)
  • agc_shader_memory: pass (0.43 s)
  • request_serializer: pass (0.06 s)

AI-assisted: yes (runs made on the device above).

@kq62

kq62 commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the AMD run. Good to see the new tests pass on RDNA 3 as well; I've added it to the description.

AMD / Windows run of this PR at 2d52296: Radeon 780M (RDNA 3, 0x15bf), AMD driver 25.10.20.01 (32.0.21020.1007), Windows 11 Home 10.0.26100, WinLibs GCC 15.2.0 r7, Release.

  • agc_driver_mesh_barycentric_emulation: pass (932 perspective and 932 linear I/J pixels, 932 raw vertex value pixels, 0.59 s)
  • agc_mesh_output_budget: pass (0.17 s)
  • agc_shader_disk_cache: pass (2.07 s)
  • agc_shader_memory: pass (0.43 s)
  • request_serializer: pass (0.06 s)

AI-assisted: yes (runs made on the device above).

@kq62

kq62 commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

Rebased on 66e71b63d (after #7308). The emulated interface is now DescribeEmulatedInterface, split out of #7308's CollectEmulatedInterface, so the geometry, tessellation and mesh routes share it. FormatVersion is 38; the Linux size asserts stay at main's value plus 40 bytes (280 and 512), checked with GCC 13.3 at the first and last commit. Full ctest: 1475 of 1478, with the three failures also seen on main or flaky. ccleste still renders correctly on the Arc. New head: 24bb8b0c0.

AI-assisted: yes (Claude).

@github-actions github-actions Bot added needs rebase Conflicts with main, rebase needed and removed needs rebase Conflicts with main, rebase needed labels Oct 18, 2026
@DavidSamir DavidSamir mentioned this pull request Oct 18, 2026
@github-actions github-actions Bot added the unblocks title Names a title ID on the Unblocks line label Oct 18, 2026
@adriadam10 adriadam10 self-assigned this Oct 19, 2026
@adriadam10
adriadam10 force-pushed the fix/mesh-barycentric-emulation branch from 24bb8b0 to 337833f Compare October 19, 2026 12:31
@github-actions github-actions Bot added needs rebase Conflicts with main, rebase needed and removed needs rebase Conflicts with main, rebase needed labels Oct 19, 2026
kq62 and others added 5 commits October 19, 2026 17:26
A pixel shader that reads barycentrics on a device without
VK_KHR_fragment_shader_barycentric used to need a vertex shader so a
generated geometry stage could follow it, which a mesh pipeline cannot
have. The mesh program is now compiled a second time with the layout
its pixel shader needs: it writes its clip position as a varying and the
three corner positions of each primitive as per-primitive outputs, and
the pixel shader solves for the weights, for both smooth and linear
interpolation.

The layout is part of the mesh cache key, the stored artifact and the
captured request. Without VK_EXT_mesh_shader the draw still throws, now
saying so. Per-vertex parameters on the mesh path still throw.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A pixel shader that reads per-vertex parameters (v_interp_mov of P10 and
P20) on a device without VK_KHR_fragment_shader_barycentric now works on
the mesh path too. The mesh program stages each such parameter in
workgroup memory and writes the values of the three vertices of every
primitive as a per-primitive output, in the order of the triangle
indices; the pixel shader reads them from there.

The emulation throws when the staging, the output components or the
output memory exceed the device's mesh limits, or when the mesh
configuration uses a provoking vertex other than the first.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… provided

A pixel shader on the mesh path that reads barycentrics on a device with
neither VK_KHR_fragment_shader_barycentric nor VK_EXT_mesh_shader
reported only the missing mesh shaders. Say that the device has neither,
so reports from such devices are told apart from the case the emulation
covers.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@adriadam10
adriadam10 force-pushed the fix/mesh-barycentric-emulation branch from 337833f to a4287f3 Compare October 19, 2026 15:35
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 19, 2026
@adriadam10
adriadam10 merged commit 9b4b3cf into boykopovar:main Oct 19, 2026
10 checks passed
@adriadam10

Copy link
Copy Markdown
Collaborator

Rebased onto current main (it moved Draw.cpp; the stencil value export had already taken request serializer version 37, so this PR's mesh barycentric field is now version 38; only RequestSerializerTests.cpp conflicted). I also updated agc_shader_memory, which still expected 37 and treated 38 as unsupported. No logic changed. The 3x3 barycentric solve, per-vertex staging in workgroup memory, output/shared-memory budget checks and cache key/serializer plumbing were checked earlier on this head; third-party runs on RTX 4070 Ti (ANV) and Radeon 780M confirm it on hardware; merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* build 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