aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs')
-rw-r--r--Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs55
1 files changed, 47 insertions, 8 deletions
diff --git a/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs b/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
index 73d89761..0c196c4d 100644
--- a/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
@@ -1,4 +1,5 @@
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.Instructions;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using System.Collections.Generic;
namespace Ryujinx.Graphics.Shader.Translation.Optimizations
@@ -30,11 +31,19 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
texOp.Inst == Instruction.TextureSize)
{
Operand bindlessHandle = Utils.FindLastOperation(texOp.GetSource(0), block);
- bool rewriteSamplerType = texOp.Inst == Instruction.TextureSize;
+
+ // Some instructions do not encode an accurate sampler type:
+ // - Most instructions uses the same type for 1D and Buffer.
+ // - Query instructions may not have any type.
+ // For those cases, we need to try getting the type from current GPU state,
+ // as long bindless elimination is successful and we know where the texture descriptor is located.
+ bool rewriteSamplerType =
+ texOp.Type == SamplerType.TextureBuffer ||
+ texOp.Inst == Instruction.TextureSize;
if (bindlessHandle.Type == OperandType.ConstantBuffer)
{
- SetHandle(config, texOp, bindlessHandle.GetCbufOffset(), bindlessHandle.GetCbufSlot(), rewriteSamplerType);
+ SetHandle(config, texOp, bindlessHandle.GetCbufOffset(), bindlessHandle.GetCbufSlot(), rewriteSamplerType, isImage: false);
continue;
}
@@ -137,7 +146,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
texOp,
TextureHandle.PackOffsets(src0.GetCbufOffset(), ((src1.Value >> 20) & 0xfff), handleType),
TextureHandle.PackSlots(src0.GetCbufSlot(), 0),
- rewriteSamplerType);
+ rewriteSamplerType,
+ isImage: false);
}
else if (src1.Type == OperandType.ConstantBuffer)
{
@@ -146,7 +156,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
texOp,
TextureHandle.PackOffsets(src0.GetCbufOffset(), src1.GetCbufOffset(), handleType),
TextureHandle.PackSlots(src0.GetCbufSlot(), src1.GetCbufSlot()),
- rewriteSamplerType);
+ rewriteSamplerType,
+ isImage: false);
}
}
else if (texOp.Inst == Instruction.ImageLoad ||
@@ -172,7 +183,9 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
}
}
- SetHandle(config, texOp, cbufOffset, cbufSlot, false);
+ bool rewriteSamplerType = texOp.Type == SamplerType.TextureBuffer;
+
+ SetHandle(config, texOp, cbufOffset, cbufSlot, rewriteSamplerType, isImage: true);
}
}
}
@@ -209,13 +222,39 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
return null;
}
- private static void SetHandle(ShaderConfig config, TextureOperation texOp, int cbufOffset, int cbufSlot, bool rewriteSamplerType)
+ private static void SetHandle(ShaderConfig config, TextureOperation texOp, int cbufOffset, int cbufSlot, bool rewriteSamplerType, bool isImage)
{
texOp.SetHandle(cbufOffset, cbufSlot);
if (rewriteSamplerType)
{
- texOp.Type = config.GpuAccessor.QuerySamplerType(cbufOffset, cbufSlot);
+ SamplerType newType = config.GpuAccessor.QuerySamplerType(cbufOffset, cbufSlot);
+
+ if (texOp.Inst.IsTextureQuery())
+ {
+ texOp.Type = newType;
+ }
+ else if (texOp.Type == SamplerType.TextureBuffer && newType == SamplerType.Texture1D)
+ {
+ int coordsCount = 1;
+
+ if (InstEmit.Sample1DAs2D)
+ {
+ newType = SamplerType.Texture2D;
+ texOp.InsertSource(coordsCount++, OperandHelper.Const(0));
+ }
+
+ if (!isImage &&
+ (texOp.Flags & TextureFlags.IntCoords) != 0 &&
+ (texOp.Flags & TextureFlags.LodLevel) == 0)
+ {
+ // IntCoords textures must always have explicit LOD.
+ texOp.SetLodLevelFlag();
+ texOp.InsertSource(coordsCount, OperandHelper.Const(0));
+ }
+
+ texOp.Type = newType;
+ }
}
config.SetUsedTexture(texOp.Inst, texOp.Type, texOp.Format, texOp.Flags, cbufSlot, cbufOffset);