From b480391a7b724cac2f6fe60dc2d0f94e91703dc7 Mon Sep 17 00:00:00 2001 From: ParantezTech <12572227+par274@users.noreply.github.com> Date: Wed, 30 Sep 2026 19:01:44 +0300 Subject: [PATCH] [SpirvTranslator] perf: Clear vertex shader interpolation parameters before translating to SPIR-V Co-authored-by: Astellou --- .../Gen5SpirvTranslator.Interpolation.cs | 9 ++++++++- .../Gen5InterpolationParameterTests.cs | 10 ++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.Interpolation.cs b/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.Interpolation.cs index 5ad3efc..9a7f160 100644 --- a/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.Interpolation.cs +++ b/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.Interpolation.cs @@ -34,7 +34,11 @@ public static partial class Gen5SpirvTranslator if (!_request.SupportsPerVertexPixelInputs) { // Reading P0 alone is the provoking vertex value, which a flat input gives. - // Other parameters still need the per-vertex values. + // Preserve that exact case. For selectors that need P1/P2, fall back to the + // ordinary interpolated input. This is not an exact reconstruction of the + // three vertex values, but it keeps shaders usable on devices without + // fragmentShaderBarycentric (notably pre-Turing NVIDIA hardware) and avoids + // emitting SPV_KHR_fragment_shader_barycentric on an unsupported device. foreach (var attribute in _perVertexAttributes.ToArray()) { if (_request.Program.Instructions.All(instruction => @@ -46,6 +50,9 @@ public static partial class Gen5SpirvTranslator _flatParameterAttributes.Add(attribute); } } + + _perVertexAttributes.Clear(); + return; } if (_perVertexAttributes.Count == 0) diff --git a/tests/SharpEmu.ShaderCompiler.Tests/Gen5InterpolationParameterTests.cs b/tests/SharpEmu.ShaderCompiler.Tests/Gen5InterpolationParameterTests.cs index 39a8306..0186767 100644 --- a/tests/SharpEmu.ShaderCompiler.Tests/Gen5InterpolationParameterTests.cs +++ b/tests/SharpEmu.ShaderCompiler.Tests/Gen5InterpolationParameterTests.cs @@ -99,12 +99,18 @@ public sealed class Gen5InterpolationParameterTests [Theory] [InlineData(0u)] [InlineData(1u)] - public void VertexDifferenceMove_KeepsPerVertexInputWithoutPerVertexSupport(uint selector) + public void VertexDifferenceMove_FallsBackToInterpolatedInputWithoutPerVertexSupport(uint selector) { var request = Request(selector, false, inputCntl: 0x1, supportsPerVertex: false); Assert.True(Gen5SpirvTranslator.TryCompileProgram(request, out var shader, out var error), error); - Assert.Contains(Instructions(shader.Spirv), instruction => instruction.Opcode == SpirvOp.Decorate && + var instructions = Instructions(shader.Spirv); + Assert.DoesNotContain(instructions, instruction => instruction.Opcode == SpirvOp.Capability && + instruction.Operands[0] == (uint)SpirvCapability.FragmentBarycentricKhr); + Assert.DoesNotContain(instructions, instruction => instruction.Opcode == SpirvOp.Decorate && instruction.Operands[1] == (uint)SpirvDecoration.PerVertexKhr); + Assert.DoesNotContain(instructions, instruction => instruction.Opcode == SpirvOp.Decorate && + instruction.Operands[1] == (uint)SpirvDecoration.Flat); + ValidateWhenAvailable(shader.Spirv); } [Fact]