Support partial invalidation on texture access (#1000)

* Support partial invalidation on texture access

* Fix typo

* PR feedback

* Fix modified size clamping
This commit is contained in:
gdkchan 2020-03-20 00:17:11 -03:00 committed by GitHub
parent 32d3f3f690
commit 8e64984158
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 113 additions and 13 deletions

View file

@ -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);
}
}
}
}
@ -595,6 +614,16 @@ namespace Ryujinx.Graphics.Gpu.Image
return texture;
}
/// <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>
@ -602,6 +631,11 @@ namespace Ryujinx.Graphics.Gpu.Image
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>