forked from Mirror/Ryujinx
Allow copy texture views to have mismatching multisample state (#3152)
This commit is contained in:
parent
a4e8bea866
commit
3139a85a2b
2 changed files with 51 additions and 12 deletions
|
@ -1136,18 +1136,34 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
/// <param name="range">Texture view physical memory ranges</param>
|
/// <param name="range">Texture view physical memory ranges</param>
|
||||||
/// <param name="layerSize">Layer size on the given texture</param>
|
/// <param name="layerSize">Layer size on the given texture</param>
|
||||||
/// <param name="caps">Host GPU capabilities</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="firstLayer">Texture view initial layer on this texture</param>
|
||||||
/// <param name="firstLevel">Texture view first mipmap level 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>
|
/// <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;
|
TextureViewCompatibility result = TextureViewCompatibility.Full;
|
||||||
|
|
||||||
result = TextureCompatibility.PropagateViewCompatibility(result, TextureCompatibility.ViewFormatCompatible(Info, info, caps));
|
result = TextureCompatibility.PropagateViewCompatibility(result, TextureCompatibility.ViewFormatCompatible(Info, info, caps));
|
||||||
if (result != TextureViewCompatibility.Incompatible)
|
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));
|
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)
|
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;
|
// 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;
|
result = TextureViewCompatibility.CopyOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Info.SamplesInX != info.SamplesInX || Info.SamplesInY != info.SamplesInY)
|
|
||||||
{
|
|
||||||
result = TextureViewCompatibility.Incompatible;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
firstLayer = 0;
|
firstLayer = 0;
|
||||||
|
|
|
@ -542,7 +542,14 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
for (int index = 0; index < overlapsCount; index++)
|
for (int index = 0; index < overlapsCount; index++)
|
||||||
{
|
{
|
||||||
Texture overlap = _textureOverlaps[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)
|
if (overlapCompatibility == TextureViewCompatibility.Full)
|
||||||
{
|
{
|
||||||
|
@ -650,7 +657,14 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
Texture overlap = _textureOverlaps[index];
|
Texture overlap = _textureOverlaps[index];
|
||||||
bool overlapInCache = overlap.CacheNode != null;
|
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)
|
if (overlap.IsView && compatibility == TextureViewCompatibility.Full)
|
||||||
{
|
{
|
||||||
|
@ -1000,20 +1014,34 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
depthOrLayers = info.DepthOrLayers;
|
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(
|
return new TextureInfo(
|
||||||
info.GpuAddress,
|
info.GpuAddress,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
depthOrLayers,
|
depthOrLayers,
|
||||||
info.Levels,
|
info.Levels,
|
||||||
info.SamplesInX,
|
samplesInX,
|
||||||
info.SamplesInY,
|
samplesInY,
|
||||||
info.Stride,
|
info.Stride,
|
||||||
info.IsLinear,
|
info.IsLinear,
|
||||||
info.GobBlocksInY,
|
info.GobBlocksInY,
|
||||||
info.GobBlocksInZ,
|
info.GobBlocksInZ,
|
||||||
info.GobBlocksInTileX,
|
info.GobBlocksInTileX,
|
||||||
info.Target,
|
target,
|
||||||
info.FormatInfo,
|
info.FormatInfo,
|
||||||
info.DepthStencilMode,
|
info.DepthStencilMode,
|
||||||
info.SwizzleR,
|
info.SwizzleR,
|
||||||
|
|
Loading…
Reference in a new issue