aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Shader/Translation
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2023-05-26 15:19:37 -0300
committerGitHub <noreply@github.com>2023-05-26 15:19:37 -0300
commit3b375525fbaded422fb2f9a9984a5770a3779fcb (patch)
tree432cd22c8f445ece592f8a8fbeb4fdef01c95390 /src/Ryujinx.Graphics.Shader/Translation
parente6658c133ca8bef4a6612d6feabfc6180f0c8318 (diff)
Force reciprocal operation with value biased by constant to be precise on macOS (#5110)
* Force operations to be precise in some cases on SPIR-V * Make it a bit more strict, add comments * Shader cache version bump
Diffstat (limited to 'src/Ryujinx.Graphics.Shader/Translation')
-rw-r--r--src/Ryujinx.Graphics.Shader/Translation/Rewriter.cs25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Shader/Translation/Rewriter.cs b/src/Ryujinx.Graphics.Shader/Translation/Rewriter.cs
index eab0f9d2..866ae522 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/Rewriter.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/Rewriter.cs
@@ -14,6 +14,7 @@ namespace Ryujinx.Graphics.Shader.Translation
public static void RunPass(HelperFunctionManager hfm, BasicBlock[] blocks, ShaderConfig config)
{
bool isVertexShader = config.Stage == ShaderStage.Vertex;
+ bool isImpreciseFragmentShader = config.Stage == ShaderStage.Fragment && config.GpuAccessor.QueryHostReducedPrecision();
bool hasConstantBufferDrawParameters = config.GpuAccessor.QueryHasConstantBufferDrawParameters();
bool hasVectorIndexingBug = config.GpuAccessor.QueryHostHasVectorIndexingBug();
bool supportsSnormBufferTextureFormat = config.GpuAccessor.QueryHostSupportsSnormBufferTextureFormat();
@@ -45,6 +46,11 @@ namespace Ryujinx.Graphics.Shader.Translation
}
}
+ if (isImpreciseFragmentShader)
+ {
+ EnableForcePreciseIfNeeded(operation);
+ }
+
if (hasVectorIndexingBug)
{
InsertVectorComponentSelect(node, config);
@@ -81,6 +87,25 @@ namespace Ryujinx.Graphics.Shader.Translation
}
}
+ private static void EnableForcePreciseIfNeeded(Operation operation)
+ {
+ // There are some cases where a small bias is added to values to prevent division by zero.
+ // When operating with reduced precision, it is possible for this bias to get rounded to 0
+ // and cause a division by zero.
+ // To prevent that, we force those operations to be precise even if the host wants
+ // imprecise operations for performance.
+
+ if (operation.Inst == (Instruction.FP32 | Instruction.Divide) &&
+ operation.GetSource(0).Type == OperandType.Constant &&
+ operation.GetSource(0).AsFloat() == 1f &&
+ operation.GetSource(1).AsgOp is Operation addOp &&
+ addOp.Inst == (Instruction.FP32 | Instruction.Add) &&
+ addOp.GetSource(1).Type == OperandType.Constant)
+ {
+ addOp.ForcePrecise = true;
+ }
+ }
+
private static void InsertVectorComponentSelect(LinkedListNode<INode> node, ShaderConfig config)
{
Operation operation = (Operation)node.Value;