From 841dd56f4ce850693aee5980cd750791624e47be Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 31 Oct 2023 19:00:39 -0300 Subject: Implement copy dependency for depth and color textures (#4365) * Implement copy dependency for depth and color textures * Revert changes added because R32 <-> D32 copies were illegal * Restore depth alias matches --- .../Image/TextureCompatibility.cs | 61 +++++++++++++++++----- 1 file changed, 47 insertions(+), 14 deletions(-) (limited to 'src/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs') diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs index 3a0efcdd..5af0471c 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs @@ -226,7 +226,7 @@ namespace Ryujinx.Graphics.Gpu.Image { // 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 || depthAlias)) + if (IsValidDepthAsColorAlias(lhs.FormatInfo.Format, rhs.FormatInfo.Format) && (forSampler || depthAlias)) { return TextureMatchQuality.FormatAlias; } @@ -239,14 +239,8 @@ namespace Ryujinx.Graphics.Gpu.Image { return TextureMatchQuality.FormatAlias; } - - if (lhs.FormatInfo.Format == Format.D16Unorm && rhs.FormatInfo.Format == Format.R16Unorm) - { - return TextureMatchQuality.FormatAlias; - } - - if ((lhs.FormatInfo.Format == Format.D24UnormS8Uint || - lhs.FormatInfo.Format == Format.S8UintD24Unorm) && rhs.FormatInfo.Format == Format.B8G8R8A8Unorm) + else if ((lhs.FormatInfo.Format == Format.D24UnormS8Uint || + lhs.FormatInfo.Format == Format.S8UintD24Unorm) && rhs.FormatInfo.Format == Format.B8G8R8A8Unorm) { return TextureMatchQuality.FormatAlias; } @@ -632,12 +626,27 @@ namespace Ryujinx.Graphics.Gpu.Image if (lhsFormat.Format.IsDepthOrStencil() || rhsFormat.Format.IsDepthOrStencil()) { - return FormatMatches(lhs, rhs, flags.HasFlag(TextureSearchFlags.ForSampler), flags.HasFlag(TextureSearchFlags.DepthAlias)) switch + bool forSampler = flags.HasFlag(TextureSearchFlags.ForSampler); + bool depthAlias = flags.HasFlag(TextureSearchFlags.DepthAlias); + + TextureMatchQuality matchQuality = FormatMatches(lhs, rhs, forSampler, depthAlias); + + if (matchQuality == TextureMatchQuality.Perfect) { - TextureMatchQuality.Perfect => TextureViewCompatibility.Full, - TextureMatchQuality.FormatAlias => TextureViewCompatibility.FormatAlias, - _ => TextureViewCompatibility.Incompatible, - }; + return TextureViewCompatibility.Full; + } + else if (matchQuality == TextureMatchQuality.FormatAlias) + { + return TextureViewCompatibility.FormatAlias; + } + else if (IsValidColorAsDepthAlias(lhsFormat.Format, rhsFormat.Format) || IsValidDepthAsColorAlias(lhsFormat.Format, rhsFormat.Format)) + { + return TextureViewCompatibility.CopyOnly; + } + else + { + return TextureViewCompatibility.Incompatible; + } } if (IsFormatHostIncompatible(lhs, caps) || IsFormatHostIncompatible(rhs, caps)) @@ -666,6 +675,30 @@ namespace Ryujinx.Graphics.Gpu.Image return TextureViewCompatibility.Incompatible; } + /// + /// Checks if it's valid to alias a color format as a depth format. + /// + /// Source format to be checked + /// Target format to be checked + /// True if it's valid to alias the formats + private static bool IsValidColorAsDepthAlias(Format lhsFormat, Format rhsFormat) + { + return (lhsFormat == Format.R32Float && rhsFormat == Format.D32Float) || + (lhsFormat == Format.R16Unorm && rhsFormat == Format.D16Unorm); + } + + /// + /// Checks if it's valid to alias a depth format as a color format. + /// + /// Source format to be checked + /// Target format to be checked + /// True if it's valid to alias the formats + private static bool IsValidDepthAsColorAlias(Format lhsFormat, Format rhsFormat) + { + return (lhsFormat == Format.D32Float && rhsFormat == Format.R32Float) || + (lhsFormat == Format.D16Unorm && rhsFormat == Format.R16Unorm); + } + /// /// Checks if aliasing of two formats that would normally be considered incompatible be allowed, /// using copy dependencies. -- cgit v1.2.3