From 4bbb747f8efb29939d1249d72a32cc5352465745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Wed, 8 Feb 2023 23:41:08 +0100 Subject: [PATCH] WIP --- PowerControl/Helpers/AMD/ADL.cs | 82 ++++++++++++++++++++++++++ PowerControl/Helpers/AMD/ModeTiming.cs | 71 ++++++++++++++++++++++ PowerControl/Options/RefreshRate.cs | 23 +++++++- PowerControl/Options/Resolution.cs | 17 +++++- 4 files changed, 191 insertions(+), 2 deletions(-) create mode 100644 PowerControl/Helpers/AMD/ModeTiming.cs diff --git a/PowerControl/Helpers/AMD/ADL.cs b/PowerControl/Helpers/AMD/ADL.cs index 8f2b8a0..81cdc96 100644 --- a/PowerControl/Helpers/AMD/ADL.cs +++ b/PowerControl/Helpers/AMD/ADL.cs @@ -160,6 +160,66 @@ namespace PowerControl.Helpers.AMD internal int GlobalEnableChanged; //Set when Global enable value is changed internal int GlobalSharpeningDegreeChanged; //Set when Global sharpening Degree value is changed }; + + [StructLayout(LayoutKind.Sequential)] + internal struct ADLDisplayModeX2 + { + internal int PelsHeight; + internal int PelsWidth; + internal int ScanType; + internal int RefreshRate; + internal int TimingStandard; + }; + + [StructLayout(LayoutKind.Sequential)] + internal struct ADLDetailedTiming + { + internal int iSize; + internal short sTimingFlags; + internal short sHTotal; + internal short sHDisplay; + internal short sHSyncStart; + internal short sHSyncWidth; + internal short sVTotal; + internal short sVDisplay; + internal short sVSyncStart; + internal short sVSyncWidth; + internal short sPixelClock; + internal short sHOverscanRight; + internal short sHOverscanLeft; + internal short sVOverscanBottom; + internal short sVOverscanTop; + internal short sOverscan8B; + internal short sOverscanGR; + }; + + [StructLayout(LayoutKind.Sequential)] + internal struct ADLDisplayModeInfo + { + internal int iTimingStandard; + internal int iPossibleStandard; + internal int iRefreshRate; + internal int iPelsWidth; + internal int iPelsHeight; + internal ADLDetailedTiming sDetailedTiming; + }; + + [StructLayout(LayoutKind.Sequential)] + internal struct ADLMode + { + internal int iAdapterIndex; + internal ADLDisplayID displayID; + internal int iXPos; + internal int iYPos; + internal int iXRes; + internal int iYRes; + internal int iColourDepth; + internal float fRefreshRate; + internal int iOrientation; + internal int iModeFlag; + internal int iModeMask; + internal int iModeValue; + }; #endregion ADLDisplayInfo #endregion Export Struct @@ -195,6 +255,13 @@ namespace PowerControl.Helpers.AMD internal const int ADL_DISPLAY_DISPLAYINFO_DISPLAYCONNECTED = 0x00000001; + internal const int ADL_DL_MODETIMING_STANDARD_CUSTOM = 0x00000008; + internal const int ADL_DL_MODETIMING_STANDARD_CVT = 0x00000001; + internal const int ADL_DL_MODETIMING_STANDARD_CVT_RB = 0x00000020; + internal const int ADL_DL_MODETIMING_STANDARD_DMT = 0x00000004; + internal const int ADL_DL_MODETIMING_STANDARD_DRIVER_DEFAULT = 0x00000010; + internal const int ADL_DL_MODETIMING_STANDARD_GTF = 0x00000002; + #endregion Internal Constant #region Internal Constant @@ -265,6 +332,21 @@ namespace PowerControl.Helpers.AMD [DllImport(Atiadlxx_FileName)] internal static extern int ADL2_RIS_Settings_Set(IntPtr context, int adapterIndex, ADL_RIS_SETTINGS settings, ADL_RIS_NOTFICATION_REASON reason); + + [DllImport(Atiadlxx_FileName)] + internal static extern int ADL2_Display_Modes_Get(IntPtr context, int adapterIndex, int displayIndex, out int lpNumModes, out IntPtr modesArray); + + [DllImport(Atiadlxx_FileName)] + internal static extern int ADL2_Display_Modes_Set(IntPtr context, int adapterIndex, int displayIndex, int lpNumModes, IntPtr modesArray); + + [DllImport(Atiadlxx_FileName)] + internal static extern int ADL2_Display_Modes_Set(IntPtr context, int adapterIndex, int displayIndex, int lpNumModes, ref ADLMode modesArray); + + [DllImport(Atiadlxx_FileName)] + internal static extern int ADL2_Display_ModeTimingOverrideX2_Get(IntPtr context, int adapterIndex, ADLDisplayID displayID, ref ADLDisplayModeX2 lpModeIn, out ADLDisplayModeInfo lpModeInfoOut); + + [DllImport(Atiadlxx_FileName)] + internal static extern int ADL2_Display_ModeTimingOverride_Set(IntPtr context, int adapterIndex, int displayIndex, ref ADLDisplayModeInfo lpMode, int iForceUpdate); #endregion DLLImport #region ADL_Main_Memory_Alloc diff --git a/PowerControl/Helpers/AMD/ModeTiming.cs b/PowerControl/Helpers/AMD/ModeTiming.cs new file mode 100644 index 0000000..baf60d2 --- /dev/null +++ b/PowerControl/Helpers/AMD/ModeTiming.cs @@ -0,0 +1,71 @@ +using System.Runtime.InteropServices; + +namespace PowerControl.Helpers.AMD +{ + internal class ModeTiming + { + internal static bool AddAndSetTiming(ADLDisplayModeX2 displayMode) + { + return AddTiming(displayMode) && SetTiming(displayMode); + } + + 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/Options/RefreshRate.cs b/PowerControl/Options/RefreshRate.cs index 118116e..9391769 100644 --- a/PowerControl/Options/RefreshRate.cs +++ b/PowerControl/Options/RefreshRate.cs @@ -13,6 +13,8 @@ namespace PowerControl.Options ResetValue = () => { return DisplayResolutionController.GetRefreshRates().Max().ToString(); }, OptionsValues = delegate () { + return new string[] { "30", "35", "40", "45", "48", "50", "55", "60" }; + var refreshRates = DisplayResolutionController.GetRefreshRates(); if (refreshRates.Count() > 1) return refreshRates.Select(item => item.ToString()).ToArray(); @@ -24,7 +26,26 @@ namespace PowerControl.Options }, ApplyValue = (selected) => { - DisplayResolutionController.SetRefreshRate(int.Parse(selected)); + var selectedRefreshRate = int.Parse(selected); + + if (ExternalHelpers.DisplayConfig.IsInternalConnected == true) + { + var currentResolution = DisplayResolutionController.GetResolution(); + if (currentResolution == null) + return null; + + ModeTiming.AddAndSetTiming(new Helpers.AMD.ADLDisplayModeX2() + { + PelsWidth = currentResolution.Value.Width, + PelsHeight = currentResolution.Value.Height, + RefreshRate = selectedRefreshRate, + TimingStandard = Helpers.AMD.ADL.ADL_DL_MODETIMING_STANDARD_CVT, + }); + } + else + { + DisplayResolutionController.SetRefreshRate(selectedRefreshRate); + } return DisplayResolutionController.GetRefreshRate().ToString(); }, diff --git a/PowerControl/Options/Resolution.cs b/PowerControl/Options/Resolution.cs index 43d2a81..ce7c039 100644 --- a/PowerControl/Options/Resolution.cs +++ b/PowerControl/Options/Resolution.cs @@ -32,7 +32,22 @@ namespace PowerControl.Options ApplyValue = (selected) => { var selectedResolution = new DisplayResolutionController.DisplayResolution(selected); - DisplayResolutionController.SetResolution(selectedResolution); + + if (ExternalHelpers.DisplayConfig.IsInternalConnected == true) + { + ModeTiming.AddTiming(new Helpers.AMD.ADLDisplayModeX2() + { + PelsWidth = selectedResolution.Width, + PelsHeight = selectedResolution.Height, + RefreshRate = DisplayResolutionController.GetRefreshRate(), + TimingStandard = Helpers.AMD.ADL.ADL_DL_MODETIMING_STANDARD_CVT, + }); + } + else + { + DisplayResolutionController.SetResolution(selectedResolution); + } + return DisplayResolutionController.GetResolution().ToString(); }, Impacts =