diff --git a/PowerControl/Helpers/AMD/ADL.cs b/PowerControl/Helpers/AMD/ADL.cs index 81cdc96..2706eff 100644 --- a/PowerControl/Helpers/AMD/ADL.cs +++ b/PowerControl/Helpers/AMD/ADL.cs @@ -90,6 +90,15 @@ namespace PowerControl.Helpers.AMD [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)ADL.ADL_MAX_ADAPTERS)] internal ADLAdapterInfo[] ADLAdapterInfo; } + + /// ADLAdapterInfo Array + [StructLayout(LayoutKind.Sequential)] + internal struct ADLDisplayModeInfoArray + { + /// ADLAdapterInfo Array + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)ADL.ADL_MAX_OVERRIDES)] + internal ADLDisplayModeInfo[] ADLDisplayModeInfo; + } #endregion ADLAdapterInfo #region ADLDisplayInfo @@ -164,8 +173,8 @@ namespace PowerControl.Helpers.AMD [StructLayout(LayoutKind.Sequential)] internal struct ADLDisplayModeX2 { - internal int PelsHeight; internal int PelsWidth; + internal int PelsHeight; internal int ScanType; internal int RefreshRate; internal int TimingStandard; @@ -240,6 +249,7 @@ namespace PowerControl.Helpers.AMD internal const int ADL_MAX_DISPLAYS = 40 /* 150 */; /// Define the maximum device name length internal const int ADL_MAX_DEVICENAME = 32; + internal const int ADL_MAX_OVERRIDES = 120; /// Define the successful internal const int ADL_SUCCESS = 0; /// Define the failure @@ -347,6 +357,9 @@ namespace PowerControl.Helpers.AMD [DllImport(Atiadlxx_FileName)] internal static extern int ADL2_Display_ModeTimingOverride_Set(IntPtr context, int adapterIndex, int displayIndex, ref ADLDisplayModeInfo lpMode, int iForceUpdate); + + [DllImport(Atiadlxx_FileName)] + internal static extern int ADL2_Display_ModeTimingOverrideList_Get(IntPtr context, int adapterIndex, int displayIndex, int maxOverrides, out ADLDisplayModeInfoArray modes, out int modesCount); #endregion DLLImport #region ADL_Main_Memory_Alloc diff --git a/PowerControl/Helpers/AMD/ModeTiming.cs b/PowerControl/Helpers/AMD/ModeTiming.cs index baf60d2..9a5af76 100644 --- a/PowerControl/Helpers/AMD/ModeTiming.cs +++ b/PowerControl/Helpers/AMD/ModeTiming.cs @@ -6,7 +6,34 @@ namespace PowerControl.Helpers.AMD { internal static bool AddAndSetTiming(ADLDisplayModeX2 displayMode) { - return AddTiming(displayMode) && SetTiming(displayMode); + RemoveTiming(displayMode); + return AddTiming(displayMode); + } + + internal static IEnumerable? GetAllModes() + { + return Helpers.AMD.ADLContext.WithSafe((context) => + { + int res = ADL.ADL2_Display_ModeTimingOverrideList_Get(context.Context, + Helpers.AMD.ADL.ADL_DEFAULT_ADAPTER, 0, + ADL.ADL_MAX_OVERRIDES, out var modes, out var modesCount); + if (res != 0) + return null; + + return modes.ADLDisplayModeInfo.Take(modesCount); + }); + } + + internal static bool ReplaceTiming(ADLDisplayModeX2 displayMode) + { + RemoveTiming(displayMode); + return AddTiming(displayMode); + } + + internal static bool RemoveTiming(ADLDisplayModeX2 displayMode) + { + displayMode.TimingStandard = Helpers.AMD.ADL.ADL_DL_MODETIMING_STANDARD_DRIVER_DEFAULT; + return AddTiming(displayMode); } internal static bool AddTiming(ADLDisplayModeX2 displayMode) diff --git a/PowerControl/Helpers/DisplayResolutionController.cs b/PowerControl/Helpers/DisplayResolutionController.cs index a2a6c7b..f1cbf5e 100644 --- a/PowerControl/Helpers/DisplayResolutionController.cs +++ b/PowerControl/Helpers/DisplayResolutionController.cs @@ -158,7 +158,7 @@ namespace PowerControl.Helpers DEVMODE? best = FindAllDisplaySettings() .Where((dm) => dm.dmPelsWidth == current.Value.dmPelsWidth && dm.dmPelsHeight == current.Value.dmPelsHeight) .Where((dm) => dm.dmDisplayFrequency == hz) - .First(); + .FirstOrDefault(); if (best is null) return false; diff --git a/PowerControl/Options/RefreshRate.cs b/PowerControl/Options/RefreshRate.cs index 9391769..6fe4569 100644 --- a/PowerControl/Options/RefreshRate.cs +++ b/PowerControl/Options/RefreshRate.cs @@ -34,7 +34,9 @@ namespace PowerControl.Options if (currentResolution == null) return null; - ModeTiming.AddAndSetTiming(new Helpers.AMD.ADLDisplayModeX2() + var modes = ModeTiming.GetAllModes(); + + ModeTiming.ReplaceTiming(new Helpers.AMD.ADLDisplayModeX2() { PelsWidth = currentResolution.Value.Width, PelsHeight = currentResolution.Value.Height, @@ -42,10 +44,8 @@ namespace PowerControl.Options TimingStandard = Helpers.AMD.ADL.ADL_DL_MODETIMING_STANDARD_CVT, }); } - else - { - DisplayResolutionController.SetRefreshRate(selectedRefreshRate); - } + + DisplayResolutionController.SetRefreshRate(selectedRefreshRate); return DisplayResolutionController.GetRefreshRate().ToString(); }, diff --git a/PowerControl/Options/Resolution.cs b/PowerControl/Options/Resolution.cs index ce7c039..4bfc40f 100644 --- a/PowerControl/Options/Resolution.cs +++ b/PowerControl/Options/Resolution.cs @@ -35,7 +35,7 @@ namespace PowerControl.Options if (ExternalHelpers.DisplayConfig.IsInternalConnected == true) { - ModeTiming.AddTiming(new Helpers.AMD.ADLDisplayModeX2() + ModeTiming.ReplaceTiming(new Helpers.AMD.ADLDisplayModeX2() { PelsWidth = selectedResolution.Width, PelsHeight = selectedResolution.Height, @@ -43,10 +43,8 @@ namespace PowerControl.Options TimingStandard = Helpers.AMD.ADL.ADL_DL_MODETIMING_STANDARD_CVT, }); } - else - { - DisplayResolutionController.SetResolution(selectedResolution); - } + + DisplayResolutionController.SetResolution(selectedResolution); return DisplayResolutionController.GetResolution().ToString(); },