diff --git a/Ryujinx.Graphics.Gpu/Image/Texture.cs b/Ryujinx.Graphics.Gpu/Image/Texture.cs
index 4d7e31c570..6f720f4c18 100644
--- a/Ryujinx.Graphics.Gpu/Image/Texture.cs
+++ b/Ryujinx.Graphics.Gpu/Image/Texture.cs
@@ -941,7 +941,7 @@ namespace Ryujinx.Graphics.Gpu.Image
return TextureMatchQuality.NoMatch;
}
- if (!TextureCompatibility.SizeMatches(Info, info, (flags & TextureSearchFlags.Strict) == 0))
+ if (!TextureCompatibility.SizeMatches(Info, info, (flags & TextureSearchFlags.Strict) == 0, FirstLevel))
{
return TextureMatchQuality.NoMatch;
}
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs b/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs
index 3140f4a125..c70b297193 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs
@@ -233,6 +233,20 @@ namespace Ryujinx.Graphics.Gpu.Image
if (size.Width == otherSize.Width && size.Height == otherSize.Height)
{
+ if (level > 0 && result == TextureViewCompatibility.Full)
+ {
+ // A resize should not change the aligned size of the largest mip.
+ // If it would, then create a copy dependency rather than a full view.
+
+ Size mip0SizeLhs = GetAlignedSize(lhs);
+ Size mip0SizeRhs = GetLargestAlignedSize(rhs, level);
+
+ if (mip0SizeLhs.Width != mip0SizeRhs.Width || mip0SizeLhs.Height != mip0SizeRhs.Height)
+ {
+ result = TextureViewCompatibility.CopyOnly;
+ }
+ }
+
return result;
}
else if (lhs.IsLinear && rhs.IsLinear)
@@ -300,8 +314,9 @@ namespace Ryujinx.Graphics.Gpu.Image
/// Texture information to compare
/// Texture information to compare with
/// True to align the sizes according to the texture layout for comparison
+ /// Mip level of the lhs texture. Aligned sizes are compared for the largest mip
/// True if the sizes matches, false otherwise
- public static bool SizeMatches(TextureInfo lhs, TextureInfo rhs, bool alignSizes)
+ public static bool SizeMatches(TextureInfo lhs, TextureInfo rhs, bool alignSizes, int lhsLevel = 0)
{
if (lhs.GetLayers() != rhs.GetLayers())
{
@@ -312,8 +327,8 @@ namespace Ryujinx.Graphics.Gpu.Image
if (alignSizes && !isTextureBuffer)
{
- Size size0 = GetAlignedSize(lhs);
- Size size1 = GetAlignedSize(rhs);
+ Size size0 = GetLargestAlignedSize(lhs, lhsLevel);
+ Size size1 = GetLargestAlignedSize(rhs, lhsLevel);
return size0.Width == size1.Width &&
size0.Height == size1.Height &&
@@ -328,17 +343,16 @@ namespace Ryujinx.Graphics.Gpu.Image
}
///
- /// Gets the aligned sizes of the specified texture information.
+ /// Gets the aligned sizes for the given dimensions, using the specified texture information.
/// The alignment depends on the texture layout and format bytes per pixel.
///
/// Texture information to calculate the aligned size from
- /// Mipmap level for texture views
+ /// The width to be aligned
+ /// The height to be aligned
+ /// The depth to be aligned
/// The aligned texture size
- public static Size GetAlignedSize(TextureInfo info, int level = 0)
+ private static Size GetAlignedSize(TextureInfo info, int width, int height, int depth)
{
- int width = Math.Max(1, info.Width >> level);
- int height = Math.Max(1, info.Height >> level);
-
if (info.IsLinear)
{
return SizeCalculator.GetLinearAlignedSize(
@@ -350,8 +364,6 @@ namespace Ryujinx.Graphics.Gpu.Image
}
else
{
- int depth = Math.Max(1, info.GetDepth() >> level);
-
return SizeCalculator.GetBlockLinearAlignedSize(
width,
height,
@@ -365,6 +377,38 @@ namespace Ryujinx.Graphics.Gpu.Image
}
}
+ ///
+ /// Gets the aligned sizes of the specified texture information, shifted to the largest mip from a given level.
+ /// The alignment depends on the texture layout and format bytes per pixel.
+ ///
+ /// Texture information to calculate the aligned size from
+ /// Mipmap level for texture views. Shifts the aligned size to represent the largest mip level
+ /// The aligned texture size of the largest mip level
+ public static Size GetLargestAlignedSize(TextureInfo info, int level)
+ {
+ int width = info.Width << level;
+ int height = info.Height << level;
+ int depth = info.GetDepth() << level;
+
+ return GetAlignedSize(info, width, height, depth);
+ }
+
+ ///
+ /// Gets the aligned sizes of the specified texture information.
+ /// The alignment depends on the texture layout and format bytes per pixel.
+ ///
+ /// Texture information to calculate the aligned size from
+ /// Mipmap level for texture views
+ /// The aligned texture size
+ public static Size GetAlignedSize(TextureInfo info, int level = 0)
+ {
+ int width = Math.Max(1, info.Width >> level);
+ int height = Math.Max(1, info.Height >> level);
+ int depth = Math.Max(1, info.GetDepth() >> level);
+
+ return GetAlignedSize(info, width, height, depth);
+ }
+
///
/// Check if it's possible to create a view with the layout of the second texture information from the first.
/// The layout information is composed of the Stride for linear textures, or GOB block size