diff --git a/Ryujinx.Graphics.Gpu/Image/TexturePool.cs b/Ryujinx.Graphics.Gpu/Image/TexturePool.cs index 4fd51988..59f2e901 100644 --- a/Ryujinx.Graphics.Gpu/Image/TexturePool.cs +++ b/Ryujinx.Graphics.Gpu/Image/TexturePool.cs @@ -144,6 +144,22 @@ namespace Ryujinx.Graphics.Gpu.Image Target target = descriptor.UnpackTextureTarget().Convert((samplesInX | samplesInY) != 1); + // We use 2D targets for 1D textures as that makes texture cache + // management easier. We don't know the target for render target + // and copies, so those would normally use 2D targets, which are + // not compatible with 1D targets. By doing that we also allow those + // to match when looking for compatible textures on the cache. + if (target == Target.Texture1D) + { + target = Target.Texture2D; + height = 1; + } + else if (target == Target.Texture1DArray) + { + target = Target.Texture2DArray; + height = 1; + } + uint format = descriptor.UnpackFormat(); bool srgb = descriptor.UnpackSrgb(); diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs index 77e3fae7..eaae993b 100644 --- a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs +++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs @@ -11,6 +11,8 @@ namespace Ryujinx.Graphics.Shader.Instructions { static partial class InstEmit { + private const bool Sample1DAs2D = true; + public static void Suld(EmitterContext context) { OpCodeImage op = (OpCodeImage)context.CurrOp; @@ -38,10 +40,7 @@ namespace Ryujinx.Graphics.Shader.Instructions return context.Copy(Register(raIndex++, RegisterType.Gpr)); } - bool isArray = op.Dimensions == ImageDimensions.Image1DArray || - op.Dimensions == ImageDimensions.Image2DArray; - - Operand arrayIndex = isArray ? Ra() : null; + Operand arrayIndex = type.HasFlag(SamplerType.Array) ? Ra() : null; List sourcesList = new List(); @@ -57,7 +56,15 @@ namespace Ryujinx.Graphics.Shader.Instructions sourcesList.Add(Ra()); } - if (isArray) + if (Sample1DAs2D && (type & SamplerType.Mask) == SamplerType.Texture1D) + { + sourcesList.Add(Const(0)); + + type &= ~SamplerType.Mask; + type |= SamplerType.Texture2D; + } + + if (type.HasFlag(SamplerType.Array)) { sourcesList.Add(arrayIndex); @@ -186,10 +193,7 @@ namespace Ryujinx.Graphics.Shader.Instructions return context.Copy(Register(rbIndex++, RegisterType.Gpr)); } - bool isArray = op.Dimensions == ImageDimensions.Image1DArray || - op.Dimensions == ImageDimensions.Image2DArray; - - Operand arrayIndex = isArray ? Ra() : null; + Operand arrayIndex = type.HasFlag(SamplerType.Array) ? Ra() : null; List sourcesList = new List(); @@ -205,7 +209,15 @@ namespace Ryujinx.Graphics.Shader.Instructions sourcesList.Add(Ra()); } - if (isArray) + if (Sample1DAs2D && (type & SamplerType.Mask) == SamplerType.Texture1D) + { + sourcesList.Add(Const(0)); + + type &= ~SamplerType.Mask; + type |= SamplerType.Texture2D; + } + + if (type.HasFlag(SamplerType.Array)) { sourcesList.Add(arrayIndex); @@ -355,6 +367,9 @@ namespace Ryujinx.Graphics.Shader.Instructions flags = ConvertTextureFlags(texsOp.Target); + // We don't need to handle 1D -> Buffer conversions here as + // only texture sample with integer coordinates can ever use buffer targets. + if ((type & SamplerType.Array) != 0) { Operand arrayIndex = Ra(); @@ -380,6 +395,15 @@ namespace Ryujinx.Graphics.Shader.Instructions { case TextureTarget.Texture1DLodZero: sourcesList.Add(Ra()); + + if (Sample1DAs2D) + { + sourcesList.Add(ConstF(0)); + + type &= ~SamplerType.Mask; + type |= SamplerType.Texture2D; + } + sourcesList.Add(ConstF(0)); break; @@ -423,7 +447,7 @@ namespace Ryujinx.Graphics.Shader.Instructions } else if (op is OpCodeTlds tldsOp) { - type = ConvertSamplerType (tldsOp.Target); + type = ConvertSamplerType(tldsOp.Target); if (type == SamplerType.None) { @@ -449,12 +473,29 @@ namespace Ryujinx.Graphics.Shader.Instructions if (type != SamplerType.TextureBuffer) { - sourcesList.Add(Const(0)); + if (Sample1DAs2D) + { + sourcesList.Add(ConstF(0)); + + type &= ~SamplerType.Mask; + type |= SamplerType.Texture2D; + } + + sourcesList.Add(ConstF(0)); } break; case TexelLoadTarget.Texture1DLodLevel: sourcesList.Add(Ra()); + + if (Sample1DAs2D) + { + sourcesList.Add(ConstF(0)); + + type &= ~SamplerType.Mask; + type |= SamplerType.Texture2D; + } + sourcesList.Add(Rb()); break; @@ -649,6 +690,15 @@ namespace Ryujinx.Graphics.Shader.Instructions sourcesList.Add(Ra()); } + bool is1DTo2D = Sample1DAs2D && type == SamplerType.Texture1D; + + if (is1DTo2D) + { + sourcesList.Add(ConstF(0)); + + type = SamplerType.Texture2D; + } + if (op.IsArray) { sourcesList.Add(arrayIndex); @@ -679,6 +729,14 @@ namespace Ryujinx.Graphics.Shader.Instructions sourcesList.Add(context.BitfieldExtractS32(packed, Const((index & 3) * 8), Const(6))); } + if (is1DTo2D) + { + for (int index = 0; index < offsetTexelsCount; index++) + { + sourcesList.Add(Const(0)); + } + } + flags |= op.Offset == TextureGatherOffset.Offsets ? TextureFlags.Offsets : TextureFlags.Offset; @@ -786,6 +844,13 @@ namespace Ryujinx.Graphics.Shader.Instructions sourcesList.Add(Ra()); } + if (Sample1DAs2D && type == SamplerType.Texture1D) + { + sourcesList.Add(ConstF(0)); + + type = SamplerType.Texture2D; + } + if (op.IsArray) { sourcesList.Add(arrayIndex); @@ -898,6 +963,15 @@ namespace Ryujinx.Graphics.Shader.Instructions sourcesList.Add(Ra()); } + bool is1DTo2D = Sample1DAs2D && type == SamplerType.Texture1D; + + if (is1DTo2D) + { + sourcesList.Add(ConstF(0)); + + type = SamplerType.Texture2D; + } + Operand packedParams = Ra(); if (op.IsArray) @@ -911,6 +985,11 @@ namespace Ryujinx.Graphics.Shader.Instructions for (int dIndex = 0; dIndex < 2 * coordsCount; dIndex++) { sourcesList.Add(Rb()); + + if (is1DTo2D) + { + sourcesList.Add(ConstF(0)); + } } if (op.HasOffset) @@ -920,6 +999,11 @@ namespace Ryujinx.Graphics.Shader.Instructions sourcesList.Add(context.BitfieldExtractS32(packedParams, Const(16 + index * 4), Const(4))); } + if (is1DTo2D) + { + sourcesList.Add(Const(0)); + } + flags |= TextureFlags.Offset; } @@ -1114,6 +1198,13 @@ namespace Ryujinx.Graphics.Shader.Instructions sourcesList.Add(Ra()); } + if (Sample1DAs2D && type == SamplerType.Texture1D) + { + sourcesList.Add(ConstF(0)); + + type = SamplerType.Texture2D; + } + if (op.IsArray) { sourcesList.Add(arrayIndex);