Merge branch 'master' into pptc_and_pool_enhancements

This commit is contained in:
LDj3SNuD
2021-01-27 06:25:40 +01:00
82 changed files with 3890 additions and 793 deletions

View File

@@ -15,7 +15,7 @@ namespace Ryujinx.Memory
void Fill(ulong va, ulong size, byte value)
{
const int MaxChunkSize = 1 << 30;
const int MaxChunkSize = 1 << 24;
for (ulong subOffset = 0; subOffset < size; subOffset += MaxChunkSize)
{

View File

@@ -134,7 +134,7 @@ namespace Ryujinx.Memory
/// <exception cref="InvalidMemoryRegionException">Throw when <paramref name="srcOffset"/>, <paramref name="dstOffset"/> or <paramref name="size"/> is out of range</exception>
public void Copy(ulong dstOffset, ulong srcOffset, ulong size)
{
const int MaxChunkSize = 1 << 30;
const int MaxChunkSize = 1 << 24;
for (ulong offset = 0; offset < size; offset += MaxChunkSize)
{
@@ -153,7 +153,7 @@ namespace Ryujinx.Memory
/// <exception cref="InvalidMemoryRegionException">Throw when either <paramref name="offset"/> or <paramref name="size"/> are out of range</exception>
public void ZeroFill(ulong offset, ulong size)
{
const int MaxChunkSize = 1 << 30;
const int MaxChunkSize = 1 << 24;
for (ulong subOffset = 0; subOffset < size; subOffset += MaxChunkSize)
{

View File

@@ -12,16 +12,16 @@ namespace Ryujinx.Memory.Range
{
private const int ArrayGrowthSize = 32;
private readonly List<T> _items;
protected readonly List<T> Items;
public int Count => _items.Count;
public int Count => Items.Count;
/// <summary>
/// Creates a new range list.
/// </summary>
public RangeList()
{
_items = new List<T>();
Items = new List<T>();
}
/// <summary>
@@ -37,7 +37,7 @@ namespace Ryujinx.Memory.Range
index = ~index;
}
_items.Insert(index, item);
Items.Insert(index, item);
}
/// <summary>
@@ -51,21 +51,21 @@ namespace Ryujinx.Memory.Range
if (index >= 0)
{
while (index > 0 && _items[index - 1].Address == item.Address)
while (index > 0 && Items[index - 1].Address == item.Address)
{
index--;
}
while (index < _items.Count)
while (index < Items.Count)
{
if (_items[index].Equals(item))
if (Items[index].Equals(item))
{
_items.RemoveAt(index);
Items.RemoveAt(index);
return true;
}
if (_items[index].Address > item.Address)
if (Items[index].Address > item.Address)
{
break;
}
@@ -110,7 +110,7 @@ namespace Ryujinx.Memory.Range
return default(T);
}
return _items[index];
return Items[index];
}
/// <summary>
@@ -137,7 +137,7 @@ namespace Ryujinx.Memory.Range
ulong endAddress = address + size;
foreach (T item in _items)
foreach (T item in Items)
{
if (item.Address >= endAddress)
{
@@ -196,7 +196,7 @@ namespace Ryujinx.Memory.Range
if (index >= 0)
{
while (index > 0 && _items[index - 1].OverlapsWith(address, size))
while (index > 0 && Items[index - 1].OverlapsWith(address, size))
{
index--;
}
@@ -208,9 +208,9 @@ namespace Ryujinx.Memory.Range
Array.Resize(ref output, outputIndex + ArrayGrowthSize);
}
output[outputIndex++] = _items[index++];
output[outputIndex++] = Items[index++];
}
while (index < _items.Count && _items[index].OverlapsWith(address, size));
while (index < Items.Count && Items[index].OverlapsWith(address, size));
}
return outputIndex;
@@ -230,14 +230,14 @@ namespace Ryujinx.Memory.Range
if (index >= 0)
{
while (index > 0 && _items[index - 1].Address == address)
while (index > 0 && Items[index - 1].Address == address)
{
index--;
}
while (index < _items.Count)
while (index < Items.Count)
{
T overlap = _items[index++];
T overlap = Items[index++];
if (overlap.Address != address)
{
@@ -264,7 +264,7 @@ namespace Ryujinx.Memory.Range
private int BinarySearch(ulong address)
{
int left = 0;
int right = _items.Count - 1;
int right = Items.Count - 1;
while (left <= right)
{
@@ -272,7 +272,7 @@ namespace Ryujinx.Memory.Range
int middle = left + (range >> 1);
T item = _items[middle];
T item = Items[middle];
if (item.Address == address)
{
@@ -301,7 +301,7 @@ namespace Ryujinx.Memory.Range
private int BinarySearch(ulong address, ulong size)
{
int left = 0;
int right = _items.Count - 1;
int right = Items.Count - 1;
while (left <= right)
{
@@ -309,7 +309,7 @@ namespace Ryujinx.Memory.Range
int middle = left + (range >> 1);
T item = _items[middle];
T item = Items[middle];
if (item.OverlapsWith(address, size))
{
@@ -331,12 +331,12 @@ namespace Ryujinx.Memory.Range
public IEnumerator<T> GetEnumerator()
{
return _items.GetEnumerator();
return Items.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _items.GetEnumerator();
return Items.GetEnumerator();
}
}
}

View File

@@ -123,6 +123,17 @@ namespace Ryujinx.Memory.Tracking
}
}
public void RegisterAction(ulong address, ulong size, RegionSignal action)
{
int startHandle = (int)((address - Address) / Granularity);
int lastHandle = (int)((address + (size - 1) - Address) / Granularity);
for (int i = startHandle; i <= lastHandle; i++)
{
_handles[i].RegisterAction(action);
}
}
public void Dispose()
{
foreach (var handle in _handles)

View File

@@ -24,6 +24,7 @@ namespace Ryujinx.Memory.Tracking
private readonly MemoryTracking _tracking;
internal MemoryPermission RequiredPermission => _preAction != null ? MemoryPermission.None : (Dirty ? MemoryPermission.ReadAndWrite : MemoryPermission.Read);
internal RegionSignal PreAction => _preAction;
/// <summary>
/// Create a new region handle. The handle is registered with the given tracking object,

View File

@@ -41,6 +41,17 @@ namespace Ryujinx.Memory.Tracking
Dirty = true;
}
public void RegisterAction(RegionSignal action)
{
foreach (var handle in _handles)
{
if (handle != null)
{
handle?.RegisterAction((address, size) => action(handle.Address, handle.Size));
}
}
}
public void QueryModified(Action<ulong, ulong> modifiedAction)
{
if (!Dirty)
@@ -66,14 +77,23 @@ namespace Ryujinx.Memory.Tracking
ulong size = HandlesToBytes(splitIndex - handleIndex);
// First, the target handle must be removed. Its data can still be used to determine the new handles.
RegionSignal signal = handle.PreAction;
handle.Dispose();
RegionHandle splitLow = _tracking.BeginTracking(address, size);
splitLow.Parent = this;
if (signal != null)
{
splitLow.RegisterAction(signal);
}
_handles[handleIndex] = splitLow;
RegionHandle splitHigh = _tracking.BeginTracking(address + size, handle.Size - size);
splitHigh.Parent = this;
if (signal != null)
{
splitHigh.RegisterAction(signal);
}
_handles[splitIndex] = splitHigh;
}

View File

@@ -22,12 +22,12 @@ namespace Ryujinx.Memory.Tracking
public override void Signal(ulong address, ulong size, bool write)
{
_tracking.ProtectVirtualRegion(this, MemoryPermission.ReadAndWrite); // Remove our protection immedately.
foreach (var handle in Handles)
{
handle.Signal(address, size, write);
}
UpdateProtection();
}
/// <summary>