aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Memory
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2019-02-24 04:24:35 -0300
committerjduncanator <1518948+jduncanator@users.noreply.github.com>2019-02-24 18:24:35 +1100
commit5001f78b1d07b988709dd5f5d1009ebe9b44c669 (patch)
treebb1307949ea9102b8ae2b68fa7e182ed7b75b2df /Ryujinx.Graphics/Memory
parenta3d46e41335efd049042cc2e38b35c4077e8ed41 (diff)
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
Diffstat (limited to 'Ryujinx.Graphics/Memory')
-rw-r--r--Ryujinx.Graphics/Memory/NvGpuVmmCache.cs32
1 files changed, 14 insertions, 18 deletions
diff --git a/Ryujinx.Graphics/Memory/NvGpuVmmCache.cs b/Ryujinx.Graphics/Memory/NvGpuVmmCache.cs
index 2f50463d..053c2161 100644
--- a/Ryujinx.Graphics/Memory/NvGpuVmmCache.cs
+++ b/Ryujinx.Graphics/Memory/NvGpuVmmCache.cs
@@ -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)
+ public bool IsRegionModified(long position, long size, NvGpuBufferType bufferType)
{
- long pa = _memory.GetPhysicalAddress(e.Position);
+ long va = position;
- CachedPages[pa >> PageBits]?.Clear();
- }
+ long pa = _memory.GetPhysicalAddress(va);
- public bool IsRegionModified(long position, long size, NvGpuBufferType bufferType)
- {
- long pa = _memory.GetPhysicalAddress(position);
+ long endAddr = (va + size + PageMask) & ~PageMask;
- long addr = pa;
+ long addrTruncated = va & ~PageMask;
- long endAddr = (addr + size + PageMask) & ~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;
}
}
} \ No newline at end of file