Update AMDLibrary and WinLibrary to skip HDR if connector doesn't support it

This works for WinLibrary and *should* work for AMDLibrary, but I don't have an AMD video card to test it with :(.
This commit is contained in:
Terry MacDonald 2022-02-06 15:33:15 +13:00
parent f4adf8a4f2
commit 4f64537d89
4 changed files with 168 additions and 83 deletions

View File

@ -26,8 +26,8 @@ using System.Resources;
[assembly: Guid("e4ceaf5e-ad01-4695-b179-31168eb74c48")]
// Version information
[assembly: AssemblyVersion("2.2.0.223")]
[assembly: AssemblyFileVersion("2.2.0.223")]
[assembly: AssemblyVersion("2.2.0.224")]
[assembly: AssemblyFileVersion("2.2.0.224")]
[assembly: NeutralResourcesLanguageAttribute( "en" )]
[assembly: CLSCompliant(true)]

View File

@ -81,7 +81,7 @@ namespace DisplayMagicianShared.AMD
ATICV_NONI2C_JPN_Dongle = 7,
Proprietary = 8,
HDMITypeA = 10,
HTMITypeB = 11,
HDMITypeB = 11,
SVideo = 12,
Composite = 13,
RCA_3Component = 14,
@ -794,7 +794,7 @@ namespace DisplayMagicianShared.AMD
public bool DisplayConnectorIsATICVDongleNonI2CNTSC => DisplayConnector == ADL_DISPLAY_CONNECTION_TYPE.ATICV_NONI2C_NTSC_Dongle;
public bool DisplayConnectorIsProprietary => DisplayConnector == ADL_DISPLAY_CONNECTION_TYPE.Proprietary;
public bool DisplayConnectorIsHDMITypeA => DisplayConnector == ADL_DISPLAY_CONNECTION_TYPE.HDMITypeA;
public bool DisplayConnectorIsHDMITypeB => DisplayConnector == ADL_DISPLAY_CONNECTION_TYPE.HTMITypeB;
public bool DisplayConnectorIsHDMITypeB => DisplayConnector == ADL_DISPLAY_CONNECTION_TYPE.HDMITypeB;
public bool DisplayConnectorIsSVideo => DisplayConnector == ADL_DISPLAY_CONNECTION_TYPE.SVideo;
public bool DisplayConnectorIsComposite => DisplayConnector == ADL_DISPLAY_CONNECTION_TYPE.Composite;
public bool DisplayConnectorIsRCA3Component => DisplayConnector == ADL_DISPLAY_CONNECTION_TYPE.RCA_3Component;

View File

