Refactor ADL sensors update (#1317)
* Refactor ADL sensors update - Check support for each sensor, on OD8 and new PMLog. - Exclude cards before Vega10 from using PMLog - Better validation for individual sensor support (for now asic-power/board-power) - Validate pmlog struct using the lastUpdate, there are situations the sensors values are corrupted, maybe because something blocking the pointer access to the struct, but this needs to be verified. * Update AmdGpu.cs --------- Co-authored-by: PhyxionNL <7643972+PhyxionNL@users.noreply.github.com>
This commit is contained in:
co-authored by
PhyxionNL
parent
769222de32
commit
0c3ebb1933
@@ -5,7 +5,6 @@
|
||||
// All Rights Reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -18,6 +17,8 @@ internal sealed class AmdGpu : GenericGpu
|
||||
{
|
||||
private readonly AtiAdlxx.ADLAdapterInfo _adapterInfo;
|
||||
private readonly AtiAdlxx.ADLPMLogStartOutput _adlPMLogStartOutput;
|
||||
private readonly AtiAdlxx.ADLPMLogSupportInfo _adlPMLogSupportInfo;
|
||||
private readonly AtiAdlxx.ADLGcnInfo _adlGcnInfo;
|
||||
private readonly IntPtr _context = IntPtr.Zero;
|
||||
private readonly Sensor _controlSensor;
|
||||
private readonly Sensor _coreClock;
|
||||
@@ -54,8 +55,8 @@ 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;
|
||||
private readonly ushort _pmLogSampleRate = 1000;
|
||||
private bool _overdrive8LogExists;
|
||||
|
||||
public AmdGpu(AtiAdlxx.ADLAdapterInfo adapterInfo, ISettings settings)
|
||||
: base(adapterInfo.AdapterName.Trim(), new Identifier("gpu-amd", adapterInfo.AdapterIndex.ToString(CultureInfo.InvariantCulture)), settings)
|
||||
@@ -136,6 +137,7 @@ internal sealed class AmdGpu : GenericGpu
|
||||
int supported = 0;
|
||||
int enabled = 0;
|
||||
int version = 0;
|
||||
_adlGcnInfo = new();
|
||||
|
||||
if (AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_Main_Control_Create)) &&
|
||||
AtiAdlxx.ADL2_Main_Control_Create(AtiAdlxx.Main_Memory_Alloc, _adapterInfo.AdapterIndex, ref _context) != AtiAdlxx.ADLStatus.ADL_OK)
|
||||
@@ -153,14 +155,21 @@ internal sealed class AmdGpu : GenericGpu
|
||||
ActivateSensor(_fullscreenFps);
|
||||
}
|
||||
|
||||
if (AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_Adapter_PMLog_Support_Get)) &&
|
||||
if (AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_GcnAsicInfo_Get)))
|
||||
{
|
||||
AtiAdlxx.ADL2_GcnAsicInfo_Get(_context, _adapterInfo.AdapterIndex, ref _adlGcnInfo);
|
||||
}
|
||||
|
||||
if (_adlGcnInfo.ASICFamilyId >= (int)AtiAdlxx.GCNFamilies.FAMILY_AI &&
|
||||
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();
|
||||
_adlPMLogSupportInfo = 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))
|
||||
@@ -173,14 +182,13 @@ internal sealed class AmdGpu : GenericGpu
|
||||
}
|
||||
|
||||
_adlPMLogStartInput.usSensors[i] = (ushort)AtiAdlxx.ADLPMLogSensors.ADL_SENSOR_MAXTYPES;
|
||||
_adlPMLogStartInput.ulSampleRate = pmLogSampleRate;
|
||||
_adlPMLogStartInput.ulSampleRate = _pmLogSampleRate;
|
||||
|
||||
if (AtiAdlxx.ADL2_Adapter_PMLog_Start(_context,
|
||||
adapterInfo.AdapterIndex,
|
||||
ref _adlPMLogStartInput,
|
||||
ref _adlPMLogStartOutput,
|
||||
_device) ==
|
||||
AtiAdlxx.ADLStatus.ADL_OK)
|
||||
_device) == AtiAdlxx.ADLStatus.ADL_OK)
|
||||
{
|
||||
_pmLogStarted = true;
|
||||
}
|
||||
@@ -348,87 +356,145 @@ internal sealed class AmdGpu : GenericGpu
|
||||
|
||||
if (_currentOverdriveApiLevel >= 8 || !_overdriveApiSupported)
|
||||
{
|
||||
_overdrive8LogExists = false;
|
||||
AtiAdlxx.ADLPMLogDataOutput logDataOutput = new();
|
||||
if (AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_New_QueryPMLogData_Get)) &&
|
||||
AtiAdlxx.ADL2_New_QueryPMLogData_Get(_context, _adapterInfo.AdapterIndex, ref logDataOutput) == AtiAdlxx.ADLStatus.ADL_OK)
|
||||
{
|
||||
_overdrive8LogExists = true;
|
||||
}
|
||||
|
||||
_newQueryPmLogDataGetExists ??= AtiAdlxx.ADL_Method_Exists(nameof(AtiAdlxx.ADL2_New_QueryPMLogData_Get));
|
||||
|
||||
AtiAdlxx.ADLPMLogData adlPMLogData = new();
|
||||
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);
|
||||
adlPMLogData = (AtiAdlxx.ADLPMLogData)Marshal.PtrToStructure(_adlPMLogStartOutput.pLoggingAddress, typeof(AtiAdlxx.ADLPMLogData));
|
||||
}
|
||||
else if (_newQueryPmLogDataGetExists == true && AtiAdlxx.ADL2_New_QueryPMLogData_Get(_context, _adapterInfo.AdapterIndex, ref logDataOutput) == AtiAdlxx.ADLStatus.ADL_OK)
|
||||
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_CLK_GFXCLK, _coreClock, reset: false);
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_CLK_SOCCLK, _socClock);
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_CLK_MEMCLK, _memoryClock, reset: false);
|
||||
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_TEMPERATURE_EDGE, _temperatureCore, reset: false);
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_TEMPERATURE_MEM, _temperatureMemory, reset: false);
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_TEMPERATURE_VRVDDC, _temperatureVddc, reset: false);
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_TEMPERATURE_VRMVDD, _temperatureMvdd, reset: false);
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_TEMPERATURE_LIQUID, _temperatureLiquid, reset: false);
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_TEMPERATURE_PLX, _temperaturePlx, reset: false);
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_TEMPERATURE_HOTSPOT, _temperatureHotSpot, reset: false);
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_TEMPERATURE_SOC, _temperatureSoC);
|
||||
|
||||
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_FAN_RPM, _fan, reset: false);
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_FAN_PERCENTAGE, _controlSensor, reset: false);
|
||||
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_GFX_VOLTAGE, _coreVoltage, 0.001f, false);
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_SOC_VOLTAGE, _socVoltage, 0.001f);
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_MEM_VOLTAGE, _memoryVoltage, 0.001f);
|
||||
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_INFO_ACTIVITY_GFX, _coreLoad, reset: false);
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_INFO_ACTIVITY_MEM, _memoryLoad);
|
||||
|
||||
if (_adlGcnInfo.ASICFamilyId >= (int)AtiAdlxx.GCNFamilies.FAMILY_NV3 || !GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_ASIC_POWER, _powerTotal, reset: false))
|
||||
{
|
||||
GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_TEMPERATURE_EDGE, _temperatureCore, reset: false);
|
||||
GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_TEMPERATURE_MEM, _temperatureMemory, reset: false);
|
||||
GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_TEMPERATURE_VRVDDC, _temperatureVddc, reset: false);
|
||||
GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_TEMPERATURE_VRMVDD, _temperatureMvdd, reset: false);
|
||||
GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_TEMPERATURE_LIQUID, _temperatureLiquid, reset: false);
|
||||
GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_TEMPERATURE_PLX, _temperaturePlx, reset: false);
|
||||
GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_TEMPERATURE_HOTSPOT, _temperatureHotSpot, reset: false);
|
||||
GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_TEMPERATURE_SOC, _temperatureSoC);
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_BOARD_POWER, _powerTotal, reset: false);
|
||||
}
|
||||
|
||||
GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_CLK_GFXCLK, _coreClock, reset: false);
|
||||
GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_CLK_SOCCLK, _socClock);
|
||||
GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_CLK_MEMCLK, _memoryClock, reset: false);
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_GFX_POWER, _powerCore, reset: false);
|
||||
GetAdlSensor(adlPMLogData, logDataOutput, AtiAdlxx.ADLPMLogSensors.ADL_PMLOG_SOC_POWER, _powerSoC, reset: false);
|
||||
}
|
||||
}
|
||||
|
||||
const int fanRpmIndex = (int)AtiAdlxx.ADLSensorType.PMLOG_FAN_RPM;
|
||||
const int fanPercentageIndex = (int)AtiAdlxx.ADLSensorType.PMLOG_FAN_PERCENTAGE;
|
||||
private bool IsSensorSupportedByPMLog(AtiAdlxx.ADLPMLogSensors sensorType)
|
||||
{
|
||||
if (!_pmLogStarted || (int)sensorType == 0)
|
||||
return false;
|
||||
|
||||
if (logDataOutput.sensors.Length is > fanRpmIndex and > fanPercentageIndex &&
|
||||
logDataOutput.sensors[fanRpmIndex].value != ushort.MaxValue &&
|
||||
logDataOutput.sensors[fanRpmIndex].supported != 0)
|
||||
{
|
||||
_fan.Value = logDataOutput.sensors[fanRpmIndex].value;
|
||||
_controlSensor.Value = logDataOutput.sensors[fanPercentageIndex].value;
|
||||
|
||||
ActivateSensor(_fan);
|
||||
ActivateSensor(_controlSensor);
|
||||
}
|
||||
|
||||
GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_GFX_VOLTAGE, _coreVoltage, 0.001f, false);
|
||||
GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_SOC_VOLTAGE, _socVoltage, 0.001f);
|
||||
GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_MEM_VOLTAGE, _memoryVoltage, 0.001f);
|
||||
|
||||
GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_INFO_ACTIVITY_GFX, _coreLoad, reset: false);
|
||||
GetPMLog(logDataOutput, AtiAdlxx.ADLSensorType.PMLOG_INFO_ACTIVITY_MEM, _memoryLoad);
|
||||
|
||||
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);
|
||||
for (int i = 0; i < AtiAdlxx.ADL_PMLOG_MAX_SENSORS; i++)
|
||||
{
|
||||
if (_adlPMLogSupportInfo.usSensors[i] == (int)sensorType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a sensor value.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="adlPMLogData">Current pmlog struct, used with pmlog-support/start.</param>
|
||||
/// <param name="od8Log">Legacy pmlogdataoutput struct, used with ADL2_New_QueryPMLogData_Get.</param>
|
||||
/// <param name="sensorType">Type of the sensor.</param>
|
||||
/// <param name="sensor">The sensor.</param>
|
||||
/// <param name="factor">The factor.</param>
|
||||
/// <param name="reset">If set to <c>true</c>, resets the sensor value to <c>null</c>.</param>
|
||||
/// <returns>true if sensor is supported, false otherwise</returns>
|
||||
private bool GetAdlSensor(AtiAdlxx.ADLPMLogData adlPMLogData, AtiAdlxx.ADLPMLogDataOutput od8Log,
|
||||
AtiAdlxx.ADLPMLogSensors sensorType, Sensor sensor, float factor = 1.0f, bool reset = true)
|
||||
{
|
||||
int i = (int)sensorType;
|
||||
bool supportedByPMLog = IsSensorSupportedByPMLog(sensorType);
|
||||
bool supportedByOD8 = _overdrive8LogExists && i < od8Log.sensors.Length && od8Log.sensors[i].supported != 0;
|
||||
|
||||
if (!supportedByPMLog && !supportedByOD8)
|
||||
{
|
||||
if (reset)
|
||||
sensor.Value = null;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_pmLogStarted)
|
||||
{
|
||||
//check if ulLastUpdated is a valid number, avoid timezone issues with unspecified kind and 48h offset
|
||||
DateTime now = new(DateTime.Now.Ticks, DateTimeKind.Unspecified);
|
||||
if (adlPMLogData.ulLastUpdated == 0 ||
|
||||
adlPMLogData.ulActiveSampleRate < 0 ||
|
||||
adlPMLogData.ulActiveSampleRate > 86400000 ||
|
||||
now.AddHours(48).ToFileTime() < (long)adlPMLogData.ulLastUpdated ||
|
||||
now.AddHours(-48).ToFileTime() > (long)adlPMLogData.ulLastUpdated)
|
||||
{
|
||||
supportedByPMLog = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (supportedByPMLog)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
else if (_overdrive8LogExists)
|
||||
{
|
||||
if (supportedByOD8)
|
||||
{
|
||||
sensor.Value = od8Log.sensors[i].value * factor;
|
||||
ActivateSensor(sensor);
|
||||
}
|
||||
else if (reset)
|
||||
{
|
||||
sensor.Value = null;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void GetOD5CurrentActivity()
|
||||
@@ -536,60 +602,6 @@ internal sealed class AmdGpu : GenericGpu
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a PMLog sensor value.
|
||||
/// </summary>
|
||||
/// <param name="data">The data.</param>
|
||||
/// <param name="sensorType">Type of the sensor.</param>
|
||||
/// <param name="sensor">The sensor.</param>
|
||||
/// <param name="factor">The factor.</param>
|
||||
/// <param name="reset">If set to <c>true</c>, resets the sensor value to <c>null</c>.</param>
|
||||
private void GetPMLog(AtiAdlxx.ADLPMLogDataOutput data, AtiAdlxx.ADLSensorType sensorType, Sensor sensor, float factor = 1.0f, bool reset = true)
|
||||
{
|
||||
int i = (int)sensorType;
|
||||
if (i < data.sensors.Length && data.sensors[i].supported != 0)
|
||||
{
|
||||
sensor.Value = data.sensors[i].value * factor;
|
||||
ActivateSensor(sensor);
|
||||
}
|
||||
else if (reset)
|
||||
{
|
||||
sensor.Value = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a PMLog sensor value.
|
||||
/// </summary>
|
||||
/// <param name="sensorType">Type of the sensor.</param>
|
||||
/// <param name="sensor">The sensor.</param>
|
||||
/// <param name="factor">The factor.</param>
|
||||
/// <param name="reset">If set to <c>true</c>, resets the sensor value to <c>null</c>.</param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Overdrive6 power.
|
||||
/// </summary>
|
||||
@@ -870,49 +882,41 @@ 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);
|
||||
AtiAdlxx.ADLPMLogData adlPMLogData = new();
|
||||
if (_pmLogStarted)
|
||||
{
|
||||
AtiAdlxx.ADLPMLogData _adlPMLogData = (AtiAdlxx.ADLPMLogData)Marshal.PtrToStructure(_adlPMLogStartOutput.pLoggingAddress, typeof(AtiAdlxx.ADLPMLogData));
|
||||
Dictionary<uint, Tuple<bool, uint>> allSensorsSupport = new();
|
||||
adlPMLogData = (AtiAdlxx.ADLPMLogData)Marshal.PtrToStructure(_adlPMLogStartOutput.pLoggingAddress, typeof(AtiAdlxx.ADLPMLogData));
|
||||
}
|
||||
|
||||
foreach (int i in Enum.GetValues(typeof(AtiAdlxx.ADLPMLogSensors)))
|
||||
foreach (AtiAdlxx.ADLPMLogSensors sensorType in Enum.GetValues(typeof(AtiAdlxx.ADLPMLogSensors)))
|
||||
{
|
||||
int i = (int)sensorType;
|
||||
if (i == 0)
|
||||
continue;
|
||||
|
||||
bool supported = false;
|
||||
|
||||
string st = ((AtiAdlxx.ADLPMLogSensors)i).ToString();
|
||||
if (IsSensorSupportedByPMLog(sensorType))
|
||||
{
|
||||
allSensorsSupport.Add((uint)i, new Tuple<bool, uint>(false, 0));
|
||||
}
|
||||
|
||||
for (int k = 0; k < _adlPMLogData.ulValues.Length - 1; k += 2)
|
||||
{
|
||||
allSensorsSupport[_adlPMLogData.ulValues[k]] = new Tuple<bool, uint>(true, _adlPMLogData.ulValues[k + 1]);
|
||||
}
|
||||
|
||||
if (_adlPMLogData.ulValues != null)
|
||||
{
|
||||
r.AppendLine(" Status: OK");
|
||||
|
||||
foreach (KeyValuePair<uint, Tuple<bool, uint>> kv in allSensorsSupport)
|
||||
for (int k = 0; k < adlPMLogData.ulValues.Length - 1; k += 2)
|
||||
{
|
||||
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);
|
||||
if (adlPMLogData.ulValues[k] == i)
|
||||
{
|
||||
r.AppendFormat(" Sensor[{0}].Value: {1}{2}", st, adlPMLogData.ulValues[k + 1], Environment.NewLine);
|
||||
supported = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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++)
|
||||
else if (_overdrive8LogExists && i < data.sensors.Length && data.sensors[i].supported != 0)
|
||||
{
|
||||
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);
|
||||
supported = true;
|
||||
}
|
||||
|
||||
r.AppendFormat(" Sensor[{0}].Supported: {1}{2}", st, supported, Environment.NewLine);
|
||||
}
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
|
||||
@@ -186,6 +186,10 @@ internal static class AtiAdlxx
|
||||
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
||||
public static extern ADLStatus ADL2_Device_PMLog_Device_Destroy(IntPtr context, uint device);
|
||||
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
|
||||
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
||||
public static extern ADLStatus ADL2_GcnAsicInfo_Get(IntPtr context, int adapterIndex, ref ADLGcnInfo gcnInfo);
|
||||
|
||||
public static bool ADL_Method_Exists(string ADL_Method)
|
||||
{
|
||||
IntPtr module = Kernel32.LoadLibrary(DllName);
|
||||
@@ -534,51 +538,6 @@ internal static class AtiAdlxx
|
||||
public ADLSingleSensorData[] sensors;
|
||||
}
|
||||
|
||||
internal enum ADLSensorType
|
||||
{
|
||||
SENSOR_MAXTYPES = 0,
|
||||
PMLOG_CLK_GFXCLK = 1,
|
||||
PMLOG_CLK_MEMCLK = 2,
|
||||
PMLOG_CLK_SOCCLK = 3,
|
||||
PMLOG_CLK_UVDCLK1 = 4,
|
||||
PMLOG_CLK_UVDCLK2 = 5,
|
||||
PMLOG_CLK_VCECLK = 6,
|
||||
PMLOG_CLK_VCNCLK = 7,
|
||||
PMLOG_TEMPERATURE_EDGE = 8,
|
||||
PMLOG_TEMPERATURE_MEM = 9,
|
||||
PMLOG_TEMPERATURE_VRVDDC = 10,
|
||||
PMLOG_TEMPERATURE_VRMVDD = 11,
|
||||
PMLOG_TEMPERATURE_LIQUID = 12,
|
||||
PMLOG_TEMPERATURE_PLX = 13,
|
||||
PMLOG_FAN_RPM = 14,
|
||||
PMLOG_FAN_PERCENTAGE = 15,
|
||||
PMLOG_SOC_VOLTAGE = 16,
|
||||
PMLOG_SOC_POWER = 17,
|
||||
PMLOG_SOC_CURRENT = 18,
|
||||
PMLOG_INFO_ACTIVITY_GFX = 19,
|
||||
PMLOG_INFO_ACTIVITY_MEM = 20,
|
||||
PMLOG_GFX_VOLTAGE = 21,
|
||||
PMLOG_MEM_VOLTAGE = 22,
|
||||
PMLOG_ASIC_POWER = 23,
|
||||
PMLOG_TEMPERATURE_VRSOC = 24,
|
||||
PMLOG_TEMPERATURE_VRMVDD0 = 25,
|
||||
PMLOG_TEMPERATURE_VRMVDD1 = 26,
|
||||
PMLOG_TEMPERATURE_HOTSPOT = 27,
|
||||
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,
|
||||
PMLOG_CLK_VCN1CLK1 = 36,
|
||||
PMLOG_CLK_VCN1CLK2 = 37,
|
||||
PMLOG_SMART_POWERSHIFT_CPU = 38,
|
||||
PMLOG_SMART_POWERSHIFT_DGPU = 39,
|
||||
PMLOG_MAX_SENSORS_REAL
|
||||
}
|
||||
|
||||
internal enum ADLPMLogSensors
|
||||
{
|
||||
ADL_SENSOR_MAXTYPES = 0,
|
||||
@@ -658,6 +617,27 @@ internal static class AtiAdlxx
|
||||
ADL_PMLOG_MAX_SENSORS_REAL
|
||||
}
|
||||
|
||||
internal enum GCNFamilies
|
||||
{
|
||||
FAMILY_UNKNOWN = 0,
|
||||
FAMILY_TN = 105, // Trinity APUs
|
||||
FAMILY_SI = 110, // Southern Islands: Tahiti, Pitcairn, CapeVerde, Oland, Hainan
|
||||
FAMILY_CI = 120, // Sea Islands: Bonaire, Hawaii
|
||||
FAMILY_KV = 125, // Kaveri, Kabini, Mullins
|
||||
FAMILY_VI = 130, // Volcanic Islands: Iceland, Tonga, Fiji
|
||||
FAMILY_CZ = 135, // Carrizo APUs: Carrizo, Stoney
|
||||
FAMILY_AI = 141, // Vega: 10, 20
|
||||
FAMILY_RV = 142, // Raven (Vega GCN 5.0)
|
||||
FAMILY_NV = 143, // Navi10, Navi2x
|
||||
FAMILY_VGH = 144, // Van Gogh (RDNA 2.0)
|
||||
FAMILY_NV3 = 145, // Navi: 3x (GC 11.0.0, RDNA 3.0)
|
||||
FAMILY_YC = 146, // Rembrandt (Yellow Carp, RDNA 2.0)
|
||||
FAMILY_GC_11_0_1 = 148, // Phoenix (GC 11.0.1, RDNA 3.0)
|
||||
FAMILY_GC_10_3_6 = 149, // Raphael (GC 10.3.6, RDNA 2.0)
|
||||
FAMILY_GC_11_5_0 = 150, // GC 11.5.0
|
||||
FAMILY_GC_10_3_7 = 151, // Mendocino (GC 10.3.7, RDNA 2.0)
|
||||
}
|
||||
|
||||
//Structure containing information related power management logging.
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct ADLPMLogSupportInfo
|
||||
@@ -717,4 +697,18 @@ internal static class AtiAdlxx
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
|
||||
public uint[] ulReserved;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal 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.
|
||||
|
||||
// see GCNFamilies enum, references:
|
||||
// https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/amd/addrlib/src/amdgpu_asic_addr.h
|
||||
// https://github.com/torvalds/linux/blob/master/include/uapi/drm/amdgpu_drm.h
|
||||
public int ASICFamilyId;
|
||||
public int ASICRevisionId;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user