steam-deck-tools/PowerControl/Helpers/AMD/ModeTiming.cs
Kamil Trzciński 70c58dd568 WIP
2023-02-09 09:29:06 +01:00

138 lines
4.5 KiB
C#

using System.Runtime.InteropServices;
namespace PowerControl.Helpers.AMD
{
internal class ModeTiming
{
internal readonly static ADLDisplayModeInfo Mode1280x800p40 = new ADLDisplayModeInfo()
{
iPelsHeight = 1280,
iPelsWidth = 800,
iPossibleStandard = 43,
iRefreshRate = 40,
iTimingStandard = 1,
sDetailedTiming = new ADLDetailedTiming()
{
iSize = 96,
sHDisplay = 800,
sHSyncStart = 848,
sHSyncWidth = 80,
sHTotal = 1056,
sPixelClock = 5525,
sTimingFlags = 4100,
sVDisplay = 1280,
sVSyncStart = 1283,
sVSyncWidth = 10,
sVTotal = 1312
}
};
internal static bool AddAndSetTiming(ADLDisplayModeX2 displayMode)
{
RemoveTiming(displayMode);
return AddTiming(displayMode);
}
internal static IEnumerable<ADLDisplayModeInfo>? 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(ADLDisplayModeInfo displayMode)
{
return Helpers.AMD.ADLContext.WithSafe((context) =>
{
int res = ADL.ADL2_Display_ModeTimingOverride_Set(
context.Context,
Helpers.AMD.ADL.ADL_DEFAULT_ADAPTER,
0,
ref displayMode,
1
);
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<ADLMode>(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);
}
});
}
}
}