[HLE] Answer GPU span coverage from a snapshot
This commit is contained in:
parent
8f7fa3933f
commit
643a565a22
|
|
@ -30,6 +30,7 @@ public sealed class GuestGpuMemory : IDisposable
|
|||
private readonly PageGuard _pages;
|
||||
private readonly ReaderWriterLockSlim _spansLock = new();
|
||||
private readonly SpanSet _spans = new();
|
||||
private SpanSnapshot _spanSnapshot = SpanSnapshot.Empty;
|
||||
private long _spanVersion;
|
||||
|
||||
public long SpanVersion => Interlocked.Read(ref _spanVersion);
|
||||
|
|
@ -153,15 +154,7 @@ public sealed class GuestGpuMemory : IDisposable
|
|||
return false;
|
||||
}
|
||||
|
||||
_spansLock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
return _spans.Contains(address, size);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_spansLock.ExitReadLock();
|
||||
}
|
||||
return Volatile.Read(ref _spanSnapshot).Contains(address, size);
|
||||
}
|
||||
|
||||
public void ForEachSpan(Action<ulong, ulong> visit)
|
||||
|
|
@ -207,6 +200,7 @@ public sealed class GuestGpuMemory : IDisposable
|
|||
try
|
||||
{
|
||||
_spans.Add(address, size);
|
||||
Volatile.Write(ref _spanSnapshot, _spans.Snapshot());
|
||||
Interlocked.Increment(ref _spanVersion);
|
||||
}
|
||||
finally
|
||||
|
|
@ -280,6 +274,7 @@ public sealed class GuestGpuMemory : IDisposable
|
|||
try
|
||||
{
|
||||
_spans.Remove(address, size);
|
||||
Volatile.Write(ref _spanSnapshot, _spans.Snapshot());
|
||||
Interlocked.Increment(ref _spanVersion);
|
||||
}
|
||||
finally
|
||||
|
|
|
|||
|
|
@ -3,6 +3,22 @@
|
|||
|
||||
namespace SharpEmu.HLE.GpuMemory;
|
||||
|
||||
public sealed class SpanSnapshot(ulong[] starts, ulong[] ends)
|
||||
{
|
||||
public static readonly SpanSnapshot Empty = new([], []);
|
||||
|
||||
public bool Contains(ulong address, ulong size)
|
||||
{
|
||||
var index = Array.BinarySearch(starts, address);
|
||||
if (index < 0)
|
||||
{
|
||||
index = ~index - 1;
|
||||
}
|
||||
|
||||
return index >= 0 && ends[index] >= address + size;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SpanSet
|
||||
{
|
||||
private readonly SortedList<ulong, ulong> _spans = new();
|
||||
|
|
@ -79,6 +95,19 @@ public sealed class SpanSet
|
|||
return index > 0 && _spans.GetValueAtIndex(index - 1) > address;
|
||||
}
|
||||
|
||||
public SpanSnapshot Snapshot()
|
||||
{
|
||||
var starts = new ulong[_spans.Count];
|
||||
var ends = new ulong[_spans.Count];
|
||||
for (var index = 0; index < starts.Length; index++)
|
||||
{
|
||||
starts[index] = _spans.GetKeyAtIndex(index);
|
||||
ends[index] = _spans.GetValueAtIndex(index);
|
||||
}
|
||||
|
||||
return new SpanSnapshot(starts, ends);
|
||||
}
|
||||
|
||||
public void ForEach(Action<ulong, ulong> visit)
|
||||
{
|
||||
foreach (var (start, end) in _spans)
|
||||
|
|
|
|||
Loading…
Reference in New Issue