diff --git a/Ryujinx.Graphics.Gpu/Constants.cs b/Ryujinx.Graphics.Gpu/Constants.cs index 231152f5e..026d12a92 100644 --- a/Ryujinx.Graphics.Gpu/Constants.cs +++ b/Ryujinx.Graphics.Gpu/Constants.cs @@ -69,5 +69,15 @@ namespace Ryujinx.Graphics.Gpu /// Maximum size of gl_ClipDistance array in shaders. /// public const int TotalClipDistances = 8; + + /// + /// Byte alignment for texture stride. + /// + public const int StrideAlignment = 32; + + /// + /// Byte alignment for block linear textures + /// + public const int GobAlignment = 64; } } \ No newline at end of file diff --git a/Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs b/Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs index 15ebb2366..dd16cb2de 100644 --- a/Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs +++ b/Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs @@ -8,9 +8,6 @@ namespace Ryujinx.Graphics.Gpu.Engine { partial class Methods { - private const int StrideAlignment = 32; - private const int GobAlignment = 64; - enum CopyFlags { SrcLinear = 1 << 7, @@ -32,14 +29,14 @@ namespace Ryujinx.Graphics.Gpu.Engine { if (linear) { - int alignWidth = StrideAlignment / bpp; + int alignWidth = Constants.StrideAlignment / bpp; return tex.RegionX == 0 && tex.RegionY == 0 && stride / bpp == BitUtils.AlignUp(cbp.XCount, alignWidth); } else { - int alignWidth = GobAlignment / bpp; + int alignWidth = Constants.GobAlignment / bpp; return tex.RegionX == 0 && tex.RegionY == 0 && tex.Width == BitUtils.AlignUp(cbp.XCount, alignWidth) && diff --git a/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs b/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs index d613612ff..3140f4a12 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs @@ -231,8 +231,21 @@ namespace Ryujinx.Graphics.Gpu.Image result = TextureViewCompatibility.CopyOnly; } - return (size.Width == otherSize.Width && - size.Height == otherSize.Height) ? result : TextureViewCompatibility.Incompatible; + if (size.Width == otherSize.Width && size.Height == otherSize.Height) + { + return result; + } + else if (lhs.IsLinear && rhs.IsLinear) + { + // Copy between linear textures with matching stride. + int stride = BitUtils.AlignUp(Math.Max(1, lhs.Stride >> level), Constants.StrideAlignment); + + return stride == rhs.Stride ? TextureViewCompatibility.CopyOnly : TextureViewCompatibility.Incompatible; + } + else + { + return TextureViewCompatibility.Incompatible; + } } /// @@ -372,8 +385,7 @@ namespace Ryujinx.Graphics.Gpu.Image // For block linear textures, the stride is ignored. if (rhs.IsLinear) { - int width = Math.Max(1, lhs.Width >> level); - int stride = width * lhs.FormatInfo.BytesPerPixel; + int stride = Math.Max(1, lhs.Stride >> level); stride = BitUtils.AlignUp(stride, 32); return stride == rhs.Stride; diff --git a/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs b/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs index 39567a823..52129d64b 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs @@ -16,9 +16,6 @@ namespace Ryujinx.Graphics.Gpu.Image /// class TextureGroup : IDisposable { - private const int StrideAlignment = 32; - private const int GobAlignment = 64; - private delegate void HandlesCallbackDelegate(int baseHandle, int regionCount, bool split = false); /// diff --git a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs index 07bc7c7e4..2b756e4c2 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs @@ -429,7 +429,7 @@ namespace Ryujinx.Graphics.Gpu.Image // Discount square textures that aren't depth-stencil like. (excludes game textures, cubemap faces, most 3D texture LUT, texture atlas) // Detect if the texture is possibly square. Widths may be aligned, so to remove the uncertainty we align both the width and height. - int widthAlignment = (info.IsLinear ? 32 : 64) / info.FormatInfo.BytesPerPixel; + int widthAlignment = (info.IsLinear ? Constants.StrideAlignment : Constants.GobAlignment) / info.FormatInfo.BytesPerPixel; bool possiblySquare = BitUtils.AlignUp(info.Width, widthAlignment) == BitUtils.AlignUp(info.Height, widthAlignment); @@ -977,8 +977,6 @@ namespace Ryujinx.Graphics.Gpu.Image { // Copy only compatibility, or target texture is already a view. - ChangeSizeIfNeeded(overlapInfo, overlap, false, sizeHint); // Force a size match for copy - overlap.SynchronizeMemory(); texture.CreateCopyDependency(overlap, oInfo.FirstLayer, oInfo.FirstLevel, false); }