diff --git a/src/SharpEmu.HLE/GpuMemory/GuestPageTracker.cs b/src/SharpEmu.HLE/GpuMemory/GuestPageTracker.cs index 0ac893a..2032867 100644 --- a/src/SharpEmu.HLE/GpuMemory/GuestPageTracker.cs +++ b/src/SharpEmu.HLE/GpuMemory/GuestPageTracker.cs @@ -198,6 +198,14 @@ public sealed class GuestPageTracker if (Volatile.Read(ref _regions[index]) is { } region) { tracked = true; + if (region.IsCpuDirtyThroughout(offset, bytes)) + { + remaining -= bytes; + offset = 0; + index++; + continue; + } + using (region.Lock.Hold()) { if (region.IsModified(WriteOrigin.Gpu, offset, bytes)) diff --git a/src/SharpEmu.HLE/GpuMemory/TrackedRegion.cs b/src/SharpEmu.HLE/GpuMemory/TrackedRegion.cs index 7dfe95c..9519cf3 100644 --- a/src/SharpEmu.HLE/GpuMemory/TrackedRegion.cs +++ b/src/SharpEmu.HLE/GpuMemory/TrackedRegion.cs @@ -46,6 +46,20 @@ public sealed class TrackedRegion return GetDirtyMask(side).AnyInRange(start, end); } + public bool IsCpuDirtyThroughout(ulong offset, ulong size) + { + var (start, end) = GetPageRange(BaseAddress + offset, size); + for (var page = start; page < end; page++) + { + if (!_cpuDirty.Get(page)) + { + return false; + } + } + + return true; + } + public bool IsCpuWriteHot(ulong offset, ulong size) { var (start, end) = GetPageRange(BaseAddress + offset, size);