diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2020-03-20 00:17:11 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-03-20 14:17:11 +1100 |
| commit | 8e649841582242a2f4826e9429fd926316e6f2cb (patch) | |
| tree | 703d8968c3c03e431cc1582a0cbaccf10049e5b3 /Ryujinx.Graphics.Gpu/Image/TextureManager.cs | |
| parent | 32d3f3f69024835d375401222b9abfbd32db37a5 (diff) | |
Support partial invalidation on texture access (#1000)
* Support partial invalidation on texture access
* Fix typo
* PR feedback
* Fix modified size clamping
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Image/TextureManager.cs')
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Image/TextureManager.cs | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs index 87fb4161..27cbc6ff 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs @@ -37,6 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Image private readonly AutoDeleteCache _cache; private readonly HashSet<Texture> _modified; + private readonly HashSet<Texture> _modifiedLinear; /// <summary> /// Constructs a new instance of the texture manager. @@ -62,6 +63,7 @@ namespace Ryujinx.Graphics.Gpu.Image _cache = new AutoDeleteCache(); _modified = new HashSet<Texture>(new ReferenceEqualityComparer<Texture>()); + _modifiedLinear = new HashSet<Texture>(new ReferenceEqualityComparer<Texture>()); } /// <summary> @@ -519,6 +521,11 @@ namespace Ryujinx.Graphics.Gpu.Image texture = overlap.CreateView(info, sizeInfo, firstLayer, firstLevel); + if (IsTextureModified(overlap)) + { + CacheTextureModified(texture); + } + // The size only matters (and is only really reliable) when the // texture is used on a sampler, because otherwise the size will be // aligned. @@ -554,6 +561,13 @@ namespace Ryujinx.Graphics.Gpu.Image overlap.HostTexture.CopyTo(newView, 0, 0); + // Inherit modification from overlapping texture, do that before replacing + // the view since the replacement operation removes it from the list. + if (IsTextureModified(overlap)) + { + CacheTextureModified(texture); + } + overlap.ReplaceView(texture, overlapInfo, newView); } } @@ -574,6 +588,11 @@ namespace Ryujinx.Graphics.Gpu.Image out int firstLevel)) { overlap.HostTexture.CopyTo(texture.HostTexture, firstLayer, firstLevel); + + if (IsTextureModified(overlap)) + { + CacheTextureModified(texture); + } } } } @@ -596,12 +615,27 @@ namespace Ryujinx.Graphics.Gpu.Image } /// <summary> + /// Checks if a texture was modified by the host GPU. + /// </summary> + /// <param name="texture">Texture to be checked</param> + /// <returns>True if the texture was modified by the host GPU, false otherwise</returns> + public bool IsTextureModified(Texture texture) + { + return _modified.Contains(texture); + } + + /// <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); + + if (texture.Info.IsLinear) + { + _modifiedLinear.Add(texture); + } } /// <summary> @@ -611,6 +645,11 @@ namespace Ryujinx.Graphics.Gpu.Image private void CacheTextureDisposed(Texture texture) { _modified.Remove(texture); + + if (texture.Info.IsLinear) + { + _modifiedLinear.Remove(texture); + } } /// <summary> @@ -747,14 +786,12 @@ namespace Ryujinx.Graphics.Gpu.Image /// </summary> public void Flush() { - foreach (Texture texture in _modified) + foreach (Texture texture in _modifiedLinear) { - if (texture.Info.IsLinear) - { - texture.Flush(); - } + texture.Flush(); } - _modified.Clear(); + + _modifiedLinear.Clear(); } /// <summary> @@ -771,7 +808,6 @@ namespace Ryujinx.Graphics.Gpu.Image texture.Flush(); } } - _modified.Clear(); } /// <summary> |
