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 }