diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2019-02-24 04:24:35 -0300 |
|---|---|---|
| committer | jduncanator <1518948+jduncanator@users.noreply.github.com> | 2019-02-24 18:24:35 +1100 |
| commit | 5001f78b1d07b988709dd5f5d1009ebe9b44c669 (patch) | |
| tree | bb1307949ea9102b8ae2b68fa7e182ed7b75b2df /Ryujinx.Graphics/Memory | |
| parent | a3d46e41335efd049042cc2e38b35c4077e8ed41 (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.cs | 32 |
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 |
