diff --git a/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.Alu.cs b/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.Alu.cs index 6fbf0597..76a054e0 100644 --- a/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.Alu.cs +++ b/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.Alu.cs @@ -38,6 +38,33 @@ public static partial class Gen5SpirvTranslator case "VReadfirstlaneB32": result = GetRawSource(instruction, 0); break; + case "VWritelaneB32": + { + // vdst[lane(src1)] = src0 + // Per-lane: if current lane == src1, write src0, else keep old value. + var oldValue = LoadV(destination); + var src0 = GetRawSource(instruction, 0); + var laneSelect = GetRawSource(instruction, 1); + var currentLane = _subgroupInvocationIdInput != 0 + ? BitwiseAnd( + Load(_uintType, _subgroupInvocationIdInput), + UInt(RdnaWaveLaneCount - 1)) + : UInt(0); + var isTargetLane = _module.AddInstruction( + SpirvOp.IEqual, + _boolType, + currentLane, + laneSelect); + result = _module.AddInstruction( + SpirvOp.Select, + _uintType, + isTargetLane, + src0, + oldValue); + // Writelane writes to a specific lane regardless of exec mask. + StoreV(destination, result, guardWithExec: false); + return true; + } case "VCndmaskB32": { var condition = instruction.Sources.Count > 2 diff --git a/src/SharpEmu.ShaderCompiler/Gen5ShaderTranslator.cs b/src/SharpEmu.ShaderCompiler/Gen5ShaderTranslator.cs index 90df5078..c4155bd8 100644 --- a/src/SharpEmu.ShaderCompiler/Gen5ShaderTranslator.cs +++ b/src/SharpEmu.ShaderCompiler/Gen5ShaderTranslator.cs @@ -911,9 +911,10 @@ public static class Gen5ShaderTranslator 0x16A => "VMulHiU32", 0x16B => "VMulLoI32", 0x16C => "VMulHiI32", - 0x360 => "VMadU32U16", - 0x361 => "VMulLoU32", + 0x360 => "VReadlaneB32", + 0x361 => "VWritelaneB32", 0x362 => "VLdexpF32", + 0x373 => "VMadU32U16", 0x346 => "VLshlAddU32", 0x347 => "VAddLshlU32", 0x36D => "VAdd3U32",