#region Copyright
/*******************************************************************************
Copyright(c) 2008 - 2009 Advanced Micro Devices, Inc. All Rights Reserved.
Copyright (c) 2002 - 2006 ATI Technologies Inc. All Rights Reserved.
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDED BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
File: ADL.cs
Purpose: Implements ADL interface
Description: Implements some of the methods defined in ADL interface.
********************************************************************************/
#endregion Copyright
#region Using
using System.Runtime.InteropServices;
using ADL_CONTEXT_HANDLE = nint;
using FARPROC = nint;
using HMODULE = nint;
#endregion Using
#region ATI.ADL
namespace ATI.ADL;
#region Export Struct
#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 = ADL.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 = ADL.ADL_MAX_PATH)]
public string AdapterName;
/// Adapter Display name
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.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 = ADL.ADL_MAX_PATH)]
public string DriverPath;
/// Adapter Driver Ext Path
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
public string DriverPathExt;
/// Adapter PNP String
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.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 = ADL.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 = ADL.ADL_MAX_PATH)]
public string DisplayName;
/// Display Manufacturer Name
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.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
#region ADL Class
/// ADL Class
public static class ADL
{
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
#region public 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;
public static Dictionary ADLDelegates = new Dictionary();
#endregion public Constant
#region Export Delegates
/// ADL Memory allocation function allows ADL to callback for memory allocation
/// input size
/// retrun ADL Error Code
public delegate HMODULE 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
public delegate int ADL_Main_Control_Create(ADL_Main_Memory_Alloc callback, int enumConnectedAdapters);
public delegate int ADL2_Main_Control_Create(ADL_Main_Memory_Alloc callback, int enumConnectedAdapters, ref ADL_CONTEXT_HANDLE context);
/// ADL Destroy Function to free up ADL Data
/// retrun ADL Error Code
public delegate int ADL_Main_Control_Destroy();
public delegate int ADL2_Main_Control_Destroy(ADL_CONTEXT_HANDLE context);
/// ADL Function to get the number of adapters
/// return number of adapters
/// retrun ADL Error Code
public delegate int ADL2_Adapter_NumberOfAdapters_Get(ADL_CONTEXT_HANDLE context, ref 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
public delegate int ADL2_Adapter_AdapterInfo_Get(ADL_CONTEXT_HANDLE context, HMODULE 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
public delegate int ADL2_Adapter_Active_Get(ADL_CONTEXT_HANDLE context, int adapterIndex, ref 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
public delegate int ADL2_Display_DisplayInfo_Get(ADL_CONTEXT_HANDLE context, int adapterIndex, ref int numDisplays, out HMODULE displayInfoArray, int forceDetect);
public delegate int ADL2_Display_Size_Get(ADL_CONTEXT_HANDLE context, int adapterIndex, int displayIndex, ref int lpWidth, ref int lpHeight, ref int lpDefaultWidth, ref int lpDefaultHeight, ref int lpMinWidth, ref int lpMinHeight, ref int lpMaxWidth, ref int lpMaxHeight, ref int lpStepWidth, ref int lpStepHeight);
public delegate int ADL2_Display_PixelFormat_Get(ADL_CONTEXT_HANDLE context, int adapterIndex, int displayIndex, ref int pixelFormat);
public delegate int ADL2_Display_PixelFormat_Set(ADL_CONTEXT_HANDLE context, int adapterIndex, int displayIndex, int pixelFormat);
public delegate int ADL2_Display_ColorDepth_Get(ADL_CONTEXT_HANDLE context, int adapterIndex, int displayIndex, ref int colorDepth);
public delegate int ADL2_Display_ColorDepth_Set(ADL_CONTEXT_HANDLE context, int adapterIndex, int displayIndex, int colorDepth);
public delegate int ADL2_Display_DitherState_Get(ADL_CONTEXT_HANDLE context, int adapterIndex, int displayIndex, ref int ditherState);
public delegate int ADL2_Display_DitherState_Set(ADL_CONTEXT_HANDLE context, int adapterIndex, int displayIndex, int ditherState);
public delegate int ADL2_Display_HDRState_Get(ADL_CONTEXT_HANDLE context, int adapterIndex, ADLDisplayID displayID, ref int support, ref int enable);
public delegate int ADL2_Display_HDRState_Set(ADL_CONTEXT_HANDLE context, int adapterIndex, ADLDisplayID displayID, int enable);
#endregion Export Delegates
#region Class ADLImport
/// ADLImport class
private static class ADLImport
{
#region public Constant
/// Atiadlxx_FileName
public const string Atiadlxx_FileName = "atiadlxx.dll";
/// Kernel32_FileName
public const string Kernel32_FileName = "kernel32.dll";
#endregion public Constant
#region DLLImport
[DllImport(Kernel32_FileName)]
public static extern HMODULE GetModuleHandle(string moduleName);
[DllImport(Atiadlxx_FileName)]
public static extern int ADL_Main_Control_IsFunctionValid(HMODULE module, string procName);
[DllImport(Atiadlxx_FileName)]
public static extern FARPROC ADL_Main_Control_GetProcAddress(HMODULE module, string procName);
#endregion DLLImport
}
#endregion Class ADLImport
#region Class ADLCheckLibrary
/// ADLCheckLibrary class
private class ADLCheckLibrary
{
#region Private Members
private HMODULE ADLLibrary = HMODULE.Zero;
#endregion Private Members
#region Static Members
/// new a private instance
private static ADLCheckLibrary ADLCheckLibrary_ = new ADLCheckLibrary();
#endregion Static Members
#region Constructor
/// Constructor
private ADLCheckLibrary()
{
try
{
if (1 == ADLImport.ADL_Main_Control_IsFunctionValid(HMODULE.Zero, "ADL_Main_Control_Create"))
{
ADLLibrary = ADLImport.GetModuleHandle(ADLImport.Atiadlxx_FileName);
}
}
catch (DllNotFoundException) { }
catch (EntryPointNotFoundException) { }
catch (Exception) { }
}
#endregion Constructor
#region Destructor
/// Destructor to force calling ADL Destroy function before free up the ADL library
~ADLCheckLibrary()
{
if (HMODULE.Zero != ADLCheckLibrary_.ADLLibrary)
{
var del = GetDelegate();
if (del != null)
{
del();
}
}
}
#endregion Destructor
#region Static IsFunctionValid
/// Check the import function to see it exists or not
/// function name
/// return true, if function exists
public static bool IsFunctionValid(string functionName)
{
var result = false;
if (HMODULE.Zero != ADLCheckLibrary_.ADLLibrary)
{
if (1 == ADLImport.ADL_Main_Control_IsFunctionValid(ADLCheckLibrary_.ADLLibrary, functionName))
{
result = true;
}
}
return result;
}
#endregion Static IsFunctionValid
#region Static GetProcAddress
/// Get the unmanaged function pointer
/// function name
/// return function pointer, if function exists
public static FARPROC GetProcAddress(string functionName)
{
var result = HMODULE.Zero;
if (HMODULE.Zero != ADLCheckLibrary_.ADLLibrary)
{
result = ADLImport.ADL_Main_Control_GetProcAddress(ADLCheckLibrary_.ADLLibrary, functionName);
}
return result;
}
#endregion Static GetProcAddress
}
#endregion Class ADLCheckLibrary
#region Export Functions
#region ADL_Main_Memory_Alloc
/// Build in memory allocation function
public static ADL_Main_Memory_Alloc ADL_Main_Memory_Alloc_Func = ADL_Main_Memory_Alloc_;
/// Build in memory allocation function
/// input size
/// return the memory buffer
private static HMODULE ADL_Main_Memory_Alloc_(int size)
{
HMODULE result = Marshal.AllocCoTaskMem(size);
return result;
}
#endregion ADL_Main_Memory_Alloc
#region ADL_Main_Memory_Free
/// Build in memory free function
/// input buffer
public static void ADL_Main_Memory_Free(HMODULE buffer)
{
if (HMODULE.Zero != buffer)
{
Marshal.FreeCoTaskMem(buffer);
}
}
#endregion ADL_Main_Memory_Free
public static T GetDelegate() where T : class
{
var type = typeof(T);
lock (ADLDelegates)
{
if (ADLDelegates.ContainsKey(type))
{
return ADLDelegates[type] as T;
}
var ptr = ADLCheckLibrary.GetProcAddress(type.Name);
if (ptr != FARPROC.Zero)
{
var delegateValue = Marshal.GetDelegateForFunctionPointer(ptr, type);
ADLDelegates.Add(type, delegateValue);
return delegateValue as T;
}
}
Logger.Error($"ADL-function not supported: {type.Name}");
return null;
//throw new InvalidProgramException("ADL-function not supported");
}
#endregion Export Functions
}
#endregion ADL Class
#endregion ATI.ADL