forked from Mirror/Ryujinx
Fix bindless 1D textures having a buffer type on the shader (#3697)
* Fix bindless 1D textures having a buffer type on the shader * Shader cache version bump
This commit is contained in:
parent
729ff5337c
commit
66f16f4392
5 changed files with 66 additions and 10 deletions
|
@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
||||||
private const ushort FileFormatVersionMajor = 1;
|
private const ushort FileFormatVersionMajor = 1;
|
||||||
private const ushort FileFormatVersionMinor = 2;
|
private const ushort FileFormatVersionMinor = 2;
|
||||||
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
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 SharedTocFileName = "shared.toc";
|
||||||
private const string SharedDataFileName = "shared.data";
|
private const string SharedDataFileName = "shared.data";
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
{ 0b0111, 0b1011, 0b1101, 0b1110, 0b1111, 0b0000, 0b0000, 0b0000 }
|
{ 0b0111, 0b1011, 0b1101, 0b1110, 0b1111, 0b0000, 0b0000, 0b0000 }
|
||||||
};
|
};
|
||||||
|
|
||||||
private const bool Sample1DAs2D = true;
|
public const bool Sample1DAs2D = true;
|
||||||
|
|
||||||
private enum TexsType
|
private enum TexsType
|
||||||
{
|
{
|
||||||
|
|
|
@ -180,6 +180,18 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
||||||
_sources[index] = source;
|
_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)
|
protected void RemoveSource(int index)
|
||||||
{
|
{
|
||||||
SetSource(index, null);
|
SetSource(index, null);
|
||||||
|
|
|
@ -60,5 +60,10 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
||||||
CbufSlot = cbufSlot;
|
CbufSlot = cbufSlot;
|
||||||
Handle = handle;
|
Handle = handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetLodLevelFlag()
|
||||||
|
{
|
||||||
|
Flags |= TextureFlags.LodLevel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.Instructions;
|
||||||
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||||
|
@ -30,11 +31,19 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||||
texOp.Inst == Instruction.TextureSize)
|
texOp.Inst == Instruction.TextureSize)
|
||||||
{
|
{
|
||||||
Operand bindlessHandle = Utils.FindLastOperation(texOp.GetSource(0), block);
|
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)
|
if (bindlessHandle.Type == OperandType.ConstantBuffer)
|
||||||
{
|
{
|
||||||
SetHandle(config, texOp, bindlessHandle.GetCbufOffset(), bindlessHandle.GetCbufSlot(), rewriteSamplerType);
|
SetHandle(config, texOp, bindlessHandle.GetCbufOffset(), bindlessHandle.GetCbufSlot(), rewriteSamplerType, isImage: false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +146,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||||
texOp,
|
texOp,
|
||||||
TextureHandle.PackOffsets(src0.GetCbufOffset(), ((src1.Value >> 20) & 0xfff), handleType),
|
TextureHandle.PackOffsets(src0.GetCbufOffset(), ((src1.Value >> 20) & 0xfff), handleType),
|
||||||
TextureHandle.PackSlots(src0.GetCbufSlot(), 0),
|
TextureHandle.PackSlots(src0.GetCbufSlot(), 0),
|
||||||
rewriteSamplerType);
|
rewriteSamplerType,
|
||||||
|
isImage: false);
|
||||||
}
|
}
|
||||||
else if (src1.Type == OperandType.ConstantBuffer)
|
else if (src1.Type == OperandType.ConstantBuffer)
|
||||||
{
|
{
|
||||||
|
@ -146,7 +156,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||||
texOp,
|
texOp,
|
||||||
TextureHandle.PackOffsets(src0.GetCbufOffset(), src1.GetCbufOffset(), handleType),
|
TextureHandle.PackOffsets(src0.GetCbufOffset(), src1.GetCbufOffset(), handleType),
|
||||||
TextureHandle.PackSlots(src0.GetCbufSlot(), src1.GetCbufSlot()),
|
TextureHandle.PackSlots(src0.GetCbufSlot(), src1.GetCbufSlot()),
|
||||||
rewriteSamplerType);
|
rewriteSamplerType,
|
||||||
|
isImage: false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (texOp.Inst == Instruction.ImageLoad ||
|
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;
|
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);
|
texOp.SetHandle(cbufOffset, cbufSlot);
|
||||||
|
|
||||||
if (rewriteSamplerType)
|
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);
|
config.SetUsedTexture(texOp.Inst, texOp.Type, texOp.Format, texOp.Flags, cbufSlot, cbufOffset);
|
||||||
|
|
Reference in a new issue