Compare commits

...

3 Commits

Author SHA1 Message Date
Ac_K
f449895e6d HOS: Load RomFs by pid (#4301)
We currently loading only one RomFs at a time, which could be wrong if one day we want to load more than one guest at time.
This PR fixes that by loading romfs by pid.
2023-01-18 13:50:42 +00:00
TSRBerry
410be95ab6 Fix NRE when disposing AddressSpace with 4KB pages support (#4307) 2023-01-17 14:50:39 +00:00
merry
cff9046fc7 ConfigurationState: Default to Vulkan on macOS (#4299) 2023-01-17 05:32:08 +01:00
6 changed files with 63 additions and 26 deletions

View File

@@ -462,7 +462,7 @@ namespace Ryujinx.Cpu
public void Dispose() public void Dispose()
{ {
_privateMemoryAllocator.Dispose(); _privateMemoryAllocator?.Dispose();
Base.Dispose(); Base.Dispose();
Mirror.Dispose(); Mirror.Dispose();
} }

View File

@@ -16,6 +16,7 @@ using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS; using Ryujinx.HLE.HOS;
using System; using System;
using System.Buffers.Text; using System.Buffers.Text;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@@ -35,7 +36,8 @@ namespace Ryujinx.HLE.FileSystem
public EmulatedGameCard GameCard { get; private set; } public EmulatedGameCard GameCard { get; private set; }
public EmulatedSdCard SdCard { get; private set; } public EmulatedSdCard SdCard { get; private set; }
public ModLoader ModLoader { get; private set; } public ModLoader ModLoader { get; private set; }
public Stream RomFs { get; private set; }
private readonly ConcurrentDictionary<ulong, Stream> _romFsByPid;
private static bool _isInitialized = false; private static bool _isInitialized = false;
@@ -55,17 +57,34 @@ namespace Ryujinx.HLE.FileSystem
{ {
ReloadKeySet(); ReloadKeySet();
ModLoader = new ModLoader(); // Should only be created once ModLoader = new ModLoader(); // Should only be created once
_romFsByPid = new ConcurrentDictionary<ulong, Stream>();
} }
public void LoadRomFs(string fileName) public void LoadRomFs(ulong pid, string fileName)
{ {
RomFs = new FileStream(fileName, FileMode.Open, FileAccess.Read); var romfsStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
_romFsByPid.AddOrUpdate(pid, romfsStream, (pid, oldStream) =>
{
oldStream.Close();
return romfsStream;
});
} }
public void SetRomFs(Stream romfsStream) public void SetRomFs(ulong pid, Stream romfsStream)
{ {
RomFs?.Close(); _romFsByPid.AddOrUpdate(pid, romfsStream, (pid, oldStream) =>
RomFs = romfsStream; {
oldStream.Close();
return romfsStream;
});
}
public Stream GetRomFs(ulong pid)
{
return _romFsByPid[pid];
} }
public string GetFullPath(string basePath, string fileName) public string GetFullPath(string basePath, string fileName)
@@ -583,7 +602,12 @@ namespace Ryujinx.HLE.FileSystem
{ {
if (disposing) if (disposing)
{ {
RomFs?.Dispose(); foreach (var stream in _romFsByPid.Values)
{
stream.Close();
}
_romFsByPid.Clear();
} }
} }
} }

View File

@@ -76,11 +76,6 @@ namespace Ryujinx.HLE.HOS
public void LoadCart(string exeFsDir, string romFsFile = null) public void LoadCart(string exeFsDir, string romFsFile = null)
{ {
if (romFsFile != null)
{
_device.Configuration.VirtualFileSystem.LoadRomFs(romFsFile);
}
LocalFileSystem codeFs = new LocalFileSystem(exeFsDir); LocalFileSystem codeFs = new LocalFileSystem(exeFsDir);
MetaLoader metaData = ReadNpdm(codeFs); MetaLoader metaData = ReadNpdm(codeFs);
@@ -95,7 +90,12 @@ namespace Ryujinx.HLE.HOS
EnsureSaveData(new ApplicationId(TitleId)); EnsureSaveData(new ApplicationId(TitleId));
} }
LoadExeFs(codeFs, string.Empty, metaData); ulong pid = LoadExeFs(codeFs, string.Empty, metaData);
if (romFsFile != null)
{
_device.Configuration.VirtualFileSystem.LoadRomFs(pid, romFsFile);
}
} }
public static (Nca main, Nca patch, Nca control) GetGameData(VirtualFileSystem fileSystem, PartitionFileSystem pfs, int programIndex) public static (Nca main, Nca patch, Nca control) GetGameData(VirtualFileSystem fileSystem, PartitionFileSystem pfs, int programIndex)
@@ -491,6 +491,8 @@ namespace Ryujinx.HLE.HOS
_displayVersion = displayVersion; _displayVersion = displayVersion;
ulong pid = LoadExeFs(codeFs, displayVersion, metaData);
if (dataStorage == null) if (dataStorage == null)
{ {
Logger.Warning?.Print(LogClass.Loader, "No RomFS found in NCA"); Logger.Warning?.Print(LogClass.Loader, "No RomFS found in NCA");
@@ -499,7 +501,7 @@ namespace Ryujinx.HLE.HOS
{ {
IStorage newStorage = _device.Configuration.VirtualFileSystem.ModLoader.ApplyRomFsMods(TitleId, dataStorage); IStorage newStorage = _device.Configuration.VirtualFileSystem.ModLoader.ApplyRomFsMods(TitleId, dataStorage);
_device.Configuration.VirtualFileSystem.SetRomFs(newStorage.AsStream(FileAccess.Read)); _device.Configuration.VirtualFileSystem.SetRomFs(pid, newStorage.AsStream(FileAccess.Read));
} }
// Don't create save data for system programs. // Don't create save data for system programs.
@@ -510,8 +512,6 @@ namespace Ryujinx.HLE.HOS
EnsureSaveData(new ApplicationId(TitleId & ~0xFul)); EnsureSaveData(new ApplicationId(TitleId & ~0xFul));
} }
LoadExeFs(codeFs, displayVersion, metaData);
Logger.Info?.Print(LogClass.Loader, $"Application Loaded: {TitleName} v{DisplayVersion} [{TitleIdText}] [{(TitleIs64Bit ? "64-bit" : "32-bit")}]"); Logger.Info?.Print(LogClass.Loader, $"Application Loaded: {TitleName} v{DisplayVersion} [{TitleIdText}] [{(TitleIs64Bit ? "64-bit" : "32-bit")}]");
} }
@@ -579,7 +579,7 @@ namespace Ryujinx.HLE.HOS
} }
} }
private void LoadExeFs(IFileSystem codeFs, string displayVersion, MetaLoader metaData = null, bool isHomebrew = false) private ulong LoadExeFs(IFileSystem codeFs, string displayVersion, MetaLoader metaData = null, bool isHomebrew = false)
{ {
if (_device.Configuration.VirtualFileSystem.ModLoader.ReplaceExefsPartition(TitleId, ref codeFs)) if (_device.Configuration.VirtualFileSystem.ModLoader.ReplaceExefsPartition(TitleId, ref codeFs))
{ {
@@ -654,6 +654,8 @@ namespace Ryujinx.HLE.HOS
DiskCacheLoadState = result.DiskCacheLoadState; DiskCacheLoadState = result.DiskCacheLoadState;
_device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, result.TamperInfo, _device.TamperMachine); _device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, result.TamperInfo, _device.TamperMachine);
return result.ProcessId;
} }
public void LoadProgram(string filePath) public void LoadProgram(string filePath)
@@ -665,6 +667,7 @@ namespace Ryujinx.HLE.HOS
bool isNro = Path.GetExtension(filePath).ToLower() == ".nro"; bool isNro = Path.GetExtension(filePath).ToLower() == ".nro";
IExecutable executable; IExecutable executable;
Stream romfsStream = null;
if (isNro) if (isNro)
{ {
@@ -697,7 +700,7 @@ namespace Ryujinx.HLE.HOS
if (romfsSize != 0) if (romfsSize != 0)
{ {
_device.Configuration.VirtualFileSystem.SetRomFs(new HomebrewRomFsStream(input, obj.FileSize + (long)romfsOffset)); romfsStream = new HomebrewRomFsStream(input, obj.FileSize + (long)romfsOffset);
} }
if (nacpSize != 0) if (nacpSize != 0)
@@ -758,6 +761,11 @@ namespace Ryujinx.HLE.HOS
ProgramLoadResult result = ProgramLoader.LoadNsos(_device.System.KernelContext, metaData, programInfo, executables: executable); ProgramLoadResult result = ProgramLoader.LoadNsos(_device.System.KernelContext, metaData, programInfo, executables: executable);
if (romfsStream != null)
{
_device.Configuration.VirtualFileSystem.SetRomFs(result.ProcessId, romfsStream);
}
DiskCacheLoadState = result.DiskCacheLoadState; DiskCacheLoadState = result.DiskCacheLoadState;
_device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, result.TamperInfo, _device.TamperMachine); _device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, result.TamperInfo, _device.TamperMachine);

