Cache delegate for QueryModified, use regular multi handle. (#1771)

This commit is contained in:
riperiperi 2020-12-03 18:34:32 +00:00 committed by GitHub
parent 0ab1c42eea
commit 2c39a4f15d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 33 deletions

View file

@ -36,6 +36,7 @@ namespace Ryujinx.Graphics.Gpu.Image
public ulong Size { get; } public ulong Size { get; }
private readonly CpuMultiRegionHandle _memoryTracking; private readonly CpuMultiRegionHandle _memoryTracking;
private readonly Action<ulong, ulong> _modifiedDelegate;
public Pool(GpuContext context, ulong address, int maximumId) public Pool(GpuContext context, ulong address, int maximumId)
{ {
@ -44,7 +45,7 @@ namespace Ryujinx.Graphics.Gpu.Image
int count = maximumId + 1; int count = maximumId + 1;
ulong size = (ulong)(uint)count * DescriptorSize;; ulong size = (ulong)(uint)count * DescriptorSize;
Items = new T[count]; Items = new T[count];
@ -52,6 +53,7 @@ namespace Ryujinx.Graphics.Gpu.Image
Size = size; Size = size;
_memoryTracking = context.PhysicalMemory.BeginGranularTracking(address, size); _memoryTracking = context.PhysicalMemory.BeginGranularTracking(address, size);
_modifiedDelegate = RegionModified;
} }
/// <summary> /// <summary>
@ -68,7 +70,15 @@ namespace Ryujinx.Graphics.Gpu.Image
/// </summary> /// </summary>
public void SynchronizeMemory() public void SynchronizeMemory()
{ {
_memoryTracking.QueryModified((ulong mAddress, ulong mSize) => _memoryTracking.QueryModified(_modifiedDelegate);
}
/// <summary>
/// Indicate that a region of the pool was modified, and must be loaded from memory.
/// </summary>
/// <param name="mAddress">Start address of the modified region</param>
/// <param name="mSize">Size of the modified region</param>
private void RegionModified(ulong mAddress, ulong mSize)
{ {
if (mAddress < Address) if (mAddress < Address)
{ {
@ -83,7 +93,6 @@ namespace Ryujinx.Graphics.Gpu.Image
} }
InvalidateRangeImpl(mAddress, mSize); InvalidateRangeImpl(mAddress, mSize);
});
} }
protected abstract void InvalidateRangeImpl(ulong address, ulong size); protected abstract void InvalidateRangeImpl(ulong address, ulong size);

View file

@ -34,8 +34,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
/// </summary> /// </summary>
public ulong EndAddress => Address + Size; public ulong EndAddress => Address + Size;
private CpuSmartMultiRegionHandle _memoryTrackingGranular; private CpuMultiRegionHandle _memoryTrackingGranular;
private CpuRegionHandle _memoryTracking; private CpuRegionHandle _memoryTracking;
private readonly Action<ulong, ulong> _modifiedDelegate;
private int _sequenceNumber; private int _sequenceNumber;
private bool _useGranular; private bool _useGranular;
@ -58,12 +59,14 @@ namespace Ryujinx.Graphics.Gpu.Memory
if (_useGranular) if (_useGranular)
{ {
_memoryTrackingGranular = context.PhysicalMemory.BeginSmartGranularTracking(address, size); _memoryTrackingGranular = context.PhysicalMemory.BeginGranularTracking(address, size);
} }
else else
{ {
_memoryTracking = context.PhysicalMemory.BeginTracking(address, size); _memoryTracking = context.PhysicalMemory.BeginTracking(address, size);
} }
_modifiedDelegate = new Action<ulong, ulong>(RegionModified);
} }
/// <summary> /// <summary>
@ -106,7 +109,25 @@ namespace Ryujinx.Graphics.Gpu.Memory
{ {
if (_useGranular) if (_useGranular)
{ {
_memoryTrackingGranular.QueryModified(address, size, (ulong mAddress, ulong mSize) => _memoryTrackingGranular.QueryModified(address, size, _modifiedDelegate, _context.SequenceNumber);
}
else
{
if (_memoryTracking.Dirty && _context.SequenceNumber != _sequenceNumber)
{
_memoryTracking.Reprotect();
_context.Renderer.SetBufferData(Handle, 0, _context.PhysicalMemory.GetSpan(Address, (int)Size));
_sequenceNumber = _context.SequenceNumber;
}
}
}
/// <summary>
/// Indicate that a region of the buffer was modified, and must be loaded from memory.
/// </summary>
/// <param name="mAddress">Start address of the modified region</param>
/// <param name="mSize">Size of the modified region</param>
private void RegionModified(ulong mAddress, ulong mSize)
{ {
if (mAddress < Address) if (mAddress < Address)
{ {
@ -123,17 +144,6 @@ namespace Ryujinx.Graphics.Gpu.Memory
int offset = (int)(mAddress - Address); int offset = (int)(mAddress - Address);
_context.Renderer.SetBufferData(Handle, offset, _context.PhysicalMemory.GetSpan(mAddress, (int)mSize)); _context.Renderer.SetBufferData(Handle, offset, _context.PhysicalMemory.GetSpan(mAddress, (int)mSize));
}, _context.SequenceNumber);
}
else
{
if (_memoryTracking.Dirty && _context.SequenceNumber != _sequenceNumber)
{
_memoryTracking.Reprotect();
_context.Renderer.SetBufferData(Handle, 0, _context.PhysicalMemory.GetSpan(Address, (int)Size));
_sequenceNumber = _context.SequenceNumber;
}
}
} }
/// <summary> /// <summary>