From 3ce4e58cd7d8de32743a662eb5b44a7e4faa3179 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Mon, 9 Jul 2018 01:09:45 -0300 Subject: [PATCH] Add locking methods to the ogl resource cache --- Ryujinx.Graphics/Gal/IGalRasterizer.cs | 3 ++ Ryujinx.Graphics/Gal/IGalTexture.cs | 3 ++ .../Gal/OpenGL/OGLCachedResource.cs | 43 ++++++++++++++++++- Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs | 12 ++++++ Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs | 10 +++++ Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs | 16 +++++++ 6 files changed, 85 insertions(+), 2 deletions(-) diff --git a/Ryujinx.Graphics/Gal/IGalRasterizer.cs b/Ryujinx.Graphics/Gal/IGalRasterizer.cs index 2598efb610..99a69fa2eb 100644 --- a/Ryujinx.Graphics/Gal/IGalRasterizer.cs +++ b/Ryujinx.Graphics/Gal/IGalRasterizer.cs @@ -2,6 +2,9 @@ namespace Ryujinx.Graphics.Gal { public interface IGalRasterizer { + void LockCaches(); + void UnlockCaches(); + void ClearBuffers(GalClearBufferFlags Flags); bool IsVboCached(long Key, long DataSize); diff --git a/Ryujinx.Graphics/Gal/IGalTexture.cs b/Ryujinx.Graphics/Gal/IGalTexture.cs index 6379e73af4..2ab4119904 100644 --- a/Ryujinx.Graphics/Gal/IGalTexture.cs +++ b/Ryujinx.Graphics/Gal/IGalTexture.cs @@ -2,6 +2,9 @@ namespace Ryujinx.Graphics.Gal { public interface IGalTexture { + void LockCache(); + void UnlockCache(); + void Create(long Key, byte[] Data, GalTexture Texture); bool TryGetCachedTexture(long Key, long DataSize, out GalTexture Texture); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLCachedResource.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLCachedResource.cs index 06d76b8bdd..01ebf98202 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLCachedResource.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLCachedResource.cs @@ -36,6 +36,10 @@ namespace Ryujinx.Graphics.Gal.OpenGL private DeleteValue DeleteValueCallback; + private Queue DeletePending; + + private bool Locked; + public OGLCachedResource(DeleteValue DeleteValueCallback) { if (DeleteValueCallback == null) @@ -48,11 +52,33 @@ namespace Ryujinx.Graphics.Gal.OpenGL Cache = new Dictionary(); SortedCache = new LinkedList(); + + DeletePending = new Queue(); + } + + public void Lock() + { + Locked = true; + } + + public void Unlock() + { + Locked = false; + + while (DeletePending.TryDequeue(out T Value)) + { + DeleteValueCallback(Value); + } + + ClearCacheIfNeeded(); } public void AddOrUpdate(long Key, T Value, long Size) { - ClearCacheIfNeeded(); + if (!Locked) + { + ClearCacheIfNeeded(); + } LinkedListNode Node = SortedCache.AddLast(Key); @@ -60,7 +86,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL if (Cache.TryGetValue(Key, out CacheBucket Bucket)) { - DeleteValueCallback(Bucket.Value); + if (Locked) + { + DeletePending.Enqueue(Bucket.Value); + } + else + { + DeleteValueCallback(Bucket.Value); + } SortedCache.Remove(Bucket.Node); @@ -78,6 +111,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL { Value = Bucket.Value; + SortedCache.Remove(Bucket.Node); + + LinkedListNode Node = SortedCache.AddLast(Key); + + Cache[Key] = new CacheBucket(Value, Bucket.DataSize, Node); + return true; } diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs index a4ec7f87cf..9d7d9f02b1 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs @@ -71,6 +71,18 @@ namespace Ryujinx.Graphics.Gal.OpenGL IndexBuffer = new IbInfo(); } + public void LockCaches() + { + VboCache.Lock(); + IboCache.Lock(); + } + + public void UnlockCaches() + { + VboCache.Unlock(); + IboCache.Unlock(); + } + public void ClearBuffers(GalClearBufferFlags Flags) { ClearBufferMask Mask = ClearBufferMask.ColorBufferBit; diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs index c50bdd71b5..5caca6ecde 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs @@ -26,6 +26,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL TextureCache = new OGLCachedResource(DeleteTexture); } + public void LockCache() + { + TextureCache.Lock(); + } + + public void UnlockCache() + { + TextureCache.Unlock(); + } + private static void DeleteTexture(TCE CachedTexture) { GL.DeleteTexture(CachedTexture.Handle); diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs index b9f9cc4974..a6c04e1fcc 100644 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs @@ -73,6 +73,8 @@ namespace Ryujinx.HLE.Gpu.Engines private void VertexEndGl(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) { + LockCaches(); + SetFrameBuffer(Vmm, 0); long[] Keys = UploadShaders(Vmm); @@ -90,6 +92,20 @@ namespace Ryujinx.HLE.Gpu.Engines UploadTextures(Vmm, Keys); UploadUniforms(Vmm); UploadVertexArrays(Vmm); + + UnlockCaches(); + } + + private void LockCaches() + { + Gpu.Renderer.Rasterizer.LockCaches(); + Gpu.Renderer.Texture.LockCache(); + } + + private void UnlockCaches() + { + Gpu.Renderer.Rasterizer.UnlockCaches(); + Gpu.Renderer.Texture.UnlockCache(); } private void ClearBuffers(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)