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
This commit is contained in:
parent
3bc107d491
commit
874540bb5c
16 changed files with 278 additions and 144 deletions
|
@ -14,7 +14,7 @@ namespace Ryujinx.Configuration
|
|||
/// <summary>
|
||||
/// The current version of the file format
|
||||
/// </summary>
|
||||
public const int CurrentVersion = 22;
|
||||
public const int CurrentVersion = 23;
|
||||
|
||||
public int Version { get; set; }
|
||||
|
||||
|
@ -173,6 +173,11 @@ namespace Ryujinx.Configuration
|
|||
/// </summary>
|
||||
public AudioBackend AudioBackend { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Expands the RAM amount on the emulated system from 4GB to 6GB
|
||||
/// </summary>
|
||||
public bool ExpandRam { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enable or disable ignoring missing services
|
||||
/// </summary>
|
||||
|
|
|
@ -218,6 +218,11 @@ namespace Ryujinx.Configuration
|
|||
/// </summary>
|
||||
public ReactiveObject<AudioBackend> AudioBackend { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the amount of RAM available on the emulated system, and how it is distributed
|
||||
/// </summary>
|
||||
public ReactiveObject<bool> ExpandRam { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enable or disable ignoring missing services
|
||||
/// </summary>
|
||||
|
@ -234,6 +239,7 @@ namespace Ryujinx.Configuration
|
|||
EnableFsIntegrityChecks = new ReactiveObject<bool>();
|
||||
FsGlobalAccessLogMode = new ReactiveObject<int>();
|
||||
AudioBackend = new ReactiveObject<AudioBackend>();
|
||||
ExpandRam = new ReactiveObject<bool>();
|
||||
IgnoreMissingServices = new ReactiveObject<bool>();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
72
Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs
Normal file
72
Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs
Normal file
|
@ -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}\".")
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
12
Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs
Normal file
12
Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.HLE.HOS.Kernel.Common
|
||||
{
|
||||
enum MemoryArrange : byte
|
||||
{
|
||||
MemoryArrange4GB,
|
||||
MemoryArrange4GBAppletDev,
|
||||
MemoryArrange4GBSystemDev,
|
||||
MemoryArrange6GB,
|
||||
MemoryArrange6GBAppletDev,
|
||||
MemoryArrange8GB
|
||||
}
|
||||
}
|
9
Ryujinx.HLE/HOS/Kernel/Common/MemroySize.cs
Normal file
9
Ryujinx.HLE/HOS/Kernel/Common/MemroySize.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace Ryujinx.HLE.HOS.Kernel.Common
|
||||
{
|
||||
enum MemorySize : byte
|
||||
{
|
||||
MemorySize4GB = 0,
|
||||
MemorySize6GB = 1,
|
||||
MemorySize8GB = 2
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
62
Ryujinx.HLE/MemoryConfiguration.cs
Normal file
62
Ryujinx.HLE/MemoryConfiguration.cs
Normal file
|
@ -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}\".")
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}");
|
||||
|
|
|
@ -1625,6 +1625,24 @@
|
|||
<property name="margin-left">10</property>
|
||||
<property name="margin-right">10</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="_expandRamToggle">
|
||||
<property name="label" translatable="yes">Expand DRAM size to 6GB</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="tooltip-text" translatable="yes">Expands the amount of memory on the emulated system from 4GB to 6GB</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="margin-top">5</property>
|
||||
<property name="margin-bottom">5</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="_ignoreToggle">
|
||||
<property name="label" translatable="yes">Ignore Missing Services</property>
|
||||
|
@ -1640,7 +1658,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
|
|
Reference in a new issue