diff --git a/Ryujinx.Profiler/Profile.cs b/Ryujinx.Profiler/Profile.cs
index 8869865e51..ac980789c2 100644
--- a/Ryujinx.Profiler/Profile.cs
+++ b/Ryujinx.Profiler/Profile.cs
@@ -1,4 +1,5 @@
-using System;
+using Ryujinx.Common;
+using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -12,6 +13,23 @@ namespace Ryujinx.Profiler
private static InternalProfile _profileInstance;
private static ProfilerSettings _settings;
+
+ [Conditional("USE_PROFILING")]
+ public static void Initalize()
+ {
+ var config = ProfilerConfiguration.Load("ProfilerConfig.jsonc");
+
+ _settings = new ProfilerSettings()
+ {
+ Enabled = config.Enabled,
+ FileDumpEnabled = config.DumpPath != "",
+ DumpLocation = config.DumpPath,
+ UpdateRate = (config.UpdateRate <= 0) ? -1 : 1.0f / config.UpdateRate,
+ History = (long)(config.History * PerformanceCounter.TicksPerSecond),
+ MaxLevel = config.MaxLevel,
+ };
+ }
+
public static bool ProfilingEnabled()
{
#if USE_PROFILING
@@ -27,12 +45,6 @@ namespace Ryujinx.Profiler
#endif
}
- [Conditional("USE_PROFILING")]
- public static void Configure(ProfilerSettings settings)
- {
- _settings = settings;
- }
-
[Conditional("USE_PROFILING")]
public static void FinishProfiling()
{
diff --git a/Ryujinx.Profiler/ProfilerConfig.jsonc b/Ryujinx.Profiler/ProfilerConfig.jsonc
new file mode 100644
index 0000000000..e716aebd4b
--- /dev/null
+++ b/Ryujinx.Profiler/ProfilerConfig.jsonc
@@ -0,0 +1,18 @@
+{
+ "$schema": "./_schema.json",
+
+ // Enable profiling (Only available on a profiling enabled build)
+ "enabled": true,
+
+ // Set profile file dump location, if blank file dumping disabled. (e.g. `ProfileDump.csv`)
+ "dump_path": "",
+
+ // Update rate for profiler UI, in hertz. -1 updates every time a frame is issued
+ "update_rate": 4,
+
+ // Set how long to keep profiling data in seconds, reduce if profiling is taking too much RAM
+ "history": 5,
+
+ // Set the maximum profiling level. Higher values may cause a heavy load on your system but will allow you to profile in more detail
+ "max_level": 0
+}
\ No newline at end of file
diff --git a/Ryujinx.Profiler/ProfilerConfiguration.cs b/Ryujinx.Profiler/ProfilerConfiguration.cs
new file mode 100644
index 0000000000..411bcd3843
--- /dev/null
+++ b/Ryujinx.Profiler/ProfilerConfiguration.cs
@@ -0,0 +1,70 @@
+using OpenTK.Input;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+using Utf8Json;
+using Utf8Json.Resolvers;
+
+namespace Ryujinx.Profiler
+{
+ public class ProfilerConfiguration
+ {
+ public bool Enabled { get; private set; }
+ public string DumpPath { get; private set; }
+ public float UpdateRate { get; private set; }
+ public int MaxLevel { get; private set; }
+ public float History { get; private set; }
+
+ ///
+ /// Loads a configuration file from disk
+ ///
+ /// The path to the JSON configuration file
+ public static ProfilerConfiguration Load(string path)
+ {
+ var resolver = CompositeResolver.Create(
+ new[] { new ConfigurationEnumFormatter() },
+ new[] { StandardResolver.AllowPrivateSnakeCase }
+ );
+
+ if (!File.Exists(path))
+ {
+ throw new FileNotFoundException($"Profiler configuration file {path} not found");
+ }
+
+ using (Stream stream = File.OpenRead(path))
+ {
+ return JsonSerializer.Deserialize(stream, resolver);
+ }
+ }
+
+ private class ConfigurationEnumFormatter : IJsonFormatter
+ where T : struct
+ {
+ public void Serialize(ref JsonWriter writer, T value, IJsonFormatterResolver formatterResolver)
+ {
+ formatterResolver.GetFormatterWithVerify()
+ .Serialize(ref writer, value.ToString(), formatterResolver);
+ }
+
+ public T Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver)
+ {
+ if (reader.ReadIsNull())
+ {
+ return default(T);
+ }
+
+ var enumName = formatterResolver.GetFormatterWithVerify()
+ .Deserialize(ref reader, formatterResolver);
+
+ if (Enum.TryParse(enumName, out T result))
+ {
+ return result;
+ }
+
+ return default(T);
+ }
+ }
+ }
+}
diff --git a/Ryujinx.Profiler/Ryujinx.Profiler.csproj b/Ryujinx.Profiler/Ryujinx.Profiler.csproj
index 2115f6d7d2..5a4c8f4f92 100644
--- a/Ryujinx.Profiler/Ryujinx.Profiler.csproj
+++ b/Ryujinx.Profiler/Ryujinx.Profiler.csproj
@@ -30,4 +30,10 @@
+
+
+ PreserveNewest
+
+
+
diff --git a/Ryujinx/Program.cs b/Ryujinx/Program.cs
index c14db0e765..3b65ea7774 100644
--- a/Ryujinx/Program.cs
+++ b/Ryujinx/Program.cs
@@ -26,6 +26,8 @@ namespace Ryujinx
Configuration.Load(Path.Combine(ApplicationDirectory, "Config.jsonc"));
Configuration.Configure(device);
+ Profile.Initalize();
+
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;