aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Image/Texture.cs
diff options
context:
space:
mode:
authorgdk <gab.dark.100@gmail.com>2019-10-30 20:45:01 -0300
committerThog <thog@protonmail.com>2020-01-09 02:13:00 +0100
commitd786d8d2b924da7cd116a2eb97d738a9f07b4e43 (patch)
tree0e84072c554066d20622d156d1394144ed5258bd /Ryujinx.Graphics.Gpu/Image/Texture.cs
parent3bcc395253e020df40763d36ba9401b126b17173 (diff)
Support copy of slices to 3D textures, remove old 3D render target layered render support, do not delete textures with existing views created from them
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Image/Texture.cs')
-rw-r--r--Ryujinx.Graphics.Gpu/Image/Texture.cs62
1 files changed, 51 insertions, 11 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/Texture.cs b/Ryujinx.Graphics.Gpu/Image/Texture.cs
index c34ff1d3..cc7e7bf6 100644
--- a/Ryujinx.Graphics.Gpu/Image/Texture.cs
+++ b/Ryujinx.Graphics.Gpu/Image/Texture.cs
@@ -6,6 +6,7 @@ using Ryujinx.Graphics.Texture;
using Ryujinx.Graphics.Texture.Astc;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
namespace Ryujinx.Graphics.Gpu.Image
{
@@ -116,6 +117,8 @@ namespace Ryujinx.Graphics.Gpu.Image
_views.Remove(texture);
texture._viewStorage = null;
+
+ DeleteIfNotUsed();
}
public void ChangeSize(int width, int height, int depthOrLayers)
@@ -187,7 +190,7 @@ namespace Ryujinx.Graphics.Gpu.Image
{
ITexture newStorage = _context.Renderer.CreateTexture(createInfo);
- HostTexture.CopyTo(newStorage);
+ HostTexture.CopyTo(newStorage, 0, 0);
ReplaceStorage(newStorage);
}
@@ -413,7 +416,21 @@ namespace Ryujinx.Graphics.Gpu.Image
_info.SamplesInY == info.SamplesInY;
}
- public bool IsViewCompatible(TextureInfo info, ulong size, out int firstLayer, out int firstLevel)
+ public bool IsViewCompatible(
+ TextureInfo info,
+ ulong size,
+ out int firstLayer,
+ out int firstLevel)
+ {
+ return IsViewCompatible(info, size, isCopy: false, out firstLayer, out firstLevel);
+ }
+
+ public bool IsViewCompatible(
+ TextureInfo info,
+ ulong size,
+ bool isCopy,
+ out int firstLayer,
+ out int firstLevel)
{
// Out of range.
if (info.Address < Address || info.Address + size > EndAddress)
@@ -441,12 +458,12 @@ namespace Ryujinx.Graphics.Gpu.Image
return false;
}
- if (!ViewSizeMatches(info, firstLevel))
+ if (!ViewSizeMatches(info, firstLevel, isCopy))
{
return false;
}
- if (!ViewTargetCompatible(info))
+ if (!ViewTargetCompatible(info, isCopy))
{
return false;
}
@@ -496,18 +513,24 @@ namespace Ryujinx.Graphics.Gpu.Image
return TextureCompatibility.FormatCompatible(_info.FormatInfo, info.FormatInfo);
}
- private bool ViewSizeMatches(TextureInfo info, int level)
+ private bool ViewSizeMatches(TextureInfo info, int level, bool isCopy)
{
Size size = GetAlignedSize(_info, level);
Size otherSize = GetAlignedSize(info);
- return size.Width == otherSize.Width &&
- size.Height == otherSize.Height &&
- size.Depth == otherSize.Depth;
+ // For copies, we can copy a subset of the 3D texture slices,
+ // so the depth may be different in this case.
+ if (!isCopy && info.Target == Target.Texture3D && size.Depth != otherSize.Depth)
+ {
+ return false;
+ }
+
+ return size.Width == otherSize.Width &&
+ size.Height == otherSize.Height;
}
- private bool ViewTargetCompatible(TextureInfo info)
+ private bool ViewTargetCompatible(TextureInfo info, bool isCopy)
{
switch (_info.Target)
{
@@ -534,7 +557,8 @@ namespace Ryujinx.Graphics.Gpu.Image
info.Target == Target.Texture2DMultisampleArray;
case Target.Texture3D:
- return info.Target == Target.Texture3D;
+ return info.Target == Target.Texture3D ||
+ (info.Target == Target.Texture2D && isCopy);
}
return false;
@@ -686,7 +710,9 @@ namespace Ryujinx.Graphics.Gpu.Image
public void DecrementReferenceCount()
{
- if (--_referenceCount == 0)
+ int newRefCount = --_referenceCount;
+
+ if (newRefCount == 0)
{
if (_viewStorage != this)
{
@@ -694,7 +720,21 @@ namespace Ryujinx.Graphics.Gpu.Image
}
_context.Methods.TextureManager.RemoveTextureFromCache(this);
+ }
+
+ Debug.Assert(newRefCount >= 0);
+ DeleteIfNotUsed();
+ }
+
+ private void DeleteIfNotUsed()
+ {
+ // We can delete the texture as long it is not being used
+ // in any cache (the reference count is 0 in this case), and
+ // also all views that may be created from this texture were
+ // already deleted (views count is 0).
+ if (_referenceCount == 0 && _views.Count == 0)
+ {
DisposeTextures();
}
}