diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodClass.cs b/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodClass.cs
index 4ce53e78..2ac84ab5 100644
--- a/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodClass.cs
+++ b/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodClass.cs
@@ -300,11 +300,16 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
IsCopyRegionComplete(srcCopyTexture, srcCopyTextureFormat, srcX1, srcY1, srcX2, srcY2) &&
IsCopyRegionComplete(dstCopyTexture, dstCopyTextureFormat, dstX1, dstY1, dstX2, dstY2);
+ // We can only allow aliasing of color formats as depth if the source and destination textures
+ // are the same, as we can't blit between different depth formats.
+ bool srcDepthAlias = srcCopyTexture.Format == dstCopyTexture.Format;
+
var srcTexture = memoryManager.Physical.TextureCache.FindOrCreateTexture(
memoryManager,
srcCopyTexture,
offset,
srcCopyTextureFormat,
+ srcDepthAlias,
!canDirectCopy,
false,
srcHint);
@@ -325,6 +330,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
// When the source texture that was found has a depth format,
// we must enforce the target texture also has a depth format,
// as copies between depth and color formats are not allowed.
+ // For depth blit, the destination texture format should always match exactly.
if (srcTexture.Format.IsDepthOrStencil())
{
@@ -340,7 +346,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
dstCopyTexture,
0,
dstCopyTextureFormat,
- true,
+ depthAlias: false,
+ shouldCreate: true,
srcTexture.ScaleMode == TextureScaleMode.Scaled,
dstHint);
diff --git a/src/Ryujinx.Graphics.Gpu/Image/Texture.cs b/src/Ryujinx.Graphics.Gpu/Image/Texture.cs
index 6c9de8d6..0427d09b 100644
--- a/src/Ryujinx.Graphics.Gpu/Image/Texture.cs
+++ b/src/Ryujinx.Graphics.Gpu/Image/Texture.cs
@@ -1118,7 +1118,7 @@ namespace Ryujinx.Graphics.Gpu.Image
{
bool forSampler = (flags & TextureSearchFlags.ForSampler) != 0;
- TextureMatchQuality matchQuality = TextureCompatibility.FormatMatches(Info, info, forSampler, (flags & TextureSearchFlags.ForCopy) != 0);
+ TextureMatchQuality matchQuality = TextureCompatibility.FormatMatches(Info, info, forSampler, (flags & TextureSearchFlags.DepthAlias) != 0);
if (matchQuality == TextureMatchQuality.NoMatch)
{
diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
index fc2c07e5..49191239 100644
--- a/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
+++ b/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
@@ -249,6 +249,8 @@ namespace Ryujinx.Graphics.Gpu.Image
/// Copy texture to find or create
/// Offset to be added to the physical texture address
/// Format information of the copy texture
+ /// Indicates if aliasing between color and depth format should be allowed
+ /// Indicates if a new texture should be created if none is found on the cache
/// Indicates if the texture should be scaled from the start
/// A hint indicating the minimum used size for the texture
/// The texture
@@ -257,6 +259,7 @@ namespace Ryujinx.Graphics.Gpu.Image
TwodTexture copyTexture,
ulong offset,
FormatInfo formatInfo,
+ bool depthAlias,
bool shouldCreate,
bool preferScaling,
Size sizeHint)
@@ -293,6 +296,11 @@ namespace Ryujinx.Graphics.Gpu.Image
TextureSearchFlags flags = TextureSearchFlags.ForCopy;
+ if (depthAlias)
+ {
+ flags |= TextureSearchFlags.DepthAlias;
+ }
+
if (preferScaling)
{
flags |= TextureSearchFlags.WithUpscale;
diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs
index e93ea0c0..5d846222 100644
--- a/src/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs
+++ b/src/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs
@@ -220,18 +220,18 @@ namespace Ryujinx.Graphics.Gpu.Image
/// Texture information to compare
/// Texture information to compare with
/// Indicates that the texture will be used for shader sampling
- /// Indicates that the texture will be used as copy source or target
+ /// Indicates if aliasing between color and depth format should be allowed
/// A value indicating how well the formats match
- public static TextureMatchQuality FormatMatches(TextureInfo lhs, TextureInfo rhs, bool forSampler, bool forCopy)
+ public static TextureMatchQuality FormatMatches(TextureInfo lhs, TextureInfo rhs, bool forSampler, bool depthAlias)
{
// D32F and R32F texture have the same representation internally,
// however the R32F format is used to sample from depth textures.
- if (lhs.FormatInfo.Format == Format.D32Float && rhs.FormatInfo.Format == Format.R32Float && (forSampler || forCopy))
+ if (lhs.FormatInfo.Format == Format.D32Float && rhs.FormatInfo.Format == Format.R32Float && (forSampler || depthAlias))
{
return TextureMatchQuality.FormatAlias;
}
- if (forCopy)
+ if (depthAlias)
{
// The 2D engine does not support depth-stencil formats, so it will instead
// use equivalent color formats. We must also consider them as compatible.
diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureSearchFlags.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureSearchFlags.cs
index 890bf173..d7b99a17 100644
--- a/src/Ryujinx.Graphics.Gpu/Image/TextureSearchFlags.cs
+++ b/src/Ryujinx.Graphics.Gpu/Image/TextureSearchFlags.cs
@@ -11,7 +11,8 @@ namespace Ryujinx.Graphics.Gpu.Image
None = 0,
ForSampler = 1 << 1,
ForCopy = 1 << 2,
- WithUpscale = 1 << 3,
- NoCreate = 1 << 4
+ DepthAlias = 1 << 3,
+ WithUpscale = 1 << 4,
+ NoCreate = 1 << 5
}
}
\ No newline at end of file