Fix depth stencil formats copy by matching equivalent color formats (#1198)

This commit is contained in:
gdkchan 2020-07-13 08:41:30 -03:00 committed by GitHub
parent a804db6eed
commit 2900dda633
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 15 deletions

View file

@ -667,7 +667,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <returns>True if the textures are strictly equal or similar, false otherwise</returns> /// <returns>True if the textures are strictly equal or similar, false otherwise</returns>
public bool IsPerfectMatch(TextureInfo info, TextureSearchFlags flags) public bool IsPerfectMatch(TextureInfo info, TextureSearchFlags flags)
{ {
if (!FormatMatches(info, (flags & TextureSearchFlags.Strict) != 0)) if (!FormatMatches(info, (flags & TextureSearchFlags.ForSampler) != 0, (flags & TextureSearchFlags.ForCopy) != 0))
{ {
return false; return false;
} }
@ -682,7 +682,7 @@ namespace Ryujinx.Graphics.Gpu.Image
return false; return false;
} }
if ((flags & TextureSearchFlags.Sampler) != 0) if ((flags & TextureSearchFlags.ForSampler) != 0 || (flags & TextureSearchFlags.Strict) != 0)
{ {
if (!SamplerParamsMatches(info)) if (!SamplerParamsMatches(info))
{ {
@ -690,7 +690,7 @@ namespace Ryujinx.Graphics.Gpu.Image
} }
} }
if ((flags & TextureSearchFlags.IgnoreMs) != 0) if ((flags & TextureSearchFlags.ForCopy) != 0)
{ {
bool msTargetCompatible = Info.Target == Target.Texture2DMultisample && info.Target == Target.Texture2D; bool msTargetCompatible = Info.Target == Target.Texture2DMultisample && info.Target == Target.Texture2D;
@ -711,17 +711,39 @@ namespace Ryujinx.Graphics.Gpu.Image
/// Checks if the texture format matches with the specified texture information. /// Checks if the texture format matches with the specified texture information.
/// </summary> /// </summary>
/// <param name="info">Texture information to compare with</param> /// <param name="info">Texture information to compare with</param>
/// <param name="strict">True to perform a strict comparison (formats must be exactly equal)</param> /// <param name="forSampler">Indicates that the texture will be used for shader sampling</param>
/// <param name="forCopy">Indicates that the texture will be used as copy source or target</param>
/// <returns>True if the format matches, with the given comparison rules</returns> /// <returns>True if the format matches, with the given comparison rules</returns>
private bool FormatMatches(TextureInfo info, bool strict) private bool FormatMatches(TextureInfo info, bool forSampler, bool forCopy)
{ {
// D32F and R32F texture have the same representation internally, // D32F and R32F texture have the same representation internally,
// however the R32F format is used to sample from depth textures. // however the R32F format is used to sample from depth textures.
if (Info.FormatInfo.Format == Format.D32Float && info.FormatInfo.Format == Format.R32Float && !strict) if (Info.FormatInfo.Format == Format.D32Float && info.FormatInfo.Format == Format.R32Float && (forSampler || forCopy))
{ {
return true; return true;
} }
if (forCopy)
{
// The 2D engine does not support depth-stencil formats, so it will instead
// use equivalent color formats. We must also consider them as compatible.
if (Info.FormatInfo.Format == Format.S8Uint && info.FormatInfo.Format == Format.R8Unorm)
{
return true;
}
if (Info.FormatInfo.Format == Format.D16Unorm && info.FormatInfo.Format == Format.R16Unorm)
{
return true;
}
if ((Info.FormatInfo.Format == Format.D24UnormS8Uint ||
Info.FormatInfo.Format == Format.D24X8Unorm) && info.FormatInfo.Format == Format.B8G8R8A8Unorm)
{
return true;
}
}
return Info.FormatInfo.Format == info.FormatInfo.Format; return Info.FormatInfo.Format == info.FormatInfo.Format;
} }

View file

@ -454,7 +454,7 @@ namespace Ryujinx.Graphics.Gpu.Image
Target.Texture2D, Target.Texture2D,
formatInfo); formatInfo);
TextureSearchFlags flags = TextureSearchFlags.IgnoreMs; TextureSearchFlags flags = TextureSearchFlags.ForCopy;
if (preferScaling) if (preferScaling)
{ {
@ -608,7 +608,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <returns>The texture</returns> /// <returns>The texture</returns>
public Texture FindOrCreateTexture(TextureInfo info, TextureSearchFlags flags = TextureSearchFlags.None) public Texture FindOrCreateTexture(TextureInfo info, TextureSearchFlags flags = TextureSearchFlags.None)
{ {
bool isSamplerTexture = (flags & TextureSearchFlags.Sampler) != 0; bool isSamplerTexture = (flags & TextureSearchFlags.ForSampler) != 0;
bool isScalable = IsUpscaleCompatible(info); bool isScalable = IsUpscaleCompatible(info);

View file

@ -59,7 +59,7 @@ namespace Ryujinx.Graphics.Gpu.Image
return null; return null;
} }
texture = Context.Methods.TextureManager.FindOrCreateTexture(info, TextureSearchFlags.Sampler); texture = Context.Methods.TextureManager.FindOrCreateTexture(info, TextureSearchFlags.ForSampler);
texture.IncrementReferenceCount(); texture.IncrementReferenceCount();

View file

@ -8,10 +8,10 @@ namespace Ryujinx.Graphics.Gpu.Image
[Flags] [Flags]
enum TextureSearchFlags enum TextureSearchFlags
{ {
None = 0, None = 0,
IgnoreMs = 1 << 0, Strict = 1 << 0,
Strict = 1 << 1 | Sampler, ForSampler = 1 << 1,
Sampler = 1 << 2, ForCopy = 1 << 2,
WithUpscale = 1 << 3 WithUpscale = 1 << 3
} }
} }