Cache delegate for QueryModified, use regular multi handle. (#1771)
This commit is contained in:
parent
0ab1c42eea
commit
2c39a4f15d
2 changed files with 52 additions and 33 deletions
|
@ -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);
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Reference in a new issue