aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Vulkan/CacheByRange.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Vulkan/CacheByRange.cs')
-rw-r--r--Ryujinx.Graphics.Vulkan/CacheByRange.cs166
1 files changed, 162 insertions, 4 deletions
diff --git a/Ryujinx.Graphics.Vulkan/CacheByRange.cs b/Ryujinx.Graphics.Vulkan/CacheByRange.cs
index c77e66ae..afd7140e 100644
--- a/Ryujinx.Graphics.Vulkan/CacheByRange.cs
+++ b/Ryujinx.Graphics.Vulkan/CacheByRange.cs
@@ -106,17 +106,125 @@ namespace Ryujinx.Graphics.Vulkan
}
}
+ struct TopologyConversionIndirectCacheKey : ICacheKey
+ {
+ private readonly TopologyConversionCacheKey _baseKey;
+ private readonly BufferHolder _indirectDataBuffer;
+ private readonly int _indirectDataOffset;
+ private readonly int _indirectDataSize;
+
+ public TopologyConversionIndirectCacheKey(
+ VulkanRenderer gd,
+ IndexBufferPattern pattern,
+ int indexSize,
+ BufferHolder indirectDataBuffer,
+ int indirectDataOffset,
+ int indirectDataSize)
+ {
+ _baseKey = new TopologyConversionCacheKey(gd, pattern, indexSize);
+ _indirectDataBuffer = indirectDataBuffer;
+ _indirectDataOffset = indirectDataOffset;
+ _indirectDataSize = indirectDataSize;
+ }
+
+ public bool KeyEqual(ICacheKey other)
+ {
+ return other is TopologyConversionIndirectCacheKey entry &&
+ entry._baseKey.KeyEqual(_baseKey) &&
+ entry._indirectDataBuffer == _indirectDataBuffer &&
+ entry._indirectDataOffset == _indirectDataOffset &&
+ entry._indirectDataSize == _indirectDataSize;
+ }
+
+ public void SetBuffer(Auto<DisposableBuffer> buffer)
+ {
+ _baseKey.SetBuffer(buffer);
+ }
+
+ public void Dispose()
+ {
+ _baseKey.Dispose();
+ }
+ }
+
+ struct IndirectDataCacheKey : ICacheKey
+ {
+ private IndexBufferPattern _pattern;
+
+ public IndirectDataCacheKey(IndexBufferPattern pattern)
+ {
+ _pattern = pattern;
+ }
+
+ public bool KeyEqual(ICacheKey other)
+ {
+ return other is IndirectDataCacheKey entry && entry._pattern == _pattern;
+ }
+
+ public void Dispose()
+ {
+ }
+ }
+
+ struct DrawCountCacheKey : ICacheKey
+ {
+ public bool KeyEqual(ICacheKey other)
+ {
+ return other is DrawCountCacheKey;
+ }
+
+ public void Dispose()
+ {
+ }
+ }
+
+ struct Dependency
+ {
+ private readonly BufferHolder _buffer;
+ private readonly int _offset;
+ private readonly int _size;
+ private readonly ICacheKey _key;
+
+ public Dependency(BufferHolder buffer, int offset, int size, ICacheKey key)
+ {
+ _buffer = buffer;
+ _offset = offset;
+ _size = size;
+ _key = key;
+ }
+
+ public void RemoveFromOwner()
+ {
+ _buffer.RemoveCachedConvertedBuffer(_offset, _size, _key);
+ }
+ }
+
struct CacheByRange<T> where T : IDisposable
{
private struct Entry
{
public ICacheKey Key;
public T Value;
+ public List<Dependency> DependencyList;
public Entry(ICacheKey key, T value)
{
Key = key;
Value = value;
+ DependencyList = null;
+ }
+
+ public void InvalidateDependencies()
+ {
+ if (DependencyList != null)
+ {
+ foreach (Dependency dependency in DependencyList)
+ {
+ dependency.RemoveFromOwner();
+ }
+
+ DependencyList.Clear();
+ }
}
}
@@ -129,6 +237,51 @@ namespace Ryujinx.Graphics.Vulkan
entries.Add(new Entry(key, value));
}
+ public void AddDependency(int offset, int size, ICacheKey key, Dependency dependency)
+ {
+ List<Entry> entries = GetEntries(offset, size);
+
+ for (int i = 0; i < entries.Count; i++)
+ {
+ Entry entry = entries[i];
+
+ if (entry.Key.KeyEqual(key))
+ {
+ if (entry.DependencyList == null)
+ {
+ entry.DependencyList = new List<Dependency>();
+ entries[i] = entry;
+ }
+
+ entry.DependencyList.Add(dependency);
+
+ break;
+ }
+ }
+ }
+
+ public void Remove(int offset, int size, ICacheKey key)
+ {
+ List<Entry> entries = GetEntries(offset, size);
+
+ for (int i = 0; i < entries.Count; i++)
+ {
+ Entry entry = entries[i];
+
+ if (entry.Key.KeyEqual(key))
+ {
+ entries.RemoveAt(i--);
+
+ DestroyEntry(entry);
+ }
+ }
+
+ if (entries.Count == 0)
+ {
+ _ranges.Remove(PackRange(offset, size));
+ }
+ }
+
public bool TryGetValue(int offset, int size, ICacheKey key, out T value)
{
List<Entry> entries = GetEntries(offset, size);
@@ -155,8 +308,7 @@ namespace Ryujinx.Graphics.Vulkan
{
foreach (Entry entry in entries)
{
- entry.Key.Dispose();
- entry.Value.Dispose();
+ DestroyEntry(entry);
}
}
@@ -185,8 +337,7 @@ namespace Ryujinx.Graphics.Vulkan
foreach (Entry entry in entries)
{
- entry.Key.Dispose();
- entry.Value.Dispose();
+ DestroyEntry(entry);
}
(toRemove ??= new List<ulong>()).Add(range.Key);
@@ -222,6 +373,13 @@ namespace Ryujinx.Graphics.Vulkan
return value;
}
+ private static void DestroyEntry(Entry entry)
+ {
+ entry.Key.Dispose();
+ entry.Value?.Dispose();
+ entry.InvalidateDependencies();
+ }
+
private static ulong PackRange(int offset, int size)
{
return (uint)offset | ((ulong)size << 32);