From 5001f78b1d07b988709dd5f5d1009ebe9b44c669 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 24 Feb 2019 04:24:35 -0300 Subject: 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 --- Ryujinx.Graphics/Memory/NvGpuVmmCache.cs | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'Ryujinx.Graphics/Memory') 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[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 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 -- cgit v1.2.3