aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs2
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs2
-rw-r--r--Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs12
-rw-r--r--Ryujinx.Graphics.Shader/IntermediateRepresentation/TextureOperation.cs5
-rw-r--r--Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs55
5 files changed, 66 insertions, 10 deletions
diff --git a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
index d257c193..24b05b90 100644
--- a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
- private const uint CodeGenVersion = 3644;
+ private const uint CodeGenVersion = 3697;
private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data";
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
index 4d20a5ce..c54b79cd 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
@@ -16,7 +16,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
{ 0b0111, 0b1011, 0b1101, 0b1110, 0b1111, 0b0000, 0b0000, 0b0000 }
};
- private const bool Sample1DAs2D = true;
+ public const bool Sample1DAs2D = true;
private enum TexsType
{
diff --git a/Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs b/Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs
index 955beafd..96132633 100644
--- a/Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs
+++ b/Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs
@@ -180,6 +180,18 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
_sources[index] = source;
}
+ public void InsertSource(int index, Operand source)
+ {
+ Operand[] newSources = new Operand[_sources.Length + 1];
+
+ Array.Copy(_sources, 0, newSources, 0, index);
+ Array.Copy(_sources, index, newSources, index + 1, _sources.Length - index);
+
+ newSources[index] = source;
+
+ _sources = newSources;
+ }
+
protected void RemoveSource(int index)
{
SetSource(index, null);
diff --git a/Ryujinx.Graphics.Shader/IntermediateRepresentation/TextureOperation.cs b/Ryujinx.Graphics.Shader/IntermediateRepresentation/TextureOperation.cs
index ea9ae39c..8cfcb0e9 100644
--- a/Ryujinx.Graphics.Shader/IntermediateRepresentation/TextureOperation.cs
+++ b/Ryujinx.Graphics.Shader/IntermediateRepresentation/TextureOperation.cs
@@ -60,5 +60,10 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
CbufSlot = cbufSlot;
Handle = handle;
}
+
+ public void SetLodLevelFlag()
+ {
+ Flags |= TextureFlags.LodLevel;
+ }
}
} \ No newline at end of file
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);