[SpirvTranslator] perf: Clear vertex shader interpolation parameters before translating to SPIR-V

Co-authored-by: Astellou <mathieu.richardeau@gmail.com>
This commit is contained in:
ParantezTech 2026-09-30 19:01:44 +03:00
parent c076513bd6
commit b480391a7b
2 changed files with 16 additions and 3 deletions

View File

@ -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)

View File

@ -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]