mirror of
https://github.com/Maassoft/ColorControl.git
synced 2026-10-22 00:22:18 -05:00
fix dithering issues
This commit is contained in:
1 parent
f609471fd2
commit
977060e927
4 files changed
+114
-74
No files matched your search
@@ -18,8 +18,8 @@
|
||||
<PublisherName>Maassoft</PublisherName>
|
||||
<Company>Maassoft</Company>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>5.2.0.0</ApplicationVersion>
|
||||
<Version>5.2.0.0</Version>
|
||||
<ApplicationVersion>5.3.0.0</ApplicationVersion>
|
||||
<Version>5.3.0.0</Version>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<PublishWizardCompleted>true</PublishWizardCompleted>
|
||||
<BootstrapperEnabled>false</BootstrapperEnabled>
|
||||
|
||||
Generated
+2
-1
@@ -1693,8 +1693,9 @@
|
||||
this.chkDitheringEnabled.Size = new System.Drawing.Size(120, 19);
|
||||
this.chkDitheringEnabled.TabIndex = 3;
|
||||
this.chkDitheringEnabled.Text = "Dithering enabled";
|
||||
this.chkDitheringEnabled.ThreeState = true;
|
||||
this.chkDitheringEnabled.UseVisualStyleBackColor = true;
|
||||
this.chkDitheringEnabled.CheckedChanged += new System.EventHandler(this.chkDitheringEnabled_CheckedChanged);
|
||||
this.chkDitheringEnabled.CheckStateChanged += new System.EventHandler(this.chkDitheringEnabled_CheckStateChanged);
|
||||
//
|
||||
// pbGradient
|
||||
//
|
||||
|
||||
+54
-34
@@ -55,6 +55,7 @@ namespace ColorControl
|
||||
private FileVersionInfo _currentVersionInfo;
|
||||
private bool _checkedForUpdates = false;
|
||||
private string _updateHtmlUrl;
|
||||
private bool _updatingDitherSettings;
|
||||
|
||||
private LgGameBar _gameBarForm;
|
||||
|
||||
@@ -1350,6 +1351,10 @@ namespace ColorControl
|
||||
{
|
||||
InitOptionsTab();
|
||||
}
|
||||
else if (tcMain.SelectedTab == tabNVIDIA)
|
||||
{
|
||||
UpdateDisplayInfoItems();
|
||||
}
|
||||
}
|
||||
|
||||
private void InitLgTab()
|
||||
@@ -1371,39 +1376,42 @@ namespace ColorControl
|
||||
grpNvidiaOptions.Visible = _nvService != null;
|
||||
if (grpNvidiaOptions.Visible)
|
||||
{
|
||||
var firstTime = cbxDitheringBitDepth.Items.Count == 0;
|
||||
|
||||
if (firstTime)
|
||||
if (cbxDitheringBitDepth.Items.Count == 0)
|
||||
{
|
||||
cbxDitheringBitDepth.Items.AddRange(Utils.GetDescriptions<NvDitherBits>().ToArray());
|
||||
cbxDitheringMode.Items.AddRange(Utils.GetDescriptions<NvDitherMode>().ToArray());
|
||||
}
|
||||
|
||||
var preset = _nvService.GetLastAppliedPreset() ?? GetSelectedNvPreset();
|
||||
if (firstTime || preset != null)
|
||||
{
|
||||
var ditheringEnabled = true;
|
||||
int ditherBitsIndex;
|
||||
int ditherModeIndex;
|
||||
if (preset == null)
|
||||
{
|
||||
var hdrEnabled = _nvService.IsHDREnabled();
|
||||
var minBits = _nvService.GetPresets().Where(p => p.HDREnabled == hdrEnabled && p.applyDithering).DefaultIfEmpty().Min(p => p?.ditheringBits);
|
||||
ditherBitsIndex = minBits.HasValue ? (int)minBits.Value : (int)(hdrEnabled ? NvDitherBits.Bits8 : NvDitherBits.Bits6);
|
||||
ditherModeIndex = (int)NvDitherMode.Temporal;
|
||||
}
|
||||
else
|
||||
{
|
||||
ditheringEnabled = preset.ditheringEnabled;
|
||||
ditherBitsIndex = (int)preset.ditheringBits;
|
||||
ditherModeIndex = (int)preset.ditheringMode;
|
||||
}
|
||||
|
||||
chkDitheringEnabled.Checked = ditheringEnabled;
|
||||
cbxDitheringBitDepth.SelectedIndex = ditherBitsIndex;
|
||||
cbxDitheringMode.SelectedIndex = ditherModeIndex;
|
||||
FillGradient();
|
||||
}
|
||||
|
||||
UpdateDitherSettings();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateDitherSettings()
|
||||
{
|
||||
var ditherInfo = _nvService.GetDithering();
|
||||
|
||||
if (ditherInfo.state == -1)
|
||||
{
|
||||
MessageForms.ErrorOk("Error retrieving dithering settings. See log for details.");
|
||||
return;
|
||||
}
|
||||
|
||||
var state = (NvDitherState)ditherInfo.state;
|
||||
|
||||
_updatingDitherSettings = true;
|
||||
try
|
||||
{
|
||||
chkDitheringEnabled.CheckState = state switch { NvDitherState.Enabled => CheckState.Checked, NvDitherState.Disabled => CheckState.Unchecked, _ => CheckState.Indeterminate };
|
||||
cbxDitheringBitDepth.SelectedIndex = ditherInfo.bits;
|
||||
cbxDitheringMode.SelectedIndex = ditherInfo.mode;
|
||||
|
||||
cbxDitheringBitDepth.Enabled = state == NvDitherState.Enabled;
|
||||
cbxDitheringMode.Enabled = state == NvDitherState.Enabled;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_updatingDitherSettings = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2061,17 +2069,21 @@ Do you want to continue?";
|
||||
}
|
||||
}
|
||||
|
||||
private void chkDitheringEnabled_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
ApplyDitheringOptions();
|
||||
}
|
||||
|
||||
private void ApplyDitheringOptions()
|
||||
{
|
||||
if (_updatingDitherSettings)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var state = chkDitheringEnabled.CheckState switch { CheckState.Checked => NvDitherState.Enabled, CheckState.Unchecked => NvDitherState.Disabled, _ => NvDitherState.Auto };
|
||||
var bitDepth = cbxDitheringBitDepth.SelectedIndex;
|
||||
var mode = cbxDitheringMode.SelectedIndex;
|
||||
|
||||
_nvService.SetDithering(chkDitheringEnabled.Checked, (uint)bitDepth, (uint)(mode > -1 ? mode : (int)NvDitherMode.Temporal));
|
||||
if (_nvService.SetDithering(state, (uint)bitDepth, (uint)(mode > -1 ? mode : (int)NvDitherMode.Temporal)) && state == NvDitherState.Auto)
|
||||
{
|
||||
UpdateDitherSettings();
|
||||
}
|
||||
}
|
||||
|
||||
private void cbxDitheringBitDepth_SelectedIndexChanged(object sender, EventArgs e)
|
||||
@@ -3034,5 +3046,13 @@ The InStart and Software Update items are now visible under the Expert-button."
|
||||
{
|
||||
ResumeLayout(true);
|
||||
}
|
||||
|
||||
private void chkDitheringEnabled_CheckStateChanged(object sender, EventArgs e)
|
||||
{
|
||||
cbxDitheringBitDepth.Enabled = chkDitheringEnabled.CheckState == CheckState.Checked;
|
||||
cbxDitheringMode.Enabled = chkDitheringEnabled.CheckState == CheckState.Checked;
|
||||
|
||||
ApplyDitheringOptions();
|
||||
}
|
||||
}
|
||||
}
|
||||
+56
-37
@@ -13,6 +13,16 @@ using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl
|
||||
{
|
||||
enum NvDitherState
|
||||
{
|
||||
[Description("Auto")]
|
||||
Auto = 0,
|
||||
[Description("Enabled")]
|
||||
Enabled = 1,
|
||||
[Description("Disabled")]
|
||||
Disabled = 2
|
||||
}
|
||||
|
||||
enum NvDitherBits
|
||||
{
|
||||
[Description("6-bit")]
|
||||
@@ -45,7 +55,7 @@ namespace ColorControl
|
||||
PreserveSig = true)]
|
||||
private static extern IntPtr NvAPI64_QueryInterface(uint interfaceId);
|
||||
|
||||
public delegate long NvAPI_Disp_SetDitherControl(
|
||||
public delegate int NvAPI_Disp_SetDitherControl(
|
||||
[In] PhysicalGPUHandle physicalGpu,
|
||||
[In] uint OutputId,
|
||||
[In] uint state,
|
||||
@@ -53,18 +63,19 @@ namespace ColorControl
|
||||
[In] uint mode
|
||||
);
|
||||
|
||||
public delegate long NvAPI_Disp_GetDitherControl(
|
||||
[In] PhysicalGPUHandle physicalGpu,
|
||||
[In] uint OutputId,
|
||||
[In] IntPtr ditherControl);
|
||||
public delegate int NvAPI_Disp_GetDitherControl(
|
||||
[In] uint DisplayId,
|
||||
[MarshalAs(UnmanagedType.Struct)] ref NV_GPU_DITHER_CONTROL_V1 ditherControl);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct NV_GPU_DITHER_CONTROL_V1
|
||||
{
|
||||
public int version;
|
||||
public uint state;
|
||||
public uint bits;
|
||||
public uint mode;
|
||||
public uint version;
|
||||
public int state;
|
||||
public int bits;
|
||||
public int mode;
|
||||
public uint bitsCaps;
|
||||
public uint modeCaps;
|
||||
};
|
||||
|
||||
private Display _currentDisplay;
|
||||
@@ -233,7 +244,7 @@ namespace ColorControl
|
||||
|
||||
if (preset.applyDithering)
|
||||
{
|
||||
if (!SetDithering(preset.ditheringEnabled, preset: preset))
|
||||
if (!SetDithering(preset.ditheringEnabled ? NvDitherState.Enabled : NvDitherState.Disabled, preset: preset))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
@@ -304,7 +315,7 @@ namespace ColorControl
|
||||
//}
|
||||
}
|
||||
|
||||
public bool SetDithering(bool enabled, uint bits = 1, uint mode = 4, NvPreset preset = null)
|
||||
public bool SetDithering(NvDitherState state, uint bits = 1, uint mode = 4, NvPreset preset = null)
|
||||
{
|
||||
var result = true;
|
||||
|
||||
@@ -317,14 +328,20 @@ namespace ColorControl
|
||||
|
||||
var gpuHandle = displayDevice.PhysicalGPU.Handle;
|
||||
var displayId = displayDevice.DisplayId;
|
||||
|
||||
if (preset != null)
|
||||
|
||||
if (state == NvDitherState.Auto)
|
||||
{
|
||||
// These seem to be ignored in Auto-state
|
||||
bits = 0;
|
||||
mode = 0;
|
||||
}
|
||||
else if (preset != null)
|
||||
{
|
||||
bits = preset.ditheringBits;
|
||||
mode = preset.ditheringMode;
|
||||
}
|
||||
|
||||
var resultValue = delegateValue(gpuHandle, displayId, (uint)(enabled ? 1 : 2), bits, mode);
|
||||
var resultValue = delegateValue(gpuHandle, displayId, (uint)state, bits, mode);
|
||||
if (resultValue != 0)
|
||||
{
|
||||
Logger.Error($"Could not set dithering because NvAPI_Disp_SetDitherControl returned a non-zero return code: {resultValue}");
|
||||
@@ -340,40 +357,31 @@ namespace ColorControl
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool GetDithering()
|
||||
public NV_GPU_DITHER_CONTROL_V1 GetDithering()
|
||||
{
|
||||
// Requires elevation, too bad :(
|
||||
//Utils.GetRegistryKeyValue(@"SYSTEM\CurrentControlSet\Services\nvlddmkm\State\DisplayDatabase", "DitherRegistryKey");
|
||||
var dither = new NV_GPU_DITHER_CONTROL_V1 { version = 0x10018 };
|
||||
|
||||
/*
|
||||
var ptr = NvAPI64_QueryInterface(0x932AC8FB);
|
||||
if (ptr != IntPtr.Zero)
|
||||
{
|
||||
var delegateValue = Marshal.GetDelegateForFunctionPointer(ptr, typeof(NvAPI_Disp_GetDitherControl)) as NvAPI_Disp_GetDitherControl;
|
||||
|
||||
var displayDevice = GetCurrentDisplay().DisplayDevice;
|
||||
|
||||
var gpuHandle = displayDevice.PhysicalGPU.Handle;
|
||||
var displayId = displayDevice.DisplayId;
|
||||
|
||||
NV_GPU_DITHER_CONTROL_V1 info = new NV_GPU_DITHER_CONTROL_V1();
|
||||
info.version = 1;
|
||||
var size = Marshal.SizeOf(info.GetType());
|
||||
IntPtr bla = Marshal.AllocHGlobal(size);
|
||||
Marshal.StructureToPtr(info, bla, false);
|
||||
|
||||
// Does not work yet...What is the exact interface of NvAPI_Disp_GetDitherControl?
|
||||
|
||||
var result = delegateValue(gpuHandle, displayId, bla);
|
||||
var result = delegateValue(displayId, ref dither);
|
||||
if (result != 0)
|
||||
{
|
||||
Logger.Error($"Could not get dithering because NvAPI_Disp_GetDitherControl returned a non-zero return code: {result}");
|
||||
dither.state = -1;
|
||||
}
|
||||
|
||||
return info.state == 1;
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
else
|
||||
{
|
||||
dither.state = -2;
|
||||
}
|
||||
|
||||
return dither;
|
||||
}
|
||||
|
||||
public bool SetRefreshRate(uint refreshRate)
|
||||
@@ -458,16 +466,27 @@ namespace ColorControl
|
||||
|
||||
values.Add($"{refreshRate}Hz");
|
||||
|
||||
var lastPreset = GetLastAppliedPreset();
|
||||
if (lastPreset != null)
|
||||
var ditherInfo = GetDithering();
|
||||
|
||||
string dithering;
|
||||
if (ditherInfo.state == -1)
|
||||
{
|
||||
values.Add(lastPreset.GetDitheringDescription());
|
||||
dithering = "Error";
|
||||
}
|
||||
else
|
||||
{
|
||||
values.Add(string.Empty);
|
||||
var state = (NvDitherState)ditherInfo.state;
|
||||
dithering = state switch { NvDitherState.Disabled => "Disabled", NvDitherState.Auto => "Auto: ", _ => string.Empty };
|
||||
if (state is NvDitherState.Enabled or NvDitherState.Auto)
|
||||
{
|
||||
var ditherBitsDescription = ((NvDitherBits)ditherInfo.bits).GetDescription();
|
||||
var ditherModeDescription = ((NvDitherMode)ditherInfo.mode).GetDescription();
|
||||
dithering = string.Format("{0}{1} {2}", dithering, ditherBitsDescription, ditherModeDescription);
|
||||
}
|
||||
}
|
||||
|
||||
values.Add(dithering);
|
||||
|
||||
var hdrEnabled = IsHDREnabled();
|
||||
values.Add(hdrEnabled ? "Yes" : "No");
|
||||
|
||||
|
||||
Reference in new issue
Block a user