From c393cdf8e3775bc95850e4d8c8e4c446b286d3b4 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Wed, 15 Aug 2018 15:59:51 -0300 Subject: More flexible memory manager (#307) * Keep track mapped buffers with fixed offsets * Started rewriting the memory manager * Initial support for MapPhysicalMemory and UnmapPhysicalMemory, other tweaks * MapPhysicalMemory/UnmapPhysicalMemory support, other tweaks * Rebased * Optimize the map/unmap physical memory svcs * Integrate shared font support * Fix address space reserve alignment * Some fixes related to gpu memory mapping * Some cleanup * Only try uploading const buffers that are really used * Check if memory region is contiguous * Rebased * Add missing count increment on IsRegionModified * Check for reads/writes outside of the address space, optimize translation with a tail call --- Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs | 47 ++++----------------------------- Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs | 14 +++++----- 2 files changed, 11 insertions(+), 50 deletions(-) (limited to 'Ryujinx.HLE/Gpu/Memory') diff --git a/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs index 7b23e49f..e7e18064 100644 --- a/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs +++ b/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs @@ -1,7 +1,6 @@ using ChocolArm64.Memory; using Ryujinx.Graphics.Gal; using System; -using System.Collections.Concurrent; namespace Ryujinx.HLE.Gpu.Memory { @@ -26,18 +25,6 @@ namespace Ryujinx.HLE.Gpu.Memory public AMemory Memory { get; private set; } - private struct MappedMemory - { - public long Size; - - public MappedMemory(long Size) - { - this.Size = Size; - } - } - - private ConcurrentDictionary Maps; - private NvGpuVmmCache Cache; private const long PteUnmapped = -1; @@ -49,8 +36,6 @@ namespace Ryujinx.HLE.Gpu.Memory { this.Memory = Memory; - Maps = new ConcurrentDictionary(); - Cache = new NvGpuVmmCache(); PageTable = new long[PTLvl0Size][]; @@ -60,14 +45,6 @@ namespace Ryujinx.HLE.Gpu.Memory { lock (PageTable) { - for (long Offset = 0; Offset < Size; Offset += PageSize) - { - if (GetPte(VA + Offset) != PteReserved) - { - return Map(PA, Size); - } - } - for (long Offset = 0; Offset < Size; Offset += PageSize) { SetPte(VA + Offset, PA + Offset); @@ -85,10 +62,6 @@ namespace Ryujinx.HLE.Gpu.Memory if (VA != -1) { - MappedMemory Map = new MappedMemory(Size); - - Maps.AddOrUpdate(VA, Map, (Key, Old) => Map); - for (long Offset = 0; Offset < Size; Offset += PageSize) { SetPte(VA + Offset, PA + Offset); @@ -99,19 +72,7 @@ namespace Ryujinx.HLE.Gpu.Memory } } - public bool Unmap(long VA) - { - if (Maps.TryRemove(VA, out MappedMemory Map)) - { - Free(VA, Map.Size); - - return true; - } - - return false; - } - - public long Reserve(long VA, long Size, long Align) + public long ReserveFixed(long VA, long Size) { lock (PageTable) { @@ -119,7 +80,7 @@ namespace Ryujinx.HLE.Gpu.Memory { if (IsPageInUse(VA + Offset)) { - return Reserve(Size, Align); + return -1; } } @@ -163,7 +124,9 @@ namespace Ryujinx.HLE.Gpu.Memory private long GetFreePosition(long Size, long Align = 1) { - long Position = 0; + //Note: Address 0 is not considered valid by the driver, + //when 0 is returned it's considered a mapping error. + long Position = PageSize; long FreeSize = 0; if (Align < 1) diff --git a/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs index 3c256044..b3f253b3 100644 --- a/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs +++ b/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs @@ -1,4 +1,5 @@ using ChocolArm64.Memory; +using Ryujinx.HLE.Memory; using System; using System.Collections.Generic; @@ -129,14 +130,11 @@ namespace Ryujinx.HLE.Gpu.Memory { (bool[] Modified, long ModifiedCount) = Memory.IsRegionModified(PA, Size); - if (Modified == null) - { - return true; - } + PA = Memory.GetPhysicalAddress(PA); ClearCachedPagesIfNeeded(); - long PageSize = Memory.GetHostPageSize(); + long PageSize = AMemory.PageSize; EnsureResidencyInitialized(PageSize); @@ -159,9 +157,9 @@ namespace Ryujinx.HLE.Gpu.Memory while (PA < PAEnd) { - long Key = PA & ~Mask; + long Key = PA & ~AMemory.PageMask; - long PAPgEnd = Math.Min((PA + PageSize) & ~Mask, PAEnd); + long PAPgEnd = Math.Min((PA + AMemory.PageSize) & ~AMemory.PageMask, PAEnd); bool IsCached = Cache.TryGetValue(Key, out CachedPage Cp); @@ -228,7 +226,7 @@ namespace Ryujinx.HLE.Gpu.Memory { if (Residency == null) { - Residency = new HashSet[AMemoryMgr.RamSize / PageSize]; + Residency = new HashSet[DeviceMemory.RamSize / PageSize]; for (int i = 0; i < Residency.Length; i++) { -- cgit v1.2.3