From c3838a89be218ca9f0c3a5628283d9ab9df7854a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Thu, 9 Feb 2023 11:42:50 +0100 Subject: [PATCH] WIP --- PowerControl/Helpers/AMD/ModeTiming.cs | 167 +++++++----------- .../Helpers/DisplayResolutionController.cs | 17 +- PowerControl/Options/RefreshRate.cs | 47 +++-- PowerControl/Options/Resolution.cs | 40 +++-- 4 files changed, 128 insertions(+), 143 deletions(-) diff --git a/PowerControl/Helpers/AMD/ModeTiming.cs b/PowerControl/Helpers/AMD/ModeTiming.cs index d4ec067..34d886a 100644 --- a/PowerControl/Helpers/AMD/ModeTiming.cs +++ b/PowerControl/Helpers/AMD/ModeTiming.cs @@ -35,10 +35,8 @@ namespace PowerControl.Helpers.AMD public IEnumerable EachModeInfo() { foreach (var refreshRate in RefreshRates) - // foreach (var pixelClock in PixelClocks) { var pixelClock = (short)Math.Ceiling((double)Timing.sHTotal * Timing.sVTotal * refreshRate / 10000); - // var refreshRate = Math.Round((double)pixelClock / (Timing.sHTotal * Timing.sVTotal)); ADLDisplayModeInfo modeInfo = new ADLDisplayModeInfo() { @@ -99,7 +97,7 @@ namespace PowerControl.Helpers.AMD } }; - internal static IEnumerable AllModeInfos() + internal static IEnumerable AllDetailedTimings() { foreach (var timing in AllTimings) { @@ -108,43 +106,7 @@ namespace PowerControl.Helpers.AMD } } - internal static void InstallAll() - { - var modeInfos = AllModeInfos()?.ToArray(); - if (modeInfos is null) - return; - - ADLDisplayModeInfo lastModeInfo = modeInfos.LastOrDefault(); - - foreach (var modeInfo in modeInfos) - { - AddTiming(modeInfo, modeInfo.Equals(lastModeInfo)); - } - } - - internal static void UninstallAll() - { - var modes = GetAllModes()?.ToArray(); - if (modes is null) - return; - - ADLDisplayModeInfo lastMode = modes.LastOrDefault(); - - foreach (var mode in modes) - { - var newMode = mode; - newMode.iTimingStandard = Helpers.AMD.ADL.ADL_DL_MODETIMING_STANDARD_DRIVER_DEFAULT; - AddTiming(newMode, mode.Equals(lastMode)); - } - } - - internal static bool AddAndSetTiming(ADLDisplayModeX2 displayMode) - { - RemoveTiming(displayMode); - return AddTiming(displayMode); - } - - internal static IEnumerable? GetAllModes() + internal static IEnumerable? AllTimingOverrideList() { return Helpers.AMD.ADLContext.WithSafe((context) => { @@ -158,19 +120,71 @@ namespace PowerControl.Helpers.AMD }); } - internal static bool ReplaceTiming(ADLDisplayModeX2 displayMode) + internal static void InstallAll() { - RemoveTiming(displayMode); - return AddTiming(displayMode); + var modeInfos = AllDetailedTimings()?.ToArray(); + if (modeInfos is null) + return; + + ADLDisplayModeInfo lastModeInfo = modeInfos.LastOrDefault(); + + foreach (var modeInfo in modeInfos) + { + SetTimingOverride(modeInfo, modeInfo.Equals(lastModeInfo)); + } } - internal static bool RemoveTiming(ADLDisplayModeX2 displayMode) + internal static void UninstallAll() { - displayMode.TimingStandard = ADL.ADL_DL_MODETIMING_STANDARD_DRIVER_DEFAULT; - return AddTiming(displayMode); + var modes = AllTimingOverrideList()?.ToArray(); + if (modes is null) + return; + + ADLDisplayModeInfo lastMode = modes.LastOrDefault(); + + foreach (var mode in modes) + { + var newMode = mode; + newMode.iTimingStandard = Helpers.AMD.ADL.ADL_DL_MODETIMING_STANDARD_DRIVER_DEFAULT; + RemoveTimingOverride(newMode, mode.Equals(lastMode)); + } } - internal static bool AddTiming(ADLDisplayModeInfo displayMode, bool forceUpdate = true) + internal static ADLDisplayModeInfo? FindTiming(ADLDisplayModeX2 displayMode) + { + foreach (var modeInfo in AllDetailedTimings()) + { + if (modeInfo.iPelsWidth == displayMode.PelsWidth && + modeInfo.iPelsHeight == displayMode.PelsHeight && + modeInfo.iRefreshRate == displayMode.RefreshRate) + return modeInfo; + } + + return null; + } + + internal static bool AddTiming(ADLDisplayModeX2 displayMode, bool removeOld = false) + { + if (removeOld) + { + var modes = AllTimingOverrideList()?.ToArray() ?? new ADLDisplayModeInfo[0]; + foreach (var oldMode in modes) + RemoveTimingOverride(oldMode, false); + } + + var timing = FindTiming(displayMode); + if (timing is not null) + return SetTimingOverride(timing.Value, true); + return false; + } + + internal static bool RemoveTimingOverride(ADLDisplayModeInfo displayMode, bool forceUpdate = true) + { + displayMode.iTimingStandard = ADL.ADL_DL_MODETIMING_STANDARD_DRIVER_DEFAULT; + return SetTimingOverride(displayMode, forceUpdate); + } + + internal static bool SetTimingOverride(ADLDisplayModeInfo displayMode, bool forceUpdate = true) { return Helpers.AMD.ADLContext.WithSafe((context) => { @@ -191,64 +205,5 @@ namespace PowerControl.Helpers.AMD return res == 0; }); } - - internal static bool AddTiming(ADLDisplayModeX2 displayMode) - { - return Helpers.AMD.ADLContext.WithSafe((context) => - { - var displays = context.DisplayInfos.ToArray(); - if (displays.Count() < 0) - return false; - - int res = ADL.ADL2_Display_ModeTimingOverrideX2_Get( - context.Context, - Helpers.AMD.ADL.ADL_DEFAULT_ADAPTER, - displays[0].DisplayID, - ref displayMode, out var modeInfOut); - - if (res == 0) - { - res = ADL.ADL2_Display_ModeTimingOverride_Set( - context.Context, - Helpers.AMD.ADL.ADL_DEFAULT_ADAPTER, - displays[0].DisplayID.DisplayLogicalIndex, - ref modeInfOut, - 1 - ); - } - - return res == 0; - }); - } - - internal static bool SetTiming(ADLDisplayModeX2 displayMode) - { - return Helpers.AMD.ADLContext.WithSafe((context) => - { - int res = ADL.ADL2_Display_Modes_Get(context.Context, - Helpers.AMD.ADL.ADL_DEFAULT_ADAPTER, - 0, out var modeCount, out var modesArray); - - try - { - if (res != 0 || modeCount < 1) - return false; - - var mode = Marshal.PtrToStructure(modesArray); - mode.iXRes = displayMode.PelsWidth; - mode.iYRes = displayMode.PelsHeight; - mode.fRefreshRate = (float)displayMode.RefreshRate; - - res = ADL.ADL2_Display_Modes_Set(context.Context, - Helpers.AMD.ADL.ADL_DEFAULT_ADAPTER, - 0, 1, ref mode); - return res == 0; - } - finally - { - ADL.ADL_Main_Memory_Free(modesArray); - } - }); - } } } diff --git a/PowerControl/Helpers/DisplayResolutionController.cs b/PowerControl/Helpers/DisplayResolutionController.cs index f1cbf5e..573cca6 100644 --- a/PowerControl/Helpers/DisplayResolutionController.cs +++ b/PowerControl/Helpers/DisplayResolutionController.cs @@ -17,16 +17,25 @@ namespace PowerControl.Helpers { public int Width { get; set; } public int Height { get; set; } + public bool? Rotated { get; set; } - public DisplayResolution() { Width = 0; Height = 0; } + public DisplayResolution() { Width = 0; Height = 0; Rotated = null; } - public DisplayResolution(int width, int height) { Width = width; Height = height; } + public DisplayResolution(int width, int height, bool? rotated = null) { Width = width; Height = height; Rotated = rotated; } public DisplayResolution(String text) { var options = text.Split("x", 2); Width = int.Parse(options[0]); Height = int.Parse(options[1]); + Rotated = null; + } + + public DisplayResolution Normalize() + { + if (Rotated == true) + return new DisplayResolution(Height, Width); + return this; } public static bool operator ==(DisplayResolution sz1, DisplayResolution sz2) => sz1.Width == sz2.Width && sz1.Height == sz2.Height; @@ -94,7 +103,9 @@ namespace PowerControl.Helpers { var dm = CurrentDisplaySettings(); if (dm is not null) - return new DisplayResolution(dm.Value.dmPelsWidth, dm.Value.dmPelsHeight); + { + return new DisplayResolution(dm.Value.dmPelsWidth, dm.Value.dmPelsHeight, (dm.Value.dmDisplayOrientation & 1) != 0); + } return null; } diff --git a/PowerControl/Options/RefreshRate.cs b/PowerControl/Options/RefreshRate.cs index 7ade6c4..1ce1937 100644 --- a/PowerControl/Options/RefreshRate.cs +++ b/PowerControl/Options/RefreshRate.cs @@ -16,12 +16,25 @@ namespace PowerControl.Options var refreshRates = DisplayResolutionController.GetRefreshRates().ToList(); var currentRefreshRate = DisplayResolutionController.GetRefreshRate(); - if (currentRefreshRate > 0 && !refreshRates.Contains(currentRefreshRate)) - { + if (currentRefreshRate > 0) refreshRates.Add(currentRefreshRate); - refreshRates.Sort(); + + var normalizedResolution = DisplayResolutionController.GetResolution()?.Normalize(); + if (normalizedResolution is not null && ExternalHelpers.DisplayConfig.IsInternalConnected == true) + { + foreach (var displayModeInfo in ModeTiming.AllDetailedTimings()) + { + if (displayModeInfo.iPelsWidth == normalizedResolution.Value.Width && + displayModeInfo.iPelsHeight == normalizedResolution.Value.Height) + { + refreshRates.Add(displayModeInfo.iRefreshRate); + } + } } + refreshRates = refreshRates.Distinct().ToList(); + refreshRates.Sort(); + if (refreshRates.Count() > 1) return refreshRates.Select(item => item.ToString()).ToArray(); return null; @@ -34,39 +47,25 @@ namespace PowerControl.Options { var selectedRefreshRate = int.Parse(selected); -#if USE_ADL2 if (ExternalHelpers.DisplayConfig.IsInternalConnected == true) { - var currentResolution = DisplayResolutionController.GetResolution(); + var currentResolution = DisplayResolutionController.GetResolution()?.Normalize(); if (currentResolution == null) return null; - var modes = ModeTiming.GetAllModes(); - - // ModeTiming.ReplaceTiming(new Helpers.AMD.ADLDisplayModeX2() - // { - // PelsWidth = currentResolution.Value.Width, - // PelsHeight = currentResolution.Value.Height, - // RefreshRate = selectedRefreshRate, - // TimingStandard = Helpers.AMD.ADL.ADL_DL_MODETIMING_STANDARD_CVT, - // }); - - ModeTiming.AddTiming(ModeTiming.Mode1280x800p40); - - ModeTiming.SetTiming(new Helpers.AMD.ADLDisplayModeX2() + bool result = ModeTiming.AddTiming(new Helpers.AMD.ADLDisplayModeX2() { PelsWidth = currentResolution.Value.Width, PelsHeight = currentResolution.Value.Height, RefreshRate = selectedRefreshRate, - TimingStandard = Helpers.AMD.ADL.ADL_DL_MODETIMING_STANDARD_CVT, + TimingStandard = Helpers.AMD.ADL.ADL_DL_MODETIMING_STANDARD_CUSTOM, }); - } - else -#endif - { - DisplayResolutionController.SetRefreshRate(selectedRefreshRate); + + if (result) + Thread.Sleep(500); } + DisplayResolutionController.SetRefreshRate(selectedRefreshRate); return DisplayResolutionController.GetRefreshRate().ToString(); }, Impacts = diff --git a/PowerControl/Options/Resolution.cs b/PowerControl/Options/Resolution.cs index a9e2ad5..58ff9b1 100644 --- a/PowerControl/Options/Resolution.cs +++ b/PowerControl/Options/Resolution.cs @@ -21,12 +21,29 @@ namespace PowerControl.Options var resolutions = DisplayResolutionController.GetAllResolutions().ToList(); var currentResolution = DisplayResolutionController.GetResolution(); - if (currentResolution is not null && !resolutions.Contains(currentResolution.Value)) - { + if (currentResolution is not null) resolutions.Add(currentResolution.Value); - resolutions.Sort(); + + if (ExternalHelpers.DisplayConfig.IsInternalConnected == true) + { + foreach (var displayModeInfo in ModeTiming.AllDetailedTimings()) + { + if (currentResolution?.Rotated == true) + { + resolutions.Add(new DisplayResolutionController.DisplayResolution( + displayModeInfo.iPelsHeight, displayModeInfo.iPelsWidth)); + } + else + { + resolutions.Add(new DisplayResolutionController.DisplayResolution( + displayModeInfo.iPelsWidth, displayModeInfo.iPelsHeight)); + } + } } + resolutions = resolutions.Distinct().ToList(); + resolutions.Sort(); + if (resolutions.Count() > 1) return resolutions.Select(item => item.ToString()).ToArray(); @@ -41,22 +58,25 @@ namespace PowerControl.Options ApplyValue = (selected) => { var selectedResolution = new DisplayResolutionController.DisplayResolution(selected); + selectedResolution.Rotated = DisplayResolutionController.GetResolution()?.Rotated; -#if USE_ADL2 if (ExternalHelpers.DisplayConfig.IsInternalConnected == true) { - ModeTiming.ReplaceTiming(new Helpers.AMD.ADLDisplayModeX2() + var normalizedResolution = selectedResolution.Normalize(); + + bool result = ModeTiming.AddTiming(new Helpers.AMD.ADLDisplayModeX2() { - PelsWidth = selectedResolution.Width, - PelsHeight = selectedResolution.Height, + PelsWidth = normalizedResolution.Width, + PelsHeight = normalizedResolution.Height, RefreshRate = DisplayResolutionController.GetRefreshRate(), - TimingStandard = Helpers.AMD.ADL.ADL_DL_MODETIMING_STANDARD_CVT, + TimingStandard = Helpers.AMD.ADL.ADL_DL_MODETIMING_STANDARD_CUSTOM, }); + + if (result) + Thread.Sleep(500); } -#endif DisplayResolutionController.SetResolution(selectedResolution); - return DisplayResolutionController.GetResolution().ToString(); }, Impacts =