Fix some invalid blits involving depth textures (#4723)

This commit is contained in:
gdkchan 2023-05-03 21:20:12 -03:00 committed by GitHub
parent 6279f5e430
commit 4d1579acbf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 24 additions and 8 deletions

View file

@ -300,11 +300,16 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
IsCopyRegionComplete(srcCopyTexture, srcCopyTextureFormat, srcX1, srcY1, srcX2, srcY2) && IsCopyRegionComplete(srcCopyTexture, srcCopyTextureFormat, srcX1, srcY1, srcX2, srcY2) &&
IsCopyRegionComplete(dstCopyTexture, dstCopyTextureFormat, dstX1, dstY1, dstX2, dstY2); 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( var srcTexture = memoryManager.Physical.TextureCache.FindOrCreateTexture(
memoryManager, memoryManager,
srcCopyTexture, srcCopyTexture,
offset, offset,
srcCopyTextureFormat, srcCopyTextureFormat,
srcDepthAlias,
!canDirectCopy, !canDirectCopy,
false, false,
srcHint); srcHint);
@ -325,6 +330,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
// When the source texture that was found has a depth format, // When the source texture that was found has a depth format,
// we must enforce the target texture also 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. // 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()) if (srcTexture.Format.IsDepthOrStencil())
{ {
@ -340,7 +346,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
dstCopyTexture, dstCopyTexture,
0, 0,
dstCopyTextureFormat, dstCopyTextureFormat,
true, depthAlias: false,
shouldCreate: true,
srcTexture.ScaleMode == TextureScaleMode.Scaled, srcTexture.ScaleMode == TextureScaleMode.Scaled,
dstHint); dstHint);

View file

@ -1118,7 +1118,7 @@ namespace Ryujinx.Graphics.Gpu.Image
{ {
bool forSampler = (flags & TextureSearchFlags.ForSampler) != 0; 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) if (matchQuality == TextureMatchQuality.NoMatch)
{ {

View file

@ -249,6 +249,8 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <param name="copyTexture">Copy texture to find or create</param> /// <param name="copyTexture">Copy texture to find or create</param>
/// <param name="offset">Offset to be added to the physical texture address</param> /// <param name="offset">Offset to be added to the physical texture address</param>
/// <param name="formatInfo">Format information of the copy texture</param> /// <param name="formatInfo">Format information of the copy texture</param>
/// <param name="depthAlias">Indicates if aliasing between color and depth format should be allowed</param>
/// <param name="shouldCreate">Indicates if a new texture should be created if none is found on the cache</param>
/// <param name="preferScaling">Indicates if the texture should be scaled from the start</param> /// <param name="preferScaling">Indicates if the texture should be scaled from the start</param>
/// <param name="sizeHint">A hint indicating the minimum used size for the texture</param> /// <param name="sizeHint">A hint indicating the minimum used size for the texture</param>
/// <returns>The texture</returns> /// <returns>The texture</returns>
@ -257,6 +259,7 @@ namespace Ryujinx.Graphics.Gpu.Image
TwodTexture copyTexture, TwodTexture copyTexture,
ulong offset, ulong offset,
FormatInfo formatInfo, FormatInfo formatInfo,
bool depthAlias,
bool shouldCreate, bool shouldCreate,
bool preferScaling, bool preferScaling,
Size sizeHint) Size sizeHint)
@ -293,6 +296,11 @@ namespace Ryujinx.Graphics.Gpu.Image
TextureSearchFlags flags = TextureSearchFlags.ForCopy; TextureSearchFlags flags = TextureSearchFlags.ForCopy;
if (depthAlias)
{
flags |= TextureSearchFlags.DepthAlias;
}
if (preferScaling) if (preferScaling)
{ {
flags |= TextureSearchFlags.WithUpscale; flags |= TextureSearchFlags.WithUpscale;

View file

@ -220,18 +220,18 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <param name="lhs">Texture information to compare</param> /// <param name="lhs">Texture information to compare</param>
/// <param name="rhs">Texture information to compare with</param> /// <param name="rhs">Texture information to compare with</param>
/// <param name="forSampler">Indicates that the texture will be used for shader sampling</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> /// <param name="depthAlias">Indicates if aliasing between color and depth format should be allowed</param>
/// <returns>A value indicating how well the formats match</returns> /// <returns>A value indicating how well the formats match</returns>
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, // 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 (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; return TextureMatchQuality.FormatAlias;
} }
if (forCopy) if (depthAlias)
{ {
// The 2D engine does not support depth-stencil formats, so it will instead // The 2D engine does not support depth-stencil formats, so it will instead
// use equivalent color formats. We must also consider them as compatible. // use equivalent color formats. We must also consider them as compatible.

View file

@ -11,7 +11,8 @@ namespace Ryujinx.Graphics.Gpu.Image
None = 0, None = 0,
ForSampler = 1 << 1, ForSampler = 1 << 1,
ForCopy = 1 << 2, ForCopy = 1 << 2,
WithUpscale = 1 << 3, DepthAlias = 1 << 3,
NoCreate = 1 << 4 WithUpscale = 1 << 4,
NoCreate = 1 << 5
} }
} }