View File

@@ -41,17 +41,19 @@ namespace Ryujinx.HLE.HOS
struct ProgramLoadResult struct ProgramLoadResult
{ {
public static ProgramLoadResult Failed => new ProgramLoadResult(false, null, null); public static ProgramLoadResult Failed => new ProgramLoadResult(false, null, null, 0);
public readonly bool Success; public readonly bool Success;
public readonly ProcessTamperInfo TamperInfo; public readonly ProcessTamperInfo TamperInfo;
public readonly IDiskCacheLoadState DiskCacheLoadState; public readonly IDiskCacheLoadState DiskCacheLoadState;
public readonly ulong ProcessId;
public ProgramLoadResult(bool success, ProcessTamperInfo tamperInfo, IDiskCacheLoadState diskCacheLoadState) public ProgramLoadResult(bool success, ProcessTamperInfo tamperInfo, IDiskCacheLoadState diskCacheLoadState, ulong pid)
{ {
Success = success; Success = success;
TamperInfo = tamperInfo; TamperInfo = tamperInfo;
DiskCacheLoadState = diskCacheLoadState; DiskCacheLoadState = diskCacheLoadState;
ProcessId = pid;
} }
} }
@@ -366,7 +368,7 @@ namespace Ryujinx.HLE.HOS
process.MemoryManager.AliasRegionStart, process.MemoryManager.AliasRegionStart,
process.MemoryManager.CodeRegionStart); process.MemoryManager.CodeRegionStart);
return new ProgramLoadResult(true, tamperInfo, processContextFactory.DiskCacheLoadState); return new ProgramLoadResult(true, tamperInfo, processContextFactory.DiskCacheLoadState, process.Pid);
} }
private static Result LoadIntoMemory(KProcess process, IExecutable image, ulong baseAddress) private static Result LoadIntoMemory(KProcess process, IExecutable image, ulong baseAddress)

View File

@@ -27,6 +27,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs
class IFileSystemProxy : DisposableIpcService class IFileSystemProxy : DisposableIpcService
{ {
private SharedRef<LibHac.FsSrv.Sf.IFileSystemProxy> _baseFileSystemProxy; private SharedRef<LibHac.FsSrv.Sf.IFileSystemProxy> _baseFileSystemProxy;
private ulong _pid;
public IFileSystemProxy(ServiceCtx context) : base(context.Device.System.FsServer) public IFileSystemProxy(ServiceCtx context) : base(context.Device.System.FsServer)
{ {
@@ -38,6 +39,8 @@ namespace Ryujinx.HLE.HOS.Services.Fs
// SetCurrentProcess(u64, pid) // SetCurrentProcess(u64, pid)
public ResultCode SetCurrentProcess(ServiceCtx context) public ResultCode SetCurrentProcess(ServiceCtx context)
{ {
_pid = context.Request.HandleDesc.PId;
return ResultCode.Success; return ResultCode.Success;
} }
@@ -702,7 +705,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs
// OpenDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage> dataStorage // OpenDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage> dataStorage
public ResultCode OpenDataStorageByCurrentProcess(ServiceCtx context) public ResultCode OpenDataStorageByCurrentProcess(ServiceCtx context)
{ {
var storage = context.Device.FileSystem.RomFs.AsStorage(true); var storage = context.Device.FileSystem.GetRomFs(_pid).AsStorage(true);
using var sharedStorage = new SharedRef<LibHac.Fs.IStorage>(storage); using var sharedStorage = new SharedRef<LibHac.Fs.IStorage>(storage);
using var sfStorage = new SharedRef<IStorage>(new StorageInterfaceAdapter(ref sharedStorage.Ref())); using var sfStorage = new SharedRef<IStorage>(new StorageInterfaceAdapter(ref sharedStorage.Ref()));
@@ -791,7 +794,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs
// OpenPatchDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage> // OpenPatchDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage>
public ResultCode OpenPatchDataStorageByCurrentProcess(ServiceCtx context) public ResultCode OpenPatchDataStorageByCurrentProcess(ServiceCtx context)
{ {
var storage = context.Device.FileSystem.RomFs.AsStorage(true); var storage = context.Device.FileSystem.GetRomFs(_pid).AsStorage(true);
using var sharedStorage = new SharedRef<LibHac.Fs.IStorage>(storage); using var sharedStorage = new SharedRef<LibHac.Fs.IStorage>(storage);
using var sfStorage = new SharedRef<IStorage>(new StorageInterfaceAdapter(ref sharedStorage.Ref())); using var sfStorage = new SharedRef<IStorage>(new StorageInterfaceAdapter(ref sharedStorage.Ref()));
@@ -811,7 +814,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs
throw new NotImplementedException($"Accessing storage from other programs is not supported (program index = {programIndex})."); throw new NotImplementedException($"Accessing storage from other programs is not supported (program index = {programIndex}).");
} }
var storage = context.Device.FileSystem.RomFs.AsStorage(true); var storage = context.Device.FileSystem.GetRomFs(_pid).AsStorage(true);
using var sharedStorage = new SharedRef<LibHac.Fs.IStorage>(storage); using var sharedStorage = new SharedRef<LibHac.Fs.IStorage>(storage);
using var sfStorage = new SharedRef<IStorage>(new StorageInterfaceAdapter(ref sharedStorage.Ref())); using var sfStorage = new SharedRef<IStorage>(new StorageInterfaceAdapter(ref sharedStorage.Ref()));

View File

@@ -617,7 +617,7 @@ namespace Ryujinx.Ui.Common.Configuration
Graphics.ResScaleCustom.Value = 1.0f; Graphics.ResScaleCustom.Value = 1.0f;
Graphics.MaxAnisotropy.Value = -1.0f; Graphics.MaxAnisotropy.Value = -1.0f;
Graphics.AspectRatio.Value = AspectRatio.Fixed16x9; Graphics.AspectRatio.Value = AspectRatio.Fixed16x9;
Graphics.GraphicsBackend.Value = GraphicsBackend.OpenGl; Graphics.GraphicsBackend.Value = OperatingSystem.IsMacOS() ? GraphicsBackend.Vulkan : GraphicsBackend.OpenGl;
Graphics.PreferredGpu.Value = ""; Graphics.PreferredGpu.Value = "";
Graphics.ShadersDumpPath.Value = ""; Graphics.ShadersDumpPath.Value = "";
Logger.EnableDebug.Value = false; Logger.EnableDebug.Value = false;