From 62ac478761ffbe1e6dc200fc622950342dc3fda1 Mon Sep 17 00:00:00 2001 From: Serhii Yolkin Date: Mon, 13 Mar 2023 17:35:35 +0100 Subject: [PATCH 01/11] feat: added GPU temperature indication. Supports both NVIDIA and AMD discrete GPUs feat: immediately update sensors when opening GHelper window --- GHelper.csproj | 1 + Gpu/AmdAdl2.cs | 485 ++++++++++++++++++++++++++++ Gpu/AmdGpuTemperatureProvider.cs | 92 ++++++ Gpu/IGpuTemperatureProvider.cs | 6 + Gpu/NvidiaGpuTemperatureProvider.cs | 44 +++ Program.cs | 42 ++- Settings.cs | 5 + 7 files changed, 674 insertions(+), 1 deletion(-) create mode 100644 Gpu/AmdAdl2.cs create mode 100644 Gpu/AmdGpuTemperatureProvider.cs create mode 100644 Gpu/IGpuTemperatureProvider.cs create mode 100644 Gpu/NvidiaGpuTemperatureProvider.cs diff --git a/GHelper.csproj b/GHelper.csproj index ed4be555..a88c141b 100644 --- a/GHelper.csproj +++ b/GHelper.csproj @@ -39,6 +39,7 @@ + diff --git a/Gpu/AmdAdl2.cs b/Gpu/AmdAdl2.cs new file mode 100644 index 00000000..8a0813d8 --- /dev/null +++ b/Gpu/AmdAdl2.cs @@ -0,0 +1,485 @@ +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace AmdAdl2; + +#region Export Struct + +[StructLayout(LayoutKind.Sequential)] +public struct ADLSingleSensorData { + public int Supported; + public int Value; +} + +[StructLayout(LayoutKind.Sequential)] +public struct ADLPMLogDataOutput { + int Size; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Adl2.ADL_PMLOG_MAX_SENSORS)] + public ADLSingleSensorData[] Sensors; +} + +[StructLayout(LayoutKind.Sequential)] +public struct ADLGcnInfo +{ + public int CuCount; //Number of compute units on the ASIC. + public int TexCount; //Number of texture mapping units. + public int RopCount; //Number of Render backend Units. + public int ASICFamilyId; //Such SI, VI. See /inc/asic_reg/atiid.h for family ids + public int ASICRevisionId; //Such as Ellesmere, Fiji. For example - VI family revision ids are stored in /inc/asic_reg/vi_id.h +} + +[Flags] +public enum ADLAsicFamilyType { + Undefined = 0, + Discrete = 1 << 0, + Integrated = 1 << 1, + Workstation = 1 << 2, + FireMV = 1 << 3, + Xgp = 1 << 4, + Fusion = 1 << 5, + Firestream = 1 << 6, + Embedded = 1 << 7, +} + +public enum ADLSensorType { + SENSOR_MAXTYPES = 0, + PMLOG_CLK_GFXCLK = 1, // Current graphic clock value in MHz + PMLOG_CLK_MEMCLK = 2, // Current memory clock value in MHz + PMLOG_CLK_SOCCLK = 3, + PMLOG_CLK_UVDCLK1 = 4, + PMLOG_CLK_UVDCLK2 = 5, + PMLOG_CLK_VCECLK = 6, + PMLOG_CLK_VCNCLK = 7, + PMLOG_TEMPERATURE_EDGE = 8, // Current edge of the die temperature value in C + PMLOG_TEMPERATURE_MEM = 9, + PMLOG_TEMPERATURE_VRVDDC = 10, + PMLOG_TEMPERATURE_VRMVDD = 11, + PMLOG_TEMPERATURE_LIQUID = 12, + PMLOG_TEMPERATURE_PLX = 13, + PMLOG_FAN_RPM = 14, // Current fan RPM value + PMLOG_FAN_PERCENTAGE = 15, // Current ratio of fan RPM and max RPM + PMLOG_SOC_VOLTAGE = 16, + PMLOG_SOC_POWER = 17, + PMLOG_SOC_CURRENT = 18, + PMLOG_INFO_ACTIVITY_GFX = 19, // Current graphic activity level in percentage + PMLOG_INFO_ACTIVITY_MEM = 20, // Current memory activity level in percentage + PMLOG_GFX_VOLTAGE = 21, // Current graphic voltage in mV + PMLOG_MEM_VOLTAGE = 22, + PMLOG_ASIC_POWER = 23, // Current ASIC power draw in Watt + PMLOG_TEMPERATURE_VRSOC = 24, + PMLOG_TEMPERATURE_VRMVDD0 = 25, + PMLOG_TEMPERATURE_VRMVDD1 = 26, + PMLOG_TEMPERATURE_HOTSPOT = 27, // Current center of the die temperature value in C + PMLOG_TEMPERATURE_GFX = 28, + PMLOG_TEMPERATURE_SOC = 29, + PMLOG_GFX_POWER = 30, + PMLOG_GFX_CURRENT = 31, + PMLOG_TEMPERATURE_CPU = 32, + PMLOG_CPU_POWER = 33, + PMLOG_CLK_CPUCLK = 34, + PMLOG_THROTTLER_STATUS = 35, // A bit map of GPU throttle information. If a bit is set, the bit represented type of thorttling occurred in the last metrics sampling period + PMLOG_CLK_VCN1CLK1 = 36, + PMLOG_CLK_VCN1CLK2 = 37, + PMLOG_SMART_POWERSHIFT_CPU = 38, + PMLOG_SMART_POWERSHIFT_DGPU = 39, + PMLOG_BUS_SPEED = 40, // Current PCIE bus speed running + PMLOG_BUS_LANES = 41, // Current PCIE bus lanes using + PMLOG_TEMPERATURE_LIQUID0 = 42, + PMLOG_TEMPERATURE_LIQUID1 = 43, + PMLOG_CLK_FCLK = 44, + PMLOG_THROTTLER_STATUS_CPU = 45, + PMLOG_SSPAIRED_ASICPOWER = 46, // apuPower + PMLOG_SSTOTAL_POWERLIMIT = 47, // Total Power limit + PMLOG_SSAPU_POWERLIMIT = 48, // APU Power limit + PMLOG_SSDGPU_POWERLIMIT = 49, // DGPU Power limit + PMLOG_TEMPERATURE_HOTSPOT_GCD = 50, + PMLOG_TEMPERATURE_HOTSPOT_MCD = 51, + PMLOG_THROTTLER_TEMP_EDGE_PERCENTAGE = 52, + PMLOG_THROTTLER_TEMP_HOTSPOT_PERCENTAGE = 53, + PMLOG_THROTTLER_TEMP_HOTSPOT_GCD_PERCENTAGE = 54, + PMLOG_THROTTLER_TEMP_HOTSPOT_MCD_PERCENTAGE = 55, + PMLOG_THROTTLER_TEMP_MEM_PERCENTAGE = 56, + PMLOG_THROTTLER_TEMP_VR_GFX_PERCENTAGE = 57, + PMLOG_THROTTLER_TEMP_VR_MEM0_PERCENTAGE = 58, + PMLOG_THROTTLER_TEMP_VR_MEM1_PERCENTAGE = 59, + PMLOG_THROTTLER_TEMP_VR_SOC_PERCENTAGE = 60, + PMLOG_THROTTLER_TEMP_LIQUID0_PERCENTAGE = 61, + PMLOG_THROTTLER_TEMP_LIQUID1_PERCENTAGE = 62, + PMLOG_THROTTLER_TEMP_PLX_PERCENTAGE = 63, + PMLOG_THROTTLER_TDC_GFX_PERCENTAGE = 64, + PMLOG_THROTTLER_TDC_SOC_PERCENTAGE = 65, + PMLOG_THROTTLER_TDC_USR_PERCENTAGE = 66, + PMLOG_THROTTLER_PPT0_PERCENTAGE = 67, + PMLOG_THROTTLER_PPT1_PERCENTAGE = 68, + PMLOG_THROTTLER_PPT2_PERCENTAGE = 69, + PMLOG_THROTTLER_PPT3_PERCENTAGE = 70, + PMLOG_THROTTLER_FIT_PERCENTAGE = 71, + PMLOG_THROTTLER_GFX_APCC_PLUS_PERCENTAGE = 72, + PMLOG_BOARD_POWER = 73, + PMLOG_MAX_SENSORS_REAL +}; + +//Throttle Status +[Flags] +public enum ADL_THROTTLE_NOTIFICATION { + ADL_PMLOG_THROTTLE_POWER = 1 << 0, + ADL_PMLOG_THROTTLE_THERMAL = 1 << 1, + ADL_PMLOG_THROTTLE_CURRENT = 1 << 2, +}; + +public enum ADL_PMLOG_SENSORS { + ADL_SENSOR_MAXTYPES = 0, + ADL_PMLOG_CLK_GFXCLK = 1, + ADL_PMLOG_CLK_MEMCLK = 2, + ADL_PMLOG_CLK_SOCCLK = 3, + ADL_PMLOG_CLK_UVDCLK1 = 4, + ADL_PMLOG_CLK_UVDCLK2 = 5, + ADL_PMLOG_CLK_VCECLK = 6, + ADL_PMLOG_CLK_VCNCLK = 7, + ADL_PMLOG_TEMPERATURE_EDGE = 8, + ADL_PMLOG_TEMPERATURE_MEM = 9, + ADL_PMLOG_TEMPERATURE_VRVDDC = 10, + ADL_PMLOG_TEMPERATURE_VRMVDD = 11, + ADL_PMLOG_TEMPERATURE_LIQUID = 12, + ADL_PMLOG_TEMPERATURE_PLX = 13, + ADL_PMLOG_FAN_RPM = 14, + ADL_PMLOG_FAN_PERCENTAGE = 15, + ADL_PMLOG_SOC_VOLTAGE = 16, + ADL_PMLOG_SOC_POWER = 17, + ADL_PMLOG_SOC_CURRENT = 18, + ADL_PMLOG_INFO_ACTIVITY_GFX = 19, + ADL_PMLOG_INFO_ACTIVITY_MEM = 20, + ADL_PMLOG_GFX_VOLTAGE = 21, + ADL_PMLOG_MEM_VOLTAGE = 22, + ADL_PMLOG_ASIC_POWER = 23, + ADL_PMLOG_TEMPERATURE_VRSOC = 24, + ADL_PMLOG_TEMPERATURE_VRMVDD0 = 25, + ADL_PMLOG_TEMPERATURE_VRMVDD1 = 26, + ADL_PMLOG_TEMPERATURE_HOTSPOT = 27, + ADL_PMLOG_TEMPERATURE_GFX = 28, + ADL_PMLOG_TEMPERATURE_SOC = 29, + ADL_PMLOG_GFX_POWER = 30, + ADL_PMLOG_GFX_CURRENT = 31, + ADL_PMLOG_TEMPERATURE_CPU = 32, + ADL_PMLOG_CPU_POWER = 33, + ADL_PMLOG_CLK_CPUCLK = 34, + ADL_PMLOG_THROTTLER_STATUS = 35, // GFX + ADL_PMLOG_CLK_VCN1CLK1 = 36, + ADL_PMLOG_CLK_VCN1CLK2 = 37, + ADL_PMLOG_SMART_POWERSHIFT_CPU = 38, + ADL_PMLOG_SMART_POWERSHIFT_DGPU = 39, + ADL_PMLOG_BUS_SPEED = 40, + ADL_PMLOG_BUS_LANES = 41, + ADL_PMLOG_TEMPERATURE_LIQUID0 = 42, + ADL_PMLOG_TEMPERATURE_LIQUID1 = 43, + ADL_PMLOG_CLK_FCLK = 44, + ADL_PMLOG_THROTTLER_STATUS_CPU = 45, + ADL_PMLOG_SSPAIRED_ASICPOWER = 46, // apuPower + ADL_PMLOG_SSTOTAL_POWERLIMIT = 47, // Total Power limit + ADL_PMLOG_SSAPU_POWERLIMIT = 48, // APU Power limit + ADL_PMLOG_SSDGPU_POWERLIMIT = 49, // DGPU Power limit + ADL_PMLOG_TEMPERATURE_HOTSPOT_GCD = 50, + ADL_PMLOG_TEMPERATURE_HOTSPOT_MCD = 51, + ADL_PMLOG_THROTTLER_TEMP_EDGE_PERCENTAGE = 52, + ADL_PMLOG_THROTTLER_TEMP_HOTSPOT_PERCENTAGE = 53, + ADL_PMLOG_THROTTLER_TEMP_HOTSPOT_GCD_PERCENTAGE = 54, + ADL_PMLOG_THROTTLER_TEMP_HOTSPOT_MCD_PERCENTAGE = 55, + ADL_PMLOG_THROTTLER_TEMP_MEM_PERCENTAGE = 56, + ADL_PMLOG_THROTTLER_TEMP_VR_GFX_PERCENTAGE = 57, + ADL_PMLOG_THROTTLER_TEMP_VR_MEM0_PERCENTAGE = 58, + ADL_PMLOG_THROTTLER_TEMP_VR_MEM1_PERCENTAGE = 59, + ADL_PMLOG_THROTTLER_TEMP_VR_SOC_PERCENTAGE = 60, + ADL_PMLOG_THROTTLER_TEMP_LIQUID0_PERCENTAGE = 61, + ADL_PMLOG_THROTTLER_TEMP_LIQUID1_PERCENTAGE = 62, + ADL_PMLOG_THROTTLER_TEMP_PLX_PERCENTAGE = 63, + ADL_PMLOG_THROTTLER_TDC_GFX_PERCENTAGE = 64, + ADL_PMLOG_THROTTLER_TDC_SOC_PERCENTAGE = 65, + ADL_PMLOG_THROTTLER_TDC_USR_PERCENTAGE = 66, + ADL_PMLOG_THROTTLER_PPT0_PERCENTAGE = 67, + ADL_PMLOG_THROTTLER_PPT1_PERCENTAGE = 68, + ADL_PMLOG_THROTTLER_PPT2_PERCENTAGE = 69, + ADL_PMLOG_THROTTLER_PPT3_PERCENTAGE = 70, + ADL_PMLOG_THROTTLER_FIT_PERCENTAGE = 71, + ADL_PMLOG_THROTTLER_GFX_APCC_PLUS_PERCENTAGE = 72, + ADL_PMLOG_BOARD_POWER = 73, + ADL_PMLOG_MAX_SENSORS_REAL +} + +#region ADLAdapterInfo + +/// ADLAdapterInfo Structure +[StructLayout(LayoutKind.Sequential)] +public struct ADLAdapterInfo { + /// The size of the structure + int Size; + + /// Adapter Index + public int AdapterIndex; + + /// Adapter UDID + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Adl2.ADL_MAX_PATH)] + public string UDID; + + /// Adapter Bus Number + public int BusNumber; + + /// Adapter Driver Number + public int DriverNumber; + + /// Adapter Function Number + public int FunctionNumber; + + /// Adapter Vendor ID + public int VendorID; + + /// Adapter Adapter name + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Adl2.ADL_MAX_PATH)] + public string AdapterName; + + /// Adapter Display name + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Adl2.ADL_MAX_PATH)] + public string DisplayName; + + /// Adapter Present status + public int Present; + + /// Adapter Exist status + public int Exist; + + /// Adapter Driver Path + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Adl2.ADL_MAX_PATH)] + public string DriverPath; + + /// Adapter Driver Ext Path + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Adl2.ADL_MAX_PATH)] + public string DriverPathExt; + + /// Adapter PNP String + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Adl2.ADL_MAX_PATH)] + public string PNPString; + + /// OS Display Index + public int OSDisplayIndex; +} + +/// ADLAdapterInfo Array +[StructLayout(LayoutKind.Sequential)] +public struct ADLAdapterInfoArray { + /// ADLAdapterInfo Array + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Adl2.ADL_MAX_ADAPTERS)] + public ADLAdapterInfo[] ADLAdapterInfo; +} + +#endregion ADLAdapterInfo + +#region ADLDisplayInfo + +/// ADLDisplayID Structure +[StructLayout(LayoutKind.Sequential)] +public struct ADLDisplayID { + /// Display Logical Index + public int DisplayLogicalIndex; + + /// Display Physical Index + public int DisplayPhysicalIndex; + + /// Adapter Logical Index + public int DisplayLogicalAdapterIndex; + + /// Adapter Physical Index + public int DisplayPhysicalAdapterIndex; +} + +/// ADLDisplayInfo Structure +[StructLayout(LayoutKind.Sequential)] +public struct ADLDisplayInfo { + /// Display Index + public ADLDisplayID DisplayID; + + /// Display Controller Index + public int DisplayControllerIndex; + + /// Display Name + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Adl2.ADL_MAX_PATH)] + public string DisplayName; + + /// Display Manufacturer Name + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Adl2.ADL_MAX_PATH)] + public string DisplayManufacturerName; + + /// Display Type : < The Display type. CRT, TV,CV,DFP are some of display types, + public int DisplayType; + + /// Display output type + public int DisplayOutputType; + + /// Connector type + public int DisplayConnector; + + /// Indicating the display info bits' mask. + public int DisplayInfoMask; + + /// Indicating the display info value. + public int DisplayInfoValue; +} + +#endregion ADLDisplayInfo + +#endregion Export Struct + +public class Adl2 { + public const string Atiadlxx_FileName = "atiadlxx.dll"; + + #region Internal Constant + + /// Define the maximum path + public const int ADL_MAX_PATH = 256; + + /// Define the maximum adapters + public const int ADL_MAX_ADAPTERS = 40 /* 150 */; + + /// Define the maximum displays + public const int ADL_MAX_DISPLAYS = 40 /* 150 */; + + /// Define the maximum device name length + public const int ADL_MAX_DEVICENAME = 32; + + /// Define the successful + public const int ADL_SUCCESS = 0; + + /// Define the failure + public const int ADL_FAIL = -1; + + /// Define the driver ok + public const int ADL_DRIVER_OK = 0; + + /// Maximum number of GL-Sync ports on the GL-Sync module + public const int ADL_MAX_GLSYNC_PORTS = 8; + + /// Maximum number of GL-Sync ports on the GL-Sync module + public const int ADL_MAX_GLSYNC_PORT_LEDS = 8; + + /// Maximum number of ADLMOdes for the adapter + public const int ADL_MAX_NUM_DISPLAYMODES = 1024; + + /// Performance Metrics Log max sensors number + public const int ADL_PMLOG_MAX_SENSORS = 256; + + #endregion Internal Constant + + // ///// ADL Create Function to create ADL Data + /// If it is 1, then ADL will only return the physical exist adapters + ///// retrun ADL Error Code + public static int ADL2_Main_Control_Create(int enumConnectedAdapters, out IntPtr adlContextHandle) { + return NativeMethods.ADL2_Main_Control_Create(ADL_Main_Memory_Alloc_Impl_Reference, enumConnectedAdapters, out adlContextHandle); + } + + public static void FreeMemory(IntPtr buffer) { + Memory_Free_Impl(buffer); + } + + private static bool? isDllLoaded; + + public static bool Load() { + if (isDllLoaded != null) + return isDllLoaded.Value; + + try { + Marshal.PrelinkAll(typeof(Adl2)); + isDllLoaded = true; + } catch (Exception e) when (e is DllNotFoundException or EntryPointNotFoundException) { + Debug.WriteLine(e); + isDllLoaded = false; + } + + return isDllLoaded.Value; + } + + private static NativeMethods.ADL_Main_Memory_Alloc ADL_Main_Memory_Alloc_Impl_Reference = Memory_Alloc_Impl; + + /// Build in memory allocation function + /// input size + /// return the memory buffer + private static IntPtr Memory_Alloc_Impl(int size) { + return Marshal.AllocCoTaskMem(size); + } + + /// Build in memory free function + /// input buffer + private static void Memory_Free_Impl(IntPtr buffer) { + if (IntPtr.Zero != buffer) { + Marshal.FreeCoTaskMem(buffer); + } + } + + public static class NativeMethods { + /// ADL Memory allocation function allows ADL to callback for memory allocation + /// input size + /// retrun ADL Error Code + public delegate IntPtr ADL_Main_Memory_Alloc(int size); + + // ///// ADL Create Function to create ADL Data + /// Call back functin pointer which is ised to allocate memeory + /// If it is 1, then ADL will only retuen the physical exist adapters + ///// retrun ADL Error Code + [DllImport(Atiadlxx_FileName)] + public static extern int ADL2_Main_Control_Create(ADL_Main_Memory_Alloc callback, int enumConnectedAdapters, out IntPtr adlContextHandle); + + /// ADL Destroy Function to free up ADL Data + /// retrun ADL Error Code + [DllImport(Atiadlxx_FileName)] + public static extern int ADL2_Main_Control_Destroy(IntPtr adlContextHandle); + + /// ADL Function to get the number of adapters + /// return number of adapters + /// retrun ADL Error Code + [DllImport(Atiadlxx_FileName)] + public static extern int ADL2_Adapter_NumberOfAdapters_Get(IntPtr adlContextHandle, out int numAdapters); + + /// ADL Function to get the GPU adapter information + /// return GPU adapter information + /// the size of the GPU adapter struct + /// retrun ADL Error Code + [DllImport(Atiadlxx_FileName)] + public static extern int ADL2_Adapter_AdapterInfo_Get(IntPtr adlContextHandle, IntPtr info, int inputSize); + + /// Function to determine if the adapter is active or not. + /// The function is used to check if the adapter associated with iAdapterIndex is active + /// Adapter Index. + /// Status of the adapter. True: Active; False: Dsiabled + /// Non zero is successfull + [DllImport(Atiadlxx_FileName)] + public static extern int ADL2_Adapter_Active_Get(IntPtr adlContextHandle, int adapterIndex, out int status); + + /// Get display information based on adapter index + /// Adapter Index + /// return the total number of supported displays + /// return ADLDisplayInfo Array for supported displays' information + /// force detect or not + /// return ADL Error Code + [DllImport(Atiadlxx_FileName)] + public static extern int ADL2_Display_DisplayInfo_Get( + IntPtr adlContextHandle, + int adapterIndex, + out int numDisplays, + out IntPtr displayInfoArray, + int forceDetect + ); + + [DllImport(Atiadlxx_FileName)] + public static extern int ADL2_Overdrive_Caps( + IntPtr adlContextHandle, + int adapterIndex, + out int supported, + out int enabled, + out int version + ); + + [DllImport(Atiadlxx_FileName)] + public static extern int ADL2_New_QueryPMLogData_Get(IntPtr adlContextHandle, int adapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput); + + [DllImport(Atiadlxx_FileName)] + public static extern int ADL2_Adapter_ASICFamilyType_Get(IntPtr adlContextHandle, int adapterIndex, out ADLAsicFamilyType asicFamilyType, out int asicFamilyTypeValids); + } +} diff --git a/Gpu/AmdGpuTemperatureProvider.cs b/Gpu/AmdGpuTemperatureProvider.cs new file mode 100644 index 00000000..8cfac2e6 --- /dev/null +++ b/Gpu/AmdGpuTemperatureProvider.cs @@ -0,0 +1,92 @@ +using System.Runtime.InteropServices; +using AmdAdl2; + +namespace GHelper.Gpu; + +// Reference: https://github.com/GPUOpen-LibrariesAndSDKs/display-library/blob/master/Sample-Managed/Program.cs +public class AmdGpuTemperatureProvider : IGpuTemperatureProvider { + private bool _isReady; + private IntPtr _adlContextHandle; + private readonly ADLAdapterInfo _internalDiscreteAdapter; + + public AmdGpuTemperatureProvider() { + 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); + if (numberOfAdapters <= 0) + return; + + 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; + + osAdapterInfoData = (ADLAdapterInfoArray) Marshal.PtrToStructure(AdapterBuffer, osAdapterInfoData.GetType())!; + + const int amdVendorId = 1002; + + // Determine which GPU is internal discrete AMD GPU + ADLAdapterInfo internalDiscreteAdapter = + osAdapterInfoData.ADLAdapterInfo + .FirstOrDefault(adapter => { + if (adapter.Exist == 0 || adapter.Present == 0) + return false; + + 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) + return false; + + asicFamilyType = (ADLAsicFamilyType) ((int) asicFamilyType & asicFamilyTypeValids); + + // FIXME: is this correct for G14 2022? + return (asicFamilyType & ADLAsicFamilyType.Discrete) != 0; + }); + + if (internalDiscreteAdapter.Exist == 0) + return; + + _internalDiscreteAdapter = internalDiscreteAdapter; + _isReady = true; + } + + public bool IsValid => _isReady && _adlContextHandle != IntPtr.Zero; + + public int? GetCurrentTemperature() { + if (!IsValid) + return null; + + if (Adl2.NativeMethods.ADL2_New_QueryPMLogData_Get(_adlContextHandle, _internalDiscreteAdapter.AdapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput) != Adl2.ADL_SUCCESS) + return null; + + ADLSingleSensorData temperatureSensor = adlpmLogDataOutput.Sensors[(int) ADLSensorType.PMLOG_TEMPERATURE_EDGE]; + if (temperatureSensor.Supported == 0) + return null; + + return temperatureSensor.Value; + } + + private void ReleaseUnmanagedResources() { + if (_adlContextHandle != IntPtr.Zero) { + Adl2.NativeMethods.ADL2_Main_Control_Destroy(_adlContextHandle); + _adlContextHandle = IntPtr.Zero; + _isReady = false; + } + } + + public void Dispose() { + ReleaseUnmanagedResources(); + GC.SuppressFinalize(this); + } + + ~AmdGpuTemperatureProvider() { + ReleaseUnmanagedResources(); + } +} diff --git a/Gpu/IGpuTemperatureProvider.cs b/Gpu/IGpuTemperatureProvider.cs new file mode 100644 index 00000000..3f5d1b77 --- /dev/null +++ b/Gpu/IGpuTemperatureProvider.cs @@ -0,0 +1,6 @@ +namespace GHelper.Gpu; + +public interface IGpuTemperatureProvider : IDisposable { + bool IsValid { get; } + int? GetCurrentTemperature(); +} diff --git a/Gpu/NvidiaGpuTemperatureProvider.cs b/Gpu/NvidiaGpuTemperatureProvider.cs new file mode 100644 index 00000000..07106a09 --- /dev/null +++ b/Gpu/NvidiaGpuTemperatureProvider.cs @@ -0,0 +1,44 @@ +using NvAPIWrapper.GPU; +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace GHelper.Gpu; + +public class NvidiaGpuTemperatureProvider : IGpuTemperatureProvider { + private readonly PhysicalGPU? _internalGpu; + + public NvidiaGpuTemperatureProvider() { + _internalGpu = GetInternalDiscreteGpu(); + } + + public bool IsValid => _internalGpu != null; + + public int? GetCurrentTemperature() { + if (!IsValid) + return null; + + IThermalSensor? gpuSensor = + GPUApi.GetThermalSettings(_internalGpu!.Handle).Sensors + .FirstOrDefault(s => s.Target == ThermalSettingsTarget.GPU); + + if (gpuSensor == null) + return null; + + return gpuSensor.CurrentTemperature; + } + + public void Dispose() { + } + + private static PhysicalGPU? GetInternalDiscreteGpu() { + try { + return PhysicalGPU + .GetPhysicalGPUs() + .FirstOrDefault(gpu => gpu.SystemType == SystemType.Laptop); + } catch (NVIDIAApiException) { + return null; + } + } +} diff --git a/Program.cs b/Program.cs index b3b2eb7e..4900f13e 100644 --- a/Program.cs +++ b/Program.cs @@ -5,13 +5,15 @@ using System.Management; using System.Reflection; using System.Runtime.InteropServices; using System.Text.Json; +using GHelper.Gpu; public class HardwareMonitor { + private static IGpuTemperatureProvider? GpuTemperatureProvider; public static float? cpuTemp = -1; public static float? batteryDischarge = -1; - + public static int? gpuTemp = null; public static void ReadSensors() { @@ -27,6 +29,8 @@ public class HardwareMonitor var cb = new PerformanceCounter("Power Meter", "Power", "Power Meter (0)", true); batteryDischarge = cb.NextValue() / 1000; cb.Dispose(); + + gpuTemp = GpuTemperatureProvider?.GetCurrentTemperature(); } catch { @@ -34,6 +38,34 @@ public class HardwareMonitor } } + public static void RecreateGpuTemperatureProvider() { + try { + if (GpuTemperatureProvider != null) { + GpuTemperatureProvider.Dispose(); + } + + // Detect valid GPU temperature provider. + // We start with NVIDIA because there's always at least an integrated AMD GPU + IGpuTemperatureProvider gpuTemperatureProvider = new NvidiaGpuTemperatureProvider(); + if (gpuTemperatureProvider.IsValid) { + GpuTemperatureProvider = gpuTemperatureProvider; + return; + } + + gpuTemperatureProvider.Dispose(); + gpuTemperatureProvider = new AmdGpuTemperatureProvider(); + if (gpuTemperatureProvider.IsValid) { + GpuTemperatureProvider = gpuTemperatureProvider; + return; + } + + gpuTemperatureProvider.Dispose(); + + GpuTemperatureProvider = null; + } finally { + Debug.WriteLine($"GpuTemperatureProvider: {GpuTemperatureProvider.GetType().Name}"); + } + } } namespace GHelper @@ -199,6 +231,14 @@ namespace GHelper settingsForm.SetMatrix(isPlugged); + HardwareMonitor.RecreateGpuTemperatureProvider(); + + // Re-enabling the discrete GPU takes a bit of time, + // so a simple workaround is to refresh again after that happens + Task.Run(async () => { + await Task.Delay(TimeSpan.FromSeconds(3)); + HardwareMonitor.RecreateGpuTemperatureProvider(); + }); } private static void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e) diff --git a/Settings.cs b/Settings.cs index 5dc75a53..9c079d81 100644 --- a/Settings.cs +++ b/Settings.cs @@ -653,6 +653,10 @@ namespace GHelper if (HardwareMonitor.batteryDischarge > 0) battery = "Discharging: " + Math.Round((decimal)HardwareMonitor.batteryDischarge, 1).ToString() + "W"; + if (HardwareMonitor.gpuTemp != null) { + gpuTemp = $": {HardwareMonitor.gpuTemp}°C - "; + } + Program.settingsForm.BeginInvoke(delegate { Program.settingsForm.labelCPUFan.Text = "CPU" + cpuTemp + cpuFan; @@ -680,6 +684,7 @@ namespace GHelper aTimer.Interval = 300; aTimer.Enabled = true; + RefreshSensors(); } else { From ef0993e442e5d349911df2fd93489b8f83727fc6 Mon Sep 17 00:00:00 2001 From: Serhii Yolkin Date: Mon, 13 Mar 2023 17:47:11 +0100 Subject: [PATCH 02/11] fix: fixed crash when launched in Eco mode --- Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Program.cs b/Program.cs index 4900f13e..ad953651 100644 --- a/Program.cs +++ b/Program.cs @@ -63,7 +63,7 @@ public class HardwareMonitor GpuTemperatureProvider = null; } finally { - Debug.WriteLine($"GpuTemperatureProvider: {GpuTemperatureProvider.GetType().Name}"); + Debug.WriteLine($"GpuTemperatureProvider: {GpuTemperatureProvider?.GetType().Name}"); } } } From 8fe01e8790fa812479a24126b6c561e5d1d7f172 Mon Sep 17 00:00:00 2001 From: seerge Date: Mon, 13 Mar 2023 19:38:39 +0100 Subject: [PATCH 03/11] New sleep/wake up detection --- GHelper.csproj | 2 +- NativeMethods.cs | 76 ++++++++++++++++++++++++++++++++++++++++++------ Program.cs | 43 ++++++++++++++++++--------- Settings.cs | 32 ++++++++++++++++++++ 4 files changed, 129 insertions(+), 24 deletions(-) diff --git a/GHelper.csproj b/GHelper.csproj index ecb29b71..ed9661a4 100644 --- a/GHelper.csproj +++ b/GHelper.csproj @@ -16,7 +16,7 @@ x64 False True - 0.25 + 0.26 diff --git a/NativeMethods.cs b/NativeMethods.cs index 88d93d09..b7af3aad 100644 --- a/NativeMethods.cs +++ b/NativeMethods.cs @@ -1,9 +1,8 @@ -using System.ComponentModel; +using System.Collections; +using System; +using System.ComponentModel; using System.Diagnostics; -using System.Management; using System.Runtime.InteropServices; -using System.Windows.Forms; -using Tools; using static Tools.ScreenInterrogatory; namespace Tools @@ -310,6 +309,62 @@ namespace Tools public class NativeMethods { + // Monitor Power detection + + internal const uint DEVICE_NOTIFY_WINDOW_HANDLE = 0x0; + internal const uint DEVICE_NOTIFY_SERVICE_HANDLE = 0x1; + internal const int WM_POWERBROADCAST = 0x0218; + internal const int PBT_POWERSETTINGCHANGE = 0x8013; + + [DllImport("User32.dll", SetLastError = true)] + internal static extern IntPtr RegisterPowerSettingNotification(IntPtr hWnd, [In] Guid PowerSettingGuid, uint Flags); + + [DllImport("User32.dll", SetLastError = true)] + internal static extern bool UnregisterPowerSettingNotification(IntPtr hWnd); + + [StructLayout(LayoutKind.Sequential, Pack = 4)] + internal struct POWERBROADCAST_SETTING + { + public Guid PowerSetting; + public uint DataLength; + public byte Data; + } + + public class PowerSettingGuid + { + // 0=Powered by AC, 1=Powered by Battery, 2=Powered by short-term source (UPC) + public Guid AcdcPowerSource { get; } = new Guid("5d3e9a59-e9D5-4b00-a6bd-ff34ff516548"); + // POWERBROADCAST_SETTING.Data = 1-100 + public Guid BatteryPercentageRemaining { get; } = new Guid("a7ad8041-b45a-4cae-87a3-eecbb468a9e1"); + // Windows 8+: 0=Monitor Off, 1=Monitor On, 2=Monitor Dimmed + public Guid ConsoleDisplayState { get; } = new Guid("6fe69556-704a-47a0-8f24-c28d936fda47"); + // Windows 8+, Session 0 enabled: 0=User providing Input, 2=User Idle + public Guid GlobalUserPresence { get; } = new Guid("786E8A1D-B427-4344-9207-09E70BDCBEA9"); + // 0=Monitor Off, 1=Monitor On. + public Guid MonitorPowerGuid { get; } = new Guid("02731015-4510-4526-99e6-e5a17ebd1aea"); + // 0=Battery Saver Off, 1=Battery Saver On. + public Guid PowerSavingStatus { get; } = new Guid("E00958C0-C213-4ACE-AC77-FECCED2EEEA5"); + + // Windows 8+: 0=Off, 1=On, 2=Dimmed + public Guid SessionDisplayStatus { get; } = new Guid("2B84C20E-AD23-4ddf-93DB-05FFBD7EFCA5"); + + // Windows 8+, no Session 0: 0=User providing Input, 2=User Idle + public Guid SessionUserPresence { get; } = new Guid("3C0F4548-C03F-4c4d-B9F2-237EDE686376"); + // 0=Exiting away mode 1=Entering away mode + public Guid SystemAwaymode { get; } = new Guid("98a7f580-01f7-48aa-9c0f-44352c29e5C0"); + + /* Windows 8+ */ + // POWERBROADCAST_SETTING.Data not used + public Guid IdleBackgroundTask { get; } = new Guid(0x515C31D8, 0xF734, 0x163D, 0xA0, 0xFD, 0x11, 0xA0, 0x8C, 0x91, 0xE8, 0xF1); + + public Guid PowerSchemePersonality { get; } = new Guid(0x245D8541, 0x3943, 0x4422, 0xB0, 0x25, 0x13, 0xA7, 0x84, 0xF6, 0x79, 0xB7); + + // The Following 3 Guids are the POWERBROADCAST_SETTING.Data result of PowerSchemePersonality + public Guid MinPowerSavings { get; } = new Guid("8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c"); + public Guid MaxPowerSavings { get; } = new Guid("a1841308-3541-4fab-bc81-f71556f20b4a"); + public Guid TypicalPowerSavings { get; } = new Guid("381b4222-f694-41f0-9685-ff5bb260df2e"); + } + public const int KEYEVENTF_EXTENDEDKEY = 1; public const int KEYEVENTF_KEYUP = 2; @@ -495,27 +550,30 @@ public class NativeMethods displayNum = count; } count++; - //Debug.WriteLine(device.outputTechnology); + Debug.WriteLine(device.outputTechnology); //Debug.WriteLine(device.monitorFriendlyDeviceName); } - if (Screen.AllScreens.Length != count) + var screens = Screen.AllScreens; + + if (screens.Length != count) { Debug.WriteLine("Mismatch between enumerated and available screens"); return null; } count = 0; - foreach (var screen in Screen.AllScreens) + foreach (var screen in screens) { if (count == displayNum) { laptopScreen = screen.DeviceName; } - //Debug.WriteLine(screen.DeviceName); + Debug.WriteLine(screen.DeviceName); count++; } - } catch + } + catch { Debug.WriteLine("Can't find internal screen"); } diff --git a/Program.cs b/Program.cs index ad9ab4eb..625b6573 100644 --- a/Program.cs +++ b/Program.cs @@ -1,5 +1,4 @@ using Microsoft.Win32; -using System; using System.Diagnostics; using System.Management; using System.Reflection; @@ -47,7 +46,7 @@ public static class Logger using (StreamWriter w = File.AppendText(logFile)) { Debug.WriteLine(logMessage); - w.WriteLine($"{DateTime.Now.ToUniversalTime()}: {logMessage}"); + w.WriteLine($"{DateTime.Now}: {logMessage}"); } } @@ -98,6 +97,11 @@ namespace GHelper public static SettingsForm settingsForm = new SettingsForm(); public static ToastForm toast = new ToastForm(); + private static IntPtr unRegPowerNotify; + private static IntPtr ds; + + private static long lastAuto; + // The main entry point for the application public static void Main() { @@ -120,6 +124,8 @@ namespace GHelper Application.EnableVisualStyles(); + ds = settingsForm.Handle; + trayIcon.MouseClick += TrayIcon_MouseClick; ; wmi.SubscribeToEvents(WatcherEventArrived); @@ -134,6 +140,9 @@ namespace GHelper SetAutoModes(); + // Subscribing for native power change events + + /* IntPtr registrationHandle = new IntPtr(); DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS recipient = new DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS(); recipient.Callback = new DeviceNotifyCallbackRoutine(DeviceNotifyCallback); @@ -143,18 +152,21 @@ namespace GHelper Marshal.StructureToPtr(recipient, pRecipient, false); uint result = PowerRegisterSuspendResumeNotification(DEVICE_NOTIFY_CALLBACK, ref recipient, ref registrationHandle); + */ + // Subscribing for monitor power on events + var settingGuid = new NativeMethods.PowerSettingGuid(); + unRegPowerNotify = NativeMethods.RegisterPowerSettingNotification(ds, settingGuid.ConsoleDisplayState, NativeMethods.DEVICE_NOTIFY_WINDOW_HANDLE); + + // Subscribing for system power change events SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; - IntPtr ds = settingsForm.Handle; CheckForUpdates(); - Application.Run(); } - private static int DeviceNotifyCallback(IntPtr context, int type, IntPtr setting) { Logger.WriteLine($"Power callback {type}"); @@ -163,10 +175,6 @@ namespace GHelper case PBT_APMRESUMEAUTOMATIC: settingsForm.BeginInvoke(delegate { - // Fix for bugging buios on wake up - Program.wmi.DeviceSet(ASUSWmi.PerformanceMode, (config.getConfig("performance_mode")+1) % 3); - Thread.Sleep(3000); - SetAutoModes(); }); break; @@ -191,7 +199,7 @@ namespace GHelper var config = JsonSerializer.Deserialize(json); var tag = config.GetProperty("tag_name").ToString().Replace("v", ""); var url = config.GetProperty("assets")[0].GetProperty("browser_download_url").ToString(); - + var gitVersion = new Version(tag); var appVersion = new Version(assembly); @@ -202,18 +210,24 @@ namespace GHelper } } - } catch { + } + catch + { Logger.WriteLine("Failed to get update"); } } - private static void SetAutoModes() + public static void SetAutoModes() { + + if (Math.Abs(DateTimeOffset.Now.ToUnixTimeMilliseconds() - lastAuto) < 1000) return; + lastAuto = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + PowerLineStatus isPlugged = SystemInformation.PowerStatus.PowerLineStatus; - Logger.WriteLine("Power " + isPlugged.ToString()); + Logger.WriteLine("AutoSetting for " + isPlugged.ToString()); settingsForm.SetBatteryChargeLimit(config.getConfig("charge_limit")); @@ -320,7 +334,7 @@ namespace GHelper int EventID = int.Parse(e.NewEvent["EventID"].ToString()); - Logger.WriteLine("WMI event "+EventID); + Logger.WriteLine("WMI event " + EventID); switch (EventID) { @@ -368,6 +382,7 @@ namespace GHelper static void OnExit(object sender, EventArgs e) { trayIcon.Visible = false; + NativeMethods.UnregisterPowerSettingNotification(unRegPowerNotify); Application.Exit(); } } diff --git a/Settings.cs b/Settings.cs index 61cb8cab..83e789eb 100644 --- a/Settings.cs +++ b/Settings.cs @@ -98,6 +98,38 @@ namespace GHelper } + + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + case NativeMethods.WM_POWERBROADCAST: + if (m.WParam == (IntPtr)NativeMethods.PBT_POWERSETTINGCHANGE) + { + var settings = (NativeMethods.POWERBROADCAST_SETTING)m.GetLParam(typeof(NativeMethods.POWERBROADCAST_SETTING)); + switch (settings.Data) + { + case 0: + Logger.WriteLine("Monitor Power Off"); + break; + case 1: + Logger.WriteLine("Monitor Power On"); + Program.settingsForm.BeginInvoke(delegate + { + Program.SetAutoModes(); + }); + break; + case 2: + Logger.WriteLine("Monitor Dimmed"); + break; + } + } + m.Result = (IntPtr)1; + break; + } + base.WndProc(ref m); + } + private void CheckGPU_CheckedChanged(object? sender, EventArgs e) { if (sender is null) return; From a211dd412f1abcdd5a8d3a117d785e5e356e0e6e Mon Sep 17 00:00:00 2001 From: seerge Date: Mon, 13 Mar 2023 20:02:59 +0100 Subject: [PATCH 04/11] Merged GPU temp reader --- Gpu/NvidiaGpuTemperatureProvider.cs | 2 +- HardwareMonitor.cs | 63 +++++++++++++++++++++++++++++ NativeMethods.cs | 4 +- Program.cs | 62 ---------------------------- 4 files changed, 66 insertions(+), 65 deletions(-) create mode 100644 HardwareMonitor.cs diff --git a/Gpu/NvidiaGpuTemperatureProvider.cs b/Gpu/NvidiaGpuTemperatureProvider.cs index 07106a09..91e3ff7d 100644 --- a/Gpu/NvidiaGpuTemperatureProvider.cs +++ b/Gpu/NvidiaGpuTemperatureProvider.cs @@ -37,7 +37,7 @@ public class NvidiaGpuTemperatureProvider : IGpuTemperatureProvider { return PhysicalGPU .GetPhysicalGPUs() .FirstOrDefault(gpu => gpu.SystemType == SystemType.Laptop); - } catch (NVIDIAApiException) { + } catch { return null; } } diff --git a/HardwareMonitor.cs b/HardwareMonitor.cs new file mode 100644 index 00000000..4c8f25c8 --- /dev/null +++ b/HardwareMonitor.cs @@ -0,0 +1,63 @@ +using System.Diagnostics; +using GHelper.Gpu; + +public class HardwareMonitor +{ + private static IGpuTemperatureProvider? GpuTemperatureProvider; + + public static float? cpuTemp = -1; + public static float? batteryDischarge = -1; + public static int? gpuTemp = null; + + public static void ReadSensors() + { + cpuTemp = -1; + batteryDischarge = -1; + + try + { + var ct = new PerformanceCounter("Thermal Zone Information", "Temperature", @"\_TZ.THRM", true); + cpuTemp = ct.NextValue() - 273; + ct.Dispose(); + + var cb = new PerformanceCounter("Power Meter", "Power", "Power Meter (0)", true); + batteryDischarge = cb.NextValue() / 1000; + cb.Dispose(); + + gpuTemp = GpuTemperatureProvider?.GetCurrentTemperature(); + } + catch + { + Logger.WriteLine("Failed reading sensors"); + } + } + + public static void RecreateGpuTemperatureProvider() { + try { + if (GpuTemperatureProvider != null) { + GpuTemperatureProvider.Dispose(); + } + + // Detect valid GPU temperature provider. + // We start with NVIDIA because there's always at least an integrated AMD GPU + IGpuTemperatureProvider gpuTemperatureProvider = new NvidiaGpuTemperatureProvider(); + if (gpuTemperatureProvider.IsValid) { + GpuTemperatureProvider = gpuTemperatureProvider; + return; + } + + gpuTemperatureProvider.Dispose(); + gpuTemperatureProvider = new AmdGpuTemperatureProvider(); + if (gpuTemperatureProvider.IsValid) { + GpuTemperatureProvider = gpuTemperatureProvider; + return; + } + + gpuTemperatureProvider.Dispose(); + + GpuTemperatureProvider = null; + } finally { + Debug.WriteLine($"GpuTemperatureProvider: {GpuTemperatureProvider?.GetType().Name}"); + } + } +} diff --git a/NativeMethods.cs b/NativeMethods.cs index b7af3aad..8553f3d8 100644 --- a/NativeMethods.cs +++ b/NativeMethods.cs @@ -550,7 +550,7 @@ public class NativeMethods displayNum = count; } count++; - Debug.WriteLine(device.outputTechnology); + //Debug.WriteLine(device.outputTechnology); //Debug.WriteLine(device.monitorFriendlyDeviceName); } @@ -569,7 +569,7 @@ public class NativeMethods { laptopScreen = screen.DeviceName; } - Debug.WriteLine(screen.DeviceName); + //Debug.WriteLine(screen.DeviceName); count++; } } diff --git a/Program.cs b/Program.cs index fa41aef7..1a10dc4e 100644 --- a/Program.cs +++ b/Program.cs @@ -4,68 +4,6 @@ using System.Management; using System.Reflection; using System.Runtime.InteropServices; using System.Text.Json; -using GHelper.Gpu; - -public class HardwareMonitor -{ - private static IGpuTemperatureProvider? GpuTemperatureProvider; - - public static float? cpuTemp = -1; - public static float? batteryDischarge = -1; - public static int? gpuTemp = null; - - public static void ReadSensors() - { - cpuTemp = -1; - batteryDischarge = -1; - - try - { - var ct = new PerformanceCounter("Thermal Zone Information", "Temperature", @"\_TZ.THRM", true); - cpuTemp = ct.NextValue() - 273; - ct.Dispose(); - - var cb = new PerformanceCounter("Power Meter", "Power", "Power Meter (0)", true); - batteryDischarge = cb.NextValue() / 1000; - cb.Dispose(); - - gpuTemp = GpuTemperatureProvider?.GetCurrentTemperature(); - } - catch - { - Logger.WriteLine("Failed reading sensors"); - } - } - - public static void RecreateGpuTemperatureProvider() { - try { - if (GpuTemperatureProvider != null) { - GpuTemperatureProvider.Dispose(); - } - - // Detect valid GPU temperature provider. - // We start with NVIDIA because there's always at least an integrated AMD GPU - IGpuTemperatureProvider gpuTemperatureProvider = new NvidiaGpuTemperatureProvider(); - if (gpuTemperatureProvider.IsValid) { - GpuTemperatureProvider = gpuTemperatureProvider; - return; - } - - gpuTemperatureProvider.Dispose(); - gpuTemperatureProvider = new AmdGpuTemperatureProvider(); - if (gpuTemperatureProvider.IsValid) { - GpuTemperatureProvider = gpuTemperatureProvider; - return; - } - - gpuTemperatureProvider.Dispose(); - - GpuTemperatureProvider = null; - } finally { - Debug.WriteLine($"GpuTemperatureProvider: {GpuTemperatureProvider?.GetType().Name}"); - } - } -} public static class Logger { public static void WriteLine(string logMessage) From 223ead2f4ecd4d04f90b3aa5d261a9aeb70e618f Mon Sep 17 00:00:00 2001 From: seerge Date: Mon, 13 Mar 2023 20:25:35 +0100 Subject: [PATCH 05/11] Minor fixes --- GHelper.csproj | 4 ++-- Settings.cs | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/GHelper.csproj b/GHelper.csproj index ced6804d..db7d18c3 100644 --- a/GHelper.csproj +++ b/GHelper.csproj @@ -2,7 +2,7 @@ WinExe - net7.0-windows10.0.17763.0 + net7.0-windows8.0 enable True enable @@ -11,7 +11,7 @@ GHelper.Program favicon.ico AnyCPU;x64 - 10.0.17763.0 + 8.0 GHelper x64 False diff --git a/Settings.cs b/Settings.cs index c22e31fc..4579c2ff 100644 --- a/Settings.cs +++ b/Settings.cs @@ -541,8 +541,12 @@ namespace GHelper { int currentFrequency = NativeMethods.GetRefreshRate(); - if (currentFrequency < 0) // Laptop screen not detected or has unknown refresh rate + + if (currentFrequency < 0) // Laptop screen not detected or has unknown refresh rate + { + InitScreen(); return; + } if (frequency >= 1000) { @@ -717,7 +721,7 @@ namespace GHelper aTimer.Interval = 300; aTimer.Enabled = true; - RefreshSensors(); + //RefreshSensors(); } else { @@ -1030,7 +1034,7 @@ namespace GHelper break; default: buttonStandard.FlatAppearance.BorderSize = buttonActive; - labelGPU.Text = "GPU Mode: iGPU and dGPU"; + labelGPU.Text = "GPU Mode: iGPU + dGPU"; Program.trayIcon.Icon = GHelper.Properties.Resources.standard; break; } From f1ae14652f09aad043425d1e100b0a600f95b777 Mon Sep 17 00:00:00 2001 From: seerge Date: Mon, 13 Mar 2023 21:20:46 +0100 Subject: [PATCH 06/11] UI tweaks --- Fans.Designer.cs | 6 +++--- HardwareMonitor.cs | 12 ++++++++++-- Settings.Designer.cs | 10 +++++----- Settings.cs | 11 ++++++----- 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/Fans.Designer.cs b/Fans.Designer.cs index ff169a11..ce8773e1 100644 --- a/Fans.Designer.cs +++ b/Fans.Designer.cs @@ -268,7 +268,7 @@ panelCPU.Controls.Add(labelCPU); panelCPU.Controls.Add(label2); panelCPU.Controls.Add(trackCPU); - panelCPU.Location = new Point(184, 90); + panelCPU.Location = new Point(184, 93); panelCPU.Margin = new Padding(4); panelCPU.Name = "panelCPU"; panelCPU.Size = new Size(160, 510); @@ -315,7 +315,7 @@ panelTotal.Controls.Add(labelTotal); panelTotal.Controls.Add(label1); panelTotal.Controls.Add(trackTotal); - panelTotal.Location = new Point(16, 90); + panelTotal.Location = new Point(16, 93); panelTotal.Margin = new Padding(4); panelTotal.Name = "panelTotal"; panelTotal.Size = new Size(160, 512); @@ -362,7 +362,7 @@ // labelApplied.AutoSize = true; labelApplied.ForeColor = Color.Tomato; - labelApplied.Location = new Point(56, 48); + labelApplied.Location = new Point(56, 54); labelApplied.Margin = new Padding(4, 0, 4, 0); labelApplied.Name = "labelApplied"; labelApplied.Size = new Size(143, 32); diff --git a/HardwareMonitor.cs b/HardwareMonitor.cs index 4c8f25c8..c5a6b118 100644 --- a/HardwareMonitor.cs +++ b/HardwareMonitor.cs @@ -24,12 +24,20 @@ public class HardwareMonitor batteryDischarge = cb.NextValue() / 1000; cb.Dispose(); - gpuTemp = GpuTemperatureProvider?.GetCurrentTemperature(); } catch { - Logger.WriteLine("Failed reading sensors"); + //Logger.WriteLine("Failed reading sensors"); } + + try + { + gpuTemp = GpuTemperatureProvider?.GetCurrentTemperature(); + } catch + { + //Logger.WriteLine("Failed reading GPU temps"); + } + } public static void RecreateGpuTemperatureProvider() { diff --git a/Settings.Designer.cs b/Settings.Designer.cs index 5198c48f..b90bfd01 100644 --- a/Settings.Designer.cs +++ b/Settings.Designer.cs @@ -462,7 +462,7 @@ // checkGPU.AutoSize = true; checkGPU.ForeColor = SystemColors.GrayText; - checkGPU.Location = new Point(27, 154); + checkGPU.Location = new Point(27, 155); checkGPU.Margin = new Padding(4, 2, 4, 2); checkGPU.Name = "checkGPU"; checkGPU.Size = new Size(550, 36); @@ -581,7 +581,7 @@ // checkScreen.AutoSize = true; checkScreen.ForeColor = SystemColors.GrayText; - checkScreen.Location = new Point(27, 153); + checkScreen.Location = new Point(27, 154); checkScreen.Margin = new Padding(4, 2, 4, 2); checkScreen.Name = "checkScreen"; checkScreen.Size = new Size(527, 36); @@ -687,7 +687,7 @@ tableLayoutKeyboard.Name = "tableLayoutKeyboard"; tableLayoutKeyboard.RowCount = 1; tableLayoutKeyboard.RowStyles.Add(new RowStyle(SizeType.Percent, 100F)); - tableLayoutKeyboard.Size = new Size(684, 62); + tableLayoutKeyboard.Size = new Size(684, 66); tableLayoutKeyboard.TabIndex = 39; // // buttonKeyboard @@ -726,7 +726,7 @@ panelColor.Location = new Point(238, 10); panelColor.Margin = new Padding(10); panelColor.Name = "panelColor"; - panelColor.Size = new Size(208, 42); + panelColor.Size = new Size(208, 46); panelColor.TabIndex = 36; // // pictureColor2 @@ -792,7 +792,7 @@ AutoScaleMode = AutoScaleMode.Dpi; AutoSize = true; AutoSizeMode = AutoSizeMode.GrowAndShrink; - ClientSize = new Size(754, 1180); + ClientSize = new Size(754, 1217); Controls.Add(panelFooter); Controls.Add(panelBattery); Controls.Add(panelMatrix); diff --git a/Settings.cs b/Settings.cs index 4579c2ff..ff0ccaf4 100644 --- a/Settings.cs +++ b/Settings.cs @@ -541,7 +541,7 @@ namespace GHelper { int currentFrequency = NativeMethods.GetRefreshRate(); - + if (currentFrequency < 0) // Laptop screen not detected or has unknown refresh rate { InitScreen(); @@ -562,7 +562,7 @@ namespace GHelper Program.wmi.DeviceSet(ASUSWmi.ScreenOverdrive, overdrive); InitScreen(); - Logger.WriteLine("Screen "+ frequency.ToString() + "Hz"); + Logger.WriteLine("Screen " + frequency.ToString() + "Hz"); } @@ -690,7 +690,8 @@ namespace GHelper if (HardwareMonitor.batteryDischarge > 0) battery = "Discharging: " + Math.Round((decimal)HardwareMonitor.batteryDischarge, 1).ToString() + "W"; - if (HardwareMonitor.gpuTemp != null) { + if (HardwareMonitor.gpuTemp != null) + { gpuTemp = $": {HardwareMonitor.gpuTemp}°C - "; } @@ -744,7 +745,7 @@ namespace GHelper Program.wmi.DeviceSet(ASUSWmi.PPT_TotalA1, limit_total); Program.wmi.DeviceSet(ASUSWmi.PPT_CPUB0, limit_cpu); - Logger.WriteLine("PowerLimits "+limit_total.ToString() + ", " + limit_cpu.ToString()); + Logger.WriteLine("PowerLimits " + limit_total.ToString() + ", " + limit_cpu.ToString()); } @@ -802,7 +803,7 @@ namespace GHelper Program.config.setConfig("performance_mode", PerformanceMode); Program.wmi.DeviceSet(ASUSWmi.PerformanceMode, PerformanceMode); - Logger.WriteLine("PerfMode " + perfName + " "+ PerformanceMode); + Logger.WriteLine("PerfMode " + perfName + " " + PerformanceMode); if (notify && (oldMode != PerformanceMode)) { From 67b541b1454b1a6a942b72e44f536210430bdca3 Mon Sep 17 00:00:00 2001 From: seerge Date: Mon, 13 Mar 2023 21:46:11 +0100 Subject: [PATCH 07/11] Turbo boost dropdown --- Fans.Designer.cs | 41 ++++++++++++++++++++++++++--------------- Fans.cs | 18 +++++++----------- HardwareMonitor.cs | 14 +++++++++++--- NativeMethods.cs | 3 ++- 4 files changed, 46 insertions(+), 30 deletions(-) diff --git a/Fans.Designer.cs b/Fans.Designer.cs index ce8773e1..cdf6b2bc 100644 --- a/Fans.Designer.cs +++ b/Fans.Designer.cs @@ -31,11 +31,12 @@ System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea(); System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea2 = new System.Windows.Forms.DataVisualization.Charting.ChartArea(); panelFans = new Panel(); + labelBoost = new Label(); + comboBoost = new ComboBox(); picturePerf = new PictureBox(); tableFanCharts = new TableLayoutPanel(); chartGPU = new System.Windows.Forms.DataVisualization.Charting.Chart(); chartCPU = new System.Windows.Forms.DataVisualization.Charting.Chart(); - checkBoost = new CheckBox(); labelFans = new Label(); checkAuto = new CheckBox(); buttonReset = new Button(); @@ -72,9 +73,10 @@ // // panelFans // + panelFans.Controls.Add(labelBoost); + panelFans.Controls.Add(comboBoost); panelFans.Controls.Add(picturePerf); panelFans.Controls.Add(tableFanCharts); - panelFans.Controls.Add(checkBoost); panelFans.Controls.Add(labelFans); panelFans.Controls.Add(checkAuto); panelFans.Controls.Add(buttonReset); @@ -87,6 +89,26 @@ panelFans.Size = new Size(824, 1159); panelFans.TabIndex = 12; // + // labelBoost + // + labelBoost.AutoSize = true; + labelBoost.Location = new Point(396, 18); + labelBoost.Name = "labelBoost"; + labelBoost.Size = new Size(125, 32); + labelBoost.TabIndex = 39; + labelBoost.Text = "CPU Boost"; + // + // comboBoost + // + comboBoost.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + comboBoost.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoost.FormattingEnabled = true; + comboBoost.Items.AddRange(new object[] { "Disabled", "Enabled", "Aggressive", "Efficient Enabled", "Efficient Aggressive" }); + comboBoost.Location = new Point(526, 15); + comboBoost.Name = "comboBoost"; + comboBoost.Size = new Size(266, 40); + comboBoost.TabIndex = 38; + // // picturePerf // picturePerf.BackgroundImage = Properties.Resources.icons8_fan_head_96; @@ -141,18 +163,6 @@ chartCPU.TabIndex = 14; chartCPU.Text = "chartCPU"; // - // checkBoost - // - checkBoost.AutoSize = true; - checkBoost.ForeColor = SystemColors.ControlText; - checkBoost.Location = new Point(475, 18); - checkBoost.Margin = new Padding(4, 2, 4, 2); - checkBoost.Name = "checkBoost"; - checkBoost.Size = new Size(320, 36); - checkBoost.TabIndex = 35; - checkBoost.Text = "CPU Turbo Boost enabled"; - checkBoost.UseVisualStyleBackColor = true; - // // labelFans // labelFans.AutoSize = true; @@ -453,9 +463,10 @@ private TableLayoutPanel tableFanCharts; private System.Windows.Forms.DataVisualization.Charting.Chart chartGPU; private System.Windows.Forms.DataVisualization.Charting.Chart chartCPU; - private CheckBox checkBoost; private Label labelFans; private PictureBox picturePerf; private PictureBox pictureBox1; + private ComboBox comboBoost; + private Label labelBoost; } } \ No newline at end of file diff --git a/Fans.cs b/Fans.cs index 3812f33a..cbb6af4b 100644 --- a/Fans.cs +++ b/Fans.cs @@ -115,7 +115,7 @@ namespace GHelper InitPower(); InitBoost(); - checkBoost.Click += CheckBoost_Click; + comboBoost.SelectedIndexChanged += ComboBoost_Changed; Shown += Fans_Shown; @@ -125,19 +125,15 @@ namespace GHelper public void InitBoost() { int boost = NativeMethods.GetCPUBoost(); - checkBoost.Checked = (boost > 0); + if (boost >= 0) + comboBoost.SelectedIndex = boost; } - private void CheckBoost_Click(object? sender, EventArgs e) + private void ComboBoost_Changed(object? sender, EventArgs e) { - if (sender is null) - return; - - CheckBox chk = (CheckBox)sender; - if (chk.Checked) - NativeMethods.SetCPUBoost(2); - else - NativeMethods.SetCPUBoost(0); + if (sender is null) return; + ComboBox cmb = (ComboBox)sender; + NativeMethods.SetCPUBoost(cmb.SelectedIndex); } private void CheckApplyPower_Click(object? sender, EventArgs e) diff --git a/HardwareMonitor.cs b/HardwareMonitor.cs index c5a6b118..e6c4f9f0 100644 --- a/HardwareMonitor.cs +++ b/HardwareMonitor.cs @@ -19,7 +19,14 @@ public class HardwareMonitor var ct = new PerformanceCounter("Thermal Zone Information", "Temperature", @"\_TZ.THRM", true); cpuTemp = ct.NextValue() - 273; ct.Dispose(); + } + catch + { + Logger.WriteLine("Failed reading CPU temp"); + } + try + { var cb = new PerformanceCounter("Power Meter", "Power", "Power Meter (0)", true); batteryDischarge = cb.NextValue() / 1000; cb.Dispose(); @@ -27,15 +34,16 @@ public class HardwareMonitor } catch { - //Logger.WriteLine("Failed reading sensors"); + Logger.WriteLine("Failed reading Battery discharge"); } try { gpuTemp = GpuTemperatureProvider?.GetCurrentTemperature(); - } catch + } catch (Exception ex) { - //Logger.WriteLine("Failed reading GPU temps"); + Logger.WriteLine("Failed reading GPU temp"); + Logger.WriteLine(ex.ToString()); } } diff --git a/NativeMethods.cs b/NativeMethods.cs index 8553f3d8..c63ef9da 100644 --- a/NativeMethods.cs +++ b/NativeMethods.cs @@ -654,6 +654,7 @@ public class NativeMethods PowerSetActiveScheme(IntPtr.Zero, activeSchemeGuid); + /* var hrDC = PowerWriteDCValueIndex( IntPtr.Zero, activeSchemeGuid, @@ -662,7 +663,7 @@ public class NativeMethods boost); PowerSetActiveScheme(IntPtr.Zero, activeSchemeGuid); - + */ } } From 7bfd10c65df5e25d79d3f727ef302aa73a843abb Mon Sep 17 00:00:00 2001 From: Serhii Yolkin Date: Mon, 13 Mar 2023 22:45:12 +0100 Subject: [PATCH 08/11] fix: improved GPU temperature reliability --- Gpu/NvidiaGpuTemperatureProvider.cs | 8 +++----- HardwareMonitor.cs | 23 ++++++++++++++++------- Program.cs | 12 +++--------- Settings.cs | 6 +++++- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/Gpu/NvidiaGpuTemperatureProvider.cs b/Gpu/NvidiaGpuTemperatureProvider.cs index 91e3ff7d..2add0c24 100644 --- a/Gpu/NvidiaGpuTemperatureProvider.cs +++ b/Gpu/NvidiaGpuTemperatureProvider.cs @@ -19,14 +19,12 @@ public class NvidiaGpuTemperatureProvider : IGpuTemperatureProvider { if (!IsValid) return null; + PhysicalGPU internalGpu = _internalGpu!; IThermalSensor? gpuSensor = - GPUApi.GetThermalSettings(_internalGpu!.Handle).Sensors + GPUApi.GetThermalSettings(internalGpu.Handle).Sensors .FirstOrDefault(s => s.Target == ThermalSettingsTarget.GPU); - if (gpuSensor == null) - return null; - - return gpuSensor.CurrentTemperature; + return gpuSensor?.CurrentTemperature; } public void Dispose() { diff --git a/HardwareMonitor.cs b/HardwareMonitor.cs index e6c4f9f0..dae5b976 100644 --- a/HardwareMonitor.cs +++ b/HardwareMonitor.cs @@ -40,20 +40,29 @@ public class HardwareMonitor try { gpuTemp = GpuTemperatureProvider?.GetCurrentTemperature(); - } catch (Exception ex) - { + } catch (Exception ex) { + gpuTemp = null; Logger.WriteLine("Failed reading GPU temp"); Logger.WriteLine(ex.ToString()); } } + public static void RecreateGpuTemperatureProviderWithRetry() { + RecreateGpuTemperatureProvider(); + + // Re-enabling the discrete GPU takes a bit of time, + // so a simple workaround is to refresh again after that happens + Task.Run(async () => { + await Task.Delay(TimeSpan.FromSeconds(3)); + RecreateGpuTemperatureProvider(); + }); + } + public static void RecreateGpuTemperatureProvider() { try { - if (GpuTemperatureProvider != null) { - GpuTemperatureProvider.Dispose(); - } - + GpuTemperatureProvider?.Dispose(); + // Detect valid GPU temperature provider. // We start with NVIDIA because there's always at least an integrated AMD GPU IGpuTemperatureProvider gpuTemperatureProvider = new NvidiaGpuTemperatureProvider(); @@ -73,7 +82,7 @@ public class HardwareMonitor GpuTemperatureProvider = null; } finally { - Debug.WriteLine($"GpuTemperatureProvider: {GpuTemperatureProvider?.GetType().Name}"); + Logger.WriteLine($"GpuTemperatureProvider: {GpuTemperatureProvider?.GetType().Name}"); } } } diff --git a/Program.cs b/Program.cs index 1a10dc4e..e49dcf63 100644 --- a/Program.cs +++ b/Program.cs @@ -8,6 +8,8 @@ public static class Logger { public static void WriteLine(string logMessage) { + Debug.WriteLine(logMessage); + var appPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\GHelper"; var logFile = appPath + "\\log.txt"; @@ -109,6 +111,7 @@ namespace GHelper settingsForm.SetStartupCheck(Startup.IsScheduled()); SetAutoModes(); + HardwareMonitor.RecreateGpuTemperatureProvider(); // Subscribing for native power change events @@ -205,15 +208,6 @@ namespace GHelper settingsForm.AutoGPUMode(isPlugged); settingsForm.SetMatrix(isPlugged); - - HardwareMonitor.RecreateGpuTemperatureProvider(); - - // Re-enabling the discrete GPU takes a bit of time, - // so a simple workaround is to refresh again after that happens - Task.Run(async () => { - await Task.Delay(TimeSpan.FromSeconds(3)); - HardwareMonitor.RecreateGpuTemperatureProvider(); - }); } private static void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e) diff --git a/Settings.cs b/Settings.cs index ff0ccaf4..84d8ef80 100644 --- a/Settings.cs +++ b/Settings.cs @@ -935,6 +935,7 @@ namespace GHelper Program.settingsForm.BeginInvoke(delegate { InitGPUMode(); + HardwareMonitor.RecreateGpuTemperatureProviderWithRetry(); Thread.Sleep(500); AutoScreen(SystemInformation.PowerStatus.PowerLineStatus); }); @@ -987,8 +988,11 @@ namespace GHelper changed = true; } - if (changed) + if (changed) { Program.config.setConfig("gpu_mode", GPUMode); + + HardwareMonitor.RecreateGpuTemperatureProviderWithRetry(); + } if (restart) { From e725760b24f2fb6c09b37be87dd865798105e37b Mon Sep 17 00:00:00 2001 From: seerge Date: Mon, 13 Mar 2023 23:07:28 +0100 Subject: [PATCH 09/11] UI Tweaks --- Fans.Designer.cs | 12 ++++++------ HardwareMonitor.cs | 2 +- Settings.Designer.cs | 20 +++++++++++++------- app.manifest | 2 +- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/Fans.Designer.cs b/Fans.Designer.cs index cdf6b2bc..149b7e6d 100644 --- a/Fans.Designer.cs +++ b/Fans.Designer.cs @@ -92,7 +92,7 @@ // labelBoost // labelBoost.AutoSize = true; - labelBoost.Location = new Point(396, 18); + labelBoost.Location = new Point(397, 19); labelBoost.Name = "labelBoost"; labelBoost.Size = new Size(125, 32); labelBoost.TabIndex = 39; @@ -128,7 +128,7 @@ tableFanCharts.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F)); tableFanCharts.Controls.Add(chartGPU, 0, 1); tableFanCharts.Controls.Add(chartCPU, 0, 0); - tableFanCharts.Location = new Point(28, 68); + tableFanCharts.Location = new Point(28, 64); tableFanCharts.Margin = new Padding(6); tableFanCharts.Name = "tableFanCharts"; tableFanCharts.RowCount = 2; @@ -136,7 +136,7 @@ tableFanCharts.RowStyles.Add(new RowStyle(SizeType.Percent, 50F)); tableFanCharts.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F)); tableFanCharts.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F)); - tableFanCharts.Size = new Size(764, 988); + tableFanCharts.Size = new Size(764, 992); tableFanCharts.TabIndex = 36; // // chartGPU @@ -144,10 +144,10 @@ chartArea1.Name = "ChartArea1"; chartGPU.ChartAreas.Add(chartArea1); chartGPU.Dock = DockStyle.Fill; - chartGPU.Location = new Point(2, 504); + chartGPU.Location = new Point(2, 506); chartGPU.Margin = new Padding(2, 10, 2, 10); chartGPU.Name = "chartGPU"; - chartGPU.Size = new Size(760, 474); + chartGPU.Size = new Size(760, 476); chartGPU.TabIndex = 17; chartGPU.Text = "chart1"; // @@ -159,7 +159,7 @@ chartCPU.Location = new Point(2, 10); chartCPU.Margin = new Padding(2, 10, 2, 10); chartCPU.Name = "chartCPU"; - chartCPU.Size = new Size(760, 474); + chartCPU.Size = new Size(760, 476); chartCPU.TabIndex = 14; chartCPU.Text = "chartCPU"; // diff --git a/HardwareMonitor.cs b/HardwareMonitor.cs index e6c4f9f0..1fe1a508 100644 --- a/HardwareMonitor.cs +++ b/HardwareMonitor.cs @@ -1,7 +1,7 @@ using System.Diagnostics; using GHelper.Gpu; -public class HardwareMonitor +public static class HardwareMonitor { private static IGpuTemperatureProvider? GpuTemperatureProvider; diff --git a/Settings.Designer.cs b/Settings.Designer.cs index b90bfd01..63b62049 100644 --- a/Settings.Designer.cs +++ b/Settings.Designer.cs @@ -112,7 +112,7 @@ panelMatrix.Controls.Add(pictureMatrix); panelMatrix.Controls.Add(labelMatrix); panelMatrix.Dock = DockStyle.Top; - panelMatrix.Location = new Point(16, 814); + panelMatrix.Location = new Point(16, 806); panelMatrix.Margin = new Padding(4); panelMatrix.Name = "panelMatrix"; panelMatrix.Size = new Size(722, 180); @@ -219,7 +219,7 @@ panelBattery.Controls.Add(labelBatteryTitle); panelBattery.Controls.Add(trackBattery); panelBattery.Dock = DockStyle.Top; - panelBattery.Location = new Point(16, 994); + panelBattery.Location = new Point(16, 986); panelBattery.Margin = new Padding(4); panelBattery.Name = "panelBattery"; panelBattery.Size = new Size(722, 148); @@ -290,7 +290,7 @@ panelFooter.Controls.Add(buttonQuit); panelFooter.Controls.Add(checkStartup); panelFooter.Dock = DockStyle.Top; - panelFooter.Location = new Point(16, 1142); + panelFooter.Location = new Point(16, 1134); panelFooter.Margin = new Padding(4); panelFooter.Name = "panelFooter"; panelFooter.Size = new Size(722, 64); @@ -330,7 +330,7 @@ panelPerformance.Location = new Point(16, 16); panelPerformance.Margin = new Padding(0); panelPerformance.Name = "panelPerformance"; - panelPerformance.Size = new Size(722, 228); + panelPerformance.Size = new Size(722, 220); panelPerformance.TabIndex = 36; // // buttonFans @@ -383,6 +383,8 @@ // tablePerf // tablePerf.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + tablePerf.AutoScroll = true; + tablePerf.AutoSizeMode = AutoSizeMode.GrowAndShrink; tablePerf.ColumnCount = 3; tablePerf.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.33333F)); tablePerf.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.33333F)); @@ -452,7 +454,7 @@ panelGPU.Controls.Add(labelGPUFan); panelGPU.Controls.Add(tableGPU); panelGPU.Dock = DockStyle.Top; - panelGPU.Location = new Point(16, 244); + panelGPU.Location = new Point(16, 236); panelGPU.Margin = new Padding(4); panelGPU.Name = "panelGPU"; panelGPU.Size = new Size(722, 216); @@ -506,6 +508,8 @@ // tableGPU // tableGPU.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + tableGPU.AutoSize = true; + tableGPU.AutoSizeMode = AutoSizeMode.GrowAndShrink; tableGPU.ColumnCount = 3; tableGPU.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.33333F)); tableGPU.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.33333F)); @@ -571,7 +575,7 @@ panelScreen.Controls.Add(pictureScreen); panelScreen.Controls.Add(labelSreen); panelScreen.Dock = DockStyle.Top; - panelScreen.Location = new Point(16, 460); + panelScreen.Location = new Point(16, 452); panelScreen.Margin = new Padding(4); panelScreen.Name = "panelScreen"; panelScreen.Size = new Size(722, 200); @@ -592,6 +596,8 @@ // tableScreen // tableScreen.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + tableScreen.AutoSize = true; + tableScreen.AutoSizeMode = AutoSizeMode.GrowAndShrink; tableScreen.ColumnCount = 3; tableScreen.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.33333F)); tableScreen.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.33333F)); @@ -666,7 +672,7 @@ panelKeyboard.Controls.Add(pictureKeyboard); panelKeyboard.Controls.Add(label1); panelKeyboard.Dock = DockStyle.Top; - panelKeyboard.Location = new Point(16, 660); + panelKeyboard.Location = new Point(16, 652); panelKeyboard.Margin = new Padding(4); panelKeyboard.Name = "panelKeyboard"; panelKeyboard.Size = new Size(722, 154); diff --git a/app.manifest b/app.manifest index fd7c117d..52900f78 100644 --- a/app.manifest +++ b/app.manifest @@ -55,7 +55,7 @@ true - PerMonitorV2, PerMonitor, System + System From e9ec8f0e8ff9cceafb2a1f8d73b0934f72aace7f Mon Sep 17 00:00:00 2001 From: seerge Date: Mon, 13 Mar 2023 23:14:28 +0100 Subject: [PATCH 10/11] - --- Program.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Program.cs b/Program.cs index e49dcf63..e16906bc 100644 --- a/Program.cs +++ b/Program.cs @@ -9,7 +9,7 @@ public static class Logger public static void WriteLine(string logMessage) { Debug.WriteLine(logMessage); - + var appPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\GHelper"; var logFile = appPath + "\\log.txt"; @@ -17,7 +17,6 @@ public static class Logger using (StreamWriter w = File.AppendText(logFile)) { - Debug.WriteLine(logMessage); w.WriteLine($"{DateTime.Now}: {logMessage}"); } From 254be71e8869293aff7a4b8737eec00426d16844 Mon Sep 17 00:00:00 2001 From: seerge Date: Mon, 13 Mar 2023 23:21:06 +0100 Subject: [PATCH 11/11] - --- HardwareMonitor.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/HardwareMonitor.cs b/HardwareMonitor.cs index 6ce45fd5..82d453b2 100644 --- a/HardwareMonitor.cs +++ b/HardwareMonitor.cs @@ -19,8 +19,7 @@ public static class HardwareMonitor var ct = new PerformanceCounter("Thermal Zone Information", "Temperature", @"\_TZ.THRM", true); cpuTemp = ct.NextValue() - 273; ct.Dispose(); - } - catch + } catch { Logger.WriteLine("Failed reading CPU temp"); } @@ -31,8 +30,7 @@ public static class HardwareMonitor batteryDischarge = cb.NextValue() / 1000; cb.Dispose(); - } - catch + } catch { Logger.WriteLine("Failed reading Battery discharge"); }