From 1ca0517c99af1914b887d6197b816c84537a9145 Mon Sep 17 00:00:00 2001 From: riperiperi Date: Sat, 8 Oct 2022 15:28:27 +0100 Subject: Vulkan: Fix some issues with CacheByRange (#3743) * Fix some issues with CacheByRange - Cache now clears under more circumstances, the most important being the fast path write. - Cache supports partial clear which should help when more buffers join. - Fixed an issue with I8->I16 conversion where it wouldn't register the buffer for use on dispose. Should hopefully fix issues with https://github.com/Ryujinx/Ryujinx-Games-List/issues/4010 and maybe others. * Fix collection modified exception * Fix accidental use of parameterless constructor * Replay DynamicState when restoring from helper shader --- Ryujinx.Graphics.Vulkan/CacheByRange.cs | 48 +++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'Ryujinx.Graphics.Vulkan/CacheByRange.cs') diff --git a/Ryujinx.Graphics.Vulkan/CacheByRange.cs b/Ryujinx.Graphics.Vulkan/CacheByRange.cs index 4c47e1c1..c77e66ae 100644 --- a/Ryujinx.Graphics.Vulkan/CacheByRange.cs +++ b/Ryujinx.Graphics.Vulkan/CacheByRange.cs @@ -25,6 +25,11 @@ namespace Ryujinx.Graphics.Vulkan return other is I8ToI16CacheKey; } + public void SetBuffer(Auto buffer) + { + _buffer = buffer; + } + public void Dispose() { _gd.PipelineInternal.DirtyIndexBuffer(_buffer); @@ -160,6 +165,44 @@ namespace Ryujinx.Graphics.Vulkan } } + public void ClearRange(int offset, int size) + { + if (_ranges != null && _ranges.Count > 0) + { + int end = offset + size; + + List toRemove = null; + + foreach (KeyValuePair> range in _ranges) + { + (int rOffset, int rSize) = UnpackRange(range.Key); + + int rEnd = rOffset + rSize; + + if (rEnd > offset && rOffset < end) + { + List entries = range.Value; + + foreach (Entry entry in entries) + { + entry.Key.Dispose(); + entry.Value.Dispose(); + } + + (toRemove ??= new List()).Add(range.Key); + } + } + + if (toRemove != null) + { + foreach (ulong range in toRemove) + { + _ranges.Remove(range); + } + } + } + } + private List GetEntries(int offset, int size) { if (_ranges == null) @@ -184,6 +227,11 @@ namespace Ryujinx.Graphics.Vulkan return (uint)offset | ((ulong)size << 32); } + private static (int offset, int size) UnpackRange(ulong range) + { + return ((int)range, (int)(range >> 32)); + } + public void Dispose() { Clear(); -- cgit v1.2.3