SharedAtomicSignedCas.cs
1 using Ryujinx.Graphics.Shader.IntermediateRepresentation; 2 using Ryujinx.Graphics.Shader.Translation.Optimizations; 3 using System.Collections.Generic; 4 using System.Diagnostics; 5 6 using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; 7 8 namespace Ryujinx.Graphics.Shader.Translation.Transforms 9 { 10 class SharedAtomicSignedCas : ITransformPass 11 { 12 public static bool IsEnabled(IGpuAccessor gpuAccessor, ShaderStage stage, TargetLanguage targetLanguage, FeatureFlags usedFeatures) 13 { 14 return targetLanguage != TargetLanguage.Spirv && stage == ShaderStage.Compute && usedFeatures.HasFlag(FeatureFlags.SharedMemory); 15 } 16 17 public static LinkedListNode<INode> RunPass(TransformContext context, LinkedListNode<INode> node) 18 { 19 Operation operation = (Operation)node.Value; 20 HelperFunctionName name; 21 22 if (operation.Inst == Instruction.AtomicMaxS32) 23 { 24 name = HelperFunctionName.SharedAtomicMaxS32; 25 } 26 else if (operation.Inst == Instruction.AtomicMinS32) 27 { 28 name = HelperFunctionName.SharedAtomicMinS32; 29 } 30 else 31 { 32 return node; 33 } 34 35 if (operation.StorageKind != StorageKind.SharedMemory) 36 { 37 return node; 38 } 39 40 Operand result = operation.Dest; 41 Operand memoryId = operation.GetSource(0); 42 Operand byteOffset = operation.GetSource(1); 43 Operand value = operation.GetSource(2); 44 45 Debug.Assert(memoryId.Type == OperandType.Constant); 46 47 int functionId = context.Hfm.GetOrCreateFunctionId(name, memoryId.Value); 48 49 Operand[] callArgs = new Operand[] { Const(functionId), byteOffset, value }; 50 51 LinkedListNode<INode> newNode = node.List.AddBefore(node, new Operation(Instruction.Call, 0, result, callArgs)); 52 53 Utils.DeleteNode(node, operation); 54 55 return newNode; 56 } 57 } 58 }