diff --git a/LibreHardwareMonitorLib/Hardware/Gpu/AmdGpu.cs b/LibreHardwareMonitorLib/Hardware/Gpu/AmdGpu.cs index 995258e..c63ed9f 100644 --- a/LibreHardwareMonitorLib/Hardware/Gpu/AmdGpu.cs +++ b/LibreHardwareMonitorLib/Hardware/Gpu/AmdGpu.cs @@ -5,8 +5,10 @@ // All Rights Reserved. using System; +using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using LibreHardwareMonitor.Interop; @@ -15,6 +17,7 @@ namespace LibreHardwareMonitor.Hardware.Gpu; internal sealed class AmdGpu : GenericGpu { private readonly AtiAdlxx.ADLAdapterInfo _adapterInfo; + private readonly AtiAdlxx.ADLPMLogStartOutput _adlPMLogStartOutput; private readonly IntPtr _context = IntPtr.Zero; private readonly Sensor _controlSensor; private readonly Sensor _coreClock; @@ -22,6 +25,7 @@ internal sealed class AmdGpu : GenericGpu private readonly Sensor _coreVoltage; private readonly int _currentOverdriveApiLevel; private readonly string _d3dDeviceId; + private readonly uint _device; private readonly Sensor _fan; private readonly Control _fanControl; private readonly bool _frameMetricsStarted; @@ -35,6 +39,7 @@ internal sealed class AmdGpu : GenericGpu private readonly Sensor _memoryLoad; private readonly Sensor _memoryVoltage; private readonly bool _overdriveApiSupported; + private readonly bool _pmLogStarted; private readonly Sensor _powerCore; private readonly Sensor _powerPpt; private readonly Sensor _powerSoC; @@ -49,7 +54,7 @@ internal sealed class AmdGpu : GenericGpu private readonly Sensor _temperaturePlx; private readonly Sensor _temperatureSoC; private readonly Sensor _temperatureVddc; - + private readonly ushort pmLogSampleRate = 1000; private bool? _newQueryPmLogDataGetExists; public AmdGpu(AtiAdlxx.ADLAdapterInfo adapterInfo, ISettings settings) @@ -139,13 +144,49 @@ internal sealed class AmdGpu : GenericGpu } if (AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_Adapter_FrameMetrics_Caps)) && - AtiAdlxx.ADL2_Adapter_FrameMetrics_Caps(_context, _adapterInfo.AdapterIndex, ref supported) == AtiAdlxx.ADLStatus.ADL_OK && supported == AtiAdlxx.ADL_TRUE && AtiAdlxx.ADL2_Adapter_FrameMetrics_Start(_context, _adapterInfo.AdapterIndex, 0) == AtiAdlxx.ADLStatus.ADL_OK) + AtiAdlxx.ADL2_Adapter_FrameMetrics_Caps(_context, _adapterInfo.AdapterIndex, ref supported) == AtiAdlxx.ADLStatus.ADL_OK && + supported == AtiAdlxx.ADL_TRUE && + AtiAdlxx.ADL2_Adapter_FrameMetrics_Start(_context, _adapterInfo.AdapterIndex, 0) == AtiAdlxx.ADLStatus.ADL_OK) { _frameMetricsStarted = true; _fullscreenFps.Value = -1; ActivateSensor(_fullscreenFps); } + if (AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_Adapter_PMLog_Support_Get)) && + AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_Device_PMLog_Device_Create)) && + AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_Adapter_PMLog_Start))) + { + AtiAdlxx.ADLPMLogSupportInfo _adlPMLogSupportInfo = new(); + AtiAdlxx.ADLPMLogStartInput _adlPMLogStartInput = new(); + _adlPMLogStartOutput = new AtiAdlxx.ADLPMLogStartOutput(); + _adlPMLogStartInput.usSensors = new ushort[AtiAdlxx.ADL_PMLOG_MAX_SENSORS]; + if (_device == 0 && + AtiAdlxx.ADLStatus.ADL_OK == AtiAdlxx.ADL2_Device_PMLog_Device_Create(_context, _adapterInfo.AdapterIndex, ref _device) && + AtiAdlxx.ADLStatus.ADL_OK == AtiAdlxx.ADL2_Adapter_PMLog_Support_Get(_context, _adapterInfo.AdapterIndex, ref _adlPMLogSupportInfo)) + { + int i = 0; + while (_adlPMLogSupportInfo.usSensors[i] != (ushort)AtiAdlxx.ADLPMLogSensors.ADL_SENSOR_MAXTYPES) + { + _adlPMLogStartInput.usSensors[i] = _adlPMLogSupportInfo.usSensors[i]; + i++; + } + + _adlPMLogStartInput.usSensors[i] = (ushort)AtiAdlxx.ADLPMLogSensors.ADL_SENSOR_MAXTYPES; + _adlPMLogStartInput.ulSampleRate = pmLogSampleRate; + + if (AtiAdlxx.ADL2_Adapter_PMLog_Start(_context, + adapterInfo.AdapterIndex, + ref _adlPMLogStartInput, + ref _adlPMLogStartOutput, + _device) == + AtiAdlxx.ADLStatus.ADL_OK) + { + _pmLogStarted = true; + } + } + } + if (AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL_Overdrive_Caps)) && AtiAdlxx.ADL_Overdrive_Caps(_adapterInfo.AdapterIndex, ref supported, ref enabled, ref version) == AtiAdlxx.ADLStatus.ADL_OK) { @@ -163,11 +204,12 @@ internal sealed class AmdGpu : GenericGpu _currentOverdriveApiLevel = 6; } } - + if (!_overdriveApiSupported) { if (AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL_Overdrive5_ODParameters_Get)) && - AtiAdlxx.ADL_Overdrive5_ODParameters_Get(_adapterInfo.AdapterIndex, out AtiAdlxx.ADLODParameters p) == AtiAdlxx.ADLStatus.ADL_OK && p.iActivityReportingSupported > 0) + AtiAdlxx.ADL_Overdrive5_ODParameters_Get(_adapterInfo.AdapterIndex, out AtiAdlxx.ADLODParameters p) == AtiAdlxx.ADLStatus.ADL_OK && + p.iActivityReportingSupported > 0) { _overdriveApiSupported = true; _currentOverdriveApiLevel = 5; @@ -310,7 +352,42 @@ internal sealed class AmdGpu : GenericGpu _newQueryPmLogDataGetExists ??= AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_New_QueryPMLogData_Get)); - if (_newQueryPmLogDataGetExists == true && AtiAdlxx.ADL2_New_QueryPMLogData_Get(_context, _adapterInfo.AdapterIndex, ref logDataOutput) == AtiAdlxx.ADLStatus.ADL_OK) + if (_pmLogStarted) + { + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_CLK_GFXCLK, _coreClock, reset: false); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_CLK_SOCCLK, _socClock); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_CLK_MEMCLK, _memoryClock, reset: false); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_BOARD_POWER, _powerTotal, reset: false); + + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_TEMPERATURE_EDGE, _temperatureCore, reset: false); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_TEMPERATURE_MEM, _temperatureMemory, reset: false); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_TEMPERATURE_VRVDDC, _temperatureVddc, reset: false); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_TEMPERATURE_VRMVDD, _temperatureMvdd, reset: false); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_TEMPERATURE_LIQUID, _temperatureLiquid, reset: false); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_TEMPERATURE_PLX, _temperaturePlx, reset: false); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_TEMPERATURE_HOTSPOT, _temperatureHotSpot, reset: false); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_TEMPERATURE_SOC, _temperatureSoC); + + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_CLK_GFXCLK, _coreClock, reset: false); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_CLK_SOCCLK, _socClock); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_CLK_MEMCLK, _memoryClock, reset: false); + + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_FAN_RPM, _fan, reset: false); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_FAN_PERCENTAGE, _controlSensor, reset: false); + + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_GFX_VOLTAGE, _coreVoltage, 0.001f, false); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_SOC_VOLTAGE, _socVoltage, 0.001f); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_MEM_VOLTAGE, _memoryVoltage, 0.001f); + + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_INFO_ACTIVITY_GFX, _coreLoad, reset: false); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_INFO_ACTIVITY_MEM, _memoryLoad); + + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_ASIC_POWER, _powerTotal, reset: false); + + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_GFX_POWER, _powerCore, reset: false); + GetPMLog(AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_SOC_POWER, _powerSoC, reset: false); + } + else if (_newQueryPmLogDataGetExists == true && AtiAdlxx.ADL2_New_QueryPMLogData_Get(_context, _adapterInfo.AdapterIndex, ref logDataOutput) == AtiAdlxx.ADLStatus.ADL_OK) { GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_TEMPERATURE_EDGE, _temperatureCore, reset: false); GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_TEMPERATURE_MEM, _temperatureMemory, reset: false); @@ -346,18 +423,10 @@ internal sealed class AmdGpu : GenericGpu GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_INFO_ACTIVITY_GFX, _coreLoad, reset: false); GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_INFO_ACTIVITY_MEM, _memoryLoad); - if (_adapterInfo.AdapterName.Contains("AMD Radeon RX 7")) - { - GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_TOTAL_BOARD_POWER_RX_7000, _powerTotal, reset: false); - } - else - { - GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_ASIC_POWER, _powerTotal, reset: false); - } + GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_ASIC_POWER, _powerTotal, reset: false); GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_GFX_POWER, _powerCore, reset: false); GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_SOC_POWER, _powerSoC, reset: false); - } } } @@ -489,6 +558,38 @@ internal sealed class AmdGpu : GenericGpu } } + /// + /// Gets a PMLog sensor value. + /// + /// Type of the sensor. + /// The sensor. + /// The factor. + /// If set to true, resets the sensor value to null. + private void GetPMLog(AtiAdlxx.ADLPMLogSensors sensorType, Sensor sensor, float factor = 1.0f, bool reset = true) + { + int i = (int)sensorType; + bool found = false; + AtiAdlxx.ADLPMLogData _adlPMLogData = (AtiAdlxx.ADLPMLogData)Marshal.PtrToStructure(_adlPMLogStartOutput.pLoggingAddress, typeof(AtiAdlxx.ADLPMLogData)); + + if (_adlPMLogData.ulValues != null) + { + for (int k = 0; k < _adlPMLogData.ulValues.Length - 1; k += 2) + { + if (_adlPMLogData.ulValues[k] == i) + { + sensor.Value = _adlPMLogData.ulValues[k + 1] * factor; + ActivateSensor(sensor); + found = true; + } + } + } + + if (!found && reset) + { + sensor.Value = null; + } + } + /// /// Gets the Overdrive6 power. /// @@ -519,6 +620,16 @@ internal sealed class AmdGpu : GenericGpu if (_frameMetricsStarted) AtiAdlxx.ADL2_Adapter_FrameMetrics_Stop(_context, _adapterInfo.AdapterIndex, 0); + if (_pmLogStarted && _device != 0) + { + AtiAdlxx.ADL2_Adapter_PMLog_Stop(_context, _adapterInfo.AdapterIndex, _device); + } + + if (_device != 0) + { + AtiAdlxx.ADL2_Device_PMLog_Device_Destroy(_context, _device); + } + if (_context != IntPtr.Zero) AtiAdlxx.ADL2_Main_Control_Destroy(_context); @@ -759,18 +870,49 @@ internal sealed class AmdGpu : GenericGpu r.AppendLine(); try { - var data = new AtiAdlxx.ADLPMLogDataOutput(); - AtiAdlxx.ADLStatus status = AtiAdlxx.ADL2_New_QueryPMLogData_Get(_context, _adapterInfo.AdapterIndex, ref data); - - r.Append(" Status: "); - r.AppendLine(status.ToString()); - - for (int i = 0; i < data.sensors.Length; i++) + if (_pmLogStarted) { - string st = ((AtiAdlxx.ADLSensorType)i).ToString(); + AtiAdlxx.ADLPMLogData _adlPMLogData = (AtiAdlxx.ADLPMLogData)Marshal.PtrToStructure(_adlPMLogStartOutput.pLoggingAddress, typeof(AtiAdlxx.ADLPMLogData)); + Dictionary> allSensorsSupport = new(); - r.AppendFormat(" Sensor[{0}].Supported: {1}{2}", st, data.sensors[i].supported, Environment.NewLine); - r.AppendFormat(" Sensor[{0}].Value: {1}{2}", st, data.sensors[i].value, Environment.NewLine); + foreach (int i in Enum.GetValues(typeof(AtiAdlxx.ADLPMLogSensors))) + { + allSensorsSupport.Add((uint)i, new Tuple(false, 0)); + } + + for (int k = 0; k < _adlPMLogData.ulValues.Length - 1; k += 2) + { + allSensorsSupport[_adlPMLogData.ulValues[k]] = new Tuple(true, _adlPMLogData.ulValues[k + 1]); + } + + if (_adlPMLogData.ulValues != null) + { + r.AppendLine(" Status: OK"); + + foreach (KeyValuePair> kv in allSensorsSupport) + { + string st = ((AtiAdlxx.ADLPMLogSensors)kv.Key).ToString(); + + r.AppendFormat(" Sensor[{0}].Supported: {1}{2}", st, kv.Value.Item1, Environment.NewLine); + r.AppendFormat(" Sensor[{0}].Value: {1}{2}", st, kv.Value.Item2, Environment.NewLine); + } + } + } + else + { + var data = new AtiAdlxx.ADLPMLogDataOutput(); + AtiAdlxx.ADLStatus status = AtiAdlxx.ADL2_New_QueryPMLogData_Get(_context, _adapterInfo.AdapterIndex, ref data); + + r.Append(" Status: "); + r.AppendLine(status.ToString()); + + for (int i = 0; i < data.sensors.Length; i++) + { + string st = ((AtiAdlxx.ADLSensorType)i).ToString(); + + r.AppendFormat(" Sensor[{0}].Supported: {1}{2}", st, data.sensors[i].supported, Environment.NewLine); + r.AppendFormat(" Sensor[{0}].Value: {1}{2}", st, data.sensors[i].value, Environment.NewLine); + } } } catch (EntryPointNotFoundException) diff --git a/LibreHardwareMonitorLib/Interop/AtiAdlxx.cs b/LibreHardwareMonitorLib/Interop/AtiAdlxx.cs index 1bfa52a..39225ef 100644 --- a/LibreHardwareMonitorLib/Interop/AtiAdlxx.cs +++ b/LibreHardwareMonitorLib/Interop/AtiAdlxx.cs @@ -24,7 +24,6 @@ internal static class AtiAdlxx public const int ADL_DL_FANCTRL_SUPPORTS_RPM_WRITE = 8; public const int ADL_DRIVER_OK = 0; - public const int ADL_FALSE = 0; public const int ADL_MAX_ADAPTERS = 40; @@ -163,6 +162,30 @@ internal static class AtiAdlxx [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] public static extern ADLStatus ADL2_Adapter_FrameMetrics_Stop(IntPtr context, int adapterIndex, int displayIndex); + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + public static extern ADLStatus ADL2_Adapter_PMLog_Support_Get(IntPtr context, int adapterIndex, + ref ADLPMLogSupportInfo pPMLogSupportInfo); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + public static extern ADLStatus ADL2_Adapter_PMLog_Start(IntPtr context, int adapterIndex, + ref ADLPMLogStartInput pPMLogStartInput, + ref ADLPMLogStartOutput pPMLogStartOutput, + uint device); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + public static extern ADLStatus ADL2_Adapter_PMLog_Stop(IntPtr context, int adapterIndex, uint device); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + public static extern ADLStatus ADL2_Device_PMLog_Device_Create(IntPtr context, int adapterIndex, ref uint device); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + public static extern ADLStatus ADL2_Device_PMLog_Device_Destroy(IntPtr context, uint device); + public static bool ADL_Method_Exists(string ADL_Method) { IntPtr module = Kernel32.LoadLibrary(DllName); @@ -553,7 +576,145 @@ internal static class AtiAdlxx PMLOG_CLK_VCN1CLK2 = 37, PMLOG_SMART_POWERSHIFT_CPU = 38, PMLOG_SMART_POWERSHIFT_DGPU = 39, - PMLOG_MAX_SENSORS_REAL, - PMLOG_TOTAL_BOARD_POWER_RX_7000 = 73 + PMLOG_MAX_SENSORS_REAL + } + + internal enum ADLPMLogSensors + { + 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 + } + + //Structure containing information related power management logging. + [StructLayout(LayoutKind.Sequential)] + internal struct ADLPMLogSupportInfo + { + /// list of sensors defined by ADL_PMLOG_SENSORS + [MarshalAs(UnmanagedType.ByValArray, SizeConst = ADL_PMLOG_MAX_SENSORS)] + public ushort[] usSensors; + + /// Reserved + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public int[] iReserved; + } + + //Structure containing information to start power management logging. + [StructLayout(LayoutKind.Sequential)] + internal struct ADLPMLogStartInput + { + /// list of sensors defined by ADL_PMLOG_SENSORS + [MarshalAs(UnmanagedType.ByValArray, SizeConst = ADL_PMLOG_MAX_SENSORS)] + public ushort[] usSensors; + + /// Sample rate in milliseconds + public uint ulSampleRate; + + /// Reserved + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)] + public int[] iReserved; + } + + //Structure containing information to start power management logging. + [StructLayout(LayoutKind.Explicit)] + internal struct ADLPMLogStartOutput + { + /// Pointer to memory address containing logging data + [FieldOffset(0)] public IntPtr pLoggingAddress; + [FieldOffset(0)] public ulong ptrLoggingAddress; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ADLPMLogData + { + /// Structure version + public uint ulVersion; + + /// Current driver sample rate + public uint ulActiveSampleRate; + + /// Timestamp of last update + public ulong ulLastUpdated; + + // 2D array of sensor and values -- unsigned int ulValues[ADL_PMLOG_MAX_SUPPORTED_SENSORS][2] + // the nested array will be accessed like a single dimension array + [MarshalAs(UnmanagedType.ByValArray, SizeConst = ADL_PMLOG_MAX_SENSORS*2)] + public uint[] ulValues; + + /// Reserved + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] + public uint[] ulReserved; } }