aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Image/Pool.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Image/Pool.cs')
-rw-r--r--Ryujinx.Graphics.Gpu/Image/Pool.cs99
1 files changed, 99 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/Pool.cs b/Ryujinx.Graphics.Gpu/Image/Pool.cs
new file mode 100644
index 00000000..196fc137
--- /dev/null
+++ b/Ryujinx.Graphics.Gpu/Image/Pool.cs
@@ -0,0 +1,99 @@
+using System;
+
+namespace Ryujinx.Graphics.Gpu.Image
+{
+ abstract class Pool<T> : IDisposable
+ {
+ protected const int DescriptorSize = 0x20;
+
+ protected GpuContext Context;
+
+ protected T[] Items;
+
+ public ulong Address { get; }
+ public ulong Size { get; }
+
+ public Pool(GpuContext context, ulong address, int maximumId)
+ {
+ Context = context;
+
+ int count = maximumId + 1;
+
+ ulong size = (ulong)(uint)count * DescriptorSize;;
+
+ Items = new T[count];
+
+ Address = address;
+ Size = size;
+ }
+
+ public abstract T Get(int id);
+
+ public void SynchronizeMemory()
+ {
+ (ulong, ulong)[] modifiedRanges = Context.PhysicalMemory.GetModifiedRanges(Address, Size);
+
+ for (int index = 0; index < modifiedRanges.Length; index++)
+ {
+ (ulong mAddress, ulong mSize) = modifiedRanges[index];
+
+ if (mAddress < Address)
+ {
+ mAddress = Address;
+ }
+
+ ulong maxSize = Address + Size - mAddress;
+
+ if (mSize > maxSize)
+ {
+ mSize = maxSize;
+ }
+
+ InvalidateRangeImpl(mAddress, mSize);
+ }
+ }
+
+ public void InvalidateRange(ulong address, ulong size)
+ {
+ ulong endAddress = address + size;
+
+ ulong texturePoolEndAddress = Address + Size;
+
+ // If the range being invalidated is not overlapping the texture pool range,
+ // then we don't have anything to do, exit early.
+ if (address >= texturePoolEndAddress || endAddress <= Address)
+ {
+ return;
+ }
+
+ if (address < Address)
+ {
+ address = Address;
+ }
+
+ if (endAddress > texturePoolEndAddress)
+ {
+ endAddress = texturePoolEndAddress;
+ }
+
+ InvalidateRangeImpl(address, size);
+ }
+
+ protected abstract void InvalidateRangeImpl(ulong address, ulong size);
+
+ protected abstract void Delete(T item);
+
+ public void Dispose()
+ {
+ if (Items != null)
+ {
+ for (int index = 0; index < Items.Length; index++)
+ {
+ Delete(Items[index]);
+ }
+
+ Items = null;
+ }
+ }
+ }
+} \ No newline at end of file