|
|
@@ -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;
|