@ -166,6 +166,7 @@ namespace DisplayMagicianShared.AMD
private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true);
private IntPtr _adlContextHandle = IntPtr.Zero;
private AMD_DISPLAY_CONFIG _activeDisplayConfig;
public List<ADL_DISPLAY_CONNECTION_TYPE> SkippedColorConnectionTypes;
static AMDLibrary() { }
public AMDLibrary()
@ -212,6 +213,16 @@ namespace DisplayMagicianShared.AMD
SharedLogger.logger.Info(ex, $"AMDLibrary/AMDLibrary: Exception trying to load the AMD ADL DLL {ADLImport.ATI_ADL_DLL}. This generally means you don't have the AMD ADL driver installed.");
}
// Populate the list of ConnectionTypes we want to skip as they don't support querying
SkippedColorConnectionTypes = new List<ADL_DISPLAY_CONNECTION_TYPE> {
ADL_DISPLAY_CONNECTION_TYPE.Composite,
ADL_DISPLAY_CONNECTION_TYPE.DVI_D,
ADL_DISPLAY_CONNECTION_TYPE.DVI_I,
ADL_DISPLAY_CONNECTION_TYPE.RCA_3Component,
ADL_DISPLAY_CONNECTION_TYPE.SVideo,
ADL_DISPLAY_CONNECTION_TYPE.VGA
};
}
~AMDLibrary()
@ -887,49 +898,105 @@ namespace DisplayMagicianShared.AMD
}
int forceDetect = 0;
int numDisplays;
IntPtr displayInfoBuffer;
ADLRet = ADLImport.ADL2_Display_DisplayInfo_Get(_adlContextHandle, adapterIndex, out numDisplays, out displayInfoBuffer, forceDetect);
if (ADLRet == ADL_STATUS.ADL_OK)
{
SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: ADL2_Display_DisplayInfo_Get returned information about all displaytargets connected to AMD adapter #{adapterIndex}.");
}
else if (ADLRet == ADL_STATUS.ADL_ERR_NULL_POINTER || ADLRet == ADL_STATUS.ADL_ERR_NOT_SUPPORTED)
{
SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: ADL2_Display_DisplayInfo_Get returned ADL_ERR_NULL_POINTER so skipping getting display info from AMD adapter #{adapterIndex}.");
continue;
}
else
{
SharedLogger.logger.Error($"AMDLibrary/PrintActiveConfig: ERROR - ADL2_Display_DisplayInfo_Get returned ADL_STATUS {ADLRet} when trying to get the display target info from AMD adapter #{adapterIndex}.");
}
ADL_DISPLAY_INFO[] displayInfoArray = { };
if (numDisplays > 0)
{
IntPtr currentDisplayInfoBuffer = displayInfoBuffer;
displayInfoArray = new ADL_DISPLAY_INFO[numDisplays];
for (int i = 0; i < numDisplays; i++)
{
// build a structure in the array slot
displayInfoArray[i] = new ADL_DISPLAY_INFO();
// fill the array slot structure with the data from the buffer
displayInfoArray[i] = (ADL_DISPLAY_INFO)Marshal.PtrToStructure(currentDisplayInfoBuffer, typeof(ADL_DISPLAY_INFO));
// destroy the bit of memory we no longer need
Marshal.DestroyStructure(currentDisplayInfoBuffer, typeof(ADL_DISPLAY_INFO));
// advance the buffer forwards to the next object
currentDisplayInfoBuffer = (IntPtr)((long)currentDisplayInfoBuffer + Marshal.SizeOf(displayInfoArray[i]));
//currentDisplayTargetBuffer = (IntPtr)((long)currentDisplayTargetBuffer + Marshal.SizeOf(displayTargetArray[i]));
}
// Free the memory used by the buffer
Marshal.FreeCoTaskMem(displayInfoBuffer);
}
myDisplayConfig.HdrConfigs = new Dictionary<int, AMD_HDR_CONFIG>();
// Now we need to get all the displays connected to this adapter so that we can get their HDR state
foreach (var displayTarget in displayTargetArray)
{
// Go through each display and see if HDR is supported
int supported = 0;
int enabled = 0;
ADLRet = ADLImport.ADL2_Display_HDRState_Get(_adlContextHandle, adapterIndex, displayTarget.DisplayID, out supported, out enabled);
if (ADLRet == ADL_STATUS.ADL_OK)
// We need to skip recording anything that doesn't support color communication
// Firstly find the display connector if we can
ADL_DISPLAY_CONNECTION_TYPE displayConnector;
try
{
if (supported > 0 && enabled > 0)
displayConnector = displayInfoArray.First(d => d.DisplayID == displayTarget.DisplayID).DisplayConnector;
}
catch (Exception ex)
{
displayConnector = ADL_DISPLAY_CONNECTION_TYPE.Unknown;
}
SharedLogger.logger.Trace($"AMDLibrary/PrintActiveConfig: Display {displayTarget.DisplayID} on AMD adapter #{adapterIndex} has a {displayConnector} connector.");
// Then only get the HDR config stuff if the connection actually suports getting the HDR info!
if (!SkippedColorConnectionTypes.Contains(displayConnector))
{
// Go through each display and see if HDR is supported
int supported = 0;
int enabled = 0;
ADLRet = ADLImport.ADL2_Display_HDRState_Get(_adlContextHandle, adapterIndex, displayTarget.DisplayID, out supported, out enabled);
if (ADLRet == ADL_STATUS.ADL_OK)
{
SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: ADL2_Display_HDRState_Get says that display {displayTarget.DisplayID.DisplayLogicalIndex} on adapter {adapterIndex} supports HDR and HDR is enabled.");
}
else if (supported > 0 && enabled == 0)
{
SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: ADL2_Display_HDRState_Get says that display {displayTarget.DisplayID.DisplayLogicalIndex} on adapter {adapterIndex} supports HDR and HDR is NOT enabled.");
if (supported > 0 && enabled > 0)
{
SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: ADL2_Display_HDRState_Get says that display {displayTarget.DisplayID.DisplayLogicalIndex} on adapter {adapterIndex} supports HDR and HDR is enabled.");
}
else if (supported > 0 && enabled == 0)
{
SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: ADL2_Display_HDRState_Get says that display {displayTarget.DisplayID.DisplayLogicalIndex} on adapter {adapterIndex} supports HDR and HDR is NOT enabled.");
}
else
{
SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: ADL2_Display_HDRState_Get says that display {displayTarget.DisplayID.DisplayLogicalIndex} on adapter {adapterIndex} does NOT support HDR.");
}
}
else
{
SharedLogger.logger.Trace($"AMDLibrary/GetAMDDisplayConfig: ADL2_Display_HDRState_Get says that display {displayTarget.DisplayID.DisplayLogicalIndex} on adapter {adapterIndex} does NOT support HDR.");
SharedLogger.logger.Error($"AMDLibrary/GetAMDDisplayConfig: ERROR - ADL2_Display_HDRState_Get returned ADL_STATUS {ADLRet} when trying to get the display target info from AMD adapter {adapterIndex} in the computer.");
throw new AMDLibraryException($"ADL2_Display_HDRState_Get returned ADL_STATUS {ADLRet} when trying to get the display target info from AMD adapter {adapterIndex} in the computer");
}
AMD_HDR_CONFIG hdrConfig = new AMD_HDR_CONFIG();
hdrConfig.AdapterIndex = displayTarget.DisplayID.DisplayPhysicalAdapterIndex;
hdrConfig.HDREnabled = enabled > 0 ? true : false;
hdrConfig.HDRSupported = supported > 0 ? true : false;
// Now add this to the HDR config list.
if (!myDisplayConfig.HdrConfigs.ContainsKey(displayTarget.DisplayID.DisplayLogicalIndex))
{
// Save the new display config only if we haven't already
myDisplayConfig.HdrConfigs.Add(displayTarget.DisplayID.DisplayLogicalIndex, hdrConfig);
}
}
else
{
SharedLogger.logger.Error($"AMDLibrary/GetAMDDisplayConfig: ERROR - ADL2_Display_HDRState_Get returned ADL_STATUS {ADLRet} when trying to get the display target info from AMD adapter {adapterIndex} in the computer.");
throw new AMDLibraryException($"ADL2_Display_HDRState_Get returned ADL_STATUS {ADLRet} when trying to get the display target info from AMD adapter {adapterIndex} in the computer");
}
AMD_HDR_CONFIG hdrConfig = new AMD_HDR_CONFIG();
hdrConfig.AdapterIndex = displayTarget.DisplayID.DisplayPhysicalAdapterIndex;
hdrConfig.HDREnabled = enabled > 0 ? true : false;
hdrConfig.HDRSupported = supported > 0 ? true : false;
// Now add this to the HDR config list.
if (!myDisplayConfig.HdrConfigs.ContainsKey(displayTarget.DisplayID.DisplayLogicalIndex))
{
// Save the new display config only if we haven't already
myDisplayConfig.HdrConfigs.Add(displayTarget.DisplayID.DisplayLogicalIndex, hdrConfig);
}
}
}
// Add the AMD Display Identifiers

View File

@ -87,6 +87,7 @@ namespace DisplayMagicianShared.Windows
private bool _initialised = false;
private WINDOWS_DISPLAY_CONFIG _activeDisplayConfig;
public List<DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY> SkippedColorConnectionTypes;
// To detect redundant calls
private bool _disposed = false;
@ -97,6 +98,15 @@ namespace DisplayMagicianShared.Windows
static WinLibrary() { }
public WinLibrary()
{
// Populate the list of ConnectionTypes we want to skip as they don't support querying
SkippedColorConnectionTypes = new List<DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY> {
DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY.DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15,
DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY.DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO,
DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY.DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO,
DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY.DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI,
DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY.DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO
};
SharedLogger.logger.Trace("WinLibrary/WinLibrary: Intialising Windows CCD library interface");
_initialised = true;
_activeDisplayConfig = GetActiveConfig();
@ -484,70 +494,78 @@ namespace DisplayMagicianShared.Windows
// Get advanced color info
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Attempting to get advanced color info for display {paths[i].TargetInfo.Id}.");
var colorInfo = new DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO();
colorInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO;
colorInfo.Header.Size = (uint)Marshal.SizeOf<DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO>();
colorInfo.Header.AdapterId = paths[i].TargetInfo.AdapterId;
colorInfo.Header.Id = paths[i].TargetInfo.Id;
err = CCDImport.DisplayConfigGetDeviceInfo(ref colorInfo);
if (err == WIN32STATUS.ERROR_SUCCESS)
// We need to skip recording anything from a connection that doesn't support color communication
if (!SkippedColorConnectionTypes.Contains(paths[i].TargetInfo.OutputTechnology))
{
gotAdvancedColorInfo = true;
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found color info for display {paths[i].TargetInfo.Id}.");
if (colorInfo.AdvancedColorSupported)
var colorInfo = new DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO();
colorInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO;
colorInfo.Header.Size = (uint)Marshal.SizeOf<DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO>();
colorInfo.Header.AdapterId = paths[i].TargetInfo.AdapterId;
colorInfo.Header.Id = paths[i].TargetInfo.Id;
err = CCDImport.DisplayConfigGetDeviceInfo(ref colorInfo);
if (err == WIN32STATUS.ERROR_SUCCESS)
{
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: HDR is supported for display {paths[i].TargetInfo.Id}.");
gotAdvancedColorInfo = true;
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found color info for display {paths[i].TargetInfo.Id}.");
if (colorInfo.AdvancedColorSupported)
{
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: HDR is supported for display {paths[i].TargetInfo.Id}.");
}
else
{
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: HDR is NOT supported for display {paths[i].TargetInfo.Id}.");
}
if (colorInfo.AdvancedColorEnabled)
{
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: HDR is enabled for display {paths[i].TargetInfo.Id}.");
}
else
{
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: HDR is NOT enabled for display {paths[i].TargetInfo.Id}.");
}
}
else
{
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: HDR is NOT supported for display {paths[i].TargetInfo.Id}.");
SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - Unabled to get advanced color settings for display {paths[i].TargetInfo.Id}.");
}
if (colorInfo.AdvancedColorEnabled)
// get SDR white levels
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Attempting to get SDR white levels for display {paths[i].TargetInfo.Id}.");
var whiteLevelInfo = new DISPLAYCONFIG_SDR_WHITE_LEVEL();
whiteLevelInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SDR_WHITE_LEVEL;
whiteLevelInfo.Header.Size = (uint)Marshal.SizeOf<DISPLAYCONFIG_SDR_WHITE_LEVEL>();
whiteLevelInfo.Header.AdapterId = paths[i].TargetInfo.AdapterId;
whiteLevelInfo.Header.Id = paths[i].TargetInfo.Id;
err = CCDImport.DisplayConfigGetDeviceInfo(ref whiteLevelInfo);
if (err == WIN32STATUS.ERROR_SUCCESS)
{
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: HDR is enabled for display {paths[i].TargetInfo.Id}.");
gotSdrWhiteLevel = true;
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found SDR White levels for display {paths[i].TargetInfo.Id}.");
}
else
{
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: HDR is NOT enabled for display {paths[i].TargetInfo.Id}.");
SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - Unabled to get SDR White levels for display {paths[i].TargetInfo.Id}.");
}
// Only create and add the ADVANCED_HDR_INFO_PER_PATH if the info is there
if (gotAdvancedColorInfo)
{
ADVANCED_HDR_INFO_PER_PATH hdrInfo = new ADVANCED_HDR_INFO_PER_PATH();
hdrInfo.AdapterId = paths[i].TargetInfo.AdapterId;
hdrInfo.Id = paths[i].TargetInfo.Id;
hdrInfo.AdvancedColorInfo = colorInfo;
if (gotSdrWhiteLevel)
{
hdrInfo.SDRWhiteLevel = whiteLevelInfo;
}
windowsDisplayConfig.DisplayHDRStates.Add(hdrInfo);
}
}
else
{
SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - Unabled to get advanced color settings for display {paths[i].TargetInfo.Id}.");
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Skipping getting HDR and SDR White levels information as display {paths[i].TargetInfo.Id} uses a {paths[i].TargetInfo.OutputTechnology} connector that doesn't support HDR.");
}
// get SDR white levels
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Attempting to get SDR white levels for display {paths[i].TargetInfo.Id}.");
var whiteLevelInfo = new DISPLAYCONFIG_SDR_WHITE_LEVEL();
whiteLevelInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SDR_WHITE_LEVEL;
whiteLevelInfo.Header.Size = (uint)Marshal.SizeOf<DISPLAYCONFIG_SDR_WHITE_LEVEL>();
whiteLevelInfo.Header.AdapterId = paths[i].TargetInfo.AdapterId;
whiteLevelInfo.Header.Id = paths[i].TargetInfo.Id;
err = CCDImport.DisplayConfigGetDeviceInfo(ref whiteLevelInfo);
if (err == WIN32STATUS.ERROR_SUCCESS)
{
gotSdrWhiteLevel = true;
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found SDR White levels for display {paths[i].TargetInfo.Id}.");
}
else
{
SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - Unabled to get SDR White levels for display {paths[i].TargetInfo.Id}.");
}
// Only create and add the ADVANCED_HDR_INFO_PER_PATH if the info is there
if (gotAdvancedColorInfo)
{
ADVANCED_HDR_INFO_PER_PATH hdrInfo = new ADVANCED_HDR_INFO_PER_PATH();
hdrInfo.AdapterId = paths[i].TargetInfo.AdapterId;
hdrInfo.Id = paths[i].TargetInfo.Id;
hdrInfo.AdvancedColorInfo = colorInfo;
if (gotSdrWhiteLevel)
{
hdrInfo.SDRWhiteLevel = whiteLevelInfo;
}
windowsDisplayConfig.DisplayHDRStates.Add(hdrInfo);
}
}