From 8d9d508dc78eb5225c99cb425fa484999f3c4305 Mon Sep 17 00:00:00 2001 From: riperiperi Date: Sat, 22 Apr 2023 22:02:39 +0100 Subject: Shader: Bias textureGather instructions on AMD/Intel (#4703) * Experimental (GLSL, forced) * SPIR-V attempt * Add capability * Fix pCount == 1 on glsl * Fix typo --- .../CodeGen/Spirv/Instructions.cs | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'Ryujinx.Graphics.Shader/CodeGen/Spirv') 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; -- cgit v1.2.3