aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Image
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Image')
-rw-r--r--Ryujinx.Graphics.Gpu/Image/Texture.cs32
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TextureCache.cs7
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TexturePool.cs5
3 files changed, 42 insertions, 2 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/Texture.cs b/Ryujinx.Graphics.Gpu/Image/Texture.cs
index 0a083ebc..c9c3c59a 100644
--- a/Ryujinx.Graphics.Gpu/Image/Texture.cs
+++ b/Ryujinx.Graphics.Gpu/Image/Texture.cs
@@ -9,6 +9,7 @@ using Ryujinx.Memory.Range;
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Linq;
namespace Ryujinx.Graphics.Gpu.Image
{
@@ -1296,6 +1297,37 @@ namespace Ryujinx.Graphics.Gpu.Image
}
/// <summary>
+ /// Determine if any of this texture's data overlaps with another.
+ /// </summary>
+ /// <param name="texture">The texture to check against</param>
+ /// <returns>True if any slice of the textures overlap, false otherwise</returns>
+ public bool DataOverlaps(Texture texture)
+ {
+ if (texture._sizeInfo.AllOffsets.Length == 1 && _sizeInfo.AllOffsets.Length == 1)
+ {
+ return Range.OverlapsWith(texture.Range);
+ }
+
+ MultiRange otherRange = texture.Range;
+
+ IEnumerable<MultiRange> regions = _sizeInfo.AllRegions().Select((region) => Range.GetSlice((ulong)region.Offset, (ulong)region.Size));
+ IEnumerable<MultiRange> otherRegions = texture._sizeInfo.AllRegions().Select((region) => otherRange.GetSlice((ulong)region.Offset, (ulong)region.Size));
+
+ foreach (MultiRange region in regions)
+ {
+ foreach (MultiRange otherRegion in otherRegions)
+ {
+ if (region.OverlapsWith(otherRegion))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
/// Increments the texture reference count.
/// </summary>
public void IncrementReferenceCount()
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureCache.cs b/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
index 37682b65..44c974e8 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
@@ -636,6 +636,13 @@ namespace Ryujinx.Graphics.Gpu.Image
continue;
}
+ if (!texture.DataOverlaps(overlap))
+ {
+ // Allow textures to overlap if their data does not actually overlap.
+ // This typically happens when mip level subranges of a layered texture are used. (each texture fills the gaps of the others)
+ continue;
+ }
+
// The overlap texture is going to contain garbage data after we draw, or is generally incompatible.
// If the texture cannot be entirely contained in the new address space, and one of its view children is compatible with us,
// it must be flushed before removal, so that the data is not lost.
diff --git a/Ryujinx.Graphics.Gpu/Image/TexturePool.cs b/Ryujinx.Graphics.Gpu/Image/TexturePool.cs
index bcce443c..5b5c5ab0 100644
--- a/Ryujinx.Graphics.Gpu/Image/TexturePool.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TexturePool.cs
@@ -85,8 +85,9 @@ namespace Ryujinx.Graphics.Gpu.Image
TextureDescriptor descriptor = GetDescriptor(id);
- int width = descriptor.UnpackWidth();
- int height = descriptor.UnpackHeight();
+ int baseLevel = descriptor.UnpackBaseLevel();
+ int width = Math.Max(1, descriptor.UnpackWidth() >> baseLevel);
+ int height = Math.Max(1, descriptor.UnpackHeight() >> baseLevel);
if (texture.Info.Width != width || texture.Info.Height != height)
{