From be6e5e8f23c39b4dae6c3277943876363bf3d58a Mon Sep 17 00:00:00 2001 From: Serge <5920850+seerge@users.noreply.github.com> Date: Sun, 4 Jun 2023 17:21:31 +0200 Subject: [PATCH] Varibright control --- app/Extra.Designer.cs | 57 +++++++++++++++-------- app/Extra.cs | 38 ++++++++++++++++ app/Gpu/AmdAdl2.cs | 58 ++++++++++++++++++++++++ app/Gpu/AmdGpuControl.cs | 97 +++++++++++++++++++++++++++++++--------- 4 files changed, 210 insertions(+), 40 deletions(-) diff --git a/app/Extra.Designer.cs b/app/Extra.Designer.cs index 07189d46..c9ce6a29 100644 --- a/app/Extra.Designer.cs +++ b/app/Extra.Designer.cs @@ -92,6 +92,7 @@ namespace GHelper checkUSBC = new CheckBox(); checkNoOverdrive = new CheckBox(); checkTopmost = new CheckBox(); + checkVariBright = new CheckBox(); groupBindings.SuspendLayout(); tableKeys.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)pictureHelp).BeginInit(); @@ -778,18 +779,19 @@ namespace GHelper // groupOther.AutoSize = true; groupOther.AutoSizeMode = AutoSizeMode.GrowAndShrink; - groupOther.Controls.Add(checkFnLock); - groupOther.Controls.Add(checkGpuApps); groupOther.Controls.Add(checkAutoApplyWindowsPowerMode); - groupOther.Controls.Add(checkUSBC); - groupOther.Controls.Add(checkNoOverdrive); groupOther.Controls.Add(checkTopmost); + groupOther.Controls.Add(checkNoOverdrive); + groupOther.Controls.Add(checkUSBC); + groupOther.Controls.Add(checkVariBright); + groupOther.Controls.Add(checkGpuApps); + groupOther.Controls.Add(checkFnLock); groupOther.Dock = DockStyle.Top; groupOther.Location = new Point(9, 946); groupOther.Margin = new Padding(4, 2, 4, 2); groupOther.Name = "groupOther"; - groupOther.Padding = new Padding(4, 2, 4, 0); - groupOther.Size = new Size(966, 320); + groupOther.Padding = new Padding(20, 2, 4, 10); + groupOther.Size = new Size(966, 296); groupOther.TabIndex = 2; groupOther.TabStop = false; groupOther.Text = "Other"; @@ -797,11 +799,12 @@ namespace GHelper // checkFnLock // checkFnLock.AutoSize = true; - checkFnLock.Location = new Point(24, 45); + checkFnLock.Dock = DockStyle.Top; + checkFnLock.Location = new Point(20, 34); checkFnLock.Margin = new Padding(4, 2, 4, 2); checkFnLock.MaximumSize = new Size(780, 0); checkFnLock.Name = "checkFnLock"; - checkFnLock.Size = new Size(397, 36); + checkFnLock.Size = new Size(780, 36); checkFnLock.TabIndex = 49; checkFnLock.Text = "Process Fn+F hotkeys without Fn"; checkFnLock.UseVisualStyleBackColor = true; @@ -809,10 +812,11 @@ namespace GHelper // checkGpuApps // checkGpuApps.AutoSize = true; - checkGpuApps.Location = new Point(24, 83); + checkGpuApps.Dock = DockStyle.Top; + checkGpuApps.Location = new Point(20, 70); checkGpuApps.Margin = new Padding(4, 2, 4, 2); checkGpuApps.Name = "checkGpuApps"; - checkGpuApps.Size = new Size(544, 36); + checkGpuApps.Size = new Size(942, 36); checkGpuApps.TabIndex = 48; checkGpuApps.Text = "Stop all apps using GPU when switching to Eco"; checkGpuApps.UseVisualStyleBackColor = true; @@ -820,10 +824,11 @@ namespace GHelper // checkAutoApplyWindowsPowerMode // checkAutoApplyWindowsPowerMode.AutoSize = true; - checkAutoApplyWindowsPowerMode.Location = new Point(24, 250); + checkAutoApplyWindowsPowerMode.Dock = DockStyle.Top; + checkAutoApplyWindowsPowerMode.Location = new Point(20, 250); checkAutoApplyWindowsPowerMode.Margin = new Padding(4, 2, 4, 2); checkAutoApplyWindowsPowerMode.Name = "checkAutoApplyWindowsPowerMode"; - checkAutoApplyWindowsPowerMode.Size = new Size(416, 36); + checkAutoApplyWindowsPowerMode.Size = new Size(942, 36); checkAutoApplyWindowsPowerMode.TabIndex = 47; checkAutoApplyWindowsPowerMode.Text = "Auto Adjust Windows Power Mode"; checkAutoApplyWindowsPowerMode.UseVisualStyleBackColor = true; @@ -831,10 +836,11 @@ namespace GHelper // checkUSBC // checkUSBC.AutoSize = true; - checkUSBC.Location = new Point(24, 126); + checkUSBC.Dock = DockStyle.Top; + checkUSBC.Location = new Point(20, 142); checkUSBC.Margin = new Padding(4, 2, 4, 2); checkUSBC.Name = "checkUSBC"; - checkUSBC.Size = new Size(659, 36); + checkUSBC.Size = new Size(942, 36); checkUSBC.TabIndex = 4; checkUSBC.Text = "Keep GPU disabled on USB-C charger in Optimized mode"; checkUSBC.UseVisualStyleBackColor = true; @@ -842,10 +848,11 @@ namespace GHelper // checkNoOverdrive // checkNoOverdrive.AutoSize = true; - checkNoOverdrive.Location = new Point(24, 166); + checkNoOverdrive.Dock = DockStyle.Top; + checkNoOverdrive.Location = new Point(20, 178); checkNoOverdrive.Margin = new Padding(4, 2, 4, 2); checkNoOverdrive.Name = "checkNoOverdrive"; - checkNoOverdrive.Size = new Size(307, 36); + checkNoOverdrive.Size = new Size(942, 36); checkNoOverdrive.TabIndex = 3; checkNoOverdrive.Text = Strings.DisableOverdrive; checkNoOverdrive.UseVisualStyleBackColor = true; @@ -853,14 +860,27 @@ namespace GHelper // checkTopmost // checkTopmost.AutoSize = true; - checkTopmost.Location = new Point(24, 209); + checkTopmost.Dock = DockStyle.Top; + checkTopmost.Location = new Point(20, 214); checkTopmost.Margin = new Padding(4, 2, 4, 2); checkTopmost.Name = "checkTopmost"; - checkTopmost.Size = new Size(390, 36); + checkTopmost.Size = new Size(942, 36); checkTopmost.TabIndex = 1; checkTopmost.Text = Strings.WindowTop; checkTopmost.UseVisualStyleBackColor = true; // + // checkVariBright + // + checkVariBright.AutoSize = true; + checkVariBright.Dock = DockStyle.Top; + checkVariBright.Location = new Point(20, 106); + checkVariBright.Margin = new Padding(4, 2, 4, 2); + checkVariBright.Name = "checkVariBright"; + checkVariBright.Size = new Size(942, 36); + checkVariBright.TabIndex = 50; + checkVariBright.Text = "AMD Display VariBright"; + checkVariBright.UseVisualStyleBackColor = true; + // // Extra // AutoScaleDimensions = new SizeF(13F, 32F); @@ -965,5 +985,6 @@ namespace GHelper private Label labelFNC; private RComboBox comboFNC; private TextBox textFNC; + private CheckBox checkVariBright; } } \ No newline at end of file diff --git a/app/Extra.cs b/app/Extra.cs index d3417b93..297b7274 100644 --- a/app/Extra.cs +++ b/app/Extra.cs @@ -1,4 +1,5 @@ using CustomControls; +using GHelper.Gpu; using Microsoft.VisualBasic.Devices; using System.Diagnostics; @@ -227,6 +228,43 @@ namespace GHelper checkFnLock.CheckedChanged += CheckFnLock_CheckedChanged; ; pictureHelp.Click += PictureHelp_Click; + + InitVariBright(); + } + + private void InitVariBright() + { + try + { + using (var amdControl = new AmdGpuControl()) + { + int variBrightSupported = 0, VariBrightEnabled; + if (amdControl.GetVariBright(out variBrightSupported, out VariBrightEnabled)) + { + Logger.WriteLine("Varibright: " + variBrightSupported + "," + VariBrightEnabled); + checkVariBright.Checked = (VariBrightEnabled == 3); + } + + checkVariBright.Visible = (variBrightSupported > 0); + checkVariBright.CheckedChanged += CheckVariBright_CheckedChanged; + } + + } catch (Exception ex) + { + Debug.WriteLine(ex.ToString()); + checkVariBright.Visible = false; + } + + + } + + private void CheckVariBright_CheckedChanged(object? sender, EventArgs e) + { + using (var amdControl = new AmdGpuControl()) + { + amdControl.SetVariBright(checkVariBright.Checked ? 1 : 0); + ProcessHelper.KillByName("RadeonSoftware"); + } } private void CheckFnLock_CheckedChanged(object? sender, EventArgs e) diff --git a/app/Gpu/AmdAdl2.cs b/app/Gpu/AmdAdl2.cs index df92189a..6123c891 100644 --- a/app/Gpu/AmdAdl2.cs +++ b/app/Gpu/AmdAdl2.cs @@ -1,5 +1,6 @@ using System.Diagnostics; using System.Runtime.InteropServices; +using static AmdAdl2.Adl2.NativeMethods; namespace AmdAdl2; @@ -515,6 +516,63 @@ public class Adl2 { out int lpNumApps, out IntPtr lppAppList); + [DllImport(Atiadlxx_FileName)] + public static extern int ADL2_Adapter_VariBright_Caps( + IntPtr context, + int iAdapterIndex, + out int iSupported, + out int iEnabled, + out int iVersion); + [DllImport(Atiadlxx_FileName)] + public static extern int ADL2_Adapter_VariBrightEnable_Set( + IntPtr context, + int iAdapterIndex, + int iEnabled); + + // Clocks + + [StructLayout(LayoutKind.Sequential)] + public struct ADLODNPerformanceLevel + { + public int iClock; + public int iVddc; + public int iEnabled; + } + + [StructLayout(LayoutKind.Sequential)] + public struct ADLODNPerformanceLevels + { + public int iSize; + public int iMode; + public int iNumberOfPerformanceLevels; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public ADLODNPerformanceLevel[] aLevels; + } + + + [DllImport(Atiadlxx_FileName)] + public static extern int ADL2_OverdriveN_SystemClocks_Get( + IntPtr context, + int adapterIndex, + ref ADLODNPerformanceLevels performanceLevels); + + [DllImport(Atiadlxx_FileName)] + public static extern int ADL2_OverdriveN_SystemClocks_Set( + IntPtr context, + int adapterIndex, + ref ADLODNPerformanceLevels performanceLevels); + + [DllImport(Atiadlxx_FileName)] + public static extern int ADL2_OverdriveN_MemoryClocks_Get( + IntPtr context, + int adapterIndex, + ref ADLODNPerformanceLevels performanceLevels); + + [DllImport(Atiadlxx_FileName)] + public static extern int ADL2_OverdriveN_MemoryClocks_Set( + IntPtr context, + int adapterIndex, + ref ADLODNPerformanceLevels performanceLevels); } } diff --git a/app/Gpu/AmdGpuControl.cs b/app/Gpu/AmdGpuControl.cs index 2083d5c1..919d2072 100644 --- a/app/Gpu/AmdGpuControl.cs +++ b/app/Gpu/AmdGpuControl.cs @@ -1,6 +1,6 @@ using AmdAdl2; -using System.Diagnostics; using System.Runtime.InteropServices; +using static AmdAdl2.Adl2.NativeMethods; namespace GHelper.Gpu; @@ -14,24 +14,19 @@ public class AmdGpuControl : IGpuControl public bool IsNvidia => false; public string FullName => _internalDiscreteAdapter!.AdapterName; - public AmdGpuControl() + + private ADLAdapterInfo? FindByType(ADLAsicFamilyType type = ADLAsicFamilyType.Discrete) { - if (!Adl2.Load()) - return; - - if (Adl2.ADL2_Main_Control_Create(1, out _adlContextHandle) != Adl2.ADL_SUCCESS) - return; - - Adl2.NativeMethods.ADL2_Adapter_NumberOfAdapters_Get(_adlContextHandle, out int numberOfAdapters); + ADL2_Adapter_NumberOfAdapters_Get(_adlContextHandle, out int numberOfAdapters); if (numberOfAdapters <= 0) - return; + return null; ADLAdapterInfoArray osAdapterInfoData = new(); int osAdapterInfoDataSize = Marshal.SizeOf(osAdapterInfoData); IntPtr AdapterBuffer = Marshal.AllocCoTaskMem(osAdapterInfoDataSize); Marshal.StructureToPtr(osAdapterInfoData, AdapterBuffer, false); - if (Adl2.NativeMethods.ADL2_Adapter_AdapterInfo_Get(_adlContextHandle, AdapterBuffer, osAdapterInfoDataSize) != Adl2.ADL_SUCCESS) - return; + if (ADL2_Adapter_AdapterInfo_Get(_adlContextHandle, AdapterBuffer, osAdapterInfoDataSize) != Adl2.ADL_SUCCESS) + return null; osAdapterInfoData = (ADLAdapterInfoArray)Marshal.PtrToStructure(AdapterBuffer, osAdapterInfoData.GetType())!; @@ -48,20 +43,37 @@ public class AmdGpuControl : IGpuControl if (adapter.VendorID != amdVendorId) return false; - if (Adl2.NativeMethods.ADL2_Adapter_ASICFamilyType_Get(_adlContextHandle, adapter.AdapterIndex, out ADLAsicFamilyType asicFamilyType, out int asicFamilyTypeValids) != Adl2.ADL_SUCCESS) + if (ADL2_Adapter_ASICFamilyType_Get(_adlContextHandle, adapter.AdapterIndex, out ADLAsicFamilyType asicFamilyType, out int asicFamilyTypeValids) != Adl2.ADL_SUCCESS) return false; asicFamilyType = (ADLAsicFamilyType)((int)asicFamilyType & asicFamilyTypeValids); - // FIXME: is this correct for G14 2022? - return (asicFamilyType & ADLAsicFamilyType.Discrete) != 0; + return (asicFamilyType & type) != 0; }); if (internalDiscreteAdapter.Exist == 0) + return null; + + return internalDiscreteAdapter; + + } + + public AmdGpuControl() + { + if (!Adl2.Load()) return; - _internalDiscreteAdapter = internalDiscreteAdapter; - _isReady = true; + if (Adl2.ADL2_Main_Control_Create(1, out _adlContextHandle) != Adl2.ADL_SUCCESS) + return; + + ADLAdapterInfo? internalDiscreteAdapter = FindByType(ADLAsicFamilyType.Discrete); + + if (internalDiscreteAdapter is not null) + { + _internalDiscreteAdapter = (ADLAdapterInfo)internalDiscreteAdapter; + _isReady = true; + } + } public bool IsValid => _isReady && _adlContextHandle != IntPtr.Zero; @@ -71,7 +83,7 @@ public class AmdGpuControl : IGpuControl if (!IsValid) return null; - if (Adl2.NativeMethods.ADL2_New_QueryPMLogData_Get(_adlContextHandle, _internalDiscreteAdapter.AdapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput) != Adl2.ADL_SUCCESS) + if (ADL2_New_QueryPMLogData_Get(_adlContextHandle, _internalDiscreteAdapter.AdapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput) != Adl2.ADL_SUCCESS) return null; ADLSingleSensorData temperatureSensor = adlpmLogDataOutput.Sensors[(int)ADLSensorType.PMLOG_TEMPERATURE_EDGE]; @@ -86,7 +98,7 @@ public class AmdGpuControl : IGpuControl { if (!IsValid) return null; - if (Adl2.NativeMethods.ADL2_New_QueryPMLogData_Get(_adlContextHandle, _internalDiscreteAdapter.AdapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput) != Adl2.ADL_SUCCESS) + if (ADL2_New_QueryPMLogData_Get(_adlContextHandle, _internalDiscreteAdapter.AdapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput) != Adl2.ADL_SUCCESS) return null; ADLSingleSensorData gpuUsage = adlpmLogDataOutput.Sensors[(int)ADLSensorType.PMLOG_INFO_ACTIVITY_GFX]; @@ -97,6 +109,46 @@ public class AmdGpuControl : IGpuControl } + + public bool SetVariBright(int enabled) + { + if (_adlContextHandle == IntPtr.Zero) return false; + + ADLAdapterInfo? iGPU = FindByType(ADLAsicFamilyType.Integrated); + if (iGPU is null) return false; + + return ADL2_Adapter_VariBrightEnable_Set(_adlContextHandle, ((ADLAdapterInfo)iGPU).AdapterIndex, enabled) == Adl2.ADL_SUCCESS; + + } + + public bool GetVariBright(out int supported, out int enabled) + { + supported = enabled = -1; + + if (_adlContextHandle == IntPtr.Zero) return false; + + ADLAdapterInfo? iGPU = FindByType(ADLAsicFamilyType.Integrated); + if (iGPU is null) return false; + + if (ADL2_Adapter_VariBright_Caps(_adlContextHandle, ((ADLAdapterInfo)iGPU).AdapterIndex, out int supportedOut, out int enabledOut, out int version) != Adl2.ADL_SUCCESS) + return false; + + supported = supportedOut; + enabled = enabledOut; + + return true; + } + + public ADLODNPerformanceLevels? GetGPUClocks() + { + if (!IsValid) return null; + + ADLODNPerformanceLevels performanceLevels = new(); + ADL2_OverdriveN_SystemClocks_Get(_adlContextHandle, _internalDiscreteAdapter.AdapterIndex, ref performanceLevels); + + return performanceLevels; + } + public void KillGPUApps() { @@ -108,7 +160,7 @@ public class AmdGpuControl : IGpuControl try { // Get switchable graphics applications information - var result = Adl2.NativeMethods.ADL2_SwitchableGraphics_Applications_Get(_adlContextHandle, 2, out appCount, out appInfoPtr); + var result = ADL2_SwitchableGraphics_Applications_Get(_adlContextHandle, 2, out appCount, out appInfoPtr); if (result != 0) { throw new Exception("Failed to get switchable graphics applications. Error code: " + result); @@ -138,7 +190,8 @@ public class AmdGpuControl : IGpuControl foreach (string kill in appNames) ProcessHelper.KillByName(kill); - } catch (Exception ex) + } + catch (Exception ex) { Logger.WriteLine(ex.Message); } @@ -158,7 +211,7 @@ public class AmdGpuControl : IGpuControl { if (_adlContextHandle != IntPtr.Zero) { - Adl2.NativeMethods.ADL2_Main_Control_Destroy(_adlContextHandle); + ADL2_Main_Control_Destroy(_adlContextHandle); _adlContextHandle = IntPtr.Zero; _isReady = false; }