aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2020-02-06 21:49:26 +0000
committerGitHub <noreply@github.com>2020-02-07 08:49:26 +1100
commit6db16b411031b17ac171dac3899ce0488a1b40df (patch)
tree5e33452e60dc563db8e2bfbd32927c147baa5fa8 /Ryujinx.Graphics.Gpu/Image/TextureManager.cs
parenta906f2071cbe4caf53c697bcb7dfa91e3e7dcfae (diff)
Only enumerate cached textures that are modified when flushing. (#918)
* Only enumarate cached textures that are modified when flushing, rather than all of them. * Remove locking. * Add missing clear. * Remove texture from modified list when data is disposed. In case the game does not call either flush method at any point. * Add ReferenceEqualityComparer from jD for the HashSet
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Image/TextureManager.cs')
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TextureManager.cs40
1 files changed, 32 insertions, 8 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
index 15727191..87fb4161 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
@@ -5,6 +5,7 @@ using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Gpu.State;
using Ryujinx.Graphics.Texture;
using System;
+using System.Collections.Generic;
namespace Ryujinx.Graphics.Gpu.Image
{
@@ -35,6 +36,8 @@ namespace Ryujinx.Graphics.Gpu.Image
private readonly AutoDeleteCache _cache;
+ private readonly HashSet<Texture> _modified;
+
/// <summary>
/// Constructs a new instance of the texture manager.
/// </summary>
@@ -57,6 +60,8 @@ namespace Ryujinx.Graphics.Gpu.Image
_textureOverlaps = new Texture[OverlapsBufferInitialCapacity];
_cache = new AutoDeleteCache();
+
+ _modified = new HashSet<Texture>(new ReferenceEqualityComparer<Texture>());
}
/// <summary>
@@ -579,6 +584,8 @@ namespace Ryujinx.Graphics.Gpu.Image
if (!isSamplerTexture)
{
_cache.Add(texture);
+ texture.Modified += CacheTextureModified;
+ texture.Disposed += CacheTextureDisposed;
}
_textures.Add(texture);
@@ -589,6 +596,24 @@ namespace Ryujinx.Graphics.Gpu.Image
}
/// <summary>
+ /// Signaled when a cache texture is modified, and adds it to a set to be enumerated when flushing textures.
+ /// </summary>
+ /// <param name="texture">The texture that was modified.</param>
+ private void CacheTextureModified(Texture texture)
+ {
+ _modified.Add(texture);
+ }
+
+ /// <summary>
+ /// Signaled when a cache texture is disposed, so it can be removed from the set of modified textures if present.
+ /// </summary>
+ /// <param name="texture">The texture that was diosposed.</param>
+ private void CacheTextureDisposed(Texture texture)
+ {
+ _modified.Remove(texture);
+ }
+
+ /// <summary>
/// Resizes the temporary buffer used for range list intersection results, if it has grown too much.
/// </summary>
private void ShrinkOverlapsBufferIfNeeded()
@@ -722,15 +747,14 @@ namespace Ryujinx.Graphics.Gpu.Image
/// </summary>
public void Flush()
{
- foreach (Texture texture in _cache)
+ foreach (Texture texture in _modified)
{
- if (texture.Info.IsLinear && texture.Modified)
+ if (texture.Info.IsLinear)
{
texture.Flush();
-
- texture.Modified = false;
}
}
+ _modified.Clear();
}
/// <summary>
@@ -740,15 +764,14 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <param name="size">The range size</param>
public void Flush(ulong address, ulong size)
{
- foreach (Texture texture in _cache)
+ foreach (Texture texture in _modified)
{
- if (texture.OverlapsWith(address, size) && texture.Modified)
+ if (texture.OverlapsWith(address, size))
{
texture.Flush();
-
- texture.Modified = false;
}
}
+ _modified.Clear();
}
/// <summary>
@@ -772,6 +795,7 @@ namespace Ryujinx.Graphics.Gpu.Image
{
foreach (Texture texture in _textures)
{
+ _modified.Remove(texture);
texture.Dispose();
}
}