/ src / Ryujinx.Graphics.Shader / Translation / Transforms / SharedAtomicSignedCas.cs
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  }