Force cache to remove entries when memory usage exceeds a given threshold (#492)
This commit is contained in:
parent
453543fb88
commit
85ffd76016
4 changed files with 30 additions and 7 deletions
|
@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
{
|
{
|
||||||
public delegate void DeleteValue(T Value);
|
public delegate void DeleteValue(T Value);
|
||||||
|
|
||||||
private const int MaxTimeDelta = 5 * 60000;
|
private const int MinTimeDelta = 5 * 60000;
|
||||||
private const int MaxRemovalsPerRun = 10;
|
private const int MaxRemovalsPerRun = 10;
|
||||||
|
|
||||||
private struct CacheBucket
|
private struct CacheBucket
|
||||||
|
@ -41,8 +41,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
|
|
||||||
private bool Locked;
|
private bool Locked;
|
||||||
|
|
||||||
public OGLCachedResource(DeleteValue DeleteValueCallback)
|
private long MaxSize;
|
||||||
|
private long TotalSize;
|
||||||
|
|
||||||
|
public OGLCachedResource(DeleteValue DeleteValueCallback, long MaxSize)
|
||||||
{
|
{
|
||||||
|
this.MaxSize = MaxSize;
|
||||||
|
|
||||||
if (DeleteValueCallback == null)
|
if (DeleteValueCallback == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(DeleteValueCallback));
|
throw new ArgumentNullException(nameof(DeleteValueCallback));
|
||||||
|
@ -98,12 +103,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
|
|
||||||
SortedCache.Remove(Bucket.Node);
|
SortedCache.Remove(Bucket.Node);
|
||||||
|
|
||||||
|
TotalSize -= Bucket.DataSize;
|
||||||
|
|
||||||
Cache[Key] = NewBucket;
|
Cache[Key] = NewBucket;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Cache.Add(Key, NewBucket);
|
Cache.Add(Key, NewBucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TotalSize += Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetValue(long Key, out T Value)
|
public bool TryGetValue(long Key, out T Value)
|
||||||
|
@ -159,7 +168,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
|
|
||||||
long TimeDelta = Timestamp - Bucket.Timestamp;
|
long TimeDelta = Timestamp - Bucket.Timestamp;
|
||||||
|
|
||||||
if ((uint)TimeDelta <= (uint)MaxTimeDelta)
|
if (TimeDelta <= MinTimeDelta && !UnderMemoryPressure())
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -169,7 +178,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
Cache.Remove(Node.Value);
|
Cache.Remove(Node.Value);
|
||||||
|
|
||||||
DeleteValueCallback(Bucket.Value);
|
DeleteValueCallback(Bucket.Value);
|
||||||
|
|
||||||
|
TotalSize -= Bucket.DataSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool UnderMemoryPressure()
|
||||||
|
{
|
||||||
|
return TotalSize >= MaxSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,11 +5,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
{
|
{
|
||||||
class OGLConstBuffer : IGalConstBuffer
|
class OGLConstBuffer : IGalConstBuffer
|
||||||
{
|
{
|
||||||
|
private const long MaxConstBufferCacheSize = 64 * 1024 * 1024;
|
||||||
|
|
||||||
private OGLCachedResource<OGLStreamBuffer> Cache;
|
private OGLCachedResource<OGLStreamBuffer> Cache;
|
||||||
|
|
||||||
public OGLConstBuffer()
|
public OGLConstBuffer()
|
||||||
{
|
{
|
||||||
Cache = new OGLCachedResource<OGLStreamBuffer>(DeleteBuffer);
|
Cache = new OGLCachedResource<OGLStreamBuffer>(DeleteBuffer, MaxConstBufferCacheSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LockCache()
|
public void LockCache()
|
||||||
|
|
|
@ -5,6 +5,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
{
|
{
|
||||||
class OGLRasterizer : IGalRasterizer
|
class OGLRasterizer : IGalRasterizer
|
||||||
{
|
{
|
||||||
|
private const long MaxVertexBufferCacheSize = 128 * 1024 * 1024;
|
||||||
|
private const long MaxIndexBufferCacheSize = 64 * 1024 * 1024;
|
||||||
|
|
||||||
private int[] VertexBuffers;
|
private int[] VertexBuffers;
|
||||||
|
|
||||||
private OGLCachedResource<int> VboCache;
|
private OGLCachedResource<int> VboCache;
|
||||||
|
@ -24,8 +27,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
{
|
{
|
||||||
VertexBuffers = new int[32];
|
VertexBuffers = new int[32];
|
||||||
|
|
||||||
VboCache = new OGLCachedResource<int>(GL.DeleteBuffer);
|
VboCache = new OGLCachedResource<int>(GL.DeleteBuffer, MaxVertexBufferCacheSize);
|
||||||
IboCache = new OGLCachedResource<int>(GL.DeleteBuffer);
|
IboCache = new OGLCachedResource<int>(GL.DeleteBuffer, MaxIndexBufferCacheSize);
|
||||||
|
|
||||||
IndexBuffer = new IbInfo();
|
IndexBuffer = new IbInfo();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,15 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
{
|
{
|
||||||
class OGLTexture : IGalTexture
|
class OGLTexture : IGalTexture
|
||||||
{
|
{
|
||||||
|
private const long MaxTextureCacheSize = 768 * 1024 * 1024;
|
||||||
|
|
||||||
private OGLCachedResource<ImageHandler> TextureCache;
|
private OGLCachedResource<ImageHandler> TextureCache;
|
||||||
|
|
||||||
public EventHandler<int> TextureDeleted { get; set; }
|
public EventHandler<int> TextureDeleted { get; set; }
|
||||||
|
|
||||||
public OGLTexture()
|
public OGLTexture()
|
||||||
{
|
{
|
||||||
TextureCache = new OGLCachedResource<ImageHandler>(DeleteTexture);
|
TextureCache = new OGLCachedResource<ImageHandler>(DeleteTexture, MaxTextureCacheSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LockCache()
|
public void LockCache()
|
||||||
|
|
Reference in a new issue