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
This commit is contained in:
riperiperi 2021-10-19 00:04:06 +01:00 committed by GitHub
parent fbf40424f4
commit 052deebf26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 3 deletions

View File

@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <summary> /// <summary>
/// Version of the codegen (to be changed when codegen or guest format change). /// Version of the codegen (to be changed when codegen or guest format change).
/// </summary> /// </summary>
private const ulong ShaderCodeGenVersion = 2534; private const ulong ShaderCodeGenVersion = 2750;
// Progress reporting helpers // Progress reporting helpers
private volatile int _shaderCount; private volatile int _shaderCount;

View File

@ -27,6 +27,22 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
throw new ArgumentException($"Invalid node type \"{node?.GetType().Name ?? "null"}\"."); 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) private static string GetExpression(CodeGenContext context, AstOperation operation)
{ {
Instruction inst = operation.Inst; Instruction inst = operation.Inst;
@ -120,7 +136,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
} }
else if ((info.Type & InstType.Special) != 0) else if ((info.Type & InstType.Special) != 0)
{ {
switch (inst) switch (inst & Instruction.Mask)
{ {
case Instruction.Ballot: case Instruction.Ballot:
return Ballot(context, operation); return Ballot(context, operation);
@ -151,6 +167,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
case Instruction.Lod: case Instruction.Lod:
return Lod(context, operation); return Lod(context, operation);
case Instruction.Negate:
return Negate(context, operation, info);
case Instruction.PackDouble2x32: case Instruction.PackDouble2x32:
return PackDouble2x32(context, operation); return PackDouble2x32(context, operation);

View File

@ -97,7 +97,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
Add(Instruction.Multiply, InstType.OpBinaryCom, "*", 1); Add(Instruction.Multiply, InstType.OpBinaryCom, "*", 1);
Add(Instruction.MultiplyHighS32, InstType.CallBinary, HelperFunctionNames.MultiplyHighS32); Add(Instruction.MultiplyHighS32, InstType.CallBinary, HelperFunctionNames.MultiplyHighS32);
Add(Instruction.MultiplyHighU32, InstType.CallBinary, HelperFunctionNames.MultiplyHighU32); 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.ReciprocalSquareRoot, InstType.CallUnary, "inversesqrt");
Add(Instruction.Return, InstType.OpNullary, "return"); Add(Instruction.Return, InstType.OpNullary, "return");
Add(Instruction.Round, InstType.CallUnary, "roundEven"); Add(Instruction.Round, InstType.CallUnary, "roundEven");