[HLE] Answer GPU span coverage from a snapshot

This commit is contained in:
ParantezTech 2026-10-11 01:40:31 +03:00
parent 8f7fa3933f
commit 643a565a22
2 changed files with 33 additions and 9 deletions

View File

@ -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

View File

@ -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)