diff --git a/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs index 4b302f31ca..3c25604433 100644 --- a/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs +++ b/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs @@ -114,7 +114,7 @@ namespace Ryujinx.HLE.Gpu.Memory private HashSet[] Residency; - private const int PageSize = AMemoryMgr.PageSize; + private long ResidencyPageSize; private int CpCount; @@ -123,13 +123,6 @@ namespace Ryujinx.HLE.Gpu.Memory Cache = new Dictionary(); SortedCache = new LinkedList(); - - Residency = new HashSet[AMemoryMgr.RamSize / PageSize]; - - for (int i = 0; i < Residency.Length; i++) - { - Residency[i] = new HashSet(); - } } public bool IsRegionModified(AMemory Memory, NvGpuBufferType BufferType, long PA, long Size) @@ -143,6 +136,10 @@ namespace Ryujinx.HLE.Gpu.Memory ClearCachedPagesIfNeeded(); + long PageSize = Memory.GetHostPageSize(); + + EnsureResidencyInitialized(PageSize); + bool HasResidents = AddResidency(PA, Size); if (!HasResidents && ModifiedCount == 0) @@ -204,6 +201,8 @@ namespace Ryujinx.HLE.Gpu.Memory private bool AddResidency(long PA, long Size) { + long PageSize = ResidencyPageSize; + long Mask = PageSize - 1; long Key = PA; @@ -225,6 +224,28 @@ namespace Ryujinx.HLE.Gpu.Memory return ResidentFound; } + private void EnsureResidencyInitialized(long PageSize) + { + if (Residency == null) + { + Residency = new HashSet[AMemoryMgr.RamSize / PageSize]; + + for (int i = 0; i < Residency.Length; i++) + { + Residency[i] = new HashSet(); + } + + ResidencyPageSize = PageSize; + } + else + { + if (ResidencyPageSize != PageSize) + { + throw new InvalidOperationException("Tried to change residency page size"); + } + } + } + private void ClearCachedPagesIfNeeded() { if (CpCount <= MaxCpCount) @@ -245,7 +266,7 @@ namespace Ryujinx.HLE.Gpu.Memory CachedPage Cp = Cache[Key]; - Cp.RemoveResidency(Residency, PageSize); + Cp.RemoveResidency(Residency, ResidencyPageSize); Cache.Remove(Key);