Repository navigation
feat(shader): emulate barycentrics and per-vertex parameters on the mesh path - #6941
Conversation
|
On Linux this head (b7cc861, merged onto The new AI-assisted: yes |
b7cc861 to
042bb42
Compare
|
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.
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.
|
|
Thanks, good catch. Both values are fixed (280 and 512) and folded into the first commit, so each commit has them. I syntax-checked |
|
Before/after on the Intel VM from my #5079 list: Arrow Lake iGPU, Mesa 26.1.6 ANV, Debian. That device does expose
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 AI-assisted: yes |
|
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). |
|
The RTX 4070 Ti run with this head (same setup, NVIDIA 595.99.02, which has both extensions) matches AI-assisted: yes |
|
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. |
042bb42 to
2d52296
Compare
|
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: AI-assisted: yes (Claude). |
|
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.
AI-assisted: yes (runs made on the device above). |
|
Thanks for the AMD run. Good to see the new tests pass on RDNA 3 as well; I've added it to the description.
|
2d52296 to
24bb8b0
Compare
|
Rebased on AI-assisted: yes (Claude). |
24bb8b0 to
337833f
Compare
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>
337833f to
a4287f3
Compare
|
Rebased onto current |
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 inDraw.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.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.v_interp_movP10/P20) are staged in workgroup memory and written per primitive, in the order of the triangle indices.DescribeEmulatedInterface, split out of feat(shader): emulate barycentrics through tessellation on devices without geometry shaders #7308'sCollectEmulatedInterface, so the geometry, tessellation and mesh routes share one description of it. The mesh path is handled first inDraw.cpp; the vertex path falls through to the geometry and tessellation builders.FormatVersion38) and the captured request (serializer 33).ShaderValidationaccepts 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.agc_mesh_output_budget.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, but1d6968225records 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
MeshBarycentricEmulationexecution test: 932 perspective, 932 linear and 932 per-vertex pixels match, in under 1 s. It fails without this change. Newagc_mesh_output_budgetchecks the output estimate against hand-computed values (ccleste's configuration: 8 + 10 locations, 36864 bytes), in 0.06 s.ShaderDiskCache.cppwere checked with GCC 13.3 at the first and last commit.BUILD_TESTING=ONon24bb8b0c0(rebased on66e71b63d, after feat(shader): emulate barycentrics through tessellation on devices without geometry shaders #7308): 1475 of 1478 pass.windows_import_modulesandagc_driver_host_import_lifetimealso fail on cleanmain;guest_usbdfailed once and passed on rerun.agc_driver_gpu_indirect_arguments_misaligned_writer_aheadis not built with MinGW GCC (agc tests:GpuIndirectArgumentsMisalignedWriterAhead.cppdoes not compile with MinGW GCC (alignas(65536)) #6716).mainit stops on the barycentric check; with this PR it renders the first level (screenshot below) at about 78 FPS and runs without errors. That run used a warm pipeline cache; the cold-run watchdog in AGC: ccleste (PPSA59322) on Intel Arc (Windows) stops on barycentric emulation after a mesh-path vertex program; a cold first run hits the title's 10 s GPU watchdog #5079 is a separate measurement.main. On an Intel Arrow Lake iGPU (Mesa 26.1.6 ANV, mesh shaders without the barycentric extension), 5 of the 11 get past the stop and 4 are refused by the mesh output memory check (34304 > 32768 bytes with the earlier estimate; 36864 with the spec-based one); see the comments.agc_driver_mesh_barycentric_emulation,agc_mesh_output_budget,agc_shader_disk_cache,agc_shader_memoryandrequest_serializerpass.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)ccleste (PPSA59322) on the Intel Arc 140T with this PR: