Optimize address translation and write tracking on the MMU (#571)
* Implement faster address translation and write tracking on the MMU * Rename MemoryAlloc to MemoryManagement, and other nits * Support multi-level page tables * Fix typo * Reword comment a bit * Support scalar vector loads/stores on the memory fast path, and minor fixes * Add missing cast * Alignment * Fix VirtualFree function signature * Change MemoryProtection enum to uint aswell for consistency
This commit is contained in:
parent
a3d46e4133
commit
5001f78b1d
24 changed files with 1005 additions and 621 deletions
|
@ -1,4 +1,3 @@
|
|||
using ChocolArm64.Events;
|
||||
using ChocolArm64.Memory;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
|
@ -19,35 +18,28 @@ namespace Ryujinx.Graphics.Memory
|
|||
{
|
||||
_memory = memory;
|
||||
|
||||
_memory.ObservedAccess += MemoryAccessHandler;
|
||||
|
||||
CachedPages = new ConcurrentDictionary<long, int>[1 << 20];
|
||||
}
|
||||
|
||||
private void MemoryAccessHandler(object sender, MemoryAccessEventArgs e)
|
||||
{
|
||||
long pa = _memory.GetPhysicalAddress(e.Position);
|
||||
|
||||
CachedPages[pa >> PageBits]?.Clear();
|
||||
}
|
||||
|
||||
public bool IsRegionModified(long position, long size, NvGpuBufferType bufferType)
|
||||
{
|
||||
long pa = _memory.GetPhysicalAddress(position);
|
||||
long va = position;
|
||||
|
||||
long addr = pa;
|
||||
long pa = _memory.GetPhysicalAddress(va);
|
||||
|
||||
long endAddr = (addr + size + PageMask) & ~PageMask;
|
||||
long endAddr = (va + size + PageMask) & ~PageMask;
|
||||
|
||||
long addrTruncated = va & ~PageMask;
|
||||
|
||||
bool modified = _memory.IsRegionModified(addrTruncated, endAddr - addrTruncated);
|
||||
|
||||
int newBuffMask = 1 << (int)bufferType;
|
||||
|
||||
_memory.StartObservingRegion(position, size);
|
||||
|
||||
long cachedPagesCount = 0;
|
||||
|
||||
while (addr < endAddr)
|
||||
while (va < endAddr)
|
||||
{
|
||||
long page = addr >> PageBits;
|
||||
long page = _memory.GetPhysicalAddress(va) >> PageBits;
|
||||
|
||||
ConcurrentDictionary<long, int> dictionary = CachedPages[page];
|
||||
|
||||
|
@ -57,6 +49,10 @@ namespace Ryujinx.Graphics.Memory
|
|||
|
||||
CachedPages[page] = dictionary;
|
||||
}
|
||||
else if (modified)
|
||||
{
|
||||
CachedPages[page].Clear();
|
||||
}
|
||||
|
||||
if (dictionary.TryGetValue(pa, out int currBuffMask))
|
||||
{
|
||||
|
@ -74,10 +70,10 @@ namespace Ryujinx.Graphics.Memory
|
|||
dictionary[pa] = newBuffMask;
|
||||
}
|
||||
|
||||
addr += PageSize;
|
||||
va += PageSize;
|
||||
}
|
||||
|
||||
return cachedPagesCount != (endAddr - pa + PageMask) >> PageBits;
|
||||
return cachedPagesCount != (endAddr - addrTruncated) >> PageBits;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue