From 052deebf26beb5e62e677e8d31c2eb024beaa82f Mon Sep 17 00:00:00 2001 From: riperiperi Date: Tue, 19 Oct 2021 00:04:06 +0100 Subject: [PATCH] Another workaround for NVIDIA driver 496.13 shader bug (#2750) * Another workaround for NVIDIA driver 496.13 shader bug This might work better than the other one. Give this a test to see if it fixes/doesn't fix issues with the other one. The problem seems to be when any variable assignment happens with a negation. `temp_1 = -temp_0;` seems to trigger weird behaviour, but `temp_1 = 0.0 - temp_0;` does not. This also might to extend towards integer types? * Update cache version * Add disclaimer comment * Wording --- Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs | 2 +- .../CodeGen/Glsl/Instructions/InstGen.cs | 21 ++++++++++++++++++- .../Glsl/Instructions/InstGenHelper.cs | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index f2180820..c33b35f6 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// /// Version of the codegen (to be changed when codegen or guest format change). /// - private const ulong ShaderCodeGenVersion = 2534; + private const ulong ShaderCodeGenVersion = 2750; // Progress reporting helpers private volatile int _shaderCount; diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs index 3fa13eb5..4c2582f0 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs @@ -27,6 +27,22 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions throw new ArgumentException($"Invalid node type \"{node?.GetType().Name ?? "null"}\"."); } + public static string Negate(CodeGenContext context, AstOperation operation, InstInfo info) + { + IAstNode src = operation.GetSource(0); + + VariableType type = GetSrcVarType(operation.Inst, 0); + + string srcExpr = GetSoureExpr(context, src, type); + + NumberFormatter.TryFormat(0, type, out string zero); + + // Starting in the 496.13 NVIDIA driver, there's an issue with assigning variables to negated expressions. + // (-expr) does not work, but (0.0 - expr) does. This should be removed once the issue is resolved. + + return $"{zero} - {Enclose(srcExpr, src, operation.Inst, info, false)}"; + } + private static string GetExpression(CodeGenContext context, AstOperation operation) { Instruction inst = operation.Inst; @@ -120,7 +136,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions } else if ((info.Type & InstType.Special) != 0) { - switch (inst) + switch (inst & Instruction.Mask) { case Instruction.Ballot: return Ballot(context, operation); @@ -151,6 +167,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions case Instruction.Lod: return Lod(context, operation); + case Instruction.Negate: + return Negate(context, operation, info); + case Instruction.PackDouble2x32: return PackDouble2x32(context, operation); diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs index 424a1c4f..022cd746 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs @@ -97,7 +97,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions Add(Instruction.Multiply, InstType.OpBinaryCom, "*", 1); Add(Instruction.MultiplyHighS32, InstType.CallBinary, HelperFunctionNames.MultiplyHighS32); Add(Instruction.MultiplyHighU32, InstType.CallBinary, HelperFunctionNames.MultiplyHighU32); - Add(Instruction.Negate, InstType.OpUnary, "-", 0); + Add(Instruction.Negate, InstType.Special); Add(Instruction.ReciprocalSquareRoot, InstType.CallUnary, "inversesqrt"); Add(Instruction.Return, InstType.OpNullary, "return"); Add(Instruction.Round, InstType.CallUnary, "roundEven");