From 6240ee4c46b18d0b99d9a8553b515555df326dfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Wed, 8 Feb 2023 14:09:19 +0100 Subject: [PATCH] PowerControl: Allow user to configure selectable TDP, CPU and GPU from `PowerControl.dll.ini` --- PowerControl/Options/CPUFrequency.cs | 63 +++++++++++++++------------- PowerControl/Options/GPUFrequency.cs | 46 +++++++++++++++----- PowerControl/Options/TDP.cs | 51 +++++++++++++++++----- PowerControl/PersistedOptions.cs | 56 +++++++++++++++++++++++++ RELEASE.md | 1 + 5 files changed, 168 insertions(+), 49 deletions(-) create mode 100644 PowerControl/PersistedOptions.cs diff --git a/PowerControl/Options/CPUFrequency.cs b/PowerControl/Options/CPUFrequency.cs index 466534c..2a55048 100644 --- a/PowerControl/Options/CPUFrequency.cs +++ b/PowerControl/Options/CPUFrequency.cs @@ -5,16 +5,40 @@ namespace PowerControl.Options { public static class CPUFrequency { + public const string SoftMin = "SoftMin"; + public const string SoftMax = "SoftMax"; + + public const int DefaultMin = 1400; + public const int DefaultMax = 3500; + + public static PersistedOptions UserOptions() + { + var options = new PersistedOptions("CPUFrequency"); + + if (options.GetOptions().Count() == 0) + { + options.SetOptions(new PersistedOptions.Option[] + { + options.ForOption("Default").Set(SoftMin, DefaultMin).Set(SoftMax, DefaultMax), + options.ForOption("Power-Save").Set(SoftMin, 1400).Set(SoftMax, 1800), + options.ForOption("Balanced").Set(SoftMin, 2200).Set(SoftMax, 2800), + options.ForOption("Max").Set(SoftMin, 3000).Set(SoftMax, 3500), + }); + } + + return options; + } + public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions() { Name = "CPU", PersistentKey = "CPUFrequency", PersistOnCreate = false, - Options = { "Default", "Power-Save", "Balanced", "Max" }, + OptionsValues = () => { return UserOptions().GetOptions(); }, ApplyDelay = 1000, ActiveOption = "?", Visible = VangoghGPU.IsSupported, - ResetValue = () => { return "Default"; }, + ResetValue = () => { return UserOptions().GetOptions().FirstOrDefault("Default"); }, ApplyValue = (selected) => { if (!AntiCheatSettings.Default.AckAntiCheat( @@ -23,6 +47,13 @@ namespace PowerControl.Options "Leave the game if it uses anti-cheat protection.")) return null; + var selectedOption = UserOptions().ForOption(selected); + if (!selectedOption.Exist) + return null; + + var softMin = selectedOption.Get(SoftMin, DefaultMin); + var softMax = selectedOption.Get(SoftMax, DefaultMax); + return CommonHelpers.Instance.WithGlobalMutex(200, () => { using (var sd = VangoghGPU.Open()) @@ -30,32 +61,8 @@ namespace PowerControl.Options if (sd is null) return null; - switch (selected.ToString()) - { - case "?": - case "Default": - sd.MinCPUClock = 1400; - sd.MaxCPUClock = 3500; - break; - - case "Power-Save": - sd.MinCPUClock = 1400; - sd.MaxCPUClock = 1800; - break; - - case "Balanced": - sd.MinCPUClock = 2200; - sd.MaxCPUClock = 2800; - break; - - case "Max": - sd.MinCPUClock = 3000; - sd.MaxCPUClock = 3500; - break; - - default: - return null; - } + sd.MinCPUClock = (uint)softMin; + sd.MaxCPUClock = (uint)softMax; return selected; } }); diff --git a/PowerControl/Options/GPUFrequency.cs b/PowerControl/Options/GPUFrequency.cs index 3f5cc42..67cd637 100644 --- a/PowerControl/Options/GPUFrequency.cs +++ b/PowerControl/Options/GPUFrequency.cs @@ -5,16 +5,41 @@ namespace PowerControl.Options { public static class GPUFrequency { + public const string HardMin = "HardMin"; + public const string SoftMax = "SoftMax"; + + public const int DefaultMin = 200; + public const int DefaultMax = 1600; + + public static PersistedOptions UserOptions() + { + var options = new PersistedOptions("GPUFrequency"); + + if (options.GetOptions().Count() == 0) + { + options.SetOptions(new PersistedOptions.Option[] + { + options.ForOption("Default").Set(HardMin, DefaultMin).Set(SoftMax, DefaultMax), + options.ForOption("400MHz").Set(HardMin, 400).Set(SoftMax, DefaultMax), + options.ForOption("800MHz").Set(HardMin, 800).Set(SoftMax, DefaultMax), + options.ForOption("1200MHz").Set(HardMin, 1200).Set(SoftMax, DefaultMax), + options.ForOption("1600MHz").Set(HardMin, 1600).Set(SoftMax, DefaultMax), + }); + } + + return options; + } + public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions() { Name = "GPU", PersistentKey = "GPUFrequency", PersistOnCreate = false, - Options = { "Default", "400MHz", "800MHz", "1200MHz", "1600MHz" }, + OptionsValues = () => { return UserOptions().GetOptions(); }, ApplyDelay = 1000, Visible = VangoghGPU.IsSupported, ActiveOption = "?", - ResetValue = () => { return "Default"; }, + ResetValue = () => { return UserOptions().GetOptions().FirstOrDefault("Default"); }, ApplyValue = (selected) => { if (!AntiCheatSettings.Default.AckAntiCheat( @@ -23,8 +48,12 @@ namespace PowerControl.Options "Leave the game if it uses anti-cheat protection.")) return null; - if (selected == "?") - selected = "Default"; + var selectedOption = UserOptions().ForOption(selected); + if (!selectedOption.Exist) + return null; + + var hardMin = selectedOption.Get(HardMin, DefaultMin); + var softMax = selectedOption.Get(SoftMax, DefaultMax); return CommonHelpers.Instance.WithGlobalMutex(200, () => { @@ -33,13 +62,8 @@ namespace PowerControl.Options if (sd is null) return null; - if (selected == "Default" || selected == "?") - { - sd.HardMinGfxClock = 200; - return selected; - } - - sd.HardMinGfxClock = uint.Parse(selected.Replace("MHz", "")); + sd.HardMinGfxClock = (uint)hardMin; + sd.SoftMaxGfxClock = (uint)softMax; return selected; } }); diff --git a/PowerControl/Options/TDP.cs b/PowerControl/Options/TDP.cs index 1e6346c..70d80df 100644 --- a/PowerControl/Options/TDP.cs +++ b/PowerControl/Options/TDP.cs @@ -6,12 +6,42 @@ namespace PowerControl.Options { public static class TDP { + public const string SlowTDP = "SlowTDP"; + public const string FastTDP = "FastTDP"; + + public const int DefaultSlowTDP = 15000; + public const int DefaultFastTDP = 15000; + + public static PersistedOptions UserOptions() + { + var options = new PersistedOptions("TDP"); + + if (options.GetOptions().Count() == 0) + { + options.SetOptions(new PersistedOptions.Option[] + { + options.ForOption("3W").Set(SlowTDP, 3000).Set(FastTDP, 3000), + options.ForOption("4W").Set(SlowTDP, 4000).Set(FastTDP, 4000), + options.ForOption("5W").Set(SlowTDP, 5000).Set(FastTDP, 5000), + options.ForOption("6W").Set(SlowTDP, 6000).Set(FastTDP, 6000), + options.ForOption("7W").Set(SlowTDP, 7000).Set(FastTDP, 7000), + options.ForOption("8W").Set(SlowTDP, 8000).Set(FastTDP, 8000), + options.ForOption("9W").Set(SlowTDP, 9000).Set(FastTDP, 9000), + options.ForOption("10W").Set(SlowTDP, 10000).Set(FastTDP, 10000), + options.ForOption("12W").Set(SlowTDP, 12000).Set(FastTDP, 12000), + options.ForOption("15W").Set(SlowTDP, 15000).Set(FastTDP, 15000), + }); + } + + return options; + } + public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions() { Name = "TDP", PersistentKey = "TDP", PersistOnCreate = false, - Options = { "3W", "4W", "5W", "6W", "7W", "8W", "10W", "12W", "15W" }, + OptionsValues = () => { return UserOptions().GetOptions(); }, ApplyDelay = 1000, ResetValue = () => { return "15W"; }, ActiveOption = "?", @@ -23,11 +53,12 @@ namespace PowerControl.Options "Leave the game if it uses anti-cheat protection.")) return null; - // If undefined, select max - if (selected == "?") - selected = "15W"; + var selectedOption = UserOptions().ForOption(selected); + if (!selectedOption.Exist) + return null; - uint mW = uint.Parse(selected.Replace("W", "")) * 1000; + var slowTDP = selectedOption.Get(SlowTDP, DefaultSlowTDP); + var fastTDP = selectedOption.Get(FastTDP, DefaultFastTDP); if (VangoghGPU.IsSupported) { @@ -38,8 +69,8 @@ namespace PowerControl.Options if (sd is null) return null; - sd.SlowTDP = mW; - sd.FastTDP = mW; + sd.SlowTDP = (uint)slowTDP; + sd.FastTDP = (uint)fastTDP; } return selected; @@ -47,15 +78,15 @@ namespace PowerControl.Options } else { - uint stampLimit = mW / 10; + int stampLimit = slowTDP / 10; Process.Start(new ProcessStartInfo() { FileName = "Resources/RyzenAdj/ryzenadj.exe", ArgumentList = { "--stapm-limit=" + stampLimit.ToString(), - "--slow-limit=" + mW.ToString(), - "--fast-limit=" + mW.ToString(), + "--slow-limit=" + slowTDP.ToString(), + "--fast-limit=" + fastTDP.ToString(), }, WindowStyle = ProcessWindowStyle.Hidden, UseShellExecute = false, diff --git a/PowerControl/PersistedOptions.cs b/PowerControl/PersistedOptions.cs new file mode 100644 index 0000000..7a1c716 --- /dev/null +++ b/PowerControl/PersistedOptions.cs @@ -0,0 +1,56 @@ +namespace PowerControl +{ + public class PersistedOptions : CommonHelpers.BaseSettings + { + public const string OptionsKey = "Options"; + + public PersistedOptions(string name) : base(name + "Options") + { + } + + public struct Option + { + public PersistedOptions Options { get; set; } + public string Key { get; set; } + + public string FullKey(string setting) + { + return String.Format("{0}_{1}", Key, setting); + } + + public bool Exist + { + get => Options.GetOptions().Contains(Key); + } + + public Option Set(string setting, T value) + { + // Get and persist value on first access + Options.Get(FullKey(setting), value, true); + return this; + } + + public T Get(string setting, T defaultValue) + { + // Get and do not persist value + return Options.Get(FullKey(setting), defaultValue, false); + } + } + + public Option ForOption(string option) + { + return new Option() { Options = this, Key = option }; + } + + public void SetOptions(IEnumerable