steam-deck-tools/PowerControl/Helpers/AMD/GPUScaling.cs
2022-11-21 21:28:16 +01:00

185 lines
6 KiB
C#

using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PowerControl.Helpers.AMD
{
internal class GPUScaling
{
public enum ScalingMode
{
AspectRatio,
FullPanel,
Centered
}
internal static bool SafeResolutionChange
{
get { return Enabled; }
}
internal static bool IsSupported
{
get
{
return ADLContext.WithSafe((context) =>
{
int res = ADL.ADL2_DFP_GPUScalingEnable_Get(
context.Context,
ADL.ADL_DEFAULT_ADAPTER,
ADL.ADL_DEFAULT_DISPLAY,
out var support, out _, out _);
if (res == 0 && support == 1)
return true;
return false;
});
}
}
internal static bool Enabled
{
get
{
return ADLContext.WithSafe((context) =>
{
int res = ADL.ADL2_DFP_GPUScalingEnable_Get(
context.Context,
ADL.ADL_DEFAULT_ADAPTER,
ADL.ADL_DEFAULT_DISPLAY,
out var support, out var current, out _);
if (res == 0 && support == 1 && current == 1)
return true;
return false;
});
}
set
{
ADLContext.WithSafe((context) =>
{
ADL.ADL2_DFP_GPUScalingEnable_Get(
context.Context,
ADL.ADL_DEFAULT_ADAPTER,
ADL.ADL_DEFAULT_DISPLAY,
out var _, out var current, out _);
if (current == (value ? 1 : 0))
return true;
ADL.ADL2_DFP_GPUScalingEnable_Set(
context.Context,
ADL.ADL_DEFAULT_ADAPTER,
ADL.ADL_DEFAULT_DISPLAY,
value ? 1 : 0
);
return true;
});
}
}
internal static ScalingMode? Mode
{
get
{
return ADLContext.WithSafe((context) =>
{
int resAR = ADL.ADL2_Display_PreservedAspectRatio_Get(
context.Context,
ADL.ADL_DEFAULT_ADAPTER,
ADL.ADL_DEFAULT_DISPLAY,
out var supportAR, out var ar, out _);
int resIE = ADL.ADL2_Display_ImageExpansion_Get(
context.Context,
ADL.ADL_DEFAULT_ADAPTER,
ADL.ADL_DEFAULT_DISPLAY,
out var supportIE, out var ie, out _);
if (resAR != 0 || resIE != 0)
return default(ScalingMode?);
TraceLine("GPUScaling: ar={0}, ie={1}",
supportAR > 0 ? ar : -1, supportIE > 0 ? ie : -1);
if (ar == 1)
return ScalingMode.AspectRatio;
else if (ie == 1)
return ScalingMode.FullPanel;
else if (ie == 0 && supportIE == 1)
return ScalingMode.Centered;
return default(ScalingMode?);
});
}
set
{
ADLContext.WithSafe((context) =>
{
int resGS = ADL.ADL2_DFP_GPUScalingEnable_Get(
context.Context,
ADL.ADL_DEFAULT_ADAPTER,
ADL.ADL_DEFAULT_DISPLAY,
out var _, out var current, out _);
if (current == 0)
{
resGS = ADL.ADL2_DFP_GPUScalingEnable_Set(
context.Context,
ADL.ADL_DEFAULT_ADAPTER,
ADL.ADL_DEFAULT_DISPLAY,
1
);
}
int resAR = -1;
int resIE = -1;
switch (value)
{
case ScalingMode.FullPanel:
resIE = ADL.ADL2_Display_ImageExpansion_Set(
context.Context,
ADL.ADL_DEFAULT_ADAPTER,
ADL.ADL_DEFAULT_DISPLAY,
1
);
break;
case ScalingMode.AspectRatio:
resAR = ADL.ADL2_Display_PreservedAspectRatio_Set(
context.Context,
ADL.ADL_DEFAULT_ADAPTER,
ADL.ADL_DEFAULT_DISPLAY,
1
);
break;
case ScalingMode.Centered:
resIE = ADL.ADL2_Display_ImageExpansion_Set(
context.Context,
ADL.ADL_DEFAULT_ADAPTER,
ADL.ADL_DEFAULT_DISPLAY,
0
);
break;
}
TraceLine("GPUScaling: mode={0} => resAR={1}, resIE={2}, resGS={3}",
value, resAR, resIE, resGS);
return true;
});
}
}
private static void TraceLine(string format, params object?[]? arg)
{
Trace.WriteLine(string.Format(format, arg));
}
}
}