From 84c830f7cef1632f7fee63f5f2d71c9091c0edbf Mon Sep 17 00:00:00 2001 From: ParantezTech <12572227+par274@users.noreply.github.com> Date: Sun, 11 Oct 2026 01:35:27 +0300 Subject: [PATCH] [ShaderCompiler] Skip EXEC selects for vector writes no lane observes --- .../Gen5SpirvTranslator.cs | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.cs b/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.cs index 1ec485f..2e30de4 100644 --- a/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.cs +++ b/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.cs @@ -1420,10 +1420,12 @@ public static partial class Gen5SpirvTranslator } _execKnownFull = IsExecKnownFull(instruction.Pc); + _unobservedWrites = ObservationPlan()?.UnobservedWrites(instruction.Pc) ?? default; var emitted = _pairedLanes && IsPairedLaneInstruction(instruction) ? TryEmitPairedLaneInstruction(instruction, out error) : TryEmitInstruction(instruction, out error); _execKnownFull = false; + _unobservedWrites = default; if (!emitted) { error = $"pc=0x{instruction.Pc:X} {instruction.Opcode}: {error}"; @@ -7719,9 +7721,29 @@ public static partial class Gen5SpirvTranslator return _execFullPcs.Contains(pc); } + private static readonly bool ExecSelectElimination = !string.Equals( + Environment.GetEnvironmentVariable("SHARPEMU_EXEC_SELECT_ELIMINATION"), "0", StringComparison.Ordinal); + + private Ir.VectorRegisterSet _unobservedWrites; + private Ir.Gen5VectorObservationPlan? _observationPlan; + private bool _observationPlanBuilt; + + private Ir.Gen5VectorObservationPlan? ObservationPlan() + { + if (!_observationPlanBuilt) + { + _observationPlanBuilt = true; + _observationPlan = ExecSelectElimination + ? Ir.Gen5VectorObservationAnalysis.Analyze(_request.Program, wave32: _waveLaneCount == 32) + : null; + } + + return _observationPlan; + } + private void StoreV(uint register, uint value, bool guardWithExec = true) { - if (guardWithExec && !_execKnownFull) + if (guardWithExec && !_execKnownFull && !_unobservedWrites.Contains(register)) { var active = Load(_boolType, _exec); var oldValue = LoadV(register);