From 6d64c1769a37c8ad04586f2abe028dc9d31ef3c2 Mon Sep 17 00:00:00 2001 From: Terry MacDonald Date: Fri, 18 Jun 2021 12:33:46 +1200 Subject: [PATCH] [WIP] Partial migration to ADL2 Its the only way to get HDR information :( --- DisplayMagicianShared/AMD/ADL.cs | 495 +++++++++++++++++++++++- DisplayMagicianShared/AMD/ADLWrapper.cs | 392 ++++++++++++------- 2 files changed, 733 insertions(+), 154 deletions(-) diff --git a/DisplayMagicianShared/AMD/ADL.cs b/DisplayMagicianShared/AMD/ADL.cs index aed1745..fa5f50c 100644 --- a/DisplayMagicianShared/AMD/ADL.cs +++ b/DisplayMagicianShared/AMD/ADL.cs @@ -42,15 +42,36 @@ namespace ATI.ADL /// retrun ADL Error Code internal delegate IntPtr ADL_Main_Memory_Alloc (int size); + // ///// ADL2 Create Function to create ADL Data + /// Call back functin pointer which is ised to allocate memory + /// If it is 1, then ADL will only retuen the physical exist adapters + /// Handle to ADL client context. + ///// retrun ADL Error Code + internal delegate int ADL2_Main_Control_Create(ADL_Main_Memory_Alloc callback, int numConnectedAdapters, out IntPtr contextHandle); + + /// ADL2 Destroy Function to free up ADL Data + /// Handle to ADL client context. + /// retrun ADL Error Code + internal delegate int ADL2_Main_Control_Destroy(IntPtr contextHandle); + + // ///// ADL2 Create Function to create ADL Data + /// Handle to ADL client context. + /// Adapter Index + /// Display Index + /// The ADLDDCInfo2 structure storing all DDC retrieved from the driver. + ///// retrun ADL Error Code + internal delegate int ADL2_Display_DDCInfo2_Get(IntPtr ADLContextHandle, int adapterIndex, int displayIndex, out ADLDDCInfo2 displayDDCInfo2); + + // ///// 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 - internal delegate int ADL_Main_Control_Create(ADL_Main_Memory_Alloc callback, int enumConnectedAdapters); + internal delegate int ADL_Main_Control_Create(ADL_Main_Memory_Alloc callback, int enumConnectedAdapters); /// ADL Destroy Function to free up ADL Data /// retrun ADL Error Code - internal delegate int ADL_Main_Control_Destroy (); + internal delegate int ADL_Main_Control_Destroy (); /// ADL Function to get the number of adapters /// return number of adapters @@ -84,6 +105,14 @@ namespace ATI.ADL /// return ADL Error Code internal delegate int ADL_AdapterX2_Caps(int adapterIndex, out ADLAdapterCapsX2 adapterCapabilities); + /// Function to get the EDID data. + /// This function retrieves the EDID data for a specififed display. + /// /// Adapter Index + /// The desired display index. It can be retrieved from the ADLDisplayInfo data structure. + /// return the ADLDisplayEDIDData structure storing the retrieved EDID data. + /// return ADL Error Code + internal delegate int ADL_Display_EdidData_Get(int adapterIndex, int displayIndex, ref ADLDisplayEDIDData EDIDData); + /// Get display information based on adapter index /// Adapter Index /// return the total number of supported displays @@ -258,8 +287,118 @@ namespace ATI.ADL } #endregion ADLAdapterInfo - + #region ADLDisplayInfo + + /// ADLDisplayEDIDData Structure + [StructLayout(LayoutKind.Sequential)] + internal struct ADLDisplayEDIDData + { + /// EDIDData [256] + [MarshalAs(UnmanagedType.LPStr, SizeConst = (int)ADL.ADL_MAX_EDIDDATA_SIZE)] + internal string EDIDData; + /// Block Index + internal int BlockIndex; + /// EDIDSize + internal int EDIDSize; + /// Flag + internal int Flag; + /// Reserved + internal int Reserved; + /// Size + internal int Size; + } + + + /// ADLDDCInfo2 Structure + [StructLayout(LayoutKind.Sequential)] + internal struct ADLDDCInfo2 + { + /// Returns 1 if the display supported packed pixel, 0 otherwise. + internal int PackedPixelSupported; + /// Returns the name of the display device. Should be zeroed if this information is not available. + [MarshalAs(UnmanagedType.LPStr, SizeConst = (int)ADL.ADL_MAX_EDIDDATA_SIZE)] + internal string DisplayName ; + /// Display diffuse screen reflectance 0-1 (100%) in units of 0.01. + internal int DiffuseScreenReflectance; + /// Bit vector for freesync flags. + internal int FreesyncFlags; + /// Display Blue Chromaticity X coordinate multiplied by 10000. + internal int NativeDisplayChromaticityBlueX; + /// Display Blue Chromaticity Y coordinate multiplied by 10000. + internal int NativeDisplayChromaticityBlueY; + /// Display Green Chromaticity X coordinate multiplied by 10000. + internal int NativeDisplayChromaticityGreenX; + /// Display Green Chromaticity Y coordinate multiplied by 10000. + internal int NativeDisplayChromaticityGreenY; + /// Display Red Chromaticity X coordinate multiplied by 10000. + internal int NativeDisplayChromaticityRedX; + /// Display Red Chromaticity Y coordinate multiplied by 10000. + internal int NativeDisplayChromaticityRedY; + /// Display White Chromaticity X coordinate multiplied by 10000. + internal int NativeDisplayChromaticityWhiteX; + /// Display White Chromaticity Y coordinate multiplied by 10000. + internal int NativeDisplayChromaticityWhiteY; + /// Returns the Pixel formats the display supports DDCInfo Pixel Formats. + internal int PanelPixelFormat; + /// Reserved1 + internal int Reserved1; + /// Reserved2 + internal int Reserved2; + /// Reserved3 + internal int Reserved3; + /// Reserved4 + internal int Reserved4; + /// Display specular screen reflectance 0-1 (100%) in units of 0.01. + internal int SpecularScreenReflectance; + /// Bit vector of supported color spaces ADLSourceContentAttributes color spaces. + internal int SupportedColorSpace; + /// Bit vector of supported color spaces ADLDDCInfo2 HDR support options. + internal int SupportedHDR; + /// Bit vector of supported transfer functions ADLSourceContentAttributes transfer functions (gamma). + internal int SupportedTransferFunction; + /// Return average monitor luminance data. + internal uint AvgLuminanceData; + /// Return EDID flags. + internal uint DDCInfoFlag; + /// Returns the manufacturer ID of the display device. Should be zeroed if this information is not available. + internal uint ManufacturerID; + /// Returns the maximum backlight maximum luminance. Should be zeroed if this information is not available. + internal uint MaxBacklightMaxLuminanceData; + /// Returns the maximum backlight minimum luminance. Should be zeroed if this information is not available. + internal uint MaxBacklightMinLuminanceData; + /// Returns the maximum Horizontal supported resolution. Should be zeroed if this information is not available. + internal uint MaxHResolution; + /// Return maximum monitor luminance data. + internal uint MaxLuminanceData; + /// Returns the maximum supported refresh rate. Should be zeroed if this information is not available. + internal uint MaxRefresh; + /// Returns the maximum Vertical supported resolution. Should be zeroed if this information is not available. + internal uint MaxVResolution; + /// Returns the minimum backlight maximum luminance. Should be zeroed if this information is not available. + internal uint MinBacklightMaxLuminanceData; + /// Returns the minimum backlight maximum luminance. Should be zeroed if this information is not available. + internal uint MinBacklightMinLuminanceData; + /// Return minimum monitor luminance data. + internal uint MinLuminanceData; + /// Return minimum monitor luminance without dimming data. + internal uint MinLuminanceNoDimmingData; + /// Returns the product ID of the display device. Should be zeroed if this information is not available. + internal uint ProductID; + /// Returns the display device preferred timing mode's horizontal resolution. + internal uint PTMCx; + /// Returns the display device preferred timing mode's vertical resolution. + internal uint PTMCy; + /// Returns the display device preferred timing mode's refresh rate. + internal uint PTMRefreshRate; + /// Return EDID serial ID. + internal uint SerialID; + /// Size of the structure. + internal uint Size; + /// Whether this display device support DDC + internal uint SupportsDDC; + } + /// ADLDisplayID Structure [StructLayout(LayoutKind.Sequential)] internal struct ADLDisplayID @@ -300,6 +439,46 @@ namespace ATI.ADL internal int DisplayInfoValue; } + internal struct ConvertedDisplayInfoValue + { + /// Indicates the display is connected . + internal bool DISPLAYCONNECTED; + /// Indicates the display is mapped within OS + internal bool DISPLAYMAPPED; + /// Indicates the display can be forced + internal bool FORCIBLESUPPORTED; + /// Indicates the display supports genlock + internal bool GENLOCKSUPPORTED; + /// Indicates the display is an LDA display. + internal bool LDA_DISPLAY; + /// Indicates the display supports 2x Horizontal stretch + internal bool MANNER_SUPPORTED_2HSTRETCH; + /// + internal bool MANNER_SUPPORTED_2VSTRETCH; + /// Indicates the display supports cloned desktops + internal bool MANNER_SUPPORTED_CLONE; + /// Indicates the display supports extended desktops + internal bool MANNER_SUPPORTED_EXTENDED; + /// Indicates the display supports N Stretched on 1 GPU + internal bool MANNER_SUPPORTED_NSTRETCH1GPU; + /// Indicates the display supports N Stretched on N GPUs + internal bool MANNER_SUPPORTED_NSTRETCHNGPU; + /// Reserved display info flag #2 + internal bool MANNER_SUPPORTED_RESERVED2; + /// Reserved display info flag #3 + internal bool MANNER_SUPPORTED_RESERVED3; + /// Indicates the display supports single desktop + internal bool MANNER_SUPPORTED_SINGLE; + /// Indicates the display supports overriding the mode timing + internal bool MODETIMING_OVERRIDESSUPPORTED; + /// Indicates the display supports multi-vpu + internal bool MULTIVPU_SUPPORTED; + /// Indicates the display is non-local to this machine + internal bool NONLOCAL; + /// Indicates the display is a projector + internal bool SHOWTYPE_PROJECTOR; + } + /// ADLDisplayInfo Array [StructLayout(LayoutKind.Sequential)] internal struct ADLDisplayInfoArray @@ -549,10 +728,50 @@ namespace ATI.ADL internal const int ADL_MAX_DISPLAYS = 40 /* 150 */; /// Define the maximum device name length internal const int ADL_MAX_DEVICENAME = 32; - /// Define the successful - internal const int ADL_SUCCESS = 0; - /// Define the failure - internal const int ADL_FAIL = -1; + /// Define the maximum EDID Data length + internal const int ADL_MAX_EDIDDATA_SIZE = 256; + + // Result Codes + /// ADL function completed successfully. + internal const int ADL_OK = 0; + /// Generic Error.Most likely one or more of the Escape calls to the driver failed! + internal const int ADL_ERR = -1; + /// Call can't be made due to disabled adapter. + internal const int ADL_ERR_DISABLED_ADAPTER = -10; + /// Invalid ADL index passed. + internal const int ADL_ERR_INVALID_ADL_IDX = -5; + /// Invalid Callback. + internal const int ADL_ERR_INVALID_CALLBACK = -11; + /// Invalid controller index passed. + internal const int ADL_ERR_INVALID_CONTROLLER_IDX = -6; + /// Invalid display index passed. + internal const int ADL_ERR_INVALID_DISPLAY_IDX = -7; + /// One of the parameter passed is invalid. + internal const int ADL_ERR_INVALID_PARAM = -3; + /// One of the parameter size is invalid. + internal const int ADL_ERR_INVALID_PARAM_SIZE = -4; + /// There's no Linux XDisplay in Linux Console environment. + internal const int ADL_ERR_NO_XDISPLAY = -21; + /// ADL not initialized. + internal const int ADL_ERR_NOT_INIT = -2; + /// Function not supported by the driver. + internal const int ADL_ERR_NOT_SUPPORTED = -8; + /// Null Pointer error. + internal const int ADL_ERR_NULL_POINTER = -9; + /// Display Resource conflict. + internal const int ADL_ERR_RESOURCE_CONFLICT = -12; + /// Err Set incomplete + internal const int ADL_ERR_SET_INCOMPLETE = -20; + /// All OK but need mode change. + internal const int ADL_OK_MODE_CHANGE = 2; + /// All OK, but need restart. + internal const int ADL_OK_RESTART = 3; + /// All OK, but need to wait + internal const int ADL_OK_WAIT = 4; + /// All OK, but with warning. + internal const int ADL_OK_WARNING = 1; + + /// Define the driver ok internal const int ADL_DRIVER_OK = 0; /// Maximum number of GL-Sync ports on the GL-Sync module @@ -624,6 +843,45 @@ namespace ATI.ADL /// Indicates Virtual Connector type. internal const int ADL_CONNECTOR_TYPE_VIRTUAL = 13; + // Display Info Constants + /// Indicates the display is connected . + internal const int ADL_DISPLAY_DISPLAYINFO_DISPLAYCONNECTED = 0x00000001; + /// Indicates the display is mapped within OS + internal const int ADL_DISPLAY_DISPLAYINFO_DISPLAYMAPPED = 0x00000002; + /// Indicates the display can be forced + internal const int ADL_DISPLAY_DISPLAYINFO_FORCIBLESUPPORTED = 0x00000008; + /// Indicates the display supports genlock + internal const int ADL_DISPLAY_DISPLAYINFO_GENLOCKSUPPORTED = 0x00000010; + /// Indicates the display is an LDA display. + internal const int ADL_DISPLAY_DISPLAYINFO_LDA_DISPLAY = 0x00000040; + /// Indicates the display supports 2x Horizontal stretch + internal const int ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_2HSTRETCH = 0x00000800; + /// Indicates the display supports 2x Vertical stretch + internal const int ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_2VSTRETCH = 0x00000400; + /// Indicates the display supports cloned desktops + internal const int ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_CLONE = 0x00000200; + /// Indicates the display supports extended desktops + internal const int ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_EXTENDED = 0x00001000; + /// Indicates the display supports N Stretched on 1 GPU + internal const int ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_NSTRETCH1GPU = 0x00010000; + /// Indicates the display supports N Stretched on N GPUs + internal const int ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_NSTRETCHNGPU = 0x00020000; + /// Reserved display info flag #2 + internal const int ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_RESERVED2 = 0x00040000; + /// Reserved display info flag #3 + internal const int ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_RESERVED3 = 0x00080000; + /// Indicates the display supports single desktop + internal const int ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_SINGLE = 0x00000100; + /// Indicates the display supports overriding the mode timing + internal const int ADL_DISPLAY_DISPLAYINFO_MODETIMING_OVERRIDESSUPPORTED = 0x00000080; + /// Indicates the display supports multi-vpu + internal const int ADL_DISPLAY_DISPLAYINFO_MULTIVPU_SUPPORTED = 0x00000020; + /// Indicates the display is non-local to this machine + internal const int ADL_DISPLAY_DISPLAYINFO_NONLOCAL = 0x00000004; + /// Indicates the display is a projector + internal const int ADL_DISPLAY_DISPLAYINFO_SHOWTYPE_PROJECTOR = 0x00100000; + + #endregion Internal Constant #region Internal Enums @@ -662,6 +920,15 @@ namespace ATI.ADL [DllImport(Kernel32_FileName)] internal static extern HMODULE GetModuleHandle (string moduleName); + [DllImport(Atiadlxx_FileName)] + internal static extern int ADL2_Main_Control_Create(ADL_Main_Memory_Alloc callback, int enumConnectedAdapters, out IntPtr contextHandle); + + [DllImport(Atiadlxx_FileName)] + internal static extern int ADL2_Main_Control_Destroy(IntPtr contextHandle); + + [DllImport(Atiadlxx_FileName)] + internal static extern int ADL2_Display_DDCInfo2_Get(IntPtr contextHandle, int adapterIndex, int displayIndex, out ADLDDCInfo2 DDCInfo); + [DllImport(Atiadlxx_FileName)] internal static extern int ADL_Main_Control_Create (ADL_Main_Memory_Alloc callback, int enumConnectedAdapters); @@ -695,6 +962,9 @@ namespace ATI.ADL [DllImport(Atiadlxx_FileName)] internal static extern int ADL_Display_DeviceConfig_Get(int adapterIndex, int displayIndex, out ADLDisplayConfig displayConfig); + [DllImport(Atiadlxx_FileName)] + internal static extern int ADL_Display_EdidData_Get(int adapterIndex, int displayIndex, ref ADLDisplayEDIDData EDIDData); + [DllImport(Atiadlxx_FileName)] internal static extern int ADL_Display_DisplayMapConfig_Get(int adapterIndex, out int numDisplayMap, out IntPtr displayMap, out int numDisplayTarget, out IntPtr displayTarget, int options); @@ -830,6 +1100,77 @@ namespace ATI.ADL } #endregion ADL_Main_Memory_Free + #region ADL2_Main_Control_Create + /// ADL2_Main_Control_Create Delegates + internal static ADL2_Main_Control_Create ADL2_Main_Control_Create + { + get + { + if (!ADL2_Main_Control_Create_Check && null == ADL2_Main_Control_Create_) + { + ADL2_Main_Control_Create_Check = true; + if (ADLCheckLibrary.IsFunctionValid("ADL2_Main_Control_Create")) + { + ADL2_Main_Control_Create_ = ADLImport.ADL2_Main_Control_Create; + } + } + return ADL2_Main_Control_Create_; + } + } + /// Private Delegate + private static ADL2_Main_Control_Create ADL2_Main_Control_Create_ = null; + /// check flag to indicate the delegate has been checked + private static bool ADL2_Main_Control_Create_Check = false; + #endregion ADL2_Main_Control_Create + + #region ADL2_Main_Control_Destroy + /// ADL2_Main_Control_Destroy Delegates + internal static ADL2_Main_Control_Destroy ADL2_Main_Control_Destroy + { + get + { + if (!ADL2_Main_Control_Destroy_Check && null == ADL2_Main_Control_Destroy_) + { + ADL2_Main_Control_Destroy_Check = true; + if (ADLCheckLibrary.IsFunctionValid("ADL2_Main_Control_Destroy")) + { + ADL2_Main_Control_Destroy_ = ADLImport.ADL2_Main_Control_Destroy; + } + } + return ADL2_Main_Control_Destroy_; + } + } + /// Private Delegate + private static ADL2_Main_Control_Destroy ADL2_Main_Control_Destroy_ = null; + /// check flag to indicate the delegate has been checked + private static bool ADL2_Main_Control_Destroy_Check = false; + #endregion ADL2_Main_Control_Destroy + + + #region ADL2_Display_DDCInfo2_Get + /// ADL2_Display_DDCInfo2_Get Delegates + internal static ADL2_Display_DDCInfo2_Get ADL2_Display_DDCInfo2_Get + { + get + { + if (!ADL2_Display_DDCInfo2_Get_Check && null == ADL2_Display_DDCInfo2_Get_) + { + ADL2_Display_DDCInfo2_Get_Check = true; + if (ADLCheckLibrary.IsFunctionValid("ADL2_Display_DDCInfo2_Get")) + { + ADL2_Display_DDCInfo2_Get_ = ADLImport.ADL2_Display_DDCInfo2_Get; + } + } + return ADL2_Display_DDCInfo2_Get_; + } + } + /// Private Delegate + private static ADL2_Display_DDCInfo2_Get ADL2_Display_DDCInfo2_Get_ = null; + /// check flag to indicate the delegate has been checked + private static bool ADL2_Display_DDCInfo2_Get_Check = false; + #endregion ADL2_Display_DDCInfo2_Get + + #region ADL_Main_Control_Create /// ADL_Main_Control_Create Delegates internal static ADL_Main_Control_Create ADL_Main_Control_Create @@ -1061,6 +1402,31 @@ namespace ATI.ADL private static bool ADL_Display_DisplayMapConfig_PossibleAddAndRemove_Check = false; #endregion ADL_Display_DisplayMapConfig_PossibleAddAndRemove + + #region ADL_Display_EdidData_Get + /// ADL_Display_EdidData_Get Delegates + internal static ADL_Display_EdidData_Get ADL_Display_EdidData_Get + { + get + { + if (!ADL_Display_EdidData_Get_Check && null == ADL_Display_EdidData_Get_) + { + ADL_Display_EdidData_Get_Check = true; + if (ADLCheckLibrary.IsFunctionValid("ADL_Display_EdidData_Get")) + { + ADL_Display_EdidData_Get_ = ADLImport.ADL_Display_EdidData_Get; + } + } + return ADL_Display_EdidData_Get_; + } + } + /// Private Delegate + private static ADL_Display_EdidData_Get ADL_Display_EdidData_Get_ = null; + /// check flag to indicate the delegate has been checked + private static bool ADL_Display_EdidData_Get_Check = false; + #endregion ADL_Display_EdidData_Get + + #region ADL_Display_DisplayInfo_Get /// ADL_Display_DisplayInfo_Get Delegates internal static ADL_Display_DisplayInfo_Get ADL_Display_DisplayInfo_Get @@ -1107,9 +1473,122 @@ namespace ATI.ADL /// check flag to indicate the delegate has been checked private static bool ADL_Display_SLSMapConfig_Get_Check = false; #endregion ADL_Display_SLSMapConfig_Get - + #endregion Export Functions + + #region ADL Helper Functions + + internal static ConvertedDisplayInfoValue ConvertDisplayInfoValue(int displayInfoValue) + { + ConvertedDisplayInfoValue expandedDisplayInfoValue = new ConvertedDisplayInfoValue(); + + // Indicates the display is connected + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_DISPLAYCONNECTED) == ADL.ADL_DISPLAY_DISPLAYINFO_DISPLAYCONNECTED) + expandedDisplayInfoValue.DISPLAYCONNECTED = true; + // Indicates the display is mapped within OS + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_DISPLAYMAPPED) == ADL.ADL_DISPLAY_DISPLAYINFO_DISPLAYMAPPED) + expandedDisplayInfoValue.DISPLAYMAPPED = true; + // Indicates the display can be forced + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_FORCIBLESUPPORTED) == ADL.ADL_DISPLAY_DISPLAYINFO_FORCIBLESUPPORTED) + expandedDisplayInfoValue.FORCIBLESUPPORTED = true; + // Indicates the display supports genlock + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_GENLOCKSUPPORTED) == ADL.ADL_DISPLAY_DISPLAYINFO_GENLOCKSUPPORTED) + expandedDisplayInfoValue.GENLOCKSUPPORTED = true; + // Indicates the display is an LDA display. + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_LDA_DISPLAY) == ADL.ADL_DISPLAY_DISPLAYINFO_LDA_DISPLAY) + expandedDisplayInfoValue.LDA_DISPLAY = true; + // Indicates the display supports 2x Horizontal stretch + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_2HSTRETCH) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_2HSTRETCH) + expandedDisplayInfoValue.MANNER_SUPPORTED_2HSTRETCH = true; + // Indicates the display supports 2x Vertical stretch + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_2VSTRETCH) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_2VSTRETCH) + expandedDisplayInfoValue.MANNER_SUPPORTED_2VSTRETCH = true; + // Indicates the display supports cloned desktops + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_CLONE) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_CLONE) + expandedDisplayInfoValue.MANNER_SUPPORTED_CLONE = true; + // Indicates the display supports extended desktops + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_EXTENDED) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_EXTENDED) + expandedDisplayInfoValue.MANNER_SUPPORTED_EXTENDED = true; + // Indicates the display supports N Stretched on 1 GPU + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_NSTRETCH1GPU) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_NSTRETCH1GPU) + expandedDisplayInfoValue.MANNER_SUPPORTED_NSTRETCH1GPU = true; + // Indicates the display supports N Stretched on N GPUs + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_NSTRETCHNGPU) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_NSTRETCHNGPU) + expandedDisplayInfoValue.MANNER_SUPPORTED_NSTRETCHNGPU = true; + // Reserved display info flag #2 + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_RESERVED2) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_RESERVED2) + expandedDisplayInfoValue.MANNER_SUPPORTED_RESERVED2 = true; + // Reserved display info flag #3 + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_RESERVED3) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_RESERVED3) + expandedDisplayInfoValue.MANNER_SUPPORTED_RESERVED3 = true; + // Indicates the display supports single desktop + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_SINGLE) == ADL.ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_SINGLE) + expandedDisplayInfoValue.MANNER_SUPPORTED_SINGLE = true; + // Indicates the display supports overriding the mode timing + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MODETIMING_OVERRIDESSUPPORTED) == ADL.ADL_DISPLAY_DISPLAYINFO_MODETIMING_OVERRIDESSUPPORTED) + expandedDisplayInfoValue.MODETIMING_OVERRIDESSUPPORTED = true; + // Indicates the display supports multi-vpu + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_MULTIVPU_SUPPORTED) == ADL.ADL_DISPLAY_DISPLAYINFO_MULTIVPU_SUPPORTED) + expandedDisplayInfoValue.MULTIVPU_SUPPORTED = true; + // Indicates the display is non-local to this machine + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_NONLOCAL) == ADL.ADL_DISPLAY_DISPLAYINFO_NONLOCAL) + expandedDisplayInfoValue.NONLOCAL = true; + // Indicates the display is a projector + if ((displayInfoValue & ADL.ADL_DISPLAY_DISPLAYINFO_SHOWTYPE_PROJECTOR) == ADL.ADL_DISPLAY_DISPLAYINFO_SHOWTYPE_PROJECTOR) + expandedDisplayInfoValue.SHOWTYPE_PROJECTOR = true; + + return expandedDisplayInfoValue; + + } + + internal static string ConvertADLReturnValueIntoWords(int adlReturnValue) + { + if (adlReturnValue == ADL.ADL_OK) + return "Success. Function worked as intended."; + if (adlReturnValue == ADL.ADL_ERR) + return "Generic Error.Most likely one or more of the Escape calls to the driver failed!"; + if (adlReturnValue == ADL.ADL_ERR_DISABLED_ADAPTER) + return "Call can't be made due to disabled adapter."; + if (adlReturnValue == ADL.ADL_ERR_INVALID_ADL_IDX) + return "Invalid ADL index passed."; + if (adlReturnValue == ADL.ADL_ERR_INVALID_CALLBACK) + return "Invalid Callback passed."; + if (adlReturnValue == ADL.ADL_ERR_INVALID_CONTROLLER_IDX) + return "Invalid controller index passed."; + if (adlReturnValue == ADL.ADL_ERR_INVALID_DISPLAY_IDX) + return "Invalid display index passed."; + if (adlReturnValue == ADL.ADL_ERR_INVALID_PARAM) + return "One of the parameter passed is invalid."; + if (adlReturnValue == ADL.ADL_ERR_INVALID_PARAM_SIZE) + return "One of the parameter size is invalid."; + if (adlReturnValue == ADL.ADL_ERR_NO_XDISPLAY) + return "There's no Linux XDisplay in Linux Console environment."; + if (adlReturnValue == ADL.ADL_ERR_NOT_INIT) + return "ADL not initialized. You need to run ADL_Main_Control_Create."; + if (adlReturnValue == ADL.ADL_ERR_NOT_SUPPORTED) + return "Function not supported by the driver."; + if (adlReturnValue == ADL.ADL_ERR_NULL_POINTER) + return "Null Pointer error."; + if (adlReturnValue == ADL.ADL_ERR_RESOURCE_CONFLICT) + return "Display Resource conflict."; + if (adlReturnValue == ADL.ADL_ERR_SET_INCOMPLETE) + return "Err Set incomplete"; + if (adlReturnValue == ADL.ADL_OK_MODE_CHANGE) + return "All OK but need mode change."; + if (adlReturnValue == ADL.ADL_OK_RESTART) + return "All OK, but need to restart."; + if (adlReturnValue == ADL.ADL_OK_WAIT) + return "All OK, but need to wait."; + if (adlReturnValue == ADL.ADL_OK_WARNING) + return "All OK, but with warning.."; + // If we get here, then we've got an ADL Return value that we don't understand! + return "ADL Return value not recognised. Your driver is likely newer than this code can understand."; + } + + + #endregion ADL Helper Functions + } #endregion ADL Class } diff --git a/DisplayMagicianShared/AMD/ADLWrapper.cs b/DisplayMagicianShared/AMD/ADLWrapper.cs index ac052ce..752ebe0 100644 --- a/DisplayMagicianShared/AMD/ADLWrapper.cs +++ b/DisplayMagicianShared/AMD/ADLWrapper.cs @@ -16,21 +16,22 @@ namespace DisplayMagicianShared.AMD // immediately when class is loaded for the first time. // .NET guarantees thread safety for static initialization private static ADLWrapper _instance = new ADLWrapper(); - + private bool _initialised = false; + private bool _initialisedADL2 = false; // To detect redundant calls private bool _disposed = false; // Instantiate a SafeHandle instance. private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true); - + private IntPtr _adlContextHandle = IntPtr.Zero; static ADLWrapper() { } public ADLWrapper() { - int ADLRet = ADL.ADL_FAIL; + int ADLRet = ADL.ADL_ERR; SharedLogger.logger.Trace("ADLWrapper/ADLWrapper: Intialising ADL library"); try @@ -41,7 +42,7 @@ namespace DisplayMagicianShared.AMD ADLRet = ADL.ADL_Main_Control_Create(ADL.ADL_Main_Memory_Alloc, 1); } - if (ADLRet == ADL.ADL_SUCCESS) + if (ADLRet == ADL.ADL_OK) { _initialised = true; SharedLogger.logger.Trace("ADLWrapper/ADLWrapper: ADL library was initialised successfully"); @@ -55,7 +56,30 @@ namespace DisplayMagicianShared.AMD { SharedLogger.logger.Error("ADLWrapper/ADLWrapper: Exception intialising ADL library. ADL_Main_Control_Create() caused an exception"); } - + + try + { + if (ADL.ADL2_Main_Control_Create != null) + { + // Second parameter is 1: Get only the present adapters + ADLRet = ADL.ADL2_Main_Control_Create(ADL.ADL_Main_Memory_Alloc, 1, out _adlContextHandle); + } + + if (ADLRet == ADL.ADL_OK) + { + _initialisedADL2 = true; + SharedLogger.logger.Trace("ADLWrapper/ADLWrapper: ADL2 library was initialised successfully"); + } + else + { + SharedLogger.logger.Error("ADLWrapper/ADLWrapper: Error intialising ADL2 library. ADL2_Main_Control_Create() returned error code " + ADL.ConvertADLReturnValueIntoWords(ADLRet)); + } + } + catch (Exception ex) + { + SharedLogger.logger.Error("ADLWrapper/ADLWrapper: Exception intialising ADL2 library. ADL2_Main_Control_Create() caused an exception"); + } + } ~ADLWrapper() @@ -65,7 +89,13 @@ namespace DisplayMagicianShared.AMD { if (null != ADL.ADL_Main_Control_Destroy) ADL.ADL_Main_Control_Destroy(); - } + } + // If the ADL2 library was initialised, then we need to free it up. + if (_initialisedADL2) + { + if (null != ADL.ADL2_Main_Control_Destroy) + ADL.ADL2_Main_Control_Destroy(_adlContextHandle); + } } // Public implementation of Dispose pattern callable by consumers. @@ -106,14 +136,15 @@ namespace DisplayMagicianShared.AMD { SharedLogger.logger.Trace($"ADLWrapper/GenerateProfileDisplayIdentifiers: Getting AMD active adapter count"); - int ADLRet = ADL.ADL_FAIL; + int ADLRet = ADL.ADL_ERR; int NumberOfAdapters = 0; int NumberOfDisplays = 0; List displayIdentifiers = new List(); + // Get the DisplayMap info (Desktops) for all adapters on the machine in one go // Keep a list of things we want to track - List allDisplayMaps = new List(); + /*List allDisplayMaps = new List(); List allDisplayTargets = new List(); if (ADL.ADL_Display_DisplayMapConfig_Get != null) @@ -123,11 +154,11 @@ namespace DisplayMagicianShared.AMD int numDisplayMaps = 0; int numDisplayTargets = 0; - // Get the DisplayMap info for all adapters on the machine in one go + // Get the DisplayMap info (Desktops) for all adapters on the machine in one go ADLRet = ADL.ADL_Display_DisplayMapConfig_Get(-1, out numDisplayMaps, out DisplayMapBuffer, out numDisplayTargets, out DisplayTargetBuffer, 0); if (ADLRet == ADL.ADL_SUCCESS) { - SharedLogger.logger.Trace($"ADLWrapper/GenerateProfileDisplayIdentifiers: Number Of DisplayMaps: {numDisplayMaps.ToString()} "); + SharedLogger.logger.Trace($"ADLWrapper/GenerateProfileDisplayIdentifiers: Number Of DisplayMaps (Desktops): {numDisplayMaps.ToString()} "); // Marshal the Display Maps ADLDisplayMap oneDisplayMap = new ADLDisplayMap(); @@ -179,9 +210,7 @@ namespace DisplayMagicianShared.AMD allPossibleAddDisplayTargets.Add(oneDisplayTarget); } - // Marshal the Possible Remove Targets - // oneDisplayTarget = new ADLDisplayTarget(); - + // Marshal the Possible Remove Targets too for (int displayTargetNum = 0; displayTargetNum < numPossibleRemoveTargets; displayTargetNum++) { // NOTE: the ToInt64 work on 64 bit, need to change to ToInt32 for 32 bit OS @@ -189,7 +218,7 @@ namespace DisplayMagicianShared.AMD allPossibleAddDisplayTargets.Add(oneDisplayTarget); } } - } + }*/ if (null != ADL.ADL_Adapter_NumberOfAdapters_Get) @@ -216,7 +245,7 @@ namespace DisplayMagicianShared.AMD // Get the Adapter info and put it in the AdapterBuffer SharedLogger.logger.Trace($"ADLWrapper/GenerateProfileDisplayIdentifiers: Running ADL_Adapter_AdapterInfo_Get to find all known AMD adapters."); ADLRet = ADL.ADL_Adapter_AdapterInfo_Get(AdapterBuffer, size); - if (ADLRet == ADL.ADL_SUCCESS) + if (ADLRet == ADL.ADL_OK) { // Use the AdapterBuffer pointer to marshal the OS Adapter Info into a structure OSAdapterInfoData = (ADLAdapterInfoArray)Marshal.PtrToStructure(AdapterBuffer, OSAdapterInfoData.GetType()); @@ -227,38 +256,53 @@ namespace DisplayMagicianShared.AMD // Go through each adapter for (int i = 0; i < NumberOfAdapters; i++) { + ADLAdapterInfo oneAdapter = OSAdapterInfoData.ADLAdapterInfo[i]; + + // Check if the adapter is active if (ADL.ADL_Adapter_Active_Get != null) - ADLRet = ADL.ADL_Adapter_Active_Get(OSAdapterInfoData.ADLAdapterInfo[i].AdapterIndex, ref IsActive); + ADLRet = ADL.ADL_Adapter_Active_Get(oneAdapter.AdapterIndex, ref IsActive); - if (ADLRet == ADL.ADL_SUCCESS) + if (ADLRet == ADL.ADL_OK) { // Only continue if the adapter is enabled if (IsActive != ADL.ADL_TRUE) { - SharedLogger.logger.Trace($"ADLWrapper/GenerateProfileDisplayIdentifiers: AMD Adapter #{i} isn't active ({OSAdapterInfoData.ADLAdapterInfo[i].AdapterName})."); + SharedLogger.logger.Trace($"ADLWrapper/GenerateProfileDisplayIdentifiers: AMD Adapter #{i} isn't active ({oneAdapter.AdapterName})."); continue; } - SharedLogger.logger.Trace($"ADLWrapper/GenerateProfileDisplayIdentifiers: AMD Adapter #{i} is active! ({OSAdapterInfoData.ADLAdapterInfo[i].AdapterName})."); + SharedLogger.logger.Trace($"ADLWrapper/GenerateProfileDisplayIdentifiers: AMD Adapter #{i} is active! ({oneAdapter.AdapterName})."); + + Console.WriteLine($"### Adapter Info for Adapter #{oneAdapter.AdapterIndex} ###"); + Console.WriteLine($"Adapter ID = {oneAdapter}"); + // Get the unique identifier from the Adapter int AdapterID = 0; if (ADL.ADL_Adapter_ID_Get != null) { - ADLRet = ADL.ADL_Adapter_ID_Get(OSAdapterInfoData.ADLAdapterInfo[i].AdapterIndex, ref AdapterID); - SharedLogger.logger.Trace($"ADLWrapper/GenerateProfileDisplayIdentifiers: AMD Adapter #{i} ({OSAdapterInfoData.ADLAdapterInfo[i].AdapterName}) AdapterID is {AdapterID.ToString()}"); + ADLRet = ADL.ADL_Adapter_ID_Get(oneAdapter.AdapterIndex, ref AdapterID); + SharedLogger.logger.Trace($"ADLWrapper/GenerateProfileDisplayIdentifiers: AMD Adapter #{i} ({oneAdapter.AdapterName}) AdapterID is {AdapterID.ToString()}"); } // Get the Adapter Capabilities ADLAdapterCapsX2 AdapterCapabilities = new ADLAdapterCapsX2(); if (ADL.ADL_AdapterX2_Caps != null) { - ADLRet = ADL.ADL_AdapterX2_Caps(OSAdapterInfoData.ADLAdapterInfo[i].AdapterIndex, out AdapterCapabilities); + ADLRet = ADL.ADL_AdapterX2_Caps(oneAdapter.AdapterIndex, out AdapterCapabilities); } //ADLAdapterCapsX2 AdapterCapabilities = (ADLAdapterCapsX2)Marshal.PtrToStructure(AdapterCapabilitiesBuffer, typeof(ADLAdapterCapsX2)); - Console.Write(AdapterCapabilities.AdapterID); + Console.WriteLine($"### Adapter Capabilities for Adapter #{oneAdapter.AdapterIndex} ###"); + Console.WriteLine($"Adapter ID = {AdapterCapabilities.AdapterID}"); + Console.WriteLine($"Adapter Capabilities Mask = {AdapterCapabilities.CapsMask}"); + Console.WriteLine($"Adapter Capabilities Value = {AdapterCapabilities.CapsValue}"); + Console.WriteLine($"Adapter Num of Connectors = {AdapterCapabilities.NumConnectors}"); + Console.WriteLine($"Adapter Num of Controllers = {AdapterCapabilities.NumControllers}"); + Console.WriteLine($"Adapter Num of Displays = {AdapterCapabilities.NumDisplays}"); + Console.WriteLine($"Adapter Num of GL Sync Connectors = {AdapterCapabilities.NumOfGLSyncConnectors}"); + Console.WriteLine($"Adapter Num of Overlays = {AdapterCapabilities.NumOverlays}"); // Obtain information about displays ADLDisplayInfo oneDisplayInfo = new ADLDisplayInfo(); @@ -269,20 +313,187 @@ namespace DisplayMagicianShared.AMD int j = 0; // Force the display detection and get the Display Info. Use 0 as last parameter to NOT force detection - ADLRet = ADL.ADL_Display_DisplayInfo_Get(OSAdapterInfoData.ADLAdapterInfo[i].AdapterIndex, ref NumberOfDisplays, out DisplayBuffer, 0); - if (ADLRet == ADL.ADL_SUCCESS) + ADLRet = ADL.ADL_Display_DisplayInfo_Get(oneAdapter.AdapterIndex, ref NumberOfDisplays, out DisplayBuffer, 0); + if (ADLRet == ADL.ADL_OK) { - List DisplayInfoData = new List(); - try { for (j = 0; j < NumberOfDisplays; j++) { + // Marshal the returned array of displayinfo into managed objects one by one // NOTE: the ToInt64 work on 64 bit, need to change to ToInt32 for 32 bit OS oneDisplayInfo = (ADLDisplayInfo)Marshal.PtrToStructure(new IntPtr(DisplayBuffer.ToInt64() + (j * Marshal.SizeOf(oneDisplayInfo))), oneDisplayInfo.GetType()); - DisplayInfoData.Add(oneDisplayInfo); + // Skip non connected displays + + Console.WriteLine($"### Display Info for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); + Console.WriteLine($"Display Connector = {oneDisplayInfo.DisplayConnector}"); + Console.WriteLine($"Display Controller Index = {oneDisplayInfo.DisplayControllerIndex}"); + Console.WriteLine($"Display Logical Adapter Index = {oneDisplayInfo.DisplayID.DisplayLogicalAdapterIndex}"); + Console.WriteLine($"Display Logical Index = {oneDisplayInfo.DisplayID.DisplayLogicalIndex}"); + Console.WriteLine($"Display Physical Adapter Index = {oneDisplayInfo.DisplayID.DisplayPhysicalAdapterIndex}"); + Console.WriteLine($"Display Physical Index = {oneDisplayInfo.DisplayID.DisplayPhysicalIndex}"); + Console.WriteLine($"Display Info Mask = {oneDisplayInfo.DisplayInfoMask}"); + Console.WriteLine($"Display Info Value = {oneDisplayInfo.DisplayInfoValue}"); + Console.WriteLine($"Display Manufacturer Name = {oneDisplayInfo.DisplayManufacturerName}"); + Console.WriteLine($"Display Name = {oneDisplayInfo.DisplayName}"); + Console.WriteLine($"Display Output Type = {oneDisplayInfo.DisplayOutputType}"); + Console.WriteLine($"Display Type = {oneDisplayInfo.DisplayType}"); + + // Convert the displayInfoValue to something usable using a library function I made + ConvertedDisplayInfoValue displayInforValue = ADL.ConvertDisplayInfoValue(oneDisplayInfo.DisplayInfoValue); + Console.WriteLine($"Display Info Value DISPLAYCONNECTED = {displayInforValue.DISPLAYCONNECTED}"); + Console.WriteLine($"Display Info Value DISPLAYMAPPED = {displayInforValue.DISPLAYMAPPED}"); + Console.WriteLine($"Display Info Value FORCIBLESUPPORTED = {displayInforValue.FORCIBLESUPPORTED}"); + Console.WriteLine($"Display Info Value GENLOCKSUPPORTED = {displayInforValue.GENLOCKSUPPORTED}"); + Console.WriteLine($"Display Info Value LDA_DISPLAY = {displayInforValue.LDA_DISPLAY}"); + Console.WriteLine($"Display Info Value MANNER_SUPPORTED_2HSTRETCH = {displayInforValue.MANNER_SUPPORTED_2HSTRETCH}"); + Console.WriteLine($"Display Info Value MANNER_SUPPORTED_2VSTRETCH = {displayInforValue.MANNER_SUPPORTED_2VSTRETCH}"); + Console.WriteLine($"Display Info Value MANNER_SUPPORTED_CLONE = {displayInforValue.MANNER_SUPPORTED_CLONE}"); + Console.WriteLine($"Display Info Value MANNER_SUPPORTED_EXTENDED = {displayInforValue.MANNER_SUPPORTED_EXTENDED}"); + Console.WriteLine($"Display Info Value MANNER_SUPPORTED_NSTRETCH1GPU = {displayInforValue.MANNER_SUPPORTED_NSTRETCH1GPU}"); + Console.WriteLine($"Display Info Value MANNER_SUPPORTED_NSTRETCHNGPU = {displayInforValue.MANNER_SUPPORTED_NSTRETCHNGPU}"); + Console.WriteLine($"Display Info Value MANNER_SUPPORTED_SINGLE = {displayInforValue.MANNER_SUPPORTED_SINGLE}"); + Console.WriteLine($"Display Info Value MODETIMING_OVERRIDESSUPPORTED = {displayInforValue.MODETIMING_OVERRIDESSUPPORTED}"); + Console.WriteLine($"Display Info Value MULTIVPU_SUPPORTED = {displayInforValue.MULTIVPU_SUPPORTED}"); + Console.WriteLine($"Display Info Value NONLOCAL = {displayInforValue.NONLOCAL}"); + Console.WriteLine($"Display Info Value SHOWTYPE_PROJECTOR = {displayInforValue.SHOWTYPE_PROJECTOR}"); + + if ((oneDisplayInfo.DisplayInfoValue & 1) != 1) + { + SharedLogger.logger.Trace($"ADLWrapper/GenerateProfileDisplayIdentifiers: AMD Adapter #{i} ({oneAdapter.AdapterName}) AdapterID display ID#{j} is not connected"); + continue; + } + + // Skip connected but non-mapped displays (not mapped in windows) - wae want all displays currently visible in the OS + if ((oneDisplayInfo.DisplayInfoValue & 2) != 2) + { + SharedLogger.logger.Trace($"ADLWrapper/GenerateProfileDisplayIdentifiers: AMD Adapter #{i} ({oneAdapter.AdapterName}) AdapterID display ID#{j} is not connected"); + continue; + } + + ADLDisplayConfig displayConfig = new ADLDisplayConfig(); + if (ADL.ADL_Display_DeviceConfig_Get != null) + { + // Get the DisplayConfig from the Display + ADLRet = ADL.ADL_Display_DeviceConfig_Get(oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID.DisplayLogicalIndex, out displayConfig); + if (ADLRet == ADL.ADL_OK) + { + Console.WriteLine($"### Display Device Config for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); + Console.WriteLine($"Display Connector Type = {displayConfig.ConnectorType}"); + Console.WriteLine($"Display Device Data = {displayConfig.DeviceData}"); + Console.WriteLine($"Display Overridded Device Data = {displayConfig.OverriddedDeviceData}"); + Console.WriteLine($"Display Reserved Data = {displayConfig.Reserved}"); + Console.WriteLine($"Display Size = {displayConfig.Size}"); + } + } + + ADLDDCInfo2 displayDDCInfo2 = new ADLDDCInfo2(); + // Create a stringbuilder buffer that EDID can be loaded into + //displayEDIDData.EDIDData = new StringBuilder(256); + + if (ADL.ADL2_Display_DDCInfo2_Get != null) + { + // Get the EDID Data from the Display + ADLRet = ADL.ADL2_Display_DDCInfo2_Get(_adlContextHandle, oneAdapter.AdapterIndex, oneDisplayInfo.DisplayID.DisplayPhysicalIndex, out displayDDCInfo2); + if (ADLRet == ADL.ADL_OK) + { + Console.WriteLine($"### Display EDID Data for Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex} ###"); + Console.WriteLine($"Display Manufacturer ID = {displayDDCInfo2.ManufacturerID}"); + /*Console.WriteLine($"Display EDID Data = {displayDDCInfo2.EDIDData}"); + Console.WriteLine($"Display EDID Size = {displayDDCInfo2.EDIDSize}"); + Console.WriteLine($"Display EDID Flag = {displayDDCInfo2.Flag}"); + Console.WriteLine($"Display EDID Reserved = {displayDDCInfo2.Reserved}"); + Console.WriteLine($"Display EDID Data Size = {displayDDCInfo2.Size}");*/ + } else + { + Console.WriteLine($"Error running ADL_Display_EdidData_Get on Display #{oneDisplayInfo.DisplayID.DisplayLogicalIndex} on Adapter #{oneAdapter.AdapterIndex}: {ADL.ConvertADLReturnValueIntoWords(ADLRet)}"); + } + } + + + + // Create an array of all the important display info we need to record + List displayInfoIdentifierSection = new List(); + displayInfoIdentifierSection.Add("AMD"); + try + { + displayInfoIdentifierSection.Add(oneAdapter.AdapterName); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"ADLWrapper/GenerateProfileDisplayIdentifiers: Exception getting AMD Adapter Name from video card. Substituting with a # instead"); + displayInfoIdentifierSection.Add("#"); + } + + try + { + displayInfoIdentifierSection.Add(oneAdapter.AdapterIndex.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"ADLWrapper/GenerateProfileDisplayIdentifiers: Exception getting AMD Adapter Index from video card. Substituting with a # instead"); + displayInfoIdentifierSection.Add("#"); + } + + try + { + displayInfoIdentifierSection.Add(oneAdapter.VendorID.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"ADLWrapper/GenerateProfileDisplayIdentifiers: Exception getting AMD VendorID from video card. Substituting with a # instead"); + displayInfoIdentifierSection.Add("1002"); + } + + try + { + displayInfoIdentifierSection.Add(AdapterID.ToString()); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"ADLWrapper/GenerateProfileDisplayIdentifiers: Exception getting AMD AdapterID from video card. Substituting with a # instead"); + displayInfoIdentifierSection.Add("#"); + } + + try + { + ADL.ADLConnectionType connector = (ADL.ADLConnectionType)oneDisplayInfo.DisplayOutputType; + displayInfoIdentifierSection.Add(connector.ToString("G")); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"ADLWrapper/GenerateProfileDisplayIdentifiers: Exception getting AMD Display Connector from video card to display. Substituting with a # instead"); + displayInfoIdentifierSection.Add("#"); + } + + try + { + displayInfoIdentifierSection.Add(oneDisplayInfo.DisplayManufacturerName); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"ADLWrapper/GenerateProfileDisplayIdentifiers: Exception getting Display manufacturer from AMD video card. Substituting with a # instead"); + displayInfoIdentifierSection.Add("#"); + } + + try + { + displayInfoIdentifierSection.Add(oneDisplayInfo.DisplayName); + } + catch (Exception ex) + { + SharedLogger.logger.Warn(ex, $"ADLWrapper/GenerateProfileDisplayIdentifiers: Exception getting Display Name from AMD video card. Substituting with a # instead"); + displayInfoIdentifierSection.Add("#"); + } + + // Create a display identifier out of it + string displayIdentifier = String.Join("|", displayInfoIdentifierSection); + // Add it to the list of display identifiers so we can return it + displayIdentifiers.Add(displayIdentifier); + + SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}"); } } catch (Exception ex) @@ -290,118 +501,6 @@ namespace DisplayMagicianShared.AMD Console.WriteLine("Exception caused trying to access attached displays"); continue; } - Console.WriteLine("\nTotal Number of Displays supported: " + NumberOfDisplays.ToString()); - Console.WriteLine("\nDispID AdpID Type OutType CnctType Connected Mapped InfoValue DisplayName "); - - for (j = 0; j < NumberOfDisplays; j++) - { - // Skip non connected displays - if ((DisplayInfoData[j].DisplayInfoValue & 1) != 1) - { - SharedLogger.logger.Trace($"ADLWrapper/GenerateProfileDisplayIdentifiers: AMD Adapter #{i} ({OSAdapterInfoData.ADLAdapterInfo[i].AdapterName}) AdapterID display ID#{j} is not connected"); - continue; - } - - // Skip connected but non-mapped displays (not mapped in windows) - wae want all displays currently visible in the OS - if ((DisplayInfoData[j].DisplayInfoValue & 2) != 2) - { - SharedLogger.logger.Trace($"ADLWrapper/GenerateProfileDisplayIdentifiers: AMD Adapter #{i} ({OSAdapterInfoData.ADLAdapterInfo[i].AdapterName}) AdapterID display ID#{j} is not connected"); - continue; - } - - /*ADLDisplayConfig DisplayConfig = new ADLDisplayConfig(); - if (ADL.ADL_Display_DeviceConfig_Get != null) - { - // Force the display detection and get the Display Info. Use 0 as last parameter to NOT force detection - ADLRet = ADL.ADL_Display_DeviceConfig_Get(OSAdapterInfoData.ADLAdapterInfo[i].AdapterIndex, DisplayInfoData[j].DisplayID.DisplayLogicalIndex, out DisplayConfig); - if (ADLRet == ADL.ADL_SUCCESS) - { - - } - }*/ - - // Create an array of all the important display info we need to record - List displayInfoIdentifierSection = new List(); - displayInfoIdentifierSection.Add("AMD"); - try - { - displayInfoIdentifierSection.Add(OSAdapterInfoData.ADLAdapterInfo[i].AdapterName); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ADLWrapper/GenerateProfileDisplayIdentifiers: Exception getting AMD Adapter Name from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(OSAdapterInfoData.ADLAdapterInfo[i].AdapterIndex.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ADLWrapper/GenerateProfileDisplayIdentifiers: Exception getting AMD Adapter Index from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(OSAdapterInfoData.ADLAdapterInfo[i].VendorID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ADLWrapper/GenerateProfileDisplayIdentifiers: Exception getting AMD VendorID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("1002"); - } - - try - { - displayInfoIdentifierSection.Add(AdapterID.ToString()); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ADLWrapper/GenerateProfileDisplayIdentifiers: Exception getting AMD AdapterID from video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - ADL.ADLConnectionType connector = (ADL.ADLConnectionType)DisplayInfoData[j].DisplayOutputType; - displayInfoIdentifierSection.Add(connector.ToString("G")); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ADLWrapper/GenerateProfileDisplayIdentifiers: Exception getting AMD Display Connector from video card to display. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(DisplayInfoData[j].DisplayManufacturerName); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ADLWrapper/GenerateProfileDisplayIdentifiers: Exception getting Display manufacturer from AMD video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - try - { - displayInfoIdentifierSection.Add(DisplayInfoData[j].DisplayName); - } - catch (Exception ex) - { - SharedLogger.logger.Warn(ex, $"ADLWrapper/GenerateProfileDisplayIdentifiers: Exception getting Display Name from AMD video card. Substituting with a # instead"); - displayInfoIdentifierSection.Add("#"); - } - - // Create a display identifier out of it - string displayIdentifier = String.Join("|", displayInfoIdentifierSection); - // Add it to the list of display identifiers so we can return it - displayIdentifiers.Add(displayIdentifier); - - SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}"); - - } } else { @@ -443,7 +542,7 @@ namespace DisplayMagicianShared.AMD { SharedLogger.logger.Trace($"ADLWrapper/GenerateProfileDisplayIdentifiers: Getting AMD active adapter count"); - int ADLRet = ADL.ADL_FAIL; + int ADLRet = ADL.ADL_ERR; int NumberOfAdapters = 0; int NumberOfDisplays = 0; @@ -474,7 +573,7 @@ namespace DisplayMagicianShared.AMD // Get the Adapter info and put it in the AdapterBuffer SharedLogger.logger.Trace($"ADLWrapper/GenerateProfileDisplayIdentifiers: Running ADL_Adapter_AdapterInfo_Get to find all known AMD adapters."); ADLRet = ADL.ADL_Adapter_AdapterInfo_Get(AdapterBuffer, size); - if (ADLRet == ADL.ADL_SUCCESS) + if (ADLRet == ADL.ADL_OK) { // Use the AdapterBuffer pointer to marshal the OS Adapter Info into a structure OSAdapterInfoData = (ADLAdapterInfoArray)Marshal.PtrToStructure(AdapterBuffer, OSAdapterInfoData.GetType()); @@ -489,7 +588,7 @@ namespace DisplayMagicianShared.AMD if (ADL.ADL_Adapter_Active_Get != null) ADLRet = ADL.ADL_Adapter_Active_Get(OSAdapterInfoData.ADLAdapterInfo[i].AdapterIndex, ref IsActive); - if (ADLRet == ADL.ADL_SUCCESS) + if (ADLRet == ADL.ADL_OK) { // Only continue if the adapter is enabled if (IsActive != ADL.ADL_TRUE) @@ -528,7 +627,7 @@ namespace DisplayMagicianShared.AMD // Force the display detection and get the Display Info. Use 0 as last parameter to NOT force detection ADLRet = ADL.ADL_Display_DisplayInfo_Get(OSAdapterInfoData.ADLAdapterInfo[i].AdapterIndex, ref NumberOfDisplays, out DisplayBuffer, 0); - if (ADLRet == ADL.ADL_SUCCESS) + if (ADLRet == ADL.ADL_OK) { List DisplayInfoData = new List(); @@ -563,9 +662,9 @@ namespace DisplayMagicianShared.AMD ADLDisplayConfig DisplayConfig = new ADLDisplayConfig(); if (ADL.ADL_Display_DeviceConfig_Get != null) { - // Force the display detection and get the Display Info. Use 0 as last parameter to NOT force detection + // Get the device config ADLRet = ADL.ADL_Display_DeviceConfig_Get(OSAdapterInfoData.ADLAdapterInfo[i].AdapterIndex, DisplayInfoData[j].DisplayID.DisplayLogicalIndex, out DisplayConfig); - if (ADLRet == ADL.ADL_SUCCESS) + if (ADLRet == ADL.ADL_OK) { } @@ -691,3 +790,4 @@ namespace DisplayMagicianShared.AMD } } } +