forked from Mirror/Ryujinx
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:
commit
468774578d
2 changed files with 49 additions and 11 deletions
|
@ -299,24 +299,28 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
_syncActionRegistered = true;
|
_syncActionRegistered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Action<ulong, ulong> registerRangeAction = (ulong address, ulong size) =>
|
||||||
|
{
|
||||||
|
if (_useGranular)
|
||||||
|
{
|
||||||
|
_memoryTrackingGranular.RegisterAction(address, size, _externalFlushDelegate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_memoryTracking.RegisterAction(_externalFlushDelegate);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (_modifiedRanges == null)
|
if (_modifiedRanges == null)
|
||||||
{
|
{
|
||||||
_modifiedRanges = from._modifiedRanges;
|
_modifiedRanges = from._modifiedRanges;
|
||||||
|
_modifiedRanges.ReregisterRanges(registerRangeAction);
|
||||||
|
|
||||||
from._modifiedRanges = null;
|
from._modifiedRanges = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_modifiedRanges.InheritRanges(from._modifiedRanges, (ulong address, ulong size) =>
|
_modifiedRanges.InheritRanges(from._modifiedRanges, registerRangeAction);
|
||||||
{
|
|
||||||
if (_useGranular)
|
|
||||||
{
|
|
||||||
_memoryTrackingGranular.RegisterAction(address, size, _externalFlushDelegate);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_memoryTracking.RegisterAction(_externalFlushDelegate);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Reference in a new issue