diff --git a/src/ARMeilleure/Translation/PTC/Ptc.cs b/src/ARMeilleure/Translation/PTC/Ptc.cs
index 2625a46df..b8ce585d0 100644
--- a/src/ARMeilleure/Translation/PTC/Ptc.cs
+++ b/src/ARMeilleure/Translation/PTC/Ptc.cs
@@ -31,14 +31,11 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\0\0";
private const string InnerHeaderMagicString = "PTCihd\0\0";
- private const uint InternalVersion = 7010; //! To be incremented manually for each change to the ARMeilleure project.
+ private const uint InternalVersion = 7020; //! To be incremented manually for each change to the ARMeilleure project. Your value was 7031, keeping this comment here just so you have the reference.
private const string ActualDir = "0";
private const string BackupDir = "1";
- private const string TitleIdTextDefault = "0000000000000000";
- private const string DisplayVersionDefault = "0";
-
public static readonly Symbol PageTableSymbol = new(SymbolType.Special, 1);
public static readonly Symbol CountTableSymbol = new(SymbolType.Special, 2);
public static readonly Symbol DispatchStubSymbol = new(SymbolType.Special, 3);
@@ -64,8 +61,7 @@ namespace ARMeilleure.Translation.PTC
private bool _disposed;
- public string TitleIdText { get; private set; }
- public string DisplayVersion { get; private set; }
+ public PtcCacheInfo CacheInfo { get; private set; }
private MemoryManagerType _memoryMode;
@@ -92,8 +88,7 @@ namespace ARMeilleure.Translation.PTC
_disposed = false;
- TitleIdText = TitleIdTextDefault;
- DisplayVersion = DisplayVersionDefault;
+ CacheInfo = new PtcCacheInfo(0, null, null, 0, null, "Unknown", "default");
CachePathActual = string.Empty;
CachePathBackup = string.Empty;
@@ -101,20 +96,24 @@ namespace ARMeilleure.Translation.PTC
Disable();
}
- public void Initialize(string titleIdText, string displayVersion, bool enabled, MemoryManagerType memoryMode, string cacheSelector)
+ public void Initialize(PtcCacheInfo cacheInfo, bool enabled, MemoryManagerType memoryMode)
{
Wait();
Profiler.Wait();
Profiler.ClearEntries();
- Logger.Info?.Print(LogClass.Ptc, $"Initializing Profiled Persistent Translation Cache v{InternalVersion}\n\t\t (title: {titleIdText}, version: '{displayVersion}', selector: '{cacheSelector}', enabled: {enabled}).");
+ CacheInfo = cacheInfo;
- if (!enabled || string.IsNullOrEmpty(titleIdText) || titleIdText == TitleIdTextDefault)
+ Logger.Info?.Print(
+ LogClass.Ptc,
+ $"Initializing Profiled Persistent Translation Cache v{InternalVersion}\n\t\t " +
+ $"(pid: {cacheInfo.ProcessId}, title: {cacheInfo.TitleIdText}, application: {cacheInfo.ApplicationIdText}, " +
+ $"programIndex: {cacheInfo.ProgramIndex}, version: '{cacheInfo.DisplayVersion}', kind: {cacheInfo.ProcessKind}, " +
+ $"selector: '{cacheInfo.CacheSelector}', key: '{cacheInfo.CacheKey}', enabled: {enabled}).");
+
+ if (!enabled || cacheInfo.TitleIdText == PtcCacheInfo.TitleIdTextDefault)
{
- TitleIdText = TitleIdTextDefault;
- DisplayVersion = DisplayVersionDefault;
-
CachePathActual = string.Empty;
CachePathBackup = string.Empty;
@@ -123,12 +122,10 @@ namespace ARMeilleure.Translation.PTC
return;
}
- TitleIdText = titleIdText;
- DisplayVersion = !string.IsNullOrEmpty(displayVersion) ? displayVersion : DisplayVersionDefault;
_memoryMode = memoryMode;
- string workPathActual = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", ActualDir);
- string workPathBackup = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", BackupDir);
+ string workPathActual = Path.Combine(AppDataManager.GamesDirPath, CacheInfo.TitleIdText, "cache", "cpu", ActualDir);
+ string workPathBackup = Path.Combine(AppDataManager.GamesDirPath, CacheInfo.TitleIdText, "cache", "cpu", BackupDir);
if (!Directory.Exists(workPathActual))
{
@@ -140,8 +137,14 @@ namespace ARMeilleure.Translation.PTC
Directory.CreateDirectory(workPathBackup);
}
- CachePathActual = Path.Combine(workPathActual, DisplayVersion) + "-" + cacheSelector;
- CachePathBackup = Path.Combine(workPathBackup, DisplayVersion) + "-" + cacheSelector;
+ CachePathActual = Path.Combine(workPathActual, CacheInfo.DisplayVersion) + "-" + CacheInfo.CacheSelector;
+ CachePathBackup = Path.Combine(workPathBackup, CacheInfo.DisplayVersion) + "-" + CacheInfo.CacheSelector;
+
+ Logger.Info?.Print(
+ LogClass.Ptc,
+ $"PPTC cache owner selected (pid: {CacheInfo.ProcessId}, title: {CacheInfo.TitleIdText}, application: {CacheInfo.ApplicationIdText}, " +
+ $"version: '{CacheInfo.DisplayVersion}', kind: {CacheInfo.ProcessKind}, selector: '{CacheInfo.CacheSelector}', " +
+ $"key: '{CacheInfo.CacheKey}', path: '{CachePathActual}').");
PreLoad();
Profiler.PreLoad();
@@ -364,7 +367,12 @@ namespace ARMeilleure.Translation.PTC
long fileSize = new FileInfo(fileName).Length;
- Logger.Info?.Print(LogClass.Ptc, $"{(isBackup ? "Loaded Backup Translation Cache" : "Loaded Translation Cache")} (size: {fileSize} bytes, translated functions: {GetEntriesCount()}).");
+ Logger.Info?.Print(
+ LogClass.Ptc,
+ $"{(isBackup ? "Loaded Backup Translation Cache" : "Loaded Translation Cache")} " +
+ $"(pid: {CacheInfo.ProcessId}, title: {CacheInfo.TitleIdText}, version: '{CacheInfo.DisplayVersion}', kind: {CacheInfo.ProcessKind}, " +
+ $"selector: '{CacheInfo.CacheSelector}', key: '{CacheInfo.CacheKey}', path: '{fileName}', " +
+ $"size: {fileSize} bytes, translated functions: {GetEntriesCount()}).");
return true;
}
@@ -505,7 +513,11 @@ namespace ARMeilleure.Translation.PTC
if (fileSize != 0L)
{
- Logger.Info?.Print(LogClass.Ptc, $"Saved Translation Cache (size: {fileSize} bytes, translated functions: {translatedFuncsCount}).");
+ Logger.Info?.Print(
+ LogClass.Ptc,
+ $"Saved Translation Cache (pid: {CacheInfo.ProcessId}, title: {CacheInfo.TitleIdText}, version: '{CacheInfo.DisplayVersion}', " +
+ $"kind: {CacheInfo.ProcessKind}, selector: '{CacheInfo.CacheSelector}', key: '{CacheInfo.CacheKey}', " +
+ $"path: '{fileName}', size: {fileSize} bytes, translated functions: {translatedFuncsCount}).");
}
}
diff --git a/src/ARMeilleure/Translation/PTC/PtcCacheInfo.cs b/src/ARMeilleure/Translation/PTC/PtcCacheInfo.cs
new file mode 100644
index 000000000..9c0c2969a
--- /dev/null
+++ b/src/ARMeilleure/Translation/PTC/PtcCacheInfo.cs
@@ -0,0 +1,37 @@
+namespace ARMeilleure.Translation.PTC
+{
+ public readonly struct PtcCacheInfo
+ {
+ public const string TitleIdTextDefault = "0000000000000000";
+ public const string ApplicationIdTextDefault = "0000000000000000";
+ public const string DisplayVersionDefault = "0";
+
+ public ulong ProcessId { get; }
+ public string TitleIdText { get; }
+ public string ApplicationIdText { get; }
+ public byte ProgramIndex { get; }
+ public string DisplayVersion { get; }
+ public string ProcessKind { get; }
+ public string CacheSelector { get; }
+
+ public string CacheKey => $"{DisplayVersion}-{CacheSelector}";
+
+ public PtcCacheInfo(
+ ulong processId,
+ string titleIdText,
+ string applicationIdText,
+ byte programIndex,
+ string displayVersion,
+ string processKind,
+ string cacheSelector)
+ {
+ ProcessId = processId;
+ TitleIdText = !string.IsNullOrEmpty(titleIdText) ? titleIdText : TitleIdTextDefault;
+ ApplicationIdText = !string.IsNullOrEmpty(applicationIdText) ? applicationIdText : ApplicationIdTextDefault;
+ ProgramIndex = programIndex;
+ DisplayVersion = !string.IsNullOrEmpty(displayVersion) ? displayVersion : DisplayVersionDefault;
+ ProcessKind = processKind ?? string.Empty;
+ CacheSelector = string.IsNullOrEmpty(cacheSelector) ? "default" : cacheSelector;
+ }
+ }
+}
diff --git a/src/ARMeilleure/Translation/PTC/PtcProfiler.cs b/src/ARMeilleure/Translation/PTC/PtcProfiler.cs
index c46d81cf5..5e7c857ba 100644
--- a/src/ARMeilleure/Translation/PTC/PtcProfiler.cs
+++ b/src/ARMeilleure/Translation/PTC/PtcProfiler.cs
@@ -23,7 +23,7 @@ namespace ARMeilleure.Translation.PTC
{
private const string OuterHeaderMagicString = "Pohd\0\0\0\0";
- private const uint InternalVersion = 6698; //! Not to be incremented manually for each change to the ARMeilleure project.
+ private const uint InternalVersion = 7031; //! Not to be incremented manually for each change to the ARMeilleure project.
private static readonly uint[] _migrateInternalVersions =
[
@@ -254,7 +254,12 @@ namespace ARMeilleure.Translation.PTC
long fileSize = new FileInfo(fileName).Length;
- Logger.Info?.Print(LogClass.Ptc, $"{(isBackup ? "Loaded Backup Profiling Info" : "Loaded Profiling Info")} (size: {fileSize} bytes, profiled functions: {ProfiledFuncs.Count}).");
+ Logger.Info?.Print(
+ LogClass.Ptc,
+ $"{(isBackup ? "Loaded Backup Profiling Info" : "Loaded Profiling Info")} " +
+ $"(pid: {_ptc.CacheInfo.ProcessId}, title: {_ptc.CacheInfo.TitleIdText}, version: '{_ptc.CacheInfo.DisplayVersion}', " +
+ $"kind: {_ptc.CacheInfo.ProcessKind}, selector: '{_ptc.CacheInfo.CacheSelector}', key: '{_ptc.CacheInfo.CacheKey}', " +
+ $"path: '{fileName}', size: {fileSize} bytes, profiled functions: {ProfiledFuncs.Count}).");
return true;
}
@@ -375,7 +380,11 @@ namespace ARMeilleure.Translation.PTC
if (fileSize != 0L)
{
- Logger.Info?.Print(LogClass.Ptc, $"Saved Profiling Info (size: {fileSize} bytes, profiled functions: {profiledFuncsCount}).");
+ Logger.Info?.Print(
+ LogClass.Ptc,
+ $"Saved Profiling Info (pid: {_ptc.CacheInfo.ProcessId}, title: {_ptc.CacheInfo.TitleIdText}, version: '{_ptc.CacheInfo.DisplayVersion}', " +
+ $"kind: {_ptc.CacheInfo.ProcessKind}, selector: '{_ptc.CacheInfo.CacheSelector}', key: '{_ptc.CacheInfo.CacheKey}', " +
+ $"path: '{fileName}', size: {fileSize} bytes, profiled functions: {profiledFuncsCount}).");
}
}
diff --git a/src/ARMeilleure/Translation/Translator.cs b/src/ARMeilleure/Translation/Translator.cs
index f96e71199..b4e5952cf 100644
--- a/src/ARMeilleure/Translation/Translator.cs
+++ b/src/ARMeilleure/Translation/Translator.cs
@@ -57,9 +57,9 @@ namespace ARMeilleure.Translation
FunctionTable.Fill = (ulong)Stubs.SlowDispatchStub;
}
- public IPtcLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled, string cacheSelector)
+ public IPtcLoadState LoadDiskCache(PtcCacheInfo cacheInfo, bool enabled)
{
- _ptc.Initialize(titleIdText, displayVersion, enabled, Memory.Type, cacheSelector);
+ _ptc.Initialize(cacheInfo, enabled, Memory.Type);
return _ptc;
}
diff --git a/src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs b/src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs
index 784949441..d485b0f42 100644
--- a/src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs
+++ b/src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs
@@ -1,4 +1,5 @@
using ARMeilleure.Memory;
+using ARMeilleure.Translation.PTC;
using System.Runtime.Versioning;
namespace Ryujinx.Cpu.AppleHv
@@ -32,7 +33,7 @@ namespace Ryujinx.Cpu.AppleHv
{
}
- public IDiskCacheLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled, string cacheSelector)
+ public IDiskCacheLoadState LoadDiskCache(PtcCacheInfo cacheInfo, bool enabled)
{
return new DummyDiskCacheLoadState();
}
diff --git a/src/Ryujinx.Cpu/ICpuContext.cs b/src/Ryujinx.Cpu/ICpuContext.cs
index 1fb3b674d..d943da9d7 100644
--- a/src/Ryujinx.Cpu/ICpuContext.cs
+++ b/src/Ryujinx.Cpu/ICpuContext.cs
@@ -1,4 +1,5 @@
using System;
+using ARMeilleure.Translation.PTC;
namespace Ryujinx.Cpu
{
@@ -44,11 +45,10 @@ namespace Ryujinx.Cpu
///
/// If the execution engine is recompiling guest code, this can be used to load cached code from disk.
///
- /// Title ID of the application in padded hex form
- /// Version of the application
+ /// Identity and selector for the process-owned disk cache
/// True if the cache should be loaded from disk if it exists, false otherwise
/// Disk cache load progress reporter and manager
- IDiskCacheLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled, string cacheSelector);
+ IDiskCacheLoadState LoadDiskCache(PtcCacheInfo cacheInfo, bool enabled);
///
/// Indicates that code has been loaded into guest memory, and that it might be executed in the future.
diff --git a/src/Ryujinx.Cpu/Jit/JitCpuContext.cs b/src/Ryujinx.Cpu/Jit/JitCpuContext.cs
index a29def8e8..b248f9fe2 100644
--- a/src/Ryujinx.Cpu/Jit/JitCpuContext.cs
+++ b/src/Ryujinx.Cpu/Jit/JitCpuContext.cs
@@ -1,6 +1,7 @@
using ARMeilleure.Common;
using ARMeilleure.Memory;
using ARMeilleure.Translation;
+using ARMeilleure.Translation.PTC;
using Ryujinx.Cpu.Signal;
namespace Ryujinx.Cpu.Jit
@@ -49,9 +50,9 @@ namespace Ryujinx.Cpu.Jit
}
///
- public IDiskCacheLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled, string cacheSelector)
+ public IDiskCacheLoadState LoadDiskCache(PtcCacheInfo cacheInfo, bool enabled)
{
- return new JitDiskCacheLoadState(_translator.LoadDiskCache(titleIdText, displayVersion, enabled, cacheSelector));
+ return new JitDiskCacheLoadState(_translator.LoadDiskCache(cacheInfo, enabled));
}
///
diff --git a/src/Ryujinx.Cpu/LightningJit/LightningJitCpuContext.cs b/src/Ryujinx.Cpu/LightningJit/LightningJitCpuContext.cs
index cd38706a0..4745d4052 100644
--- a/src/Ryujinx.Cpu/LightningJit/LightningJitCpuContext.cs
+++ b/src/Ryujinx.Cpu/LightningJit/LightningJitCpuContext.cs
@@ -1,5 +1,6 @@
using ARMeilleure.Common;
using ARMeilleure.Memory;
+using ARMeilleure.Translation.PTC;
using Ryujinx.Cpu.Jit;
using Ryujinx.Cpu.LightningJit.State;
@@ -51,7 +52,7 @@ namespace Ryujinx.Cpu.LightningJit
}
///
- public IDiskCacheLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled, string cacheSelector)
+ public IDiskCacheLoadState LoadDiskCache(PtcCacheInfo cacheInfo, bool enabled)
{
return new DummyDiskCacheLoadState();
}
diff --git a/src/Ryujinx.HLE/HOS/ArmProcessContext.cs b/src/Ryujinx.HLE/HOS/ArmProcessContext.cs
index 9ce57a2a7..2ccba835c 100644
--- a/src/Ryujinx.HLE/HOS/ArmProcessContext.cs
+++ b/src/Ryujinx.HLE/HOS/ArmProcessContext.cs
@@ -1,4 +1,5 @@
using ARMeilleure.Memory;
+using ARMeilleure.Translation.PTC;
using Ryujinx.Cpu;
using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.HOS.Kernel.Process;
@@ -9,12 +10,10 @@ namespace Ryujinx.HLE.HOS
interface IArmProcessContext : IProcessContext
{
IDiskCacheLoadState Initialize(
- string titleIdText,
- string displayVersion,
+ PtcCacheInfo cacheInfo,
bool diskCacheEnabled,
ulong codeAddress,
- ulong codeSize,
- string cacheSelector);
+ ulong codeSize);
}
class ArmProcessContext : IArmProcessContext where T : class, IVirtualMemoryManagerTracked, IMemoryManager
@@ -67,15 +66,13 @@ namespace Ryujinx.HLE.HOS
}
public IDiskCacheLoadState Initialize(
- string titleIdText,
- string displayVersion,
+ PtcCacheInfo cacheInfo,
bool diskCacheEnabled,
ulong codeAddress,
- ulong codeSize,
- string cacheSelector)
+ ulong codeSize)
{
_cpuContext.PrepareCodeRange(codeAddress, codeSize);
- return _cpuContext.LoadDiskCache(titleIdText, displayVersion, diskCacheEnabled, cacheSelector);
+ return _cpuContext.LoadDiskCache(cacheInfo, diskCacheEnabled);
}
public void InvalidateCacheRegion(ulong address, ulong size)
diff --git a/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs b/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs
index ecb3b4dd8..839a9167e 100644
--- a/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs
+++ b/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs
@@ -1,3 +1,4 @@
+using ARMeilleure.Translation.PTC;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Cpu;
@@ -8,6 +9,7 @@ using Ryujinx.Cpu.Nce;
using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.HOS.Kernel;
using Ryujinx.HLE.HOS.Kernel.Process;
+using Ryujinx.HLE.Loaders.Processes;
using Ryujinx.Memory;
using System;
using System.Runtime.InteropServices;
@@ -18,8 +20,10 @@ namespace Ryujinx.HLE.HOS
{
private readonly ITickSource _tickSource;
private readonly GpuContext _gpu;
- private readonly string _titleIdText;
+ private readonly ulong _programId;
+ private readonly byte _programIndex;
private readonly string _displayVersion;
+ private readonly ProcessKind _processKind;
private readonly bool _diskCacheEnabled;
private readonly string _diskCacheSelector;
private readonly ulong _codeAddress;
@@ -30,8 +34,10 @@ namespace Ryujinx.HLE.HOS
public ArmProcessContextFactory(
ITickSource tickSource,
GpuContext gpu,
- string titleIdText,
+ ulong programId,
+ byte programIndex,
string displayVersion,
+ ProcessKind processKind,
bool diskCacheEnabled,
string diskCacheSelector,
ulong codeAddress,
@@ -39,8 +45,10 @@ namespace Ryujinx.HLE.HOS
{
_tickSource = tickSource;
_gpu = gpu;
- _titleIdText = titleIdText;
+ _programId = programId;
+ _programIndex = programIndex;
_displayVersion = displayVersion;
+ _processKind = processKind;
_diskCacheEnabled = diskCacheEnabled;
_diskCacheSelector = diskCacheSelector;
_codeAddress = codeAddress;
@@ -160,8 +168,18 @@ namespace Ryujinx.HLE.HOS
}
string cacheSelector = _diskCacheSelector ?? "default";
+ string programIdText = _programId == 0 ? string.Empty : $"{_programId:x16}";
+ string applicationIdText = _programId == 0 ? string.Empty : $"{_programId & ~0xFul:x16}";
+ PtcCacheInfo cacheInfo = new(
+ pid,
+ programIdText,
+ applicationIdText,
+ _programIndex,
+ _displayVersion,
+ _processKind.ToString(),
+ cacheSelector);
- DiskCacheLoadState = processContext.Initialize(_titleIdText, _displayVersion, _diskCacheEnabled, _codeAddress, _codeSize, cacheSelector);
+ DiskCacheLoadState = processContext.Initialize(cacheInfo, _diskCacheEnabled, _codeAddress, _codeSize);
return processContext;
}
diff --git a/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs b/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs
index 498b6bb7c..c1d70e5cb 100644
--- a/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs
+++ b/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs
@@ -183,8 +183,10 @@ namespace Ryujinx.HLE.Loaders.Processes
ArmProcessContextFactory processContextFactory = new(
context.Device.System.TickSource,
context.Device.Gpu,
- string.Empty,
- string.Empty,
+ kip.ProgramId,
+ 0,
+ kip.Version.ToString(),
+ ProcessResult.GetProcessKind(kip.ProgramId),
false,
null,
codeAddress,
@@ -392,8 +394,10 @@ namespace Ryujinx.HLE.Loaders.Processes
ArmProcessContextFactory processContextFactory = new(
context.Device.System.TickSource,
context.Device.Gpu,
- $"{programId:x16}",
+ programId,
+ programIndex,
displayVersion,
+ ProcessResult.GetProcessKind(programId),
diskCacheEnabled,
diskCacheSelector,
codeStart,
diff --git a/src/Ryujinx.HLE/Loaders/Processes/ProcessResult.cs b/src/Ryujinx.HLE/Loaders/Processes/ProcessResult.cs
index 279268de6..53fdae8e0 100644
--- a/src/Ryujinx.HLE/Loaders/Processes/ProcessResult.cs
+++ b/src/Ryujinx.HLE/Loaders/Processes/ProcessResult.cs
@@ -87,7 +87,7 @@ namespace Ryujinx.HLE.Loaders.Processes
AllowCodeMemoryForJit = allowCodeMemoryForJit;
}
- private static ProcessKind GetProcessKind(ulong programId)
+ internal static ProcessKind GetProcessKind(ulong programId)
{
if (programId == 0)
{