aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs')
-rw-r--r--Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs30
1 files changed, 30 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs b/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
index 14d6ab52..b3db1905 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
+++ b/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
@@ -4,6 +4,7 @@ using Ryujinx.Graphics.Shader.Translation;
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Linq;
using System.Numerics;
using static Spv.Specification;
@@ -1556,6 +1557,33 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
}
}
+ SpvInstruction ApplyBias(SpvInstruction vector, SpvInstruction image)
+ {
+ int gatherBiasPrecision = context.Config.GpuAccessor.QueryHostGatherBiasPrecision();
+ if (isGather && gatherBiasPrecision != 0)
+ {
+ // GPU requires texture gather to be slightly offset to match NVIDIA behaviour when point is exactly between two texels.
+ // Offset by the gather precision divided by 2 to correct for rounding.
+ var sizeType = pCount == 1 ? context.TypeS32() : context.TypeVector(context.TypeS32(), pCount);
+ var pVectorType = pCount == 1 ? context.TypeFP32() : context.TypeVector(context.TypeFP32(), pCount);
+
+ var bias = context.Constant(context.TypeFP32(), (float)(1 << (gatherBiasPrecision + 1)));
+ var biasVector = context.CompositeConstruct(pVectorType, Enumerable.Repeat(bias, pCount).ToArray());
+
+ var one = context.Constant(context.TypeFP32(), 1f);
+ var oneVector = context.CompositeConstruct(pVectorType, Enumerable.Repeat(one, pCount).ToArray());
+
+ var divisor = context.FMul(
+ pVectorType,
+ context.ConvertSToF(pVectorType, context.ImageQuerySize(sizeType, image)),
+ biasVector);
+
+ vector = context.FAdd(pVectorType, vector, context.FDiv(pVectorType, oneVector, divisor));
+ }
+
+ return vector;
+ }
+
SpvInstruction pCoords = AssemblePVector(pCount);
pCoords = ScalingHelpers.ApplyScaling(context, texOp, pCoords, intCoords, isBindless, isIndexed, isArray, pCount);
@@ -1716,6 +1744,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
image = context.Image(imageType, image);
}
+ pCoords = ApplyBias(pCoords, image);
+
var operands = operandsList.ToArray();
SpvInstruction result;