From 874540bb5c1c5737bc9b0bfdc96fe1cf12ff164d Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 4 Apr 2021 09:06:59 -0300 Subject: [PATCH] Allow DRAM size to be increased from 4GB to 6GB (#2174) * Allow DRAM size to be increased from 4GB to 6GB * Add option on the UI --- .../Configuration/ConfigurationFileFormat.cs | 7 +- .../Configuration/ConfigurationState.cs | 9 ++ Ryujinx.HLE/HOS/Horizon.cs | 8 +- .../HOS/Kernel/Common/KSystemControl.cs | 72 ++++++++++ Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs | 131 ++++++------------ .../HOS/Kernel/Common/MemoryArrange.cs | 12 ++ Ryujinx.HLE/HOS/Kernel/Common/MemroySize.cs | 9 ++ Ryujinx.HLE/HOS/Kernel/KernelContext.cs | 10 +- .../HOS/Kernel/Memory/DramMemoryMap.cs | 2 - .../HOS/Kernel/Memory/KMemoryArrange.cs | 22 --- .../HOS/Kernel/Memory/KMemoryArrangeRegion.cs | 16 --- Ryujinx.HLE/MemoryConfiguration.cs | 62 +++++++++ Ryujinx.HLE/Switch.cs | 17 ++- Ryujinx/Ui/MainWindow.cs | 16 ++- Ryujinx/Ui/Windows/SettingsWindow.cs | 9 +- Ryujinx/Ui/Windows/SettingsWindow.glade | 20 ++- 16 files changed, 278 insertions(+), 144 deletions(-) create mode 100644 Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs create mode 100644 Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs create mode 100644 Ryujinx.HLE/HOS/Kernel/Common/MemroySize.cs delete mode 100644 Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrange.cs delete mode 100644 Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrangeRegion.cs create mode 100644 Ryujinx.HLE/MemoryConfiguration.cs diff --git a/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs b/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs index 901c823e5a..32e76375d0 100644 --- a/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs +++ b/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs @@ -14,7 +14,7 @@ namespace Ryujinx.Configuration /// /// The current version of the file format /// - public const int CurrentVersion = 22; + public const int CurrentVersion = 23; public int Version { get; set; } @@ -173,6 +173,11 @@ namespace Ryujinx.Configuration /// public AudioBackend AudioBackend { get; set; } + /// + /// Expands the RAM amount on the emulated system from 4GB to 6GB + /// + public bool ExpandRam { get; set; } + /// /// Enable or disable ignoring missing services /// diff --git a/Ryujinx.Common/Configuration/ConfigurationState.cs b/Ryujinx.Common/Configuration/ConfigurationState.cs index d51ee9efc6..e257fa232b 100644 --- a/Ryujinx.Common/Configuration/ConfigurationState.cs +++ b/Ryujinx.Common/Configuration/ConfigurationState.cs @@ -218,6 +218,11 @@ namespace Ryujinx.Configuration /// public ReactiveObject AudioBackend { get; private set; } + /// + /// Defines the amount of RAM available on the emulated system, and how it is distributed + /// + public ReactiveObject ExpandRam { get; private set; } + /// /// Enable or disable ignoring missing services /// @@ -234,6 +239,7 @@ namespace Ryujinx.Configuration EnableFsIntegrityChecks = new ReactiveObject(); FsGlobalAccessLogMode = new ReactiveObject(); AudioBackend = new ReactiveObject(); + ExpandRam = new ReactiveObject(); IgnoreMissingServices = new ReactiveObject(); } } @@ -433,6 +439,7 @@ namespace Ryujinx.Configuration EnableFsIntegrityChecks = System.EnableFsIntegrityChecks, FsGlobalAccessLogMode = System.FsGlobalAccessLogMode, AudioBackend = System.AudioBackend, + ExpandRam = System.ExpandRam, IgnoreMissingServices = System.IgnoreMissingServices, GuiColumns = new GuiColumns { @@ -497,6 +504,7 @@ namespace Ryujinx.Configuration System.EnableFsIntegrityChecks.Value = true; System.FsGlobalAccessLogMode.Value = 0; System.AudioBackend.Value = AudioBackend.OpenAl; + System.ExpandRam.Value = false; System.IgnoreMissingServices.Value = false; Ui.GuiColumns.FavColumn.Value = true; Ui.GuiColumns.IconColumn.Value = true; @@ -838,6 +846,7 @@ namespace Ryujinx.Configuration System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks; System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode; System.AudioBackend.Value = configurationFileFormat.AudioBackend; + System.ExpandRam.Value = configurationFileFormat.ExpandRam; System.IgnoreMissingServices.Value = configurationFileFormat.IgnoreMissingServices; Ui.GuiColumns.FavColumn.Value = configurationFileFormat.GuiColumns.FavColumn; Ui.GuiColumns.IconColumn.Value = configurationFileFormat.GuiColumns.IconColumn; diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs index daa8dcc3fb..80f097f415 100644 --- a/Ryujinx.HLE/HOS/Horizon.cs +++ b/Ryujinx.HLE/HOS/Horizon.cs @@ -110,9 +110,13 @@ namespace Ryujinx.HLE.HOS internal LibHac.Horizon LibHacHorizonServer { get; private set; } internal HorizonClient LibHacHorizonClient { get; private set; } - public Horizon(Switch device, ContentManager contentManager) + public Horizon(Switch device, ContentManager contentManager, MemoryConfiguration memoryConfiguration) { - KernelContext = new KernelContext(device, device.Memory); + KernelContext = new KernelContext( + device, + device.Memory, + memoryConfiguration.ToKernelMemorySize(), + memoryConfiguration.ToKernelMemoryArrange()); Device = device; diff --git a/Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs b/Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs new file mode 100644 index 0000000000..630baacfc2 --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs @@ -0,0 +1,72 @@ +using Ryujinx.HLE.HOS.Kernel.Memory; +using System; + +namespace Ryujinx.HLE.HOS.Kernel.Common +{ + static class KSystemControl + { + private const ulong Kb = 1024; + private const ulong Mb = 1024 * Kb; + private const ulong Gb = 1024 * Mb; + + private const ulong PageSize = 4 * Kb; + + private const ulong RequiredNonSecureSystemPoolSizeVi = 0x2238 * PageSize; + private const ulong RequiredNonSecureSystemPoolSizeNvservices = 0x710 * PageSize; + private const ulong RequiredNonSecureSystemPoolSizeOther = 0x80 * PageSize; + + private const ulong RequiredNonSecureSystemPoolSize = + RequiredNonSecureSystemPoolSizeVi + + RequiredNonSecureSystemPoolSizeNvservices + + RequiredNonSecureSystemPoolSizeOther; + + public static ulong GetApplicationPoolSize(MemoryArrange arrange) + { + return arrange switch + { + MemoryArrange.MemoryArrange4GB or + MemoryArrange.MemoryArrange4GBSystemDev or + MemoryArrange.MemoryArrange6GBAppletDev => 3285 * Mb, + MemoryArrange.MemoryArrange4GBAppletDev => 2048 * Mb, + MemoryArrange.MemoryArrange6GB or + MemoryArrange.MemoryArrange8GB => 4916 * Mb, + _ => throw new ArgumentException($"Invalid memory arrange \"{arrange}\".") + }; + } + + public static ulong GetAppletPoolSize(MemoryArrange arrange) + { + return arrange switch + { + MemoryArrange.MemoryArrange4GB => 507 * Mb, + MemoryArrange.MemoryArrange4GBAppletDev => 1554 * Mb, + MemoryArrange.MemoryArrange4GBSystemDev => 448 * Mb, + MemoryArrange.MemoryArrange6GB => 562 * Mb, + MemoryArrange.MemoryArrange6GBAppletDev or + MemoryArrange.MemoryArrange8GB => 2193 * Mb, + _ => throw new ArgumentException($"Invalid memory arrange \"{arrange}\".") + }; + } + + public static ulong GetMinimumNonSecureSystemPoolSize() + { + return RequiredNonSecureSystemPoolSize; + } + + public static ulong GetDramEndAddress(MemorySize size) + { + return DramMemoryMap.DramBase + GetDramSize(size); + } + + public static ulong GetDramSize(MemorySize size) + { + return size switch + { + MemorySize.MemorySize4GB => 4 * Gb, + MemorySize.MemorySize6GB => 6 * Gb, + MemorySize.MemorySize8GB => 8 * Gb, + _ => throw new ArgumentException($"Invalid memory size \"{size}\".") + }; + } + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs b/Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs index bbb75f182d..1949df311c 100644 --- a/Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs +++ b/Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs @@ -5,7 +5,21 @@ namespace Ryujinx.HLE.HOS.Kernel.Common { static class KernelInit { - public static void InitializeResourceLimit(KResourceLimit resourceLimit) + private struct MemoryRegion + { + public ulong Address { get; } + public ulong Size { get; } + + public ulong EndAddress => Address + Size; + + public MemoryRegion(ulong address, ulong size) + { + Address = address; + Size = size; + } + } + + public static void InitializeResourceLimit(KResourceLimit resourceLimit, MemorySize size) { void EnsureSuccess(KernelResult result) { @@ -15,11 +29,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Common } } - int kernelMemoryCfg = 0; + ulong ramSize = KSystemControl.GetDramSize(size); - long ramSize = GetRamSize(kernelMemoryCfg); - - EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Memory, ramSize)); + EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Memory, (long)ramSize)); EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Thread, 800)); EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Event, 700)); EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.TransferMemory, 200)); @@ -32,106 +44,45 @@ namespace Ryujinx.HLE.HOS.Kernel.Common } } - public static KMemoryRegionManager[] GetMemoryRegions() + public static KMemoryRegionManager[] GetMemoryRegions(MemorySize size, MemoryArrange arrange) { - KMemoryArrange arrange = GetMemoryArrange(); + ulong poolEnd = KSystemControl.GetDramEndAddress(size); + ulong applicationPoolSize = KSystemControl.GetApplicationPoolSize(arrange); + ulong appletPoolSize = KSystemControl.GetAppletPoolSize(arrange); - return new KMemoryRegionManager[] - { - GetMemoryRegion(arrange.Application), - GetMemoryRegion(arrange.Applet), - GetMemoryRegion(arrange.Service), - GetMemoryRegion(arrange.NvServices) - }; - } + MemoryRegion servicePool; + MemoryRegion nvServicesPool; + MemoryRegion appletPool; + MemoryRegion applicationPool; - private static KMemoryRegionManager GetMemoryRegion(KMemoryArrangeRegion region) - { - return new KMemoryRegionManager(region.Address, region.Size, region.EndAddr); - } + ulong nvServicesPoolSize = KSystemControl.GetMinimumNonSecureSystemPoolSize(); - private static KMemoryArrange GetMemoryArrange() - { - int mcEmemCfg = 0x1000; + applicationPool = new MemoryRegion(poolEnd - applicationPoolSize, applicationPoolSize); - ulong ememApertureSize = (ulong)(mcEmemCfg & 0x3fff) << 20; + ulong nvServicesPoolEnd = applicationPool.Address - appletPoolSize; - int kernelMemoryCfg = 0; - - ulong ramSize = (ulong)GetRamSize(kernelMemoryCfg); - - ulong ramPart0; - ulong ramPart1; - - if (ramSize * 2 > ememApertureSize) - { - ramPart0 = ememApertureSize / 2; - ramPart1 = ememApertureSize / 2; - } - else - { - ramPart0 = ememApertureSize; - ramPart1 = 0; - } - - int memoryArrange = 1; - - ulong applicationRgSize; - - switch (memoryArrange) - { - case 2: applicationRgSize = 0x80000000; break; - case 0x11: - case 0x21: applicationRgSize = 0x133400000; break; - default: applicationRgSize = 0xcd500000; break; - } - - ulong appletRgSize; - - switch (memoryArrange) - { - case 2: appletRgSize = 0x61200000; break; - case 3: appletRgSize = 0x1c000000; break; - case 0x11: appletRgSize = 0x23200000; break; - case 0x12: - case 0x21: appletRgSize = 0x89100000; break; - default: appletRgSize = 0x1fb00000; break; - } - - KMemoryArrangeRegion serviceRg; - KMemoryArrangeRegion nvServicesRg; - KMemoryArrangeRegion appletRg; - KMemoryArrangeRegion applicationRg; - - const ulong nvServicesRgSize = 0x29ba000; - - ulong applicationRgEnd = DramMemoryMap.DramEnd; //- RamPart0; - - applicationRg = new KMemoryArrangeRegion(applicationRgEnd - applicationRgSize, applicationRgSize); - - ulong nvServicesRgEnd = applicationRg.Address - appletRgSize; - - nvServicesRg = new KMemoryArrangeRegion(nvServicesRgEnd - nvServicesRgSize, nvServicesRgSize); - appletRg = new KMemoryArrangeRegion(nvServicesRgEnd, appletRgSize); + nvServicesPool = new MemoryRegion(nvServicesPoolEnd - nvServicesPoolSize, nvServicesPoolSize); + appletPool = new MemoryRegion(nvServicesPoolEnd, appletPoolSize); // Note: There is an extra region used by the kernel, however // since we are doing HLE we are not going to use that memory, so give all // the remaining memory space to services. - ulong serviceRgSize = nvServicesRg.Address - DramMemoryMap.SlabHeapEnd; + ulong servicePoolSize = nvServicesPool.Address - DramMemoryMap.SlabHeapEnd; - serviceRg = new KMemoryArrangeRegion(DramMemoryMap.SlabHeapEnd, serviceRgSize); + servicePool = new MemoryRegion(DramMemoryMap.SlabHeapEnd, servicePoolSize); - return new KMemoryArrange(serviceRg, nvServicesRg, appletRg, applicationRg); + return new KMemoryRegionManager[] + { + GetMemoryRegion(applicationPool), + GetMemoryRegion(appletPool), + GetMemoryRegion(servicePool), + GetMemoryRegion(nvServicesPool) + }; } - private static long GetRamSize(int kernelMemoryCfg) + private static KMemoryRegionManager GetMemoryRegion(MemoryRegion region) { - switch ((kernelMemoryCfg >> 16) & 3) - { - case 1: return 0x180000000; - case 2: return 0x200000000; - default: return 0x100000000; - } + return new KMemoryRegionManager(region.Address, region.Size, region.EndAddress); } } } \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs b/Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs new file mode 100644 index 0000000000..136b0240b2 --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs @@ -0,0 +1,12 @@ +namespace Ryujinx.HLE.HOS.Kernel.Common +{ + enum MemoryArrange : byte + { + MemoryArrange4GB, + MemoryArrange4GBAppletDev, + MemoryArrange4GBSystemDev, + MemoryArrange6GB, + MemoryArrange6GBAppletDev, + MemoryArrange8GB + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/Common/MemroySize.cs b/Ryujinx.HLE/HOS/Kernel/Common/MemroySize.cs new file mode 100644 index 0000000000..1148b0f404 --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/Common/MemroySize.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.HLE.HOS.Kernel.Common +{ + enum MemorySize : byte + { + MemorySize4GB = 0, + MemorySize6GB = 1, + MemorySize8GB = 2 + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/KernelContext.cs b/Ryujinx.HLE/HOS/Kernel/KernelContext.cs index cacb7fb3b6..b57b950473 100644 --- a/Ryujinx.HLE/HOS/Kernel/KernelContext.cs +++ b/Ryujinx.HLE/HOS/Kernel/KernelContext.cs @@ -51,7 +51,11 @@ namespace Ryujinx.HLE.HOS.Kernel private long _processId; private long _threadUid; - public KernelContext(Switch device, MemoryBlock memory) + public KernelContext( + Switch device, + MemoryBlock memory, + MemorySize memorySize, + MemoryArrange memoryArrange) { Device = device; Memory = memory; @@ -64,9 +68,9 @@ namespace Ryujinx.HLE.HOS.Kernel ResourceLimit = new KResourceLimit(this); - KernelInit.InitializeResourceLimit(ResourceLimit); + KernelInit.InitializeResourceLimit(ResourceLimit, memorySize); - MemoryRegions = KernelInit.GetMemoryRegions(); + MemoryRegions = KernelInit.GetMemoryRegions(memorySize, memoryArrange); LargeMemoryBlockAllocator = new KMemoryBlockAllocator(KernelConstants.MemoryBlockAllocatorSize * 2); SmallMemoryBlockAllocator = new KMemoryBlockAllocator(KernelConstants.MemoryBlockAllocatorSize); diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/DramMemoryMap.cs b/Ryujinx.HLE/HOS/Kernel/Memory/DramMemoryMap.cs index 261c2972b3..dea2a4efea 100644 --- a/Ryujinx.HLE/HOS/Kernel/Memory/DramMemoryMap.cs +++ b/Ryujinx.HLE/HOS/Kernel/Memory/DramMemoryMap.cs @@ -3,8 +3,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory static class DramMemoryMap { public const ulong DramBase = 0x80000000; - public const ulong DramSize = 0x100000000; - public const ulong DramEnd = DramBase + DramSize; public const ulong KernelReserveBase = DramBase + 0x60000; diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrange.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrange.cs deleted file mode 100644 index 7dfc2b7780..0000000000 --- a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrange.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Ryujinx.HLE.HOS.Kernel.Memory -{ - class KMemoryArrange - { - public KMemoryArrangeRegion Service { get; private set; } - public KMemoryArrangeRegion NvServices { get; private set; } - public KMemoryArrangeRegion Applet { get; private set; } - public KMemoryArrangeRegion Application { get; private set; } - - public KMemoryArrange( - KMemoryArrangeRegion service, - KMemoryArrangeRegion nvServices, - KMemoryArrangeRegion applet, - KMemoryArrangeRegion application) - { - Service = service; - NvServices = nvServices; - Applet = applet; - Application = application; - } - } -} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrangeRegion.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrangeRegion.cs deleted file mode 100644 index eaf0fe5fb8..0000000000 --- a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrangeRegion.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Ryujinx.HLE.HOS.Kernel.Memory -{ - struct KMemoryArrangeRegion - { - public ulong Address { get; private set; } - public ulong Size { get; private set; } - - public ulong EndAddr => Address + Size; - - public KMemoryArrangeRegion(ulong address, ulong size) - { - Address = address; - Size = size; - } - } -} \ No newline at end of file diff --git a/Ryujinx.HLE/MemoryConfiguration.cs b/Ryujinx.HLE/MemoryConfiguration.cs new file mode 100644 index 0000000000..2a59e04f22 --- /dev/null +++ b/Ryujinx.HLE/MemoryConfiguration.cs @@ -0,0 +1,62 @@ +using Ryujinx.HLE.HOS.Kernel.Common; +using System; + +namespace Ryujinx.HLE +{ + public enum MemoryConfiguration + { + MemoryConfiguration4GB = 0, + MemoryConfiguration4GBAppletDev = 1, + MemoryConfiguration4GBSystemDev = 2, + MemoryConfiguration6GB = 3, + MemoryConfiguration6GBAppletDev = 4, + MemoryConfiguration8GB = 5 + } + + static class MemoryConfigurationExtensions + { + private const ulong Gb = 1024 * 1024 * 1024; + + public static MemoryArrange ToKernelMemoryArrange(this MemoryConfiguration configuration) + { + return configuration switch + { + MemoryConfiguration.MemoryConfiguration4GB => MemoryArrange.MemoryArrange4GB, + MemoryConfiguration.MemoryConfiguration4GBAppletDev => MemoryArrange.MemoryArrange4GBAppletDev, + MemoryConfiguration.MemoryConfiguration4GBSystemDev => MemoryArrange.MemoryArrange4GBSystemDev, + MemoryConfiguration.MemoryConfiguration6GB => MemoryArrange.MemoryArrange6GB, + MemoryConfiguration.MemoryConfiguration6GBAppletDev => MemoryArrange.MemoryArrange6GBAppletDev, + MemoryConfiguration.MemoryConfiguration8GB => MemoryArrange.MemoryArrange8GB, + _ => throw new AggregateException($"Invalid memory configuration \"{configuration}\".") + }; + } + + public static MemorySize ToKernelMemorySize(this MemoryConfiguration configuration) + { + return configuration switch + { + MemoryConfiguration.MemoryConfiguration4GB or + MemoryConfiguration.MemoryConfiguration4GBAppletDev or + MemoryConfiguration.MemoryConfiguration4GBSystemDev => MemorySize.MemorySize4GB, + MemoryConfiguration.MemoryConfiguration6GB or + MemoryConfiguration.MemoryConfiguration6GBAppletDev => MemorySize.MemorySize6GB, + MemoryConfiguration.MemoryConfiguration8GB => MemorySize.MemorySize8GB, + _ => throw new AggregateException($"Invalid memory configuration \"{configuration}\".") + }; + } + + public static ulong ToDramSize(this MemoryConfiguration configuration) + { + return configuration switch + { + MemoryConfiguration.MemoryConfiguration4GB or + MemoryConfiguration.MemoryConfiguration4GBAppletDev or + MemoryConfiguration.MemoryConfiguration4GBSystemDev => 4 * Gb, + MemoryConfiguration.MemoryConfiguration6GB or + MemoryConfiguration.MemoryConfiguration6GBAppletDev => 6 * Gb, + MemoryConfiguration.MemoryConfiguration8GB => 8 * Gb, + _ => throw new AggregateException($"Invalid memory configuration \"{configuration}\".") + }; + } + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/Switch.cs b/Ryujinx.HLE/Switch.cs index 61c0776957..6770b25e51 100644 --- a/Ryujinx.HLE/Switch.cs +++ b/Ryujinx.HLE/Switch.cs @@ -24,6 +24,8 @@ namespace Ryujinx.HLE { public class Switch : IDisposable { + private MemoryConfiguration _memoryConfiguration; + public IHardwareDeviceDriver AudioDeviceDriver { get; private set; } internal MemoryBlock Memory { get; private set; } @@ -52,7 +54,13 @@ namespace Ryujinx.HLE public bool EnableDeviceVsync { get; set; } = true; - public Switch(VirtualFileSystem fileSystem, ContentManager contentManager, UserChannelPersistence userChannelPersistence, IRenderer renderer, IHardwareDeviceDriver audioDeviceDriver) + public Switch( + VirtualFileSystem fileSystem, + ContentManager contentManager, + UserChannelPersistence userChannelPersistence, + IRenderer renderer, + IHardwareDeviceDriver audioDeviceDriver, + MemoryConfiguration memoryConfiguration) { if (renderer == null) { @@ -71,9 +79,11 @@ namespace Ryujinx.HLE UserChannelPersistence = userChannelPersistence; + _memoryConfiguration = memoryConfiguration; + AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(audioDeviceDriver); - Memory = new MemoryBlock(1UL << 32); + Memory = new MemoryBlock(memoryConfiguration.ToDramSize()); Gpu = new GpuContext(renderer); @@ -102,7 +112,7 @@ namespace Ryujinx.HLE FileSystem = fileSystem; - System = new Horizon(this, contentManager); + System = new Horizon(this, contentManager, memoryConfiguration); System.InitializeServices(); Statistics = new PerformanceStatistics(); @@ -146,6 +156,7 @@ namespace Ryujinx.HLE Logger.Info?.Print(LogClass.Application, $"AudioBackend: {ConfigurationState.Instance.System.AudioBackend.Value}"); Logger.Info?.Print(LogClass.Application, $"IsDocked: {ConfigurationState.Instance.System.EnableDockedMode.Value}"); Logger.Info?.Print(LogClass.Application, $"Vsync: {ConfigurationState.Instance.Graphics.EnableVsync.Value}"); + Logger.Info?.Print(LogClass.Application, $"MemoryConfiguration: {_memoryConfiguration}"); } public static IntegrityCheckLevel GetIntegrityCheckLevel() diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs index 1fa52d323f..369c6238d0 100644 --- a/Ryujinx/Ui/MainWindow.cs +++ b/Ryujinx/Ui/MainWindow.cs @@ -337,7 +337,17 @@ namespace Ryujinx.Ui } } - _emulationContext = new HLE.Switch(_virtualFileSystem, _contentManager, _userChannelPersistence, renderer, deviceDriver) + var memoryConfiguration = ConfigurationState.Instance.System.ExpandRam.Value + ? HLE.MemoryConfiguration.MemoryConfiguration6GB + : HLE.MemoryConfiguration.MemoryConfiguration4GB; + + _emulationContext = new HLE.Switch( + _virtualFileSystem, + _contentManager, + _userChannelPersistence, + renderer, + deviceDriver, + memoryConfiguration) { UiHandler = _uiHandler }; @@ -664,7 +674,7 @@ namespace Ryujinx.Ui GlRendererWidget.Exit(); - if(GlRendererWidget.Window != Window && GlRendererWidget.Window != null) + if (GlRendererWidget.Window != Window && GlRendererWidget.Window != null) { GlRendererWidget.Window.Dispose(); } @@ -1061,7 +1071,7 @@ namespace Ryujinx.Ui if (responseInstallDialog == ResponseType.Yes) { Logger.Info?.Print(LogClass.Application, $"Installing firmware {firmwareVersion.VersionString}"); - + Thread thread = new Thread(() => { Application.Invoke(delegate diff --git a/Ryujinx/Ui/Windows/SettingsWindow.cs b/Ryujinx/Ui/Windows/SettingsWindow.cs index 17d4c961f0..d4d680909d 100644 --- a/Ryujinx/Ui/Windows/SettingsWindow.cs +++ b/Ryujinx/Ui/Windows/SettingsWindow.cs @@ -51,6 +51,7 @@ namespace Ryujinx.Ui.Windows [GUI] CheckButton _shaderCacheToggle; [GUI] CheckButton _ptcToggle; [GUI] CheckButton _fsicToggle; + [GUI] CheckButton _expandRamToggle; [GUI] CheckButton _ignoreToggle; [GUI] CheckButton _directKeyboardAccess; [GUI] ComboBoxText _systemLanguageSelect; @@ -214,6 +215,11 @@ namespace Ryujinx.Ui.Windows _fsicToggle.Click(); } + if (ConfigurationState.Instance.System.ExpandRam) + { + _expandRamToggle.Click(); + } + if (ConfigurationState.Instance.System.IgnoreMissingServices) { _ignoreToggle.Click(); @@ -417,6 +423,7 @@ namespace Ryujinx.Ui.Windows ConfigurationState.Instance.Graphics.EnableShaderCache.Value = _shaderCacheToggle.Active; ConfigurationState.Instance.System.EnablePtc.Value = _ptcToggle.Active; ConfigurationState.Instance.System.EnableFsIntegrityChecks.Value = _fsicToggle.Active; + ConfigurationState.Instance.System.ExpandRam.Value = _expandRamToggle.Active; ConfigurationState.Instance.System.IgnoreMissingServices.Value = _ignoreToggle.Active; ConfigurationState.Instance.Hid.EnableKeyboard.Value = _directKeyboardAccess.Active; ConfigurationState.Instance.Ui.EnableCustomTheme.Value = _custThemeToggle.Active; @@ -436,7 +443,7 @@ namespace Ryujinx.Ui.Windows { AudioBackend audioBackend = (AudioBackend)_audioBackendStore.GetValue(activeIter, 1); if (audioBackend != ConfigurationState.Instance.System.AudioBackend.Value) - { + { ConfigurationState.Instance.System.AudioBackend.Value = audioBackend; Logger.Info?.Print(LogClass.Application, $"AudioBackend toggled to: {audioBackend}"); diff --git a/Ryujinx/Ui/Windows/SettingsWindow.glade b/Ryujinx/Ui/Windows/SettingsWindow.glade index e9d241f80b..3dc0bdce8a 100644 --- a/Ryujinx/Ui/Windows/SettingsWindow.glade +++ b/Ryujinx/Ui/Windows/SettingsWindow.glade @@ -1625,6 +1625,24 @@ 10 10 vertical + + + Expand DRAM size to 6GB + True + True + False + Expands the amount of memory on the emulated system from 4GB to 6GB + start + 5 + 5 + True + + + False + True + 0 + + Ignore Missing Services @@ -1640,7 +1658,7 @@ False True - 0 + 1