From 0914001177902fb94e39cb90a72aa06334ee7704 Mon Sep 17 00:00:00 2001 From: riperiperi Date: Sun, 2 Feb 2020 16:46:01 +0000 Subject: [PATCH] Only enumarate cached textures that are modified when flushing, rather than all of them. --- .../Engine/MethodCopyTexture.cs | 2 +- Ryujinx.Graphics.Gpu/Engine/Methods.cs | 4 +- Ryujinx.Graphics.Gpu/Image/Texture.cs | 12 +++++- Ryujinx.Graphics.Gpu/Image/TextureManager.cs | 42 ++++++++++++++----- 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs b/Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs index 8d1b2b714f..4900db1b01 100644 --- a/Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs +++ b/Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs @@ -94,7 +94,7 @@ namespace Ryujinx.Graphics.Gpu.Engine srcTexture.HostTexture.CopyTo(dstTexture.HostTexture, srcRegion, dstRegion, linearFilter); } - dstTexture.Modified = true; + dstTexture.SignalModified(); } } } \ No newline at end of file diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs index d9e7582b7a..a2c9876e42 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs @@ -286,7 +286,7 @@ namespace Ryujinx.Graphics.Gpu.Engine if (color != null) { - color.Modified = true; + color.SignalModified(); } } @@ -306,7 +306,7 @@ namespace Ryujinx.Graphics.Gpu.Engine if (depthStencil != null) { - depthStencil.Modified = true; + depthStencil.SignalModified(); } } diff --git a/Ryujinx.Graphics.Gpu/Image/Texture.cs b/Ryujinx.Graphics.Gpu/Image/Texture.cs index 7d5e9079da..5a00ddd95b 100644 --- a/Ryujinx.Graphics.Gpu/Image/Texture.cs +++ b/Ryujinx.Graphics.Gpu/Image/Texture.cs @@ -54,9 +54,9 @@ namespace Ryujinx.Graphics.Gpu.Image public LinkedListNode CacheNode { get; set; } /// - /// Texture data modified by the GPU. + /// Event to fire when texture data modified by the GPU. /// - public bool Modified { get; set; } + public event Action Modified; /// /// Start address of the texture in guest memory. @@ -933,6 +933,14 @@ namespace Ryujinx.Graphics.Gpu.Image _layers = info.GetLayers(); } + /// + /// Signals that the texture has been modified. + /// + public void SignalModified() + { + Modified?.Invoke(this); + } + /// /// Replaces the host texture, while disposing of the old one if needed. /// diff --git a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs index 1572719118..7c953f46ac 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 _modified; + /// /// Constructs a new instance of the texture manager. /// @@ -57,6 +60,8 @@ namespace Ryujinx.Graphics.Gpu.Image _textureOverlaps = new Texture[OverlapsBufferInitialCapacity]; _cache = new AutoDeleteCache(); + + _modified = new HashSet(); } /// @@ -579,6 +584,7 @@ namespace Ryujinx.Graphics.Gpu.Image if (!isSamplerTexture) { _cache.Add(texture); + texture.Modified += CacheTextureModified; } _textures.Add(texture); @@ -588,6 +594,18 @@ namespace Ryujinx.Graphics.Gpu.Image return texture; } + /// + /// Signaled when a cache texture is modified, and adds it to a set to be enumerated when flushing textures. + /// + /// The texture that was modified. + private void CacheTextureModified(Texture texture) + { + lock (_modified) + { + _modified.Add(texture); + } + } + /// /// Resizes the temporary buffer used for range list intersection results, if it has grown too much. /// @@ -722,14 +740,16 @@ namespace Ryujinx.Graphics.Gpu.Image /// public void Flush() { - foreach (Texture texture in _cache) + lock (_modified) { - if (texture.Info.IsLinear && texture.Modified) + foreach (Texture texture in _modified) { - texture.Flush(); - - texture.Modified = false; + if (texture.Info.IsLinear) + { + texture.Flush(); + } } + _modified.Clear(); } } @@ -740,14 +760,16 @@ namespace Ryujinx.Graphics.Gpu.Image /// The range size public void Flush(ulong address, ulong size) { - foreach (Texture texture in _cache) + lock (_modified) { - if (texture.OverlapsWith(address, size) && texture.Modified) + foreach (Texture texture in _modified) { - texture.Flush(); - - texture.Modified = false; + if (texture.OverlapsWith(address, size)) + { + texture.Flush(); + } } + _modified.Clear(); } }