/ src / Ryujinx.Graphics.Shader / Translation / Transforms / ForcePreciseEnable.cs
ForcePreciseEnable.cs
 1  using Ryujinx.Graphics.Shader.IntermediateRepresentation;
 2  using System.Collections.Generic;
 3  
 4  namespace Ryujinx.Graphics.Shader.Translation.Transforms
 5  {
 6      class ForcePreciseEnable : ITransformPass
 7      {
 8          public static bool IsEnabled(IGpuAccessor gpuAccessor, ShaderStage stage, TargetLanguage targetLanguage, FeatureFlags usedFeatures)
 9          {
10              return stage == ShaderStage.Fragment && gpuAccessor.QueryHostReducedPrecision();
11          }
12  
13          public static LinkedListNode<INode> RunPass(TransformContext context, LinkedListNode<INode> node)
14          {
15              // There are some cases where a small bias is added to values to prevent division by zero.
16              // When operating with reduced precision, it is possible for this bias to get rounded to 0
17              // and cause a division by zero.
18              // To prevent that, we force those operations to be precise even if the host wants
19              // imprecise operations for performance.
20  
21              Operation operation = (Operation)node.Value;
22  
23              if (operation.Inst == (Instruction.FP32 | Instruction.Divide) &&
24                  operation.GetSource(0).Type == OperandType.Constant &&
25                  operation.GetSource(0).AsFloat() == 1f &&
26                  operation.GetSource(1).AsgOp is Operation addOp &&
27                  addOp.Inst == (Instruction.FP32 | Instruction.Add) &&
28                  addOp.GetSource(1).Type == OperandType.Constant)
29              {
30                  addOp.ForcePrecise = true;
31              }
32  
33              return node;
34          }
35      }
36  }