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,14 +299,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
_syncActionRegistered = true; _syncActionRegistered = true;
} }
if (_modifiedRanges == null) Action<ulong, ulong> registerRangeAction = (ulong address, ulong size) =>
{
_modifiedRanges = from._modifiedRanges;
from._modifiedRanges = null;
}
else
{
_modifiedRanges.InheritRanges(from._modifiedRanges, (ulong address, ulong size) =>
{ {
if (_useGranular) if (_useGranular)
{ {
@ -316,7 +309,18 @@ namespace Ryujinx.Graphics.Gpu.Memory
{ {
_memoryTracking.RegisterAction(_externalFlushDelegate); _memoryTracking.RegisterAction(_externalFlushDelegate);
} }
}); };
if (_modifiedRanges == null)
{
_modifiedRanges = from._modifiedRanges;
_modifiedRanges.ReregisterRanges(registerRangeAction);
from._modifiedRanges = null;
}
else
{
_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) private void ClearPart(BufferModifiedRange overlap, ulong address, ulong endAddress)
{ {
Remove(overlap); Remove(overlap);