Allow copy texture views to have mismatching multisample state (#3152)

This commit is contained in:
gdkchan 2022-04-08 06:26:48 -03:00 committed by GitHub
parent a4e8bea866
commit 3139a85a2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 12 deletions

View File

@ -1136,18 +1136,34 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <param name="range">Texture view physical memory ranges</param>
/// <param name="layerSize">Layer size on the given texture</param>
/// <param name="caps">Host GPU capabilities</param>
/// <param name="allowMs">Indicates that multisample textures are allowed to match non-multisample requested textures</param>
/// <param name="firstLayer">Texture view initial layer on this texture</param>
/// <param name="firstLevel">Texture view first mipmap level on this texture</param>
/// <returns>The level of compatiblilty a view with the given parameters created from this texture has</returns>
public TextureViewCompatibility IsViewCompatible(TextureInfo info, MultiRange range, int layerSize, Capabilities caps, out int firstLayer, out int firstLevel)
public TextureViewCompatibility IsViewCompatible(TextureInfo info, MultiRange range, int layerSize, Capabilities caps, bool allowMs, out int firstLayer, out int firstLevel)
{
TextureViewCompatibility result = TextureViewCompatibility.Full;
result = TextureCompatibility.PropagateViewCompatibility(result, TextureCompatibility.ViewFormatCompatible(Info, info, caps));
if (result != TextureViewCompatibility.Incompatible)
{
bool msTargetCompatible = false;
if (allowMs)
{
msTargetCompatible = Info.Target == Target.Texture2DMultisample && info.Target == Target.Texture2D;
}
if (!msTargetCompatible)
{
result = TextureCompatibility.PropagateViewCompatibility(result, TextureCompatibility.ViewTargetCompatible(Info, info));
if (Info.SamplesInX != info.SamplesInX || Info.SamplesInY != info.SamplesInY)
{
result = TextureViewCompatibility.Incompatible;
}
}
if (result == TextureViewCompatibility.Full && Info.FormatInfo.Format != info.FormatInfo.Format && !_context.Capabilities.SupportsMismatchingViewFormat)
{
// AMD and Intel have a bug where the view format is always ignored;
@ -1156,11 +1172,6 @@ namespace Ryujinx.Graphics.Gpu.Image
result = TextureViewCompatibility.CopyOnly;
}
if (Info.SamplesInX != info.SamplesInX || Info.SamplesInY != info.SamplesInY)
{
result = TextureViewCompatibility.Incompatible;
}
}
firstLayer = 0;

View File

@ -542,7 +542,14 @@ namespace Ryujinx.Graphics.Gpu.Image
for (int index = 0; index < overlapsCount; index++)
{
Texture overlap = _textureOverlaps[index];
TextureViewCompatibility overlapCompatibility = overlap.IsViewCompatible(info, range.Value, sizeInfo.LayerSize, _context.Capabilities, out int firstLayer, out int firstLevel);
TextureViewCompatibility overlapCompatibility = overlap.IsViewCompatible(
info,
range.Value,
sizeInfo.LayerSize,
_context.Capabilities,
flags.HasFlag(TextureSearchFlags.ForCopy),
out int firstLayer,
out int firstLevel);
if (overlapCompatibility == TextureViewCompatibility.Full)
{
@ -650,7 +657,14 @@ namespace Ryujinx.Graphics.Gpu.Image
Texture overlap = _textureOverlaps[index];
bool overlapInCache = overlap.CacheNode != null;
TextureViewCompatibility compatibility = texture.IsViewCompatible(overlap.Info, overlap.Range, overlap.LayerSize, _context.Capabilities, out int firstLayer, out int firstLevel);
TextureViewCompatibility compatibility = texture.IsViewCompatible(
overlap.Info,
overlap.Range,
overlap.LayerSize,
_context.Capabilities,
false,
out int firstLayer,
out int firstLevel);
if (overlap.IsView && compatibility == TextureViewCompatibility.Full)
{
@ -1000,20 +1014,34 @@ namespace Ryujinx.Graphics.Gpu.Image
depthOrLayers = info.DepthOrLayers;
}
// 2D and 2D multisample textures are not considered compatible.
// This specific case is required for copies, where the source texture might be multisample.
// In this case, we inherit the parent texture multisample state.
Target target = info.Target;
int samplesInX = info.SamplesInX;
int samplesInY = info.SamplesInY;
if (target == Target.Texture2D && parent.Target == Target.Texture2DMultisample)
{
target = Target.Texture2DMultisample;
samplesInX = parent.Info.SamplesInX;
samplesInY = parent.Info.SamplesInY;
}
return new TextureInfo(
info.GpuAddress,
width,
height,
depthOrLayers,
info.Levels,
info.SamplesInX,
info.SamplesInY,
samplesInX,
samplesInY,
info.Stride,
info.IsLinear,
info.GobBlocksInY,
info.GobBlocksInZ,
info.GobBlocksInTileX,
info.Target,
target,
info.FormatInfo,
info.DepthStencilMode,
info.SwizzleR,