Skip to content

Instantly share code, notes, and snippets.

@sebastian-dev
Created September 30, 2019 16:36
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save sebastian-dev/60da0af2a574691d63f3a3559d5e38ba to your computer and use it in GitHub Desktop.
Save sebastian-dev/60da0af2a574691d63f3a3559d5e38ba to your computer and use it in GitHub Desktop.
ADL2 Log
using System;
using System.Runtime.InteropServices;
namespace ATIDisplay
{
static class Kernel32
{
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);
}
class Program
{
public const int ADL_OK = 0;
public const int ADL_ERR = -1;
public const int ADL_TRUE = 1;
public const int ADL_FALSE = 0;
internal const string DllName = "atiadlxx.dll";
internal static IntPtr libRef;
internal const int ADL_PMLOG_MAX_SUPPORTED_SENSORS = 256;
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
}
[StructLayout(LayoutKind.Sequential)]
internal struct ADLPMLogSupportInfo
{
/// list of sensors defined by ADL_PMLOG_SENSORS
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ADL_PMLOG_MAX_SUPPORTED_SENSORS)]
public ushort[] sensors;
/// Reserved
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
int[] reserved;
}
[StructLayout(LayoutKind.Sequential)]
internal struct ADLPMLogStartInput
{
/// list of sensors defined by ADL_PMLOG_SENSORS
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ADL_PMLOG_MAX_SUPPORTED_SENSORS)]
public ushort[] usSensors;
/// Sample rate in milliseconds
public uint ulSampleRate;
/// Reserved
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)]
public int[] ulReserved;
}
[StructLayout(LayoutKind.Sequential)]
internal struct ADLPMLogStartOutput
{
public IntPtr pLoggingAddress;
// /// Pointer to memory address containing logging data
// union
// {
// void* pLoggingAddress;
// unsigned long long ptr_LoggingAddress;
// };
/// Reserved
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
public int[] ulReserved;
}
[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; //unsigned long long ???
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ADL_PMLOG_MAX_SUPPORTED_SENSORS * 2)]
public uint[] ulValues;
/// Reserved
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public uint[] ulReserved;
}
public delegate IntPtr Context(int size);
public static Context Context_Alloc = delegate (int size)
{
return Marshal.AllocHGlobal(size);
};
public delegate IntPtr ADL_Main_Memory_AllocDelegate(int size);
public static ADL_Main_Memory_AllocDelegate Main_Memory_Alloc = delegate (int size)
{
return Marshal.AllocHGlobal(size);
};
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern int ADL2_Desktop_Device_Create(IntPtr context, int adapterIndex, out IntPtr dev1, out IntPtr dev2);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern int ADL_Main_Control_Create(ADL_Main_Memory_AllocDelegate callback, int enumConnectedAdapters);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern int ADL2_Main_Control_Create(ADL_Main_Memory_AllocDelegate callback, int enumConnectedAdapters, ref IntPtr context);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern int ADL_Main_Control_Destroy();
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern int ADL2_Main_Control_Destroy(IntPtr context);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern int ADL2_Adapter_PMLog_Support_Get(IntPtr context, int adapterIndex, ref ADLPMLogSupportInfo PMLogSupportInfo);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern int ADL2_Adapter_PMLog_Start(IntPtr context, int iAdapterIndex, ref ADLPMLogStartInput pPMLogStartInput, ref ADLPMLogStartOutput pPMLogStartOutput, IntPtr hDevice);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern int ADL2_Adapter_PMLog_Stop(IntPtr context, int iAdapterIndex, IntPtr hDevice);
[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
static void Main(string[] args)
{
IntPtr context = IntPtr.Zero;
const int adapterIndex = 1;
ADL_Main_Control_Create(1);
if (ADL2_Main_Control_Create(Main_Memory_Alloc, adapterIndex, ref context) == ADL_OK)
{
Console.WriteLine("Context is: {0:D}", context);
var supportInfo = new ADLPMLogSupportInfo();
if (ADL2_Adapter_PMLog_Support_Get(context, adapterIndex, ref supportInfo) == ADL_OK)
{
Console.WriteLine("PMLog Support.");
foreach (ADL_PMLOG_SENSORS sensorId in Enum.GetValues(typeof(ADL_PMLOG_SENSORS)))
{
Console.WriteLine("Sensor {0,0}({1}) is {2}", sensorId.ToString(), (int)sensorId, supportInfo.sensors[(int)sensorId]);
}
}
int length = Marshal.SizeOf<ADLPMLogData>();
IntPtr buffer = Marshal.AllocHGlobal(length);
//Marshal.StructureToPtr(logData, buffer, false);
ADLPMLogStartInput start = new ADLPMLogStartInput();
start.usSensors = new ushort[ADL_PMLOG_MAX_SUPPORTED_SENSORS];
start.ulSampleRate = 1000;
//for (int i = 0; i < 50; i++)
// start.usSensors[i] = supportInfo.sensors[i];
//for (int i = 0; i < 50; i++)
// start.usSensors[i] = (ushort)i;
ADLPMLogStartOutput startOut = new ADLPMLogStartOutput();
IntPtr hDevice1;
IntPtr hDevice2;
int desktop = ADL2_Desktop_Device_Create(context, adapterIndex, out hDevice1, out hDevice2);
Console.WriteLine("-------------------------------------------------");
int result = ADL2_Adapter_PMLog_Start(context, adapterIndex, ref start, ref startOut, hDevice1);
if (result == 0)
{
ADLPMLogData logData;
logData = Marshal.PtrToStructure<ADLPMLogData>(startOut.pLoggingAddress);
Console.WriteLine("ulVersion: {0}", logData.ulVersion);
Console.WriteLine("ulLastUpdated: {0}", logData.ulLastUpdated);
Console.WriteLine("ulActiveSampleRate: {0}", logData.ulActiveSampleRate);
for (int i = 0; i < 50; i++)
{
int idx = i * 2;
Console.WriteLine("{0}# {1} ; {2}", i.ToString(), logData.ulValues[idx].ToString(), logData.ulValues[idx + 1].ToString());
}
int l_start_in = Marshal.SizeOf<ADLPMLogStartInput>();
int l_start_out = Marshal.SizeOf<ADLPMLogStartOutput>();
Marshal.FreeHGlobal(buffer);
}
ADL2_Main_Control_Destroy(context);
ADL_Main_Control_Destroy();
}
else
{
Console.WriteLine("Alloc failed");
}
Console.ReadKey();
}
public static int ADL_Main_Control_Create(int enumConnectedAdapters)
{
try
{
libRef = Kernel32.LoadLibrary(DllName);
if (libRef != IntPtr.Zero)
{
return ADL_Main_Control_Create(Main_Memory_Alloc, enumConnectedAdapters);
}
else
{
return ADL_ERR;
}
}
catch
{
return ADL_ERR;
}
}
public static void Main_Memory_Free(IntPtr buffer)
{
if (IntPtr.Zero != buffer)
{
Marshal.FreeHGlobal(buffer);
Kernel32.FreeLibrary(libRef);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment