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 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";
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -60,5 +60,10 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||
CbufSlot = cbufSlot;
|
||||
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;
|
||||
|
||||
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);
|
||||
|
|
Reference in a new issue