Merge pull request #2713 from riperiperi/fix/modified-inherit

Reregister flush actions when taking a buffer's modified range list.
This commit is contained in:
riperiperi 2021-10-07 13:43:31 +01:00 committed by GitHub
commit 468774578d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 11 deletions

View File

@ -299,24 +299,28 @@ namespace Ryujinx.Graphics.Gpu.Memory
_syncActionRegistered = true;
}
Action<ulong, ulong> registerRangeAction = (ulong address, ulong size) =>
{
if (_useGranular)
{
_memoryTrackingGranular.RegisterAction(address, size, _externalFlushDelegate);
}
else
{
_memoryTracking.RegisterAction(_externalFlushDelegate);
}
};
if (_modifiedRanges == null)
{
_modifiedRanges = from._modifiedRanges;
_modifiedRanges.ReregisterRanges(registerRangeAction);
from._modifiedRanges = null;
}
else
{
_modifiedRanges.InheritRanges(from._modifiedRanges, (ulong address, ulong size) =>
{
if (_useGranular)
{
_memoryTrackingGranular.RegisterAction(address, size, _externalFlushDelegate);
}
else
{
_memoryTracking.RegisterAction(_externalFlushDelegate);
}
});
_modifiedRanges.InheritRanges(from._modifiedRanges, registerRangeAction);
}
}
}

View File

@ -318,6 +318,40 @@ namespace Ryujinx.Graphics.Gpu.Memory
}
}
/// <summary>
/// Calls the given action for modified ranges that aren't from the current sync number.
/// </summary>
/// <param name="rangeAction">The action to call for each modified range</param>
public void ReregisterRanges(Action<ulong, ulong> rangeAction)
{
ref var ranges = ref ThreadStaticArray<BufferModifiedRange>.Get();
// Range list must be consistent for this operation.
lock (_lock)
{
if (ranges.Length < Count)
{
Array.Resize(ref ranges, Count);
}
int i = 0;
foreach (BufferModifiedRange range in this)
{
ranges[i++] = range;
}
}
ulong currentSync = _context.SyncNumber;
for (int i = 0; i < Count; i++)
{
BufferModifiedRange range = ranges[i];
if (range.SyncNumber != currentSync)
{
rangeAction(range.Address, range.Size);
}
}
}
private void ClearPart(BufferModifiedRange overlap, ulong address, ulong endAddress)
{
Remove(overlap);