diff --git a/ColorControl.sln b/ColorControl.sln index c50f372..d2a632b 100644 --- a/ColorControl.sln +++ b/ColorControl.sln @@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ColorControl", "ColorContro EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nspector", "Nspector\Nspector.csproj", "{76797290-48F5-4A82-86C3-FAD25DAE4500}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NvAPIWrapper", "NvAPIWrapper\NvAPIWrapper.csproj", "{42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -31,6 +33,14 @@ Global {76797290-48F5-4A82-86C3-FAD25DAE4500}.Release|Any CPU.Build.0 = Release|Any CPU {76797290-48F5-4A82-86C3-FAD25DAE4500}.Release|x64.ActiveCfg = Release|Any CPU {76797290-48F5-4A82-86C3-FAD25DAE4500}.Release|x64.Build.0 = Release|Any CPU + {42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}.Debug|x64.ActiveCfg = Debug|Any CPU + {42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}.Debug|x64.Build.0 = Debug|Any CPU + {42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}.Release|Any CPU.Build.0 = Release|Any CPU + {42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}.Release|x64.ActiveCfg = Release|Any CPU + {42E2B4A6-6857-4427-AEF1-DF4C7EF8CC7C}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ColorControl/ColorControl.csproj b/ColorControl/ColorControl.csproj index 3db78ac..986d732 100644 --- a/ColorControl/ColorControl.csproj +++ b/ColorControl/ColorControl.csproj @@ -93,13 +93,13 @@ - + diff --git a/ColorControl/Common/PipeUtils.cs b/ColorControl/Common/PipeUtils.cs index 7b300fb..d173640 100644 --- a/ColorControl/Common/PipeUtils.cs +++ b/ColorControl/Common/PipeUtils.cs @@ -10,12 +10,12 @@ namespace ColorControl.Common { private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); - public static string SendMessage(string message) + public static string SendMessage(string message, int timeout = 500) { var pipeClient = new NamedPipeClientStream(".", "testpipe", PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.None); try { - pipeClient.Connect(500); + pipeClient.Connect(timeout); try { var ss = new StreamString(pipeClient); @@ -39,11 +39,11 @@ namespace ColorControl.Common } } - public static SvcResultMessage SendMessage(SvcMessage message) + public static SvcResultMessage SendMessage(SvcMessage message, int timeout = 500) { var messageJson = JsonConvert.SerializeObject(message); - var resultJson = SendMessage(messageJson); + var resultJson = SendMessage(messageJson, timeout); if (resultJson == null) { diff --git a/ColorControl/Common/Utils.cs b/ColorControl/Common/Utils.cs index 328fca3..7b645b1 100644 --- a/ColorControl/Common/Utils.cs +++ b/ColorControl/Common/Utils.cs @@ -1242,5 +1242,8 @@ The best and suggested method to provide this is via a Windows Service. Only whe { return SHA256CheckSum(filePath1) == SHA256CheckSum(filePath2); } + + public static string ToUnitString(this uint value, int div = 1000, string units = "MHz") => $"{value / div}{units}"; + public static string ToUnitString(this int value, int div = 1000, string units = "MHz") => $"{value / div}{units}"; } } diff --git a/ColorControl/Forms/FormUtils.cs b/ColorControl/Forms/FormUtils.cs index 88169f3..91b3113 100644 --- a/ColorControl/Forms/FormUtils.cs +++ b/ColorControl/Forms/FormUtils.cs @@ -198,6 +198,11 @@ namespace ColorControl.Forms item.Click += onClick; } } + else + { + item.Text = text; + item.Tag = tag; + } //else if (onClick != null) //{ // RemoveEvents(item, "Click"); diff --git a/ColorControl/Forms/MessageForms.cs b/ColorControl/Forms/MessageForms.cs index 75f627f..ea33604 100644 --- a/ColorControl/Forms/MessageForms.cs +++ b/ColorControl/Forms/MessageForms.cs @@ -16,6 +16,8 @@ namespace ColorControl.Forms DropDown, Flags, Shortcut, + CheckBox, + TrackBar } public class FieldDefinition @@ -29,10 +31,14 @@ namespace ColorControl.Forms public object Value { get; set; } public int ValueAsInt => int.Parse(Value.ToString()); + public uint ValueAsUInt => uint.Parse(Value.ToString()); } public class MessageForm : Form { + private ToolTip _toolTip; + public Dictionary _controls = new(); + public void edtShortcut_KeyDown(object sender, KeyEventArgs e) { ((TextBox)sender).Text = Utils.FormatKeyboardShortcut(e); @@ -42,6 +48,25 @@ namespace ColorControl.Forms { Utils.HandleKeyboardShortcutUp(e); } + + public void TrackBar_Scroll(object sender, EventArgs e) + { + var trackBar = sender as TrackBar; + var edit = (NumericUpDown)_controls[trackBar]; + + edit.Value = trackBar.Value; + + _toolTip ??= new ToolTip(); + _toolTip.Show(trackBar.Value.ToString(), trackBar, 50, 10, 1500); + } + + public void TrackBarEdit_ValueChanged(object sender, EventArgs e) + { + var edit = (NumericUpDown)sender; + var trackBar = (TrackBar)_controls.First(c => c.Value == edit).Key; + + trackBar.Value = (int)edit.Value; + } } public static Form MainForm; @@ -179,12 +204,30 @@ namespace ColorControl.Forms if (field.Values != null && field.Values.Any()) { comboBox.Items.AddRange(field.Values.ToArray()); - comboBox.SelectedIndex = field.Value is string strValue ? comboBox.Items.IndexOf(strValue) : 0; + comboBox.SelectedIndex = field.Value != null ? comboBox.Items.IndexOf(field.Value.ToString()) : 0; + + if (comboBox.SelectedIndex == -1) + { + comboBox.SelectedIndex = 0; + } } control = comboBox; break; + case FieldType.CheckBox: + var checkBox = new CheckBox + { + Left = 40, + Top = top, + Width = 24, + }; + + checkBox.Checked = field.Value is bool boolValue && boolValue; + + control = checkBox; + break; + case FieldType.Flags: var checkedListBox = new CheckedListBox { @@ -215,6 +258,43 @@ namespace ColorControl.Forms control = checkedListBox; break; + case FieldType.TrackBar: + var trackBar = new TrackBar { Left = 40, Top = top, Width = 300 }; + var trackBarEdit = new NumericUpDown() { Left = trackBar.Left + trackBar.Width + 10, Top = top + 10, Width = 90 }; + + trackBarEdit.ValueChanged += prompt.TrackBarEdit_ValueChanged; + + prompt._controls.Add(trackBar, trackBarEdit); + + trackBar.Orientation = Orientation.Horizontal; + trackBar.TickStyle = TickStyle.Both; + trackBar.Scroll += prompt.TrackBar_Scroll; + + if (field.MinValue != field.MaxValue) + { + trackBar.Minimum = (int)field.MinValue; + trackBar.Maximum = (int)field.MaxValue; + trackBar.TickFrequency = (trackBar.Maximum - trackBar.Minimum) / 100; + + trackBarEdit.Minimum = field.MinValue; + trackBarEdit.Maximum = field.MaxValue; + } + + if (field.Value != null) + { + trackBar.Value = field.Value is uint ? (int)(uint)field.Value : (int)field.Value; + trackBarEdit.Value = trackBar.Value; + } + + top += trackBar.Height - 25; + prompt.Height += trackBar.Height - 25; + + prompt.Controls.Add(trackBarEdit); + + control = trackBar; + break; + + default: continue; } @@ -248,6 +328,21 @@ namespace ColorControl.Forms field.Value = compoundValue; break; + + case FieldType.CheckBox: + var checkBox = (CheckBox)box; + + field.Value = checkBox.Checked; + + break; + + case FieldType.TrackBar: + var trackBar = (TrackBar)box; + + field.Value = trackBar.Value; + + break; + default: field.Value = box.Text.Trim(); break; diff --git a/ColorControl/MainForm.Designer.cs b/ColorControl/MainForm.Designer.cs index 4048312..fea08e3 100644 --- a/ColorControl/MainForm.Designer.cs +++ b/ColorControl/MainForm.Designer.cs @@ -82,6 +82,8 @@ this.miHDREnabled = new System.Windows.Forms.ToolStripMenuItem(); this.mnuNvDriverSettings = new System.Windows.Forms.ToolStripMenuItem(); this.miNvDriverSettingsIncluded = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuNvOverclocking = new System.Windows.Forms.ToolStripMenuItem(); + this.miNvOverclockingIncluded = new System.Windows.Forms.ToolStripMenuItem(); this.miNvCopyId = new System.Windows.Forms.ToolStripMenuItem(); this.btnApply = new System.Windows.Forms.Button(); this.lvNvPresets = new System.Windows.Forms.ListView(); @@ -359,33 +361,31 @@ this.lblNvOverclock.Location = new System.Drawing.Point(578, 496); this.lblNvOverclock.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.lblNvOverclock.Name = "lblNvOverclock"; - this.lblNvOverclock.Size = new System.Drawing.Size(62, 15); + this.lblNvOverclock.Size = new System.Drawing.Size(51, 15); this.lblNvOverclock.TabIndex = 66; - this.lblNvOverclock.Text = "Set clocks:"; - this.lblNvOverclock.Visible = false; + this.lblNvOverclock.Text = "OC info:"; // // edtNvOverclock // - this.edtNvOverclock.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.edtNvOverclock.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.edtNvOverclock.Enabled = false; this.edtNvOverclock.Location = new System.Drawing.Point(648, 493); this.edtNvOverclock.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.edtNvOverclock.Name = "edtNvOverclock"; - this.edtNvOverclock.Size = new System.Drawing.Size(212, 23); + this.edtNvOverclock.Size = new System.Drawing.Size(457, 23); this.edtNvOverclock.TabIndex = 65; - this.edtNvOverclock.Visible = false; // // btnNvSetClocks // this.btnNvSetClocks.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnNvSetClocks.Location = new System.Drawing.Point(866, 490); + this.btnNvSetClocks.Location = new System.Drawing.Point(868, 433); this.btnNvSetClocks.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.btnNvSetClocks.Name = "btnNvSetClocks"; this.btnNvSetClocks.Size = new System.Drawing.Size(88, 27); this.btnNvSetClocks.TabIndex = 64; this.btnNvSetClocks.Text = "Change..."; this.btnNvSetClocks.UseVisualStyleBackColor = true; - this.btnNvSetClocks.Visible = false; this.btnNvSetClocks.Click += new System.EventHandler(this.btnNvSetClocks_Click); // // lblNvGpuInfo @@ -398,18 +398,17 @@ this.lblNvGpuInfo.Size = new System.Drawing.Size(31, 15); this.lblNvGpuInfo.TabIndex = 63; this.lblNvGpuInfo.Text = "Info:"; - this.lblNvGpuInfo.Visible = false; // // edtNvGpuInfo // - this.edtNvGpuInfo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.edtNvGpuInfo.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.edtNvGpuInfo.Enabled = false; this.edtNvGpuInfo.Location = new System.Drawing.Point(648, 466); this.edtNvGpuInfo.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.edtNvGpuInfo.Name = "edtNvGpuInfo"; - this.edtNvGpuInfo.Size = new System.Drawing.Size(212, 23); + this.edtNvGpuInfo.Size = new System.Drawing.Size(457, 23); this.edtNvGpuInfo.TabIndex = 62; - this.edtNvGpuInfo.Visible = false; // // lblNvGPU // @@ -421,7 +420,6 @@ this.lblNvGPU.Size = new System.Drawing.Size(33, 15); this.lblNvGPU.TabIndex = 61; this.lblNvGPU.Text = "GPU:"; - this.lblNvGPU.Visible = false; // // cbxNvGPU // @@ -433,7 +431,7 @@ this.cbxNvGPU.Name = "cbxNvGPU"; this.cbxNvGPU.Size = new System.Drawing.Size(212, 23); this.cbxNvGPU.TabIndex = 60; - this.cbxNvGPU.Visible = false; + this.cbxNvGPU.SelectedIndexChanged += new System.EventHandler(this.cbxNvGPU_SelectedIndexChanged); // // btnNvSettings // @@ -595,9 +593,10 @@ this.miNvPresetDithering, this.miNvHDR, this.mnuNvDriverSettings, + this.mnuNvOverclocking, this.miNvCopyId}); this.mnuNvPresets.Name = "mnuNvPresets"; - this.mnuNvPresets.Size = new System.Drawing.Size(185, 230); + this.mnuNvPresets.Size = new System.Drawing.Size(185, 252); this.mnuNvPresets.Opening += new System.ComponentModel.CancelEventHandler(this.mnuNvPresets_Opening); // // miNvApply @@ -838,6 +837,21 @@ this.miNvDriverSettingsIncluded.Text = "Included"; this.miNvDriverSettingsIncluded.Click += new System.EventHandler(this.miNvDriverSettingsIncluded_Click); // + // mnuNvOverclocking + // + this.mnuNvOverclocking.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.miNvOverclockingIncluded}); + this.mnuNvOverclocking.Name = "mnuNvOverclocking"; + this.mnuNvOverclocking.Size = new System.Drawing.Size(184, 22); + this.mnuNvOverclocking.Text = "Overclocking"; + // + // miNvOverclockingIncluded + // + this.miNvOverclockingIncluded.Name = "miNvOverclockingIncluded"; + this.miNvOverclockingIncluded.Size = new System.Drawing.Size(120, 22); + this.miNvOverclockingIncluded.Text = "Included"; + this.miNvOverclockingIncluded.Click += new System.EventHandler(this.miNvOverclockingIncluded_Click); + // // miNvCopyId // this.miNvCopyId.Name = "miNvCopyId"; @@ -3168,7 +3182,6 @@ private System.Windows.Forms.Button btnNvPresetDelete; private System.Windows.Forms.Button btnAddModesNv; private System.Windows.Forms.ToolStripMenuItem miNvApply; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; private System.Windows.Forms.GroupBox grpGeneralOptions; private System.Windows.Forms.CheckBox chkStartMinimized; private System.Windows.Forms.CheckBox chkStartAfterLogin; @@ -3385,6 +3398,8 @@ private System.Windows.Forms.Button btnNvSetClocks; private System.Windows.Forms.Label lblNvOverclock; private System.Windows.Forms.TextBox edtNvOverclock; + private System.Windows.Forms.ToolStripMenuItem mnuNvOverclocking; + private System.Windows.Forms.ToolStripMenuItem miNvOverclockingIncluded; } } diff --git a/ColorControl/MainForm.cs b/ColorControl/MainForm.cs index 49aa5a3..9bca56c 100644 --- a/ColorControl/MainForm.cs +++ b/ColorControl/MainForm.cs @@ -209,7 +209,7 @@ namespace ColorControl catch (Exception ex) { //Logger.Error("Error initializing NvService: " + e.ToLogString()); - Logger.Debug($"No NVIDIA device detected: {ex.Message}"); + Logger.Debug($"No NVIDIA device detected: {ex.ToLogString()}"); tcMain.TabPages.Remove(tabNVIDIA); } } @@ -577,24 +577,23 @@ namespace ColorControl } } - //cbxNvGPU.Items.Clear(); - //cbxNvGPU.Items.AddRange(gpus.ToArray()); - //if (cbxNvGPU.Items.Count > 0) - //{ - // cbxNvGPU.SelectedIndex = 0; - - // var gpu = gpus[0]; - - // var gpuThermal = gpu.ThermalInformation.ThermalSensors.FirstOrDefault(s => s.Target == NvAPIWrapper.Native.GPU.ThermalSettingsTarget.GPU); - - // edtNvGpuInfo.Text = $"GPU: {gpu.CurrentClockFrequencies.GraphicsClock.Frequency / 1000}MHz @ {gpuThermal.CurrentTemperature}°C, Mem: {gpu.CurrentClockFrequencies.MemoryClock.Frequency / 1000}MHz"; - - // edtNvOverclock.Text = _nvService.GetGpuClocks(gpu); - //} + UpdateNvGpuInfo(gpus); FormUtils.SetNotifyIconText(_trayIcon, text); } + private void UpdateNvGpuInfo(List gpus = null) + { + gpus ??= _nvService.GetGPUs(); + + cbxNvGPU.Items.Clear(); + cbxNvGPU.Items.AddRange(gpus.ToArray()); + if (cbxNvGPU.Items.Count > 0 && cbxNvGPU.SelectedIndex == -1) + { + cbxNvGPU.SelectedIndex = 0; + } + } + private void UpdateDisplayInfoItemsAmd() { var displays = _amdService?.GetDisplayInfos(); @@ -724,7 +723,7 @@ namespace ColorControl var preset = GetSelectedNvPreset(); var enabled = preset != null; - FormUtils.EnableControls(tabNVIDIA, enabled, new List { lvNvPresets, btnAddModesNv, btnChange, edtNvGpuInfo, btnNvSetClocks, btnNvSettings }); + FormUtils.EnableControls(tabNVIDIA, enabled, new List { lvNvPresets, btnAddModesNv, btnChange, edtNvGpuInfo, btnNvSetClocks, btnNvSettings, edtNvOverclock }); if (enabled) { @@ -1223,6 +1222,7 @@ NOTE: installing the service may cause a User Account Control popup."); miNvCopyId.Visible = presetItemsVisible; miNvDriverSettingsIncluded.Visible = presetItemsVisible; mnuNvDriverSettings.Enabled = preset != null; + mnuNvOverclocking.Visible = preset != null && _nvService.Config.ShowOverclocking; if (preset == null) { @@ -1301,6 +1301,9 @@ NOTE: installing the service may cause a User Account Control popup."); mnuNvResolution.Font = _menuItemFonts[preset.applyResolution]; miNvPresetDithering.Font = _menuItemFonts[preset.applyDithering]; miNvHDR.Font = _menuItemFonts[preset.applyHDR]; + mnuNvOverclocking.Font = _menuItemFonts[preset.applyOverclocking]; + + BuildNvOverclockingMenu(preset); UpdateNvPresetMenuFont(); @@ -1309,6 +1312,52 @@ NOTE: installing the service may cause a User Account Control popup."); mnuNvDriverSettings.Font = _menuItemFonts[preset.applyDriverSettings]; } + private void BuildNvOverclockingMenu(NvPreset preset) + { + miNvOverclockingIncluded.Checked = preset.applyOverclocking; + + var gpus = _nvService.GetGPUs(); + + foreach (var gpu in gpus) + { + var gpuPciId = gpu.BusInformation.PCIIdentifiers.ToString(); + + var name = $"{mnuNvOverclocking.Name}_{gpu.GPUId}"; + + var gpuItem = FormUtils.BuildMenuItem(mnuNvOverclocking.DropDownItems, name, gpu.FullName); + + var subName = $"{name}_change"; + + var ocSettings = preset.ocSettings.FirstOrDefault(s => s.PCIIdentifier == gpuPciId) ?? new NvGpuOcSettings { PCIIdentifier = gpuPciId }; + + var subText = $"{ocSettings} (click to change)"; + + var subItem = FormUtils.BuildMenuItem(gpuItem.DropDownItems, subName, subText, ocSettings, nvChangeOverclockingMenuItem_Click); + } + } + + private void nvChangeOverclockingMenuItem_Click(object sender, EventArgs e) + { + var preset = GetSelectedNvPreset(); + + var menuItem = (ToolStripItem)sender; + + var currentSettings = (NvGpuOcSettings)menuItem.Tag; + + var gpuInfo = NvGpuInfo.GetGpuInfo(currentSettings.PCIIdentifier); + + var newSettings = AskNvOcSettings(gpuInfo, currentSettings); + + if (newSettings == null) + { + return; + } + + preset.UpdateOverclockingSetting(newSettings); + + AddOrUpdateItem(); + } + private void BuildNvRefreshRateResolutionMenu(NvPreset preset) { var displayName = preset.primaryDisplay ? null : preset.displayName; @@ -2969,9 +3018,9 @@ Do you want to continue?"; ClientPath = new FileInfo(Application.ExecutablePath).Directory.FullName }; - var result = PipeUtils.SendMessage(message); + var result = PipeUtils.SendMessage(message, 10000); - if (!result.Result) + if (result != null && !result.Result) { MessageForms.ErrorOk($"Error while updating: {result.ErrorMessage}"); @@ -4400,20 +4449,43 @@ The InStart and Software Update items are now visible under the Expert-button." private void miNvSettings_Click(object sender, EventArgs e) { - var shortcut = EditShortcut(_config.NvQuickAccessShortcut, "Quick Access shortcut", "NVIDIA controller settings"); + EditNvSettings(); + } - if (shortcut == null) + private void EditNvSettings() + { + var values = MessageForms.ShowDialog("NVIDIA controller settings", new[] { + new MessageForms.FieldDefinition + { + Label = "Quick Access shortcut", + FieldType = MessageForms.FieldType.Shortcut, + Value = _config.NvQuickAccessShortcut + }, + new MessageForms.FieldDefinition + { + Label = "Enable overclocking", + FieldType = MessageForms.FieldType.CheckBox, + Value = _nvService.Config.ShowOverclocking + } + }); + if (!values.Any()) { return; } + var shortcut = values[0].Value.ToString(); + var enableOc = (bool)values[1].Value; + var clear = !string.IsNullOrEmpty(_config.NvQuickAccessShortcut); _config.NvQuickAccessShortcut = shortcut; Utils.RegisterShortcut(Handle, SHORTCUTID_NVQA, _config.NvQuickAccessShortcut, clear); + + _nvService.Config.ShowOverclocking = enableOc; } + private void btnNvSettings_Click(object sender, EventArgs e) { mnuNvSettings.Show(btnNvSettings, btnNvSettings.PointToClient(Cursor.Position)); @@ -4876,30 +4948,316 @@ Currently ColorControl is {(Utils.IsAdministrator() ? "" : "not ")}running as ad private void btnNvSetClocks_Click(object sender, EventArgs e) { + var gpu = cbxNvGPU.SelectedItem as PhysicalGPU; + + if (gpu == null) + { + return; + } + + var gpuInfo = NvGpuInfo.GetGpuInfo(gpu); + var currentSettings = gpuInfo.GetOverclockSettings(); + + var newSettings = AskNvOcSettings(gpuInfo, currentSettings); + + if (newSettings == null) + { + return; + } + + _nvService.ApplyOverclocking(newSettings); + + UpdateNvGpuInfo(); + } + + public NvGpuOcSettings AskNvOcSettings(NvGpuInfo gpuInfo, NvGpuOcSettings currentSettings) + { + var overclockTypes = Utils.GetDescriptions(); + + var values = MessageForms.ShowDialog("Choose desired overclock settings", new[] { + new MessageForms.FieldDefinition + { + Label = "Overclock method", + FieldType = MessageForms.FieldType.DropDown, + Values = overclockTypes, + Value = currentSettings.Type + } }); + if (!values.Any()) + { + return null; + } + + var overclockType = Enum.Parse(values[0].Value.ToString()); + var newSettings = default(NvGpuOcSettings); + + if (overclockType == NvGpuOcType.Curve) + { + newSettings = AskNvCurveOcSettings(gpuInfo, currentSettings); + } + else if (overclockType == NvGpuOcType.Offset) + { + newSettings = AskNvOffsetOcSettings(gpuInfo, currentSettings); + } + else + { + newSettings = new NvGpuOcSettings + { + Type = overclockType, + PCIIdentifier = gpuInfo.GPU.BusInformation.PCIIdentifiers.ToString() + }; + } + + return newSettings; + } + + public NvGpuOcSettings AskNvCurveOcSettings(NvGpuInfo gpuInfo, NvGpuOcSettings currentSettings) + { + var nvOverclockSettings = new NvGpuOcSettings + { + Type = NvGpuOcType.Curve, + PCIIdentifier = gpuInfo.GPU.BusInformation.PCIIdentifiers.ToString() + }; + + var curveEntries = gpuInfo.CurveV3.GPUCurveEntries; + + var graphicsDelta = gpuInfo.GetDeltaClockMinMax(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics); + + var minCurveFreq = curveEntries.Max(e => e.DefaultFrequencyInkHz) + graphicsDelta.Item1; + var freqValues = curveEntries + .Where(e => e.DefaultFrequencyInkHz == 0 || e.DefaultFrequencyInkHz >= minCurveFreq) + .Select(e => (e.DefaultFrequencyInkHz / 1000).ToString()).Distinct() + .OrderBy(x => x) + .ToList(); + var voltValues = curveEntries + .Where(e => e.DefaultVoltageInMicroV == 0 || e.DefaultFrequencyInkHz >= minCurveFreq) + .OrderBy(e => e.DefaultVoltageInMicroV) + .Select(e => (e.DefaultVoltageInMicroV / 1000).ToString()) + .Distinct() + .ToList(); + + var currentGraphicsVoltage = currentSettings.MaximumVoltageUv > 0 ? currentSettings.MaximumVoltageUv : 1050000; + + var curveEntry = curveEntries.FirstOrDefault(e => e.VoltageInMicroV == currentGraphicsVoltage); + var currentGpuFreq = curveEntry.FrequencyInkHz; + + var memoryDelta = gpuInfo.GetDeltaClockMinMax(NvAPIWrapper.Native.GPU.PublicClockDomain.Memory); + + var powerLimits = gpuInfo.GetPowerLimits(); + + var defaultPowerLimitMw = gpuInfo.DefaultPowerInMilliWatts; + + var powerField = defaultPowerLimitMw > 0 ? + new MessageForms.FieldDefinition + { + Label = $"Power limit in milli watts. Min: {gpuInfo.MinPowerInMilliWatts}, max: {gpuInfo.MaxPowerInMilliWatts}", + FieldType = MessageForms.FieldType.TrackBar, + Value = (int)((decimal)defaultPowerLimitMw / 100000 * currentSettings.PowerPCM), + MinValue = gpuInfo.MinPowerInMilliWatts, + MaxValue = gpuInfo.MaxPowerInMilliWatts + } + : new MessageForms.FieldDefinition + { + Label = $"Power limit in PCM (per cent mille). Min: {powerLimits.Item1}, max: {powerLimits.Item2}", + FieldType = MessageForms.FieldType.TrackBar, + Value = currentSettings.PowerPCM, + MinValue = powerLimits.Item1, + MaxValue = powerLimits.Item2 + }; + var values = MessageForms.ShowDialog("Set desired clock speeds and voltage", new[] { + new MessageForms.FieldDefinition + { + Label = $"Core offset in MHz ({graphicsDelta.Item1.ToUnitString()} to {graphicsDelta.Item2.ToUnitString()})", + FieldType = MessageForms.FieldType.Numeric, + MinValue = graphicsDelta.Item1 / 1000, + MaxValue = graphicsDelta.Item2 / 1000, + Value = currentSettings.GraphicsOffsetKHz / 1000 + }, + new MessageForms.FieldDefinition + { + Label = "Optional undervolt: maximum voltage in milli volt", + FieldType = MessageForms.FieldType.DropDown, + Value = currentSettings.MaximumVoltageUv / 1000, + Values = voltValues, + }, + new MessageForms.FieldDefinition + { + Label = "Optional undervolt: maximum core frequency in MHz", + FieldType = MessageForms.FieldType.DropDown, + Value = currentSettings.MaximumFrequencyKHz / 1000, + Values = freqValues, + }, + new MessageForms.FieldDefinition + { + Label = $"Memory offset in MHz ({memoryDelta.Item1.ToUnitString()} to {memoryDelta.Item2.ToUnitString()})", + FieldType = MessageForms.FieldType.Numeric, + MinValue = memoryDelta.Item1 / 1000, + MaxValue = memoryDelta.Item2 / 1000, + Value = currentSettings.MemoryOffsetKHz / 1000 + }, + new MessageForms.FieldDefinition + { + Label = "Voltage boost in %", + FieldType = MessageForms.FieldType.Numeric, + Value = currentSettings.VoltageBoostPercent, + MinValue = 0, + MaxValue = 100 + }, + powerField, + }); + if (!values.Any()) + { + return null; + } + + nvOverclockSettings.GraphicsOffsetKHz = values[0].ValueAsInt * 1000; + nvOverclockSettings.MaximumVoltageUv = values[1].ValueAsUInt * 1000; + nvOverclockSettings.MaximumFrequencyKHz = values[2].ValueAsUInt * 1000; + nvOverclockSettings.MemoryOffsetKHz = values[3].ValueAsInt * 1000; + nvOverclockSettings.VoltageBoostPercent = values[4].ValueAsUInt; + + var power = values[5].ValueAsUInt; + + nvOverclockSettings.PowerPCM = defaultPowerLimitMw > 0 ? (uint)((decimal)power / defaultPowerLimitMw * 100000) : power; + + return nvOverclockSettings; + } + + public NvGpuOcSettings AskNvOffsetOcSettings(NvGpuInfo gpuInfo, NvGpuOcSettings currentSettings) + { + var nvOverclockSettings = new NvGpuOcSettings + { + Type = NvGpuOcType.Offset, + PCIIdentifier = gpuInfo.GPU.BusInformation.PCIIdentifiers.ToString() + }; + + var curveEntries = gpuInfo.CurveV3.GPUCurveEntries; + + var freqValues = curveEntries.Select(e => (e.DefaultFrequencyInkHz / 1000).ToString()).Distinct().ToList(); + var voltValues = curveEntries.Select(e => (e.DefaultVoltageInMicroV / 1000).ToString()).Distinct().ToList(); + + var currentGraphicsVoltage = currentSettings.MaximumVoltageUv > 0 ? currentSettings.MaximumVoltageUv : 1050000; + + var curveEntry = curveEntries.FirstOrDefault(e => e.VoltageInMicroV == currentGraphicsVoltage); + var currentGpuFreq = curveEntry.FrequencyInkHz; + + var graphicsDelta = gpuInfo.GetDeltaClockMinMax(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics); + var memoryDelta = gpuInfo.GetDeltaClockMinMax(NvAPIWrapper.Native.GPU.PublicClockDomain.Memory); + + var powerLimits = gpuInfo.GetPowerLimits(); + + var values = MessageForms.ShowDialog("Set desired clock speeds and voltage", new[] { + new MessageForms.FieldDefinition + { + Label = $"Core offset in MHz ({graphicsDelta.Item1.ToUnitString()} to {graphicsDelta.Item2.ToUnitString()})", + FieldType = MessageForms.FieldType.Numeric, + MinValue = graphicsDelta.Item1 / 1000, + MaxValue = graphicsDelta.Item2 / 1000, + Value = currentSettings.GraphicsOffsetKHz / 1000 + }, + new MessageForms.FieldDefinition + { + Label = $"Memory offset in MHz ({memoryDelta.Item1.ToUnitString()} to {memoryDelta.Item2.ToUnitString()})", + FieldType = MessageForms.FieldType.Numeric, + MinValue = memoryDelta.Item1 / 1000, + MaxValue = memoryDelta.Item2 / 1000, + Value = currentSettings.MemoryOffsetKHz / 1000 + }, + new MessageForms.FieldDefinition + { + Label = "Voltage boost in %", + FieldType = MessageForms.FieldType.Numeric, + Value = currentSettings.VoltageBoostPercent, + MinValue = 0, + MaxValue = 100 + }, + new MessageForms.FieldDefinition + { + Label = $"Power limit in PCM (per cent mille). Min: {powerLimits.Item1}, max: {powerLimits.Item2}", + FieldType = MessageForms.FieldType.Numeric, + Value = currentSettings.PowerPCM, + MinValue = powerLimits.Item1, + MaxValue = powerLimits.Item2 + }, + }); + if (!values.Any()) + { + return null; + } + + nvOverclockSettings.GraphicsOffsetKHz = values[0].ValueAsInt * 1000; + nvOverclockSettings.MemoryOffsetKHz = values[1].ValueAsInt * 1000; + nvOverclockSettings.VoltageBoostPercent = values[2].ValueAsUInt; + nvOverclockSettings.PowerPCM = values[3].ValueAsUInt; + + return nvOverclockSettings; + } + + public void SetClocks() + { + var gpu = cbxNvGPU.SelectedItem as PhysicalGPU; + + var gpuInfo = NvGpuInfo.GetGpuInfo(gpu); + + var curveEntries = gpuInfo.CurveV3.GPUCurveEntries; + + var freqValues = curveEntries.Select(e => e.DefaultFrequencyInkHz.ToString()).Distinct().ToList(); + var voltValues = curveEntries.Select(e => e.DefaultVoltageInMicroV.ToString()).Distinct().ToList(); + + var lockedGraphics = gpuInfo.GetLockedBoost(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics); + + var currentGraphicsVoltage = lockedGraphics.Item1 > 0 ? lockedGraphics.Item1 : 1050000; + + var curveEntry = curveEntries.FirstOrDefault(e => e.VoltageInMicroV == currentGraphicsVoltage); + var currentGpuFreq = curveEntry.FrequencyInkHz; + + var graphicsDelta = gpuInfo.GetDeltaClockLimits(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics); + var memoryDelta = gpuInfo.GetDeltaClockLimits(NvAPIWrapper.Native.GPU.PublicClockDomain.Memory); + + var graphicsMinValue = graphicsDelta?.DeltaRange.Minimum ?? -502000; + var graphicsMaxValue = graphicsDelta?.DeltaRange.Maximum ?? 1000000; + var memoryMinValue = memoryDelta?.DeltaRange.Minimum ?? -502000; + var memoryMaxValue = memoryDelta?.DeltaRange.Maximum ?? 3000000; + + var currentGraphicsOffset = gpuInfo.GetOffset(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics); + var currentMemoryOffset = gpuInfo.GetOffset(NvAPIWrapper.Native.GPU.PublicClockDomain.Memory); + + var values = MessageForms.ShowDialog("Set desired clock speeds and voltage", new[] { + new MessageForms.FieldDefinition + { + Label = $"Core offset in MHz ({graphicsMinValue}KHz to {graphicsMaxValue}KHz)", + FieldType = MessageForms.FieldType.Numeric, + MinValue = graphicsDelta?.DeltaRange.Minimum ?? -502000, + MaxValue = graphicsDelta?.DeltaRange.Maximum ?? 1000000, + Value = currentGraphicsOffset + }, new MessageForms.FieldDefinition { Label = "Voltage in micro volt", - FieldType = MessageForms.FieldType.Numeric, - MinValue = 650000, - MaxValue = 1100000, - Value = 1050000 + FieldType = MessageForms.FieldType.DropDown, + Values = voltValues, + //FieldType = MessageForms.FieldType.Numeric, + //MinValue = 650000, + //MaxValue = 1100000, + //Value = currentGraphicsVoltage }, new MessageForms.FieldDefinition { - Label = "Core offset in KHz", - FieldType = MessageForms.FieldType.Numeric, - MinValue = -502000, - MaxValue = 1000000, - Value = 0 + Label = "Core frequency in KHz", + FieldType = MessageForms.FieldType.DropDown, + Values = freqValues, + //FieldType = MessageForms.FieldType.Numeric, + //MinValue = 2000000, + //MaxValue = 3200000, + //Value = currentGpuFreq }, new MessageForms.FieldDefinition { - Label = "Memory offset in KHz", + Label = $"Memory offset in KHz ({memoryMinValue}KHz to {memoryMaxValue}KHz)", FieldType = MessageForms.FieldType.Numeric, - MinValue = -502000, + MinValue = graphicsDelta?.DeltaRange.Minimum ?? -502000, MaxValue = 2500000, - Value = 0 + Value = currentMemoryOffset }, }); if (!values.Any()) @@ -4908,10 +5266,47 @@ Currently ColorControl is {(Utils.IsAdministrator() ? "" : "not ")}running as ad } var voltage = (uint)values[0].ValueAsInt; - var coreOffset = values[1].ValueAsInt; + //var coreOffset = values[1].ValueAsInt; + var coreFreq = values[1].ValueAsInt; var memoryOffset = values[2].ValueAsInt; - _nvService.SetGpuClocks(null, voltage, coreOffset, memoryOffset); + var normalized = (coreFreq / 15000) * 15000; + var newCurveEntryFreq = curveEntries.FirstOrDefault(e => e.DefaultFrequencyInkHz == normalized); + var newCurveEntryVolt = curveEntries.FirstOrDefault(e => e.DefaultVoltageInMicroV == voltage); + + var coreOffset = (int)(newCurveEntryFreq.DefaultFrequencyInkHz - newCurveEntryVolt.DefaultFrequencyInkHz); + + gpuInfo.SetGpuClocks(voltage, coreOffset, memoryOffset); + } + + private void miNvOverclockingIncluded_Click(object sender, EventArgs e) + { + var preset = GetSelectedNvPreset(); + + preset.applyOverclocking = !preset.applyOverclocking; + + AddOrUpdateItem(); + } + + private void cbxNvGPU_SelectedIndexChanged(object sender, EventArgs e) + { + RefreshNvGpuInfo(); + } + + private void RefreshNvGpuInfo() + { + var gpu = (PhysicalGPU)cbxNvGPU.SelectedItem; + + if (gpu == null) + { + return; + } + + var gpuInfo = NvGpuInfo.GetGpuInfo(gpu); + var ocSettings = gpuInfo.GetOverclockSettings(); + + edtNvGpuInfo.Text = gpuInfo.ToString(); + edtNvOverclock.Text = ocSettings.ToString(); } } } \ No newline at end of file diff --git a/ColorControl/Services/NVIDIA/Kernel32.cs b/ColorControl/Services/NVIDIA/Kernel32.cs new file mode 100644 index 0000000..af1948b --- /dev/null +++ b/ColorControl/Services/NVIDIA/Kernel32.cs @@ -0,0 +1,1557 @@ +// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// Copyright (C) LibreHardwareMonitor and Contributors. +// All Rights Reserved. + +using Microsoft.Win32.SafeHandles; +using System; +using System.IO; +using System.Runtime.InteropServices; + +// ReSharper disable InconsistentNaming + +namespace ColorControl.Services.NVIDIA; + +public class Kernel32 +{ + public const int ERROR_SERVICE_ALREADY_RUNNING = unchecked((int)0x80070420); + + public const int ERROR_SERVICE_EXISTS = unchecked((int)0x80070431); + + internal const uint BATTERY_UNKNOWN_TIME = 0xFFFFFFFF; + internal const string IntelNVMeMiniPortSignature1 = "NvmeMini"; + internal const string IntelNVMeMiniPortSignature2 = "IntelNvm"; + + internal const uint LPTR = 0x0000 | 0x0040; + + internal const int MAX_DRIVE_ATTRIBUTES = 512; + internal const uint NVME_PASS_THROUGH_SRB_IO_CODE = 0xe0002000; + internal const byte SMART_LBA_HI = 0xC2; + internal const byte SMART_LBA_HI_EXCEEDED = 0x2C; + internal const byte SMART_LBA_MID = 0x4F; + internal const byte SMART_LBA_MID_EXCEEDED = 0xF4; + + private const string DllName = "kernel32.dll"; + + [Flags] + public enum NVME_CRITICAL_WARNING + { + None = 0x00, + + /// + /// If set to 1, then the available spare space has fallen below the threshold. + /// + AvailableSpaceLow = 0x01, + + /// + /// If set to 1, then a temperature is above an over temperature threshold or below an under temperature threshold. + /// + TemperatureThreshold = 0x02, + + /// + /// If set to 1, then the device reliability has been degraded due to significant media related errors or any internal error that degrades device reliability. + /// + ReliabilityDegraded = 0x04, + + /// + /// If set to 1, then the media has been placed in read only mode + /// + ReadOnly = 0x08, + + /// + /// If set to 1, then the volatile memory backup device has failed. This field is only valid if the controller has a volatile memory backup solution. + /// + VolatileMemoryBackupDeviceFailed = 0x10 + } + + /// + /// Create a instance from a struct with zero initialized memory arrays + /// no need to init every inner array with the correct sizes + /// + /// type of struct that is needed + /// + internal static T CreateStruct() + { + int size = Marshal.SizeOf(); + IntPtr ptr = Marshal.AllocHGlobal(size); + RtlZeroMemory(ptr, size); + T result = Marshal.PtrToStructure(ptr); + Marshal.FreeHGlobal(ptr); + return result; + } + + internal static SafeHandle OpenDevice(string devicePath) + { + SafeHandle hDevice = CreateFile(devicePath, FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero); + if (hDevice.IsInvalid || hDevice.IsClosed) + hDevice = null; + + return hDevice; + } + + [DllImport(DllName, CharSet = CharSet.Auto, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX lpBuffer); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + internal static extern SafeFileHandle CreateFile + ( + [MarshalAs(UnmanagedType.LPTStr)] string lpFileName, + [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess, + [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode, + IntPtr lpSecurityAttributes, + [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition, + [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes, + IntPtr hTemplateFile); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeHandle hDevice, + DFP dwIoControlCode, + ref SENDCMDINPARAMS lpInBuffer, + int nInBufferSize, + out ATTRIBUTECMDOUTPARAMS lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeHandle hDevice, + DFP dwIoControlCode, + ref SENDCMDINPARAMS lpInBuffer, + int nInBufferSize, + out THRESHOLDCMDOUTPARAMS lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeHandle hDevice, + DFP dwIoControlCode, + ref SENDCMDINPARAMS lpInBuffer, + int nInBufferSize, + out SENDCMDOUTPARAMS lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeHandle hDevice, + DFP dwIoControlCode, + ref SENDCMDINPARAMS lpInBuffer, + int nInBufferSize, + out IDENTIFYCMDOUTPARAMS lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeHandle hDevice, + DFP dwIoControlCode, + ref SENDCMDINPARAMS lpInBuffer, + int nInBufferSize, + out STATUSCMDOUTPARAMS lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeHandle hDevice, + IOCTL dwIoControlCode, + ref STORAGE_PROPERTY_QUERY lpInBuffer, + int nInBufferSize, + out STORAGE_DEVICE_DESCRIPTOR_HEADER lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeHandle hDevice, + IOCTL dwIoControlCode, + ref STORAGE_PROPERTY_QUERY lpInBuffer, + int nInBufferSize, + IntPtr lpOutBuffer, + uint nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeHandle hDevice, + IOCTL dwIoControlCode, + IntPtr lpInBuffer, + int nInBufferSize, + IntPtr lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeFileHandle hDevice, + IOCTL dwIoControlCode, + ref BATTERY_QUERY_INFORMATION lpInBuffer, + int nInBufferSize, + ref BATTERY_INFORMATION lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeFileHandle hDevice, + IOCTL dwIoControlCode, + ref uint lpInBuffer, + int nInBufferSize, + ref uint lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeFileHandle hDevice, + IOCTL dwIoControlCode, + ref BATTERY_WAIT_STATUS lpInBuffer, + int nInBufferSize, + ref BATTERY_STATUS lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeFileHandle hDevice, + IOCTL dwIoControlCode, + ref BATTERY_QUERY_INFORMATION lpInBuffer, + int nInBufferSize, + IntPtr lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeFileHandle hDevice, + IOCTL dwIoControlCode, + ref BATTERY_QUERY_INFORMATION lpInBuffer, + int nInBufferSize, + ref uint lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + internal static extern IntPtr LocalAlloc(uint uFlags, ulong uBytes); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + internal static extern IntPtr LocalFree(IntPtr hMem); + + [DllImport(DllName, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + internal static extern void RtlZeroMemory(IntPtr Destination, int Length); + + [DllImport(DllName, SetLastError = false)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + internal static extern void RtlCopyMemory(IntPtr Destination, IntPtr Source, uint Length); + + [DllImport(DllName, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + internal static extern IntPtr LoadLibrary(string lpFileName); + + [DllImport(DllName, ExactSpelling = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + internal static extern IntPtr GetProcAddress(IntPtr module, string methodName); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool FreeLibrary(IntPtr module); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + internal static extern IntPtr GetCurrentThread(); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + internal static extern ushort GetActiveProcessorGroupCount(); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + internal static extern bool SetThreadGroupAffinity(IntPtr thread, ref GROUP_AFFINITY groupAffinity, out GROUP_AFFINITY previousGroupAffinity); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + internal static extern IntPtr VirtualAlloc(IntPtr lpAddress, UIntPtr dwSize, MEM flAllocationType, PAGE flProtect); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + internal static extern bool VirtualFree(IntPtr lpAddress, UIntPtr dwSize, MEM dwFreeType); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + internal static extern bool DeviceIoControl + ( + SafeFileHandle device, + IOControlCode ioControlCode, + [MarshalAs(UnmanagedType.AsAny)][In] object inBuffer, + uint inBufferSize, + [MarshalAs(UnmanagedType.AsAny)][Out] object outBuffer, + uint nOutBufferSize, + out uint bytesReturned, + IntPtr overlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + internal static extern IntPtr CreateFile + ( + string lpFileName, + uint dwDesiredAccess, + FileShare dwShareMode, + IntPtr lpSecurityAttributes, + FileMode dwCreationDisposition, + FileAttributes dwFlagsAndAttributes, + IntPtr hTemplateFile); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + internal static extern int EnumSystemFirmwareTables(Provider firmwareTableProviderSignature, IntPtr firmwareTableBuffer, int bufferSize); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, SetLastError = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + internal static extern int GetSystemFirmwareTable(Provider firmwareTableProviderSignature, int firmwareTableID, IntPtr firmwareTableBuffer, int bufferSize); + + [StructLayout(LayoutKind.Sequential, Pack = 4)] + public struct GROUP_AFFINITY + { + public UIntPtr Mask; + + [MarshalAs(UnmanagedType.U2)] + public ushort Group; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U2)] + public ushort[] Reserved; + } + + internal enum DFP : uint + { + DFP_GET_VERSION = 0x00074080, + DFP_SEND_DRIVE_COMMAND = 0x0007c084, + DFP_RECEIVE_DRIVE_DATA = 0x0007c088 + } + + internal enum IOCTL : uint + { + IOCTL_SCSI_PASS_THROUGH = 0x04d004, + IOCTL_SCSI_MINIPORT = 0x04d008, + IOCTL_SCSI_PASS_THROUGH_DIRECT = 0x04d014, + IOCTL_SCSI_GET_ADDRESS = 0x41018, + IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400, + IOCTL_BATTERY_QUERY_TAG = 0x294040, + IOCTL_BATTERY_QUERY_INFORMATION = 0x294044, + IOCTL_BATTERY_QUERY_STATUS = 0x29404C + } + + [Flags] + internal enum BatteryCapabilities : uint + { + BATTERY_CAPACITY_RELATIVE = 0x40000000, + BATTERY_IS_SHORT_TERM = 0x20000000, + BATTERY_SET_CHARGE_SUPPORTED = 0x00000001, + BATTERY_SET_DISCHARGE_SUPPORTED = 0x00000002, + BATTERY_SYSTEM_BATTERY = 0x80000000 + } + + internal enum BATTERY_QUERY_INFORMATION_LEVEL + { + BatteryInformation, + BatteryGranularityInformation, + BatteryTemperature, + BatteryEstimatedTime, + BatteryDeviceName, + BatteryManufactureDate, + BatteryManufactureName, + BatteryUniqueID, + BatterySerialNumber + } + + [StructLayout(LayoutKind.Sequential)] + internal struct BATTERY_QUERY_INFORMATION + { + public uint BatteryTag; + public BATTERY_QUERY_INFORMATION_LEVEL InformationLevel; + public uint AtRate; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct BATTERY_INFORMATION + { + public BatteryCapabilities Capabilities; + public byte Technology; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] Reserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public char[] Chemistry; + + public uint DesignedCapacity; + public uint FullChargedCapacity; + public uint DefaultAlert1; + public uint DefaultAlert2; + public uint CriticalBias; + public uint CycleCount; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct BATTERY_WAIT_STATUS + { + public uint BatteryTag; + public uint Timeout; + public uint PowerState; + public uint LowCapacity; + public uint HighCapacity; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct BATTERY_STATUS + { + public uint PowerState; + public uint Capacity; + public uint Voltage; + public int Rate; + } + + [Flags] + internal enum NVME_DIRECTION : uint + { + NVME_FROM_HOST_TO_DEV = 1, + NVME_FROM_DEV_TO_HOST = 2, + NVME_BI_DIRECTION = NVME_FROM_DEV_TO_HOST | NVME_FROM_HOST_TO_DEV + } + + internal enum NVME_LOG_PAGES + { + NVME_LOG_PAGE_ERROR_INFO = 0x01, + NVME_LOG_PAGE_HEALTH_INFO = 0x02, + NVME_LOG_PAGE_FIRMWARE_SLOT_INFO = 0x03, + NVME_LOG_PAGE_CHANGED_NAMESPACE_LIST = 0x04, + NVME_LOG_PAGE_COMMAND_EFFECTS = 0x05, + NVME_LOG_PAGE_DEVICE_SELF_TEST = 0x06, + NVME_LOG_PAGE_TELEMETRY_HOST_INITIATED = 0x07, + NVME_LOG_PAGE_TELEMETRY_CTLR_INITIATED = 0x08, + NVME_LOG_PAGE_RESERVATION_NOTIFICATION = 0x80, + NVME_LOG_PAGE_SANITIZE_STATUS = 0x81 + } + + internal enum ATA_COMMAND : byte + { + /// + /// SMART data requested. + /// + ATA_SMART = 0xB0, + + /// + /// Identify data is requested. + /// + ATA_IDENTIFY_DEVICE = 0xEC + } + + internal enum SCSI_IOCTL_DATA + { + SCSI_IOCTL_DATA_OUT = 0, + SCSI_IOCTL_DATA_IN = 1, + SCSI_IOCTL_DATA_UNSPECIFIED = 2 + } + + internal enum SMART_FEATURES : byte + { + /// + /// Read SMART data. + /// + SMART_READ_DATA = 0xD0, + + /// + /// Read SMART thresholds. + /// obsolete + /// + READ_THRESHOLDS = 0xD1, + + /// + /// Autosave SMART data. + /// + ENABLE_DISABLE_AUTOSAVE = 0xD2, + + /// + /// Save SMART attributes. + /// + SAVE_ATTRIBUTE_VALUES = 0xD3, + + /// + /// Set SMART to offline immediately. + /// + EXECUTE_OFFLINE_DIAGS = 0xD4, + + /// + /// Read SMART log. + /// + SMART_READ_LOG = 0xD5, + + /// + /// Write SMART log. + /// + SMART_WRITE_LOG = 0xD6, + + /// + /// Write SMART thresholds. + /// obsolete + /// + WRITE_THRESHOLDS = 0xD7, + + /// + /// Enable SMART. + /// + ENABLE_SMART = 0xD8, + + /// + /// Disable SMART. + /// + DISABLE_SMART = 0xD9, + + /// + /// Get SMART status. + /// + RETURN_SMART_STATUS = 0xDA, + + /// + /// Set SMART to offline automatically. + /// + ENABLE_DISABLE_AUTO_OFFLINE = 0xDB /* obsolete */ + } + + internal enum STORAGE_BUS_TYPE + { + BusTypeUnknown = 0x00, + BusTypeScsi, + BusTypeAtapi, + BusTypeAta, + BusType1394, + BusTypeSsa, + BusTypeFibre, + BusTypeUsb, + BusTypeRAID, + BusTypeiScsi, + BusTypeSas, + BusTypeSata, + BusTypeSd, + BusTypeMmc, + BusTypeVirtual, + BusTypeFileBackedVirtual, + BusTypeSpaces, + BusTypeNvme, + BusTypeSCM, + BusTypeMax, + BusTypeMaxReserved = 0x7F + } + + internal enum STORAGE_PROPERTY_ID + { + StorageDeviceProperty = 0, + StorageAdapterProperty, + StorageDeviceIdProperty, + StorageDeviceUniqueIdProperty, + StorageDeviceWriteCacheProperty, + StorageMiniportProperty, + StorageAccessAlignmentProperty, + StorageDeviceSeekPenaltyProperty, + StorageDeviceTrimProperty, + StorageDeviceWriteAggregationProperty, + StorageDeviceDeviceTelemetryProperty, + StorageDeviceLBProvisioningProperty, + StorageDevicePowerProperty, + StorageDeviceCopyOffloadProperty, + StorageDeviceResiliencyProperty, + StorageDeviceMediumProductType, + StorageAdapterRpmbProperty, + StorageDeviceIoCapabilityProperty = 48, + StorageAdapterProtocolSpecificProperty, + StorageDeviceProtocolSpecificProperty, + StorageAdapterTemperatureProperty, + StorageDeviceTemperatureProperty, + StorageAdapterPhysicalTopologyProperty, + StorageDevicePhysicalTopologyProperty, + StorageDeviceAttributesProperty, + StorageDeviceManagementStatus, + StorageAdapterSerialNumberProperty, + StorageDeviceLocationProperty + } + + internal enum STORAGE_PROTOCOL_NVME_DATA_TYPE + { + NVMeDataTypeUnknown = 0, + NVMeDataTypeIdentify, + NVMeDataTypeLogPage, + NVMeDataTypeFeature + } + + internal enum STORAGE_PROTOCOL_NVME_PROTOCOL_DATA_REQUEST_VALUE + { + NVMeIdentifyCnsSpecificNamespace = 0, + NVMeIdentifyCnsController = 1, + NVMeIdentifyCnsActiveNamespaces = 2 + } + + internal enum STORAGE_PROTOCOL_TYPE + { + ProtocolTypeUnknown = 0x00, + ProtocolTypeScsi, + ProtocolTypeAta, + ProtocolTypeNvme, + ProtocolTypeSd, + ProtocolTypeProprietary = 0x7E, + ProtocolTypeMaxReserved = 0x7F + } + + internal enum STORAGE_QUERY_TYPE + { + PropertyStandardQuery = 0, + PropertyExistsQuery, + PropertyMaskQuery, + PropertyQueryMaxDefined + } + + [StructLayout(LayoutKind.Sequential)] + internal struct MEMORYSTATUSEX + { + public uint dwLength; + public uint dwMemoryLoad; + public ulong ullTotalPhys; + public ulong ullAvailPhys; + public ulong ullTotalPageFile; + public ulong ullAvailPageFile; + public ulong ullTotalVirtual; + public ulong ullAvailVirtual; + public ulong ullAvailExtendedVirtual; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct SMART_ATTRIBUTE + { + public byte Id; + public short Flags; + public byte CurrentValue; + public byte WorstValue; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] RawValue; + + public byte Reserved; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct SMART_THRESHOLD + { + public byte Id; + public byte Threshold; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] + public byte[] Reserved; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct SENDCMDINPARAMS + { + public uint cBufferSize; + public IDEREGS irDriveRegs; + public byte bDriveNumber; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] bReserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public uint[] dwReserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] bBuffer; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct IDEREGS + { + public SMART_FEATURES bFeaturesReg; + public byte bSectorCountReg; + public byte bSectorNumberReg; + public byte bCylLowReg; + public byte bCylHighReg; + public byte bDriveHeadReg; + public ATA_COMMAND bCommandReg; + public byte bReserved; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct DRIVERSTATUS + { + public byte bDriverError; + public byte bIDEError; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] + public byte[] Reserved; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct SENDCMDOUTPARAMS + { + public uint cBufferSize; + public DRIVERSTATUS DriverStatus; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] bBuffer; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct ATTRIBUTECMDOUTPARAMS + { + public uint cBufferSize; + public DRIVERSTATUS DriverStatus; + public byte Version; + public byte Reserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DRIVE_ATTRIBUTES)] + public SMART_ATTRIBUTE[] Attributes; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct THRESHOLDCMDOUTPARAMS + { + public uint cBufferSize; + public DRIVERSTATUS DriverStatus; + public byte Version; + public byte Reserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DRIVE_ATTRIBUTES)] + public SMART_THRESHOLD[] Thresholds; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct STATUSCMDOUTPARAMS + { + public uint cBufferSize; + public DRIVERSTATUS DriverStatus; + public IDEREGS irDriveRegs; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct IDENTIFY_DATA + { + public ushort GeneralConfiguration; + public ushort NumberOfCylinders; + public ushort Reserved1; + public ushort NumberOfHeads; + public ushort UnformattedBytesPerTrack; + public ushort UnformattedBytesPerSector; + public ushort SectorsPerTrack; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public ushort[] VendorUnique; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public byte[] SerialNumber; + + public ushort BufferType; + public ushort BufferSectorSize; + public ushort NumberOfEccBytes; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] FirmwareRevision; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)] + public byte[] ModelNumber; + + public byte MaximumBlockTransfer; + public byte VendorUnique2; + public ushort DoubleWordIo; + public ushort Capabilities; + public ushort Reserved2; + public byte VendorUnique3; + public byte PioCycleTimingMode; + public byte VendorUnique4; + public byte DmaCycleTimingMode; + public ushort TranslationFieldsValid; + public ushort NumberOfCurrentCylinders; + public ushort NumberOfCurrentHeads; + public ushort CurrentSectorsPerTrack; + public uint CurrentSectorCapacity; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 197)] + public ushort[] Reserved3; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct IDENTIFYCMDOUTPARAMS + { + public uint cBufferSize; + public DRIVERSTATUS DriverStatus; + public IDENTIFY_DATA Identify; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct STORAGE_PROPERTY_QUERY + { + public STORAGE_PROPERTY_ID PropertyId; + public STORAGE_QUERY_TYPE QueryType; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] AdditionalParameters; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct STORAGE_DEVICE_DESCRIPTOR_HEADER + { + public uint Version; + public uint Size; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct STORAGE_DEVICE_DESCRIPTOR + { + public uint Version; + public uint Size; + public byte DeviceType; + public byte DeviceTypeModifier; + + [MarshalAs(UnmanagedType.U1)] + public bool RemovableMedia; + + [MarshalAs(UnmanagedType.U1)] + public bool CommandQueueing; + + public uint VendorIdOffset; + public uint ProductIdOffset; + public uint ProductRevisionOffset; + public uint SerialNumberOffset; + public STORAGE_BUS_TYPE BusType; + public uint RawPropertiesLength; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct SRB_IO_CONTROL + { + public uint HeaderLenght; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] Signature; + + public uint Timeout; + public uint ControlCode; + public uint ReturnCode; + public uint Length; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct NVME_PASS_THROUGH_IOCTL + { + public SRB_IO_CONTROL srb; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public uint[] VendorSpecific; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public uint[] NVMeCmd; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public uint[] CplEntry; + + public NVME_DIRECTION Direction; + public uint QueueId; + public uint DataBufferLen; + public uint MetaDataLen; + public uint ReturnBufferLen; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4096)] + public byte[] DataBuffer; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct SCSI_PASS_THROUGH + { + [MarshalAs(UnmanagedType.U2)] + public ushort Length; + + public byte ScsiStatus; + public byte PathId; + public byte TargetId; + public byte Lun; + public byte CdbLength; + public byte SenseInfoLength; + public byte DataIn; + public uint DataTransferLength; + public uint TimeOutValue; + public IntPtr DataBufferOffset; + public uint SenseInfoOffset; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] Cdb; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct SCSI_PASS_THROUGH_WITH_BUFFERS + { + public SCSI_PASS_THROUGH Spt; + + public uint Filler; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] SenseBuf; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4096)] + public byte[] DataBuf; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct NVME_POWER_STATE_DESC + { + /// + /// bit 0:15 Maximum Power (MP) in centiwatts + /// + public ushort MP; + + /// + /// bit 16:23 + /// + public byte Reserved0; + + /// + /// bit 24 Max Power Scale (MPS), bit 25 Non-Operational State (NOPS) + /// + public byte MPS_NOPS; + + /// + /// bit 32:63 Entry Latency (ENLAT) in microseconds + /// + public uint ENLAT; + + /// + /// bit 64:95 Exit Latency (EXLAT) in microseconds + /// + public uint EXLAT; + + /// + /// bit 96:100 Relative Read Throughput (RRT) + /// + public byte RRT; + + /// + /// bit 104:108 Relative Read Latency (RRL) + /// + public byte RRL; + + /// + /// bit 112:116 Relative Write Throughput (RWT) + /// + public byte RWT; + + /// + /// bit 120:124 Relative Write Latency (RWL) + /// + public byte RWL; + + /// + /// bit 128:143 Idle Power (IDLP) + /// + public ushort IDLP; + + /// + /// bit 150:151 Idle Power Scale (IPS) + /// + public byte IPS; + + /// + /// bit 152:159 + /// + public byte Reserved7; + + /// + /// bit 160:175 Active Power (ACTP) + /// + public ushort ACTP; + + /// + /// bit 176:178 Active Power Workload (APW), bit 182:183 Active Power Scale (APS) + /// + public byte APW_APS; + + /// + /// bit 184:255. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)] + public byte[] Reserved9; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct NVME_IDENTIFY_CONTROLLER_DATA + { + /// + /// byte 0:1 M - PCI Vendor ID (VID) + /// + public ushort VID; + + /// + /// byte 2:3 M - PCI Subsystem Vendor ID (SSVID) + /// + public ushort SSVID; + + /// + /// byte 4: 23 M - Serial Number (SN) + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public byte[] SN; + + /// + /// byte 24:63 M - Model Number (MN) + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)] + public byte[] MN; + + /// + /// byte 64:71 M - Firmware Revision (FR) + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] FR; + + /// + /// byte 72 M - Recommended Arbitration Burst (RAB) + /// + public byte RAB; + + /// + /// byte 73:75 M - IEEE OUI Identifier (IEEE). Controller Vendor code. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] IEEE; + + /// + /// byte 76 O - Controller Multi-Path I/O and Namespace Sharing Capabilities (CMIC) + /// + public byte CMIC; + + /// + /// byte 77 M - Maximum Data Transfer Size (MDTS) + /// + public byte MDTS; + + /// + /// byte 78:79 M - Controller ID (CNTLID) + /// + public ushort CNTLID; + + /// + /// byte 80:83 M - Version (VER) + /// + public uint VER; + + /// + /// byte 84:87 M - RTD3 Resume Latency (RTD3R) + /// + public uint RTD3R; + + /// + /// byte 88:91 M - RTD3 Entry Latency (RTD3E) + /// + public uint RTD3E; + + /// + /// byte 92:95 M - Optional Asynchronous Events Supported (OAES) + /// + public uint OAES; + + /// + /// byte 96:239. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 144)] + public byte[] Reserved0; + + /// + /// byte 240:255. Refer to the NVMe Management Interface Specification for definition. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] ReservedForManagement; + + /// + /// byte 256:257 M - Optional Admin Command Support (OACS) + /// + public ushort OACS; + + /// + /// byte 258 M - Abort Command Limit (ACL) + /// + public byte ACL; + + /// + /// byte 259 M - Asynchronous Event Request Limit (AERL) + /// + public byte AERL; + + /// + /// byte 260 M - Firmware Updates (FRMW) + /// + public byte FRMW; + + /// + /// byte 261 M - Log Page Attributes (LPA) + /// + public byte LPA; + + /// + /// byte 262 M - Error Log Page Entries (ELPE) + /// + public byte ELPE; + + /// + /// byte 263 M - Number of Power States Support (NPSS) + /// + public byte NPSS; + + /// + /// byte 264 M - Admin Vendor Specific Command Configuration (AVSCC) + /// + public byte AVSCC; + + /// + /// byte 265 O - Autonomous Power State Transition Attributes (APSTA) + /// + public byte APSTA; + + /// + /// byte 266:267 M - Warning Composite Temperature Threshold (WCTEMP) + /// + public ushort WCTEMP; + + /// + /// byte 268:269 M - Critical Composite Temperature Threshold (CCTEMP) + /// + public ushort CCTEMP; + + /// + /// byte 270:271 O - Maximum Time for Firmware Activation (MTFA) + /// + public ushort MTFA; + + /// + /// byte 272:275 O - Host Memory Buffer Preferred Size (HMPRE) + /// + public uint HMPRE; + + /// + /// byte 276:279 O - Host Memory Buffer Minimum Size (HMMIN) + /// + public uint HMMIN; + + /// + /// byte 280:295 O - Total NVM Capacity (TNVMCAP) + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] TNVMCAP; + + /// + /// byte 296:311 O - Unallocated NVM Capacity (UNVMCAP) + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] UNVMCAP; + + /// + /// byte 312:315 O - Replay Protected Memory Block Support (RPMBS) + /// + public uint RPMBS; + + /// + /// byte 316:511 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 196)] + public byte[] Reserved1; + + /// + /// byte 512 M - Submission Queue Entry Size (SQES) + /// + public byte SQES; + + /// + /// byte 513 M - Completion Queue Entry Size (CQES) + /// + public byte CQES; + + /// + /// byte 514:515 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] Reserved2; + + /// + /// byte 516:519 M - Number of Namespaces (NN) + /// + public uint NN; + + /// + /// byte 520:521 M - Optional NVM Command Support (ONCS) + /// + public ushort ONCS; + + /// + /// byte 522:523 M - Fused Operation Support (FUSES) + /// + public ushort FUSES; + + /// + /// byte 524 M - Format NVM Attributes (FNA) + /// + public byte FNA; + + /// + /// byte 525 M - Volatile Write Cache (VWC) + /// + public byte VWC; + + /// + /// byte 526:527 M - Atomic Write Unit Normal (AWUN) + /// + public ushort AWUN; + + /// + /// byte 528:529 M - Atomic Write Unit Power Fail (AWUPF) + /// + public ushort AWUPF; + + /// + /// byte 530 M - NVM Vendor Specific Command Configuration (NVSCC) + /// + public byte NVSCC; + + /// + /// byte 531 + /// + public byte Reserved3; + + /// + /// byte 532:533 O - Atomic Compare and Write Unit (ACWU) + /// + public ushort ACWU; + + /// + /// byte 534:535 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] Reserved4; + + /// + /// byte 536:539 O - SGL Support (SGLS) + /// + public uint SGLS; + + /// + /// byte 540:703 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 164)] + public byte[] Reserved5; + + /// + /// byte 704:2047 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1344)] + public byte[] Reserved6; + + /// + /// byte 2048:3071 Power State Descriptors + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public NVME_POWER_STATE_DESC[] PDS; + + /// + /// byte 3072:4095 Vendor Specific + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)] + public byte[] VS; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct NVME_HEALTH_INFO_LOG + { + /// + /// This field indicates critical warnings for the state of the controller. + /// Each bit corresponds to a critical warning type; multiple bits may be set. + /// + public byte CriticalWarning; + + /// + /// Composite Temperature: Contains the temperature of the overall device (controller and NVM included) in units of Kelvin. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] CompositeTemp; + + /// + /// Available Spare: Contains a normalized percentage (0 to 100%) of the remaining spare capacity available + /// + public byte AvailableSpare; + + /// + /// Available Spare Threshold: When the Available Spare falls below the threshold indicated in this field, + /// an asynchronous event completion may occur. The value is indicated as a normalized percentage (0 to 100%). + /// + public byte AvailableSpareThreshold; + + /// + /// Percentage Used: Contains a vendor specific estimate of the percentage of NVM subsystem life used based on + /// the actual usage and the manufacturer’s prediction of NVM life. A value of 100 indicates that the estimated endurance of + /// the NVM in the NVM subsystem has been consumed, but may not indicate an NVM subsystem failure. The value is allowed to exceed 100. + /// + public byte PercentageUsed; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)] + public byte[] Reserved1; + + /// + /// Data Units Read: Contains the number of 512 byte data units the host has read from the controller; + /// this value does not include metadata. This value is reported in thousands + /// (i.e., a value of 1 corresponds to 1000 units of 512 bytes read) and is rounded up. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] DataUnitRead; + + /// + /// Data Units Written: Contains the number of 512 byte data units the host has written to the controller; + /// this value does not include metadata. This value is reported in thousands + /// (i.e., a value of 1 corresponds to 1000 units of 512 bytes written) and is rounded up. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] DataUnitWritten; + + /// + /// Host Read Commands: Contains the number of read commands completed by the controller. + /// For the NVM command set, this is the number of Compare and Read commands. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] HostReadCommands; + + /// + /// Host Write Commands: Contains the number of write commands completed by the controller. + /// For the NVM command set, this is the number of Write commands. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] HostWriteCommands; + + /// + /// Controller Busy Time: Contains the amount of time the controller is busy with I/O commands. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] ControllerBusyTime; + + /// + /// Power Cycles: Contains the number of power cycles. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] PowerCycles; + + /// + /// Power On Hours: Contains the number of power-on hours. + /// This does not include time that the controller was powered and in a low power state condition. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] PowerOnHours; + + /// + /// Unsafe Shutdowns: Contains the number of unsafe shutdowns. + /// This count is incremented when a shutdown notification is not received prior to loss of power. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] UnsafeShutdowns; + + /// + /// Media Errors: Contains the number of occurrences where the controller detected an unrecoverable data integrity error. + /// Errors such as uncorrectable ECC, CRC checksum failure, or LBA tag mismatch are included in this field. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] MediaAndDataIntegrityErrors; + + /// + /// Number of Error Information Log Entries: Contains the number of Error Information log entries over the life of the controller + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] NumberErrorInformationLogEntries; + + /// + /// Warning Composite Temperature Time: Contains the amount of time in minutes that the controller is operational and the Composite Temperature is greater than or equal to the Warning Composite + /// Temperature Threshold. + /// + public uint WarningCompositeTemperatureTime; + + /// + /// Critical Composite Temperature Time: Contains the amount of time in minutes that the controller is operational and the Composite Temperature is greater than the Critical Composite Temperature + /// Threshold. + /// + public uint CriticalCompositeTemperatureTime; + + /// + /// Contains the current temperature reported by temperature sensor 1-8. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public ushort[] TemperatureSensor; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 296)] + internal byte[] Reserved2; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct STORAGE_PROTOCOL_SPECIFIC_DATA + { + public STORAGE_PROTOCOL_TYPE ProtocolType; + public uint DataType; + public uint ProtocolDataRequestValue; + public uint ProtocolDataRequestSubValue; + public uint ProtocolDataOffset; + public uint ProtocolDataLength; + public uint FixedProtocolReturnData; + public uint ProtocolDataRequestSubValue2; + public uint ProtocolDataRequestSubValue3; + public uint Reserved; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct STORAGE_QUERY_BUFFER + { + public STORAGE_PROPERTY_ID PropertyId; + public STORAGE_QUERY_TYPE QueryType; + public STORAGE_PROTOCOL_SPECIFIC_DATA ProtocolSpecific; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4096)] + internal byte[] Buffer; + } + + [Flags] + internal enum MEM : uint + { + MEM_COMMIT = 0x1000, + MEM_RESERVE = 0x2000, + MEM_DECOMMIT = 0x4000, + MEM_RELEASE = 0x8000, + MEM_RESET = 0x80000, + MEM_LARGE_PAGES = 0x20000000, + MEM_PHYSICAL = 0x400000, + MEM_TOP_DOWN = 0x100000, + MEM_WRITE_WATCH = 0x200000 + } + + [Flags] + internal enum PAGE : uint + { + PAGE_EXECUTE = 0x10, + PAGE_EXECUTE_READ = 0x20, + PAGE_EXECUTE_READWRITE = 0x40, + PAGE_EXECUTE_WRITECOPY = 0x80, + PAGE_NOACCESS = 0x01, + PAGE_READONLY = 0x02, + PAGE_READWRITE = 0x04, + PAGE_WRITECOPY = 0x08, + PAGE_GUARD = 0x100, + PAGE_NOCACHE = 0x200, + PAGE_WRITECOMBINE = 0x400 + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct IOControlCode + { + /// + /// Gets the resulting IO control code. + /// + public uint Code { get; } + + /// + /// Initializes a new instance of the struct. + /// + /// Type of the device. + /// The function. + /// The access. + public IOControlCode(uint deviceType, uint function, Access access) : this(deviceType, function, Method.Buffered, access) + { } + + /// + /// Initializes a new instance of the struct. + /// + /// Type of the device. + /// The function. + /// The method. + /// The access. + public IOControlCode(uint deviceType, uint function, Method method, Access access) + { + Code = (deviceType << 16) | ((uint)access << 14) | (function << 2) | (uint)method; + } + + public enum Method : uint + { + Buffered = 0, + InDirect = 1, + OutDirect = 2, + Neither = 3 + } + + public enum Access : uint + { + Any = 0, + Read = 1, + Write = 2 + } + } + + internal enum Provider + { + ACPI = (byte)'A' << 24 | (byte)'C' << 16 | (byte)'P' << 8 | (byte)'I', + FIRM = (byte)'F' << 24 | (byte)'I' << 16 | (byte)'R' << 8 | (byte)'M', + RSMB = (byte)'R' << 24 | (byte)'S' << 16 | (byte)'M' << 8 | (byte)'B' + } +} diff --git a/ColorControl/Services/NVIDIA/NvGpuInfo.cs b/ColorControl/Services/NVIDIA/NvGpuInfo.cs new file mode 100644 index 0000000..d052d51 --- /dev/null +++ b/ColorControl/Services/NVIDIA/NvGpuInfo.cs @@ -0,0 +1,666 @@ +using ColorControl.Common; +using NvAPIWrapper.GPU; +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; +using NvAPIWrapper.Native.Interfaces.GPU; +using System; +using System.Collections.Generic; +using System.Linq; +using static NvAPIWrapper.Native.GPU.Structures.PerformanceStates20ClockEntryV1; +using static NvAPIWrapper.Native.GPU.Structures.PrivateClockBoostLockV2; + +namespace ColorControl.Services.NVIDIA +{ + public enum NvGpuOcType + { + None = 0, + Offset = 1, + Curve = 2, + BoostLock = 3 + } + + public class NvGpuOcSettings + { + public string PCIIdentifier { get; set; } + public int MemoryOffsetKHz { get; set; } + public NvGpuOcType Type { get; set; } + public int GraphicsOffsetKHz { get; set; } + public uint MaximumFrequencyKHz { get; set; } + public uint MaximumVoltageUv { get; set; } + public uint VoltageBoostPercent { get; set; } + public uint PowerPCM { get; set; } + + public override string ToString() + { + var value = ""; + + if (Type == NvGpuOcType.BoostLock) + { + value += $"GPU: Locked: {(GraphicsOffsetKHz >= 0 ? "+" : "-")}{GraphicsOffsetKHz.ToUnitString()} @ {MaximumVoltageUv}uv"; + } + else if (Type == NvGpuOcType.Curve) + { + value += $"GPU: Curve: {(GraphicsOffsetKHz >= 0 ? "+" : "-")}{GraphicsOffsetKHz.ToUnitString()}"; + + if (MaximumVoltageUv > 0) + { + value += $", UV: {MaximumFrequencyKHz.ToUnitString()} @ {MaximumVoltageUv / 1000}mv"; + } + } + else if (Type == NvGpuOcType.Offset) + { + value += $"GPU: {(GraphicsOffsetKHz >= 0 ? "+" : "-")}{GraphicsOffsetKHz.ToUnitString()}"; + } + + if (MemoryOffsetKHz != 0) + { + if (!string.IsNullOrEmpty(value)) + { + value += ", "; + } + + value += $"Memory: {(MemoryOffsetKHz >= 0 ? "+" : "-")}{MemoryOffsetKHz.ToUnitString()}"; + } + + if (PowerPCM != 100000) + { + if (!string.IsNullOrEmpty(value)) + { + value += ", "; + } + + value += $"Power: {PowerPCM / 1000}%"; + } + + if (string.IsNullOrEmpty(value)) + { + value = "None"; + } + + return value; + } + } + + public class NvGpuInfo + { + private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); + + public PhysicalGPU GPU { get; } + public List ClockBoostLocks { get; private set; } + public List ClockEntries { get; private set; } + public ClockDomainInfo StockGraphicsClock { get; private set; } + public ClockDomainInfo StockMemoryClock { get; private set; } + public PrivateVFPCurveV3 CurveV3 { get; private set; } + public PrivateVFPCurveV1 CurveV1 { get; private set; } + public int? DefaultPowerInMilliWatts { get; private set; } + public int MinPowerInMilliWatts { get; private set; } + public int MaxPowerInMilliWatts { get; private set; } + + + public static readonly PublicClockDomain[] Domains = new[] { PublicClockDomain.Graphics, PublicClockDomain.Memory }; + + public static NvGpuInfo GetGpuInfo(string pciId) + { + var gpuHandles = GPUApi.EnumPhysicalGPUs(); + + var gpus = gpuHandles.Select(h => new PhysicalGPU(h)).ToList(); + + //var displays = Display.GetDisplays(); + //var gpus = displays.Select(d => d.DisplayDevice.PhysicalGPU).Distinct().ToList(); + + var gpu = gpus.FirstOrDefault(g => g.BusInformation.PCIIdentifiers.ToString() == pciId); + + return GetGpuInfo(gpu); + } + + public static NvGpuInfo GetGpuInfo(PhysicalGPU gpu) + { + var gpuInfo = new NvGpuInfo(gpu); + + return gpuInfo; + } + + private NvGpuInfo(PhysicalGPU gpu) + { + GPU = gpu; + + StockGraphicsClock = GPU.BoostClockFrequencies.GraphicsClock; + StockMemoryClock = GPU.BoostClockFrequencies.MemoryClock; + + var handle = gpu.Handle; + + //var xx = GPUApi.ClientPowerTopologyGetStatus(handle); + + var perf = GPUApi.GetPerformanceStates20(handle); + var clock3D = perf.Clocks.FirstOrDefault(c => c.Key == PerformanceStateId.P0_3DPerformance); + + var boostLock = GPUApi.GetClockBoostLock(handle); + + ReadCurve(); + + if (NvidiaML.IsAvailable || NvidiaML.Initialize()) + { + var device = NvidiaML.NvmlDeviceGetHandleByIndex(0); + DefaultPowerInMilliWatts = NvidiaML.NvmlDeviceGetPowerManagementDefaultLimit(device.Value); + + var powerLimits = GetPowerLimits(); + + MinPowerInMilliWatts = (int)((decimal)DefaultPowerInMilliWatts / 100000 * powerLimits.Item1); + MaxPowerInMilliWatts = (int)((decimal)DefaultPowerInMilliWatts / 100000 * powerLimits.Item2); + + } + + //var bla2 = GPUApi.GetClockBoostRanges(handle); + //var bla3 = GPUApi.GetClockBoostTableV2(handle); + + //for (var i = 0; i < bla3.GPUDeltas.Count(); i++) + //{ + // if (bla3.GPUDeltas[i].ClockType == 0) + // { + // bla3.GPUDeltas[i].FrequencyDeltaInkHz = 145000; + // } + // else if (bla3.GPUDeltas[i].ClockType == 1) + // { + // //bla3.GPUDeltas[i]._FrequencyDeltaInkHz = 50000; + // } + + //} + + //GPUApi.SetClockBoostTableV2(handle, bla3); + + //var bla4 = GPUApi.GetAllClockFrequencies(handle); + + ClockBoostLocks = boostLock.ClockBoostLocks.Where(l => l.LockMode == ClockLockMode.Manual).ToList(); + ClockEntries = clock3D.Value.ToList(); + } + + public (uint, uint) GetPowerLimits() + { + var power = GPU.PerformanceControl.PowerLimitInformation.FirstOrDefault(); + + if (power == null) + { + return (20000, 100000); + } + + return (power.MinimumPowerInPCM, power.MaximumPowerInPCM); + } + + public uint GetPowerUsageInMilliWatts() + { + if (DefaultPowerInMilliWatts.HasValue) + { + var powerInPCM = GPU.PowerTopologyInformation.PowerTopologyEntries.FirstOrDefault(e => e.Domain == PowerTopologyDomain.Board); + var power = (uint)((decimal)powerInPCM.PowerUsageInPCM / 100000 * DefaultPowerInMilliWatts); + + return power; + } + + return 0; + } + + private void ReadCurve() + { + try + { + CurveV3 = GPUApi.GetVFPCurveV3(GPU.Handle); + } + catch (Exception ex) + { + Logger.Debug(ex); + + var bla = GPUApi.GetClockBoostMask(GPU.Handle); + + var masks = bla._Masks; + Logger.Debug("MASKS: " + masks[0]); + + Logger.Debug("MASK: " + bla._Unknown1[0]); + + CurveV1 = GPUApi.GetVFPCurve(GPU.Handle, masks); + + var length = CurveV1.GPUCurveEntries.Length; + var minFreq = CurveV1.GPUCurveEntries.Min(e => e.FrequencyInkHz); + var maxFreq = CurveV1.GPUCurveEntries.Max(e => e.FrequencyInkHz); + var minV = CurveV1.GPUCurveEntries.Min(e => e.VoltageInMicroV); + var maxV = CurveV1.GPUCurveEntries.Max(e => e.VoltageInMicroV); + + Logger.Debug($"CurveV1: L: {length}, MinF: {minFreq}, MaxF: {maxFreq}, MinV: {minV}, MaxV: {maxV}"); + } + } + + public bool ApplyOcSettings(NvGpuOcSettings settings) + { + var pciId = GPU.BusInformation.PCIIdentifiers.ToString(); + + if (settings.PCIIdentifier != pciId) + { + Logger.Warn($"Cannot apply OC-settings: PCI-identifier does not match GPU: {settings.PCIIdentifier}"); + + return false; + } + + ResetGpuClocks(); + + if (settings.PowerPCM >= 0) + { + SetPower(settings.PowerPCM); + } + + if (settings.MemoryOffsetKHz != 0) + { + SetMemoryClockOffsetDelta(settings.MemoryOffsetKHz); + } + + if (settings.VoltageBoostPercent >= 0) + { + SetVoltageBoostPercent(settings.VoltageBoostPercent); + } + + if (settings.Type == NvGpuOcType.None) + { + return true; + } + + if (settings.Type == NvGpuOcType.BoostLock) + { + LockGpuClock(settings.MaximumVoltageUv, settings.GraphicsOffsetKHz); + + return true; + } + + if (settings.Type == NvGpuOcType.Offset && settings.MaximumVoltageUv == 0) + { + SetGraphicsClockOffset(settings.GraphicsOffsetKHz); + + return true; + } + + SetCurveOffset(settings.GraphicsOffsetKHz, settings.MaximumVoltageUv, settings.MaximumFrequencyKHz); + + return true; + } + + public void SetPower(uint powerPercent) + { + if (powerPercent == 0) + { + powerPercent = 100000; + } + + var entry = new PrivatePowerPoliciesStatusV1.PowerPolicyStatusEntry(powerPercent); + var status = new PrivatePowerPoliciesStatusV1(new[] { entry }); + + GPUApi.ClientPowerPoliciesSetStatus(GPU.Handle, status); + } + + public override string ToString() + { + var gpuThermal = GPU.ThermalInformation.ThermalSensors.FirstOrDefault(s => s.Target == ThermalSettingsTarget.GPU); + var gpuVoltage = GPUApi.GetCurrentVoltage(GPU.Handle).ValueInMicroVolt; + + try + { + var temps = GPUApi.QueryThermalSensors(GPU.Handle, 255u); + var hotspotTemp = Math.Round(temps.Temperatures[1]); + var memoryTemp = temps.Temperatures[7]; + var power = GetPowerUsageInMilliWatts(); + + return $"GPU: {GPU.CurrentClockFrequencies.GraphicsClock.Frequency.ToUnitString()} @ {gpuVoltage / 1000}mv, {gpuThermal.CurrentTemperature}°/{hotspotTemp}°C, Mem: {GPU.CurrentClockFrequencies.MemoryClock.Frequency.ToUnitString()}, {memoryTemp}°C, Pwr: {power / 1000}W"; + } + catch (Exception) { } + + return $"GPU: {GPU.CurrentClockFrequencies.GraphicsClock.Frequency.ToUnitString()} @ {gpuVoltage / 1000}mv, {gpuThermal.CurrentTemperature}°C, Mem: {GPU.CurrentClockFrequencies.MemoryClock.Frequency.ToUnitString()}"; + } + + public (int, int) GetDeltaClockMinMax(PublicClockDomain domain) + { + var delta = ClockEntries.FirstOrDefault(e => e.DomainId == domain)?.FrequencyDeltaInkHz; + + return (delta?.DeltaRange.Minimum ?? -502000, delta?.DeltaRange.Maximum ?? (domain == PublicClockDomain.Graphics ? 1000000 : 3000000)); + } + + public PerformanceStates20ParameterDelta? GetDeltaClockLimits(PublicClockDomain domain) + { + return ClockEntries.FirstOrDefault(e => e.DomainId == domain)?.FrequencyDeltaInkHz; + } + + public bool HasLock(PublicClockDomain domain) + { + return ClockBoostLocks.Any(l => l.ClockDomain == domain && l.LockMode == ClockLockMode.Manual); + } + + public int GetOffset(PublicClockDomain domain) + { + var entry = ClockEntries.FirstOrDefault(e => e.DomainId == domain); + + var value = entry?.FrequencyDeltaInkHz.DeltaValue ?? 0; + + if (value == 0 && domain == PublicClockDomain.Memory && entry != null) + { + var maxFreq = entry.SingleFrequency.FrequencyInkHz; + var defaultFreq = GPU.BoostClockFrequencies.MemoryClock.Frequency; + + value = (int)(maxFreq - defaultFreq); + } + + return value; + } + + public (uint, int) GetLockedBoost(PublicClockDomain domain) + { + var boostLock = ClockBoostLocks.FirstOrDefault(l => l.ClockDomain == domain && l.LockMode == ClockLockMode.Manual); + + if (boostLock.LockMode != ClockLockMode.Manual) + { + return (0, 0); + } + + var offset = GetOffset(domain); + + return (boostLock.VoltageInMicroV, offset); + } + + public NvGpuOcSettings GetOverclockSettings() + { + var ocSettings = new NvGpuOcSettings(); + + var power = GPUApi.ClientPowerPoliciesGetStatus(GPU.Handle); + + ocSettings.PowerPCM = power.PowerPolicyStatusEntries.FirstOrDefault(e => e.PerformanceStateId == PerformanceStateId.P0_3DPerformance).PowerTargetInPCM; + + foreach (var domain in Domains) + { + var locked = GetLockedBoost(domain); + + if (locked.Item1 != 0) + { + if (ocSettings.Type == NvGpuOcType.None) + { + ocSettings.Type = NvGpuOcType.BoostLock; + } + + ocSettings.MaximumVoltageUv = locked.Item1; + + if (domain == PublicClockDomain.Graphics) + { + ocSettings.GraphicsOffsetKHz = locked.Item2; + } + else + { + ocSettings.MemoryOffsetKHz = locked.Item2; + } + } + + if (ocSettings.Type == NvGpuOcType.None && domain == PublicClockDomain.Graphics && CurveV3.GPUCurveEntries != null) + { + var entry = CurveV3.GPUCurveEntries.MaxBy(e => (int)e.FrequencyInkHz - (int)e.DefaultFrequencyInkHz); + var offsetCurve = (int)entry.FrequencyInkHz - (int)entry.DefaultFrequencyInkHz; + if (offsetCurve != 0) + { + var isChanged = CurveV3.GPUCurveEntries.Any(e => e.ClockType == 0 && e.DefaultFrequencyInkHz != 0 && ((int)e.FrequencyInkHz - (int)e.DefaultFrequencyInkHz) != offsetCurve); + + ocSettings.Type = isChanged ? NvGpuOcType.Curve : NvGpuOcType.Offset; + ocSettings.GraphicsOffsetKHz = offsetCurve; + + if (offsetCurve > 0 && ocSettings.Type == NvGpuOcType.Curve) + { + var maxOcEntry = CurveV3.GPUCurveEntries.MaxBy(e => e.FrequencyInkHz); + var maxDefEntry = CurveV3.GPUCurveEntries.MaxBy(e => e.DefaultFrequencyInkHz); + + if (maxOcEntry.FrequencyInkHz < maxDefEntry.DefaultFrequencyInkHz) + { + ocSettings.MaximumVoltageUv = maxOcEntry.VoltageInMicroV; + ocSettings.MaximumFrequencyKHz = maxDefEntry.FrequencyInkHz; + } + } + } + } + + if (ocSettings.Type == NvGpuOcType.None || domain == PublicClockDomain.Memory) + { + var offset = GetOffset(domain); + + if (offset != 0) + { + if (ocSettings.Type == NvGpuOcType.None) + { + ocSettings.Type = NvGpuOcType.Offset; + } + + if (domain == PublicClockDomain.Graphics) + { + ocSettings.GraphicsOffsetKHz = offset; + } + else + { + ocSettings.MemoryOffsetKHz = offset; + } + } + } + } + + return ocSettings; + } + + public void SetGpuClocks(uint lockedVoltageMicroV = 1000000, int coreOffsetKHz = 0, int memOffsetKHz = 0) + { + var handle = GPU.Handle; + + var perf = GPUApi.GetPerformanceStates20(handle); + + var lockv2 = new PrivateClockBoostLockV2(new[] { new ClockBoostLock(PublicClockDomain.Graphics, ClockLockMode.Manual, lockedVoltageMicroV) }); + + var bla = GPUApi.GetClockBoostLock(handle); + + GPUApi.SetClockBoostLock(handle, lockv2); + + //var curve = GPUApi.GetVFPCurve(handle); + + var currentFreq = perf.Clocks.First().Value.First(v => v.DomainId == PublicClockDomain.Graphics).SingleFrequency; + + var delta = new PerformanceStates20ParameterDelta(coreOffsetKHz); + //var delta2 = new PerformanceStates20ParameterDelta(0); + //var delta3 = new PerformanceStates20ParameterDelta(0); + //var single1 = new PerformanceStates20ClockDependentSingleFrequency(2670000); + //var single2 = new PerformanceStates20ClockDependentSingleFrequency(2760000); + //var single3 = new PerformanceStates20ClockDependentSingleFrequency(2775000); + + //var clockEntry1 = new PerformanceStates20ClockEntryV1(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics, delta, single1); + //var clockEntry2 = new PerformanceStates20ClockEntryV1(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics, delta2, single2); + //var clockEntry3 = new PerformanceStates20ClockEntryV1(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics, delta3, single3); + + var range = new PerformanceStates20ClockDependentFrequencyRange(2400000, 3000000, PerformanceVoltageDomain.Core, 950000, 1050000); + var clockEntry = new PerformanceStates20ClockEntryV1(PublicClockDomain.Graphics, delta, range); + + var memDelta = new PerformanceStates20ParameterDelta(memOffsetKHz); + var memClockEntry = new PerformanceStates20ClockEntryV1(PublicClockDomain.Memory, memDelta); + + //var range2 = new PerformanceStates20ClockDependentFrequencyRange(2800001, 3000000, NvAPIWrapper.Native.GPU.PerformanceVoltageDomain.Core, 1000000, 1000000); + //var clockEntry2 = new PerformanceStates20ClockEntryV1(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics, delta2, range2); + + var deltaVoltage = new PerformanceStates20ParameterDelta(0); + var voltage = new PerformanceStates20BaseVoltageEntryV1(PerformanceVoltageDomain.Core, deltaVoltage); + + var state = new PerformanceStates20InfoV1.PerformanceState20(PerformanceStateId.P0_3DPerformance, new[] { clockEntry, memClockEntry }, new[] { voltage }); + + var newPerf = new PerformanceStates20InfoV3(new[] { state }, 2, 1); + + GPUApi.SetPerformanceStates20(handle, newPerf); + } + + public void LockGpuClock(uint lockedVoltageMicroV = 1000000, int coreOffsetKHz = 0) + { + var handle = GPU.Handle; + + var lockv2 = new PrivateClockBoostLockV2(new[] { new ClockBoostLock(PublicClockDomain.Graphics, ClockLockMode.Manual, lockedVoltageMicroV) }); + + GPUApi.SetClockBoostLock(handle, lockv2); + + var delta = new PerformanceStates20ParameterDelta(coreOffsetKHz); + + var range = new PerformanceStates20ClockDependentFrequencyRange(1200000, 3000000, PerformanceVoltageDomain.Core, 0, 0); + var clockEntry = new PerformanceStates20ClockEntryV1(PublicClockDomain.Graphics, delta, range); + + var state = new PerformanceStates20InfoV1.PerformanceState20(PerformanceStateId.P0_3DPerformance, new[] { clockEntry }, Array.Empty()); + + var newPerf = new PerformanceStates20InfoV3(new[] { state }, 1, 1); + + GPUApi.SetPerformanceStates20(handle, newPerf); + } + + public void SetGraphicsClockOffset(int coreOffsetKHz = 0) + { + var delta = new PerformanceStates20ParameterDelta(coreOffsetKHz); + + var range = new PerformanceStates20ClockDependentFrequencyRange(1200000, 3000000, PerformanceVoltageDomain.Core, 0, 0); + var clockEntry = new PerformanceStates20ClockEntryV1(PublicClockDomain.Graphics, delta, range); + + var state = new PerformanceStates20InfoV1.PerformanceState20(PerformanceStateId.P0_3DPerformance, new[] { clockEntry }, Array.Empty()); + + var newPerf = new PerformanceStates20InfoV3(new[] { state }, 1, 0); + + GPUApi.SetPerformanceStates20(GPU.Handle, newPerf); + } + + public void SetMemoryClockOffsetDelta(int memOffsetKHz = 0) + { + var handle = GPU.Handle; + + var memDelta = new PerformanceStates20ParameterDelta(memOffsetKHz); + var memClockEntry = new PerformanceStates20ClockEntryV1(PublicClockDomain.Memory, memDelta); + + var state = new PerformanceStates20InfoV1.PerformanceState20(PerformanceStateId.P0_3DPerformance, new[] { memClockEntry }, Array.Empty()); + + var newPerf = new PerformanceStates20InfoV3(new[] { state }, 1, 0); + + GPUApi.SetPerformanceStates20(handle, newPerf); + } + + public void SetMemoryClockOffsetRange(int memOffsetKHz = 0) + { + var handle = GPU.Handle; + + var memDelta = new PerformanceStates20ParameterDelta(0); + + var defaultFreq = GPU.BoostClockFrequencies.MemoryClock.Frequency; + var newFreq = (uint)(defaultFreq + memOffsetKHz); + + var memFreq = new PerformanceStates20ClockDependentFrequencyRange(newFreq, newFreq, PerformanceVoltageDomain.Undefined, 0, 0); + var memFreq2 = new PerformanceStates20ClockDependentSingleFrequency(newFreq); + var memClockEntry = new PerformanceStates20ClockEntryV1(PublicClockDomain.Memory, memDelta, memFreq); + var memClockEntry2 = new PerformanceStates20ClockEntryV1(PublicClockDomain.Memory, memDelta, memFreq2); + + var state = new PerformanceStates20InfoV1.PerformanceState20(PerformanceStateId.P0_3DPerformance, new[] { memClockEntry, memClockEntry2 }, Array.Empty()); + + var newPerf = new PerformanceStates20InfoV3(new[] { state }, 1, 0); + + GPUApi.SetPerformanceStates20(handle, newPerf); + } + + public void SetCurveOffset(int offsetKHz = 0, uint maxVoltageUv = 0, uint maxFreqKHz = 0) + { + var normalizedOffset = (offsetKHz / 15000) * 15000; + + var handle = GPU.Handle; + + var boostTable = GPUApi.GetClockBoostTableV2(handle); + + var curveEntries = CurveV3.GPUCurveEntries; + + if (maxVoltageUv > 0) + { + var newCurveEntryVolt = curveEntries.FirstOrDefault(e => e.DefaultVoltageInMicroV == maxVoltageUv); + var newFreq = (uint)(newCurveEntryVolt.DefaultFrequencyInkHz + offsetKHz); + var newCurveEntryFreq = curveEntries.FirstOrDefault(e => e.DefaultFrequencyInkHz == newFreq); + + maxFreqKHz = newFreq; + } + + for (var i = 0; i < boostTable.GPUDeltas.Count(); i++) + { + if (boostTable.GPUDeltas[i].ClockType != 0) + { + break; + } + + var curOffset = offsetKHz; + + if (maxFreqKHz > 0 && CurveV3.GPUCurveEntries?.Length > i) + { + var curveEntry = CurveV3.GPUCurveEntries[i]; + + if (curveEntry.DefaultFrequencyInkHz + offsetKHz > maxFreqKHz) + { + curOffset += (int)(maxFreqKHz - (curveEntry.DefaultFrequencyInkHz + offsetKHz)); + } + } + + boostTable.GPUDeltas[i].FrequencyDeltaInkHz = curOffset; + + } + GPUApi.SetClockBoostTableV2(handle, boostTable); + + ReadCurve(); + } + + public void ResetGpuClocks() + { + var handle = GPU.Handle; + + var lockv2 = new PrivateClockBoostLockV2(new[] { new ClockBoostLock(PublicClockDomain.Graphics, ClockLockMode.None, 0) }); + + GPUApi.SetClockBoostLock(handle, lockv2); + + SetMemoryClockOffsetDelta(0); + SetGraphicsClockOffset(0); + SetCurveOffset(0); + SetVoltageBoostPercent(0); + } + + public uint GetGpuVoltage() + { + var voltage = GPUApi.GetCurrentVoltage(GPU.Handle); + + return voltage.ValueInMicroVolt; + } + + public void SetVoltageBoostPercent(uint percent) + { + var voltBoost = new PrivateVoltageBoostPercentV1(percent); + + GPUApi.SetCoreVoltageBoostPercent(GPU.Handle, voltBoost); + } + + public string GetGpuLimits() + { + var handle = GPU.Handle; + + var perf = GPUApi.GetPerformanceStates20(handle); + var clock3D = perf.Clocks.FirstOrDefault(c => c.Key == NvAPIWrapper.Native.GPU.PerformanceStateId.P0_3DPerformance); + + var boostLock = GPUApi.GetClockBoostLock(handle); + + var clockFreqs = GPUApi.GetAllClockFrequencies(handle); + + //GPUApi.ClientPowerPoliciesGetStatus(handle); + + //var mask = GPUApi.GetClockBoostMask(handle); + + //var ranges = GPUApi.GetClockBoostRanges(handle); + + //var table = GPUApi.GetClockBoostTable(handle); + + var voltageBoost = GPUApi.GetCoreVoltageBoostPercent(handle); + + //var voltage = GPUApi.GetCurrentVoltage(handle); + + //var dynPerf = GPUApi.GetDynamicPerformanceStatesInfoEx(handle); + + //var pols = GPUApi.PerformancePoliciesGetInfo(handle); + + return string.Empty; + } + + } +} diff --git a/ColorControl/Services/NVIDIA/NvPreset.cs b/ColorControl/Services/NVIDIA/NvPreset.cs index 72d080b..0f05ad4 100644 --- a/ColorControl/Services/NVIDIA/NvPreset.cs +++ b/ColorControl/Services/NVIDIA/NvPreset.cs @@ -32,6 +32,9 @@ namespace ColorControl.Services.NVIDIA public uint ditheringMode { get; set; } public bool applyDriverSettings { get; set; } public Dictionary driverSettings { get; set; } + public bool applyOverclocking { get; set; } + public List ocSettings { get; set; } + [JsonIgnore] public bool IsDisplayPreset => Display != null; public Display Display { get; set; } @@ -54,6 +57,7 @@ namespace ColorControl.Services.NVIDIA ditheringMode = 4; applyDriverSettings = false; driverSettings = new Dictionary(); + ocSettings = new List(); } public NvPreset(ColorData colorData) : this() @@ -96,7 +100,7 @@ namespace ColorControl.Services.NVIDIA public static string[] GetColumnNames() { - return new[] { "Name", "Display|140", "Color settings (BPC, format, dyn. range, color space)|260", "Refresh rate|100", "Resolution|120", "Dithering", "HDR", "Driver settings|300", "Shortcut", "Apply on startup" }; + return new[] { "Name", "Display|140", "Color settings (BPC, format, dyn. range, color space)|260", "Refresh rate|100", "Resolution|120", "Dithering", "HDR", "Driver settings|300", "Overclocking|300", "Shortcut", "Apply on startup" }; } public override List GetDisplayValues(Config config = null) @@ -129,6 +133,8 @@ namespace ColorControl.Services.NVIDIA values.Add(string.Format("{0}: {1}", applyDriverSettings ? "Included" : "Excluded", GetDriverSettingsDescription())); + values.Add(string.Format("{0}: {1}", applyOverclocking ? "Included" : "Excluded", GetOverclockingSettingsDescription())); + values.Add(shortcut); values.Add(string.Format("{0}", config?.NvPresetId_ApplyOnStartup == id ? "Yes" : string.Empty)); @@ -136,6 +142,25 @@ namespace ColorControl.Services.NVIDIA return values; } + public string GetOverclockingSettingsDescription(bool useNewLines = false) + { + if (ocSettings.Count == 0) + { + return "None"; + } + + var values = new List(); + + foreach (var ocSetting in ocSettings) + { + var value = ocSetting.ToString(); + + values.Add($"{value}"); + } + + return string.Join(useNewLines ? "\r\n" : ", ", values); + } + public string GetDriverSettingsDescription(bool useNewLines = false) { if (driverSettings.Count == 0) @@ -293,6 +318,20 @@ namespace ColorControl.Services.NVIDIA { driverSettings.Remove(settingId); } + + internal void UpdateOverclockingSetting(NvGpuOcSettings newSettings) + { + var index = ocSettings.FindIndex(s => s.PCIIdentifier == newSettings.PCIIdentifier); + + if (index >= 0) + { + ocSettings[index] = newSettings; + } + else + { + ocSettings.Add(newSettings); + } + } } } diff --git a/ColorControl/Services/NVIDIA/NvService.cs b/ColorControl/Services/NVIDIA/NvService.cs index 80e226c..3f586f1 100644 --- a/ColorControl/Services/NVIDIA/NvService.cs +++ b/ColorControl/Services/NVIDIA/NvService.cs @@ -3,6 +3,7 @@ using ColorControl.Forms; using ColorControl.Services.Common; using ColorControl.Svc; using Microsoft.Extensions.DependencyInjection; +using Newtonsoft.Json; using nspector.Common; using nspector.Common.Meta; using NvAPIWrapper.Display; @@ -14,11 +15,10 @@ using NWin32.NativeTypes; using System; using System.Collections.Generic; using System.ComponentModel; +using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Threading; -using static NvAPIWrapper.Native.GPU.Structures.PerformanceStates20ClockEntryV1; -using static NvAPIWrapper.Native.GPU.Structures.PrivateClockBoostLockV2; namespace ColorControl.Services.NVIDIA { @@ -93,6 +93,8 @@ namespace ColorControl.Services.NVIDIA private Display _currentDisplay; private string _baseProfileName = ""; + private string _configFilename; + public NvServiceConfig Config { get; private set; } private DrsSettingsService _drs; private DrsSettingsMetaService _meta; @@ -139,7 +141,7 @@ namespace ColorControl.Services.NVIDIA NvPreset.NvService = this; AddJsonConverter(new ColorDataConverter()); - + LoadConfig(); LoadPresets(); } @@ -211,6 +213,7 @@ namespace ColorControl.Services.NVIDIA public void GlobalSave() { SavePresets(); + SaveConfig(); } protected override List GetDefaultPresets() @@ -317,6 +320,11 @@ namespace ColorControl.Services.NVIDIA SetDriverSettings(preset.driverSettings); } + if (preset.applyOverclocking) + { + ApplyOverclocking(preset.ocSettings); + } + _lastAppliedPreset = preset; PresetApplied(); @@ -324,6 +332,36 @@ namespace ColorControl.Services.NVIDIA return result; } + public void ApplyOverclocking(NvGpuOcSettings setting) + { + ApplyOverclocking(new List { setting }); + } + + public void ApplyOverclocking(List settings) + { + if (!Utils.IsAdministrator()) + { + PipeUtils.SendMessage(new SvcNvOverclockingMessage + { + OverclockingSettings = settings + }); + + return; + } + + foreach (var ocSetting in settings) + { + var gpuInfo = NvGpuInfo.GetGpuInfo(ocSetting.PCIIdentifier); + + if (gpuInfo == null) + { + continue; + } + + gpuInfo.ApplyOcSettings(ocSetting); + } + } + public bool SetColorData(Display display, ColorData colorData) { try @@ -361,7 +399,7 @@ namespace ColorControl.Services.NVIDIA return result; } - private static void CheckServiceInstance() + public static NvService CheckServiceInstance() { if (ServiceInstance == null) { @@ -371,6 +409,8 @@ namespace ColorControl.Services.NVIDIA ServiceInstance.Initialize(); ServiceInstance.RefreshProfileSettings(); } + + return ServiceInstance; } private void SetDriverSettings(Dictionary settings) @@ -621,6 +661,15 @@ namespace ColorControl.Services.NVIDIA return Display.GetDisplays(); } + public List GetGPUs() + { + var gpuHandles = GPUApi.EnumPhysicalGPUs(); + + var gpus = gpuHandles.Select(h => new PhysicalGPU(h)).ToList(); + + return gpus; + } + public List GetDisplayInfos() { try @@ -890,94 +939,26 @@ namespace ColorControl.Services.NVIDIA } } - public void SetGpuClocks(PhysicalGPU gpu, uint lockedVoltageMicroV = 1000000, int coreOffsetKHz = 0, int memOffsetKHz = 0) + private void LoadConfig() { - // TEST ONLY - gpu ??= PhysicalGPU.GetPhysicalGPUs().FirstOrDefault(); - - if (gpu == null) + _configFilename = Path.Combine(_dataPath, "NvConfig.json"); + try { - Logger.Debug("No GPU"); - return; + if (File.Exists(_configFilename)) + { + Config = JsonConvert.DeserializeObject(File.ReadAllText(_configFilename)); + } } - - var handle = gpu.Handle; - - var perf = GPUApi.GetPerformanceStates20(handle); - - var lockv2 = new PrivateClockBoostLockV2(new[] { new ClockBoostLock(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics, NvAPIWrapper.Native.GPU.ClockLockMode.Manual, lockedVoltageMicroV) }); - - var bla = GPUApi.GetClockBoostLock(handle); - - GPUApi.SetClockBoostLock(handle, lockv2); - - var curve = GPUApi.GetVFPCurve(handle); - - var currentFreq = perf.Clocks.First().Value.First(v => v.DomainId == NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics).SingleFrequency; - - var delta = new PerformanceStates20ParameterDelta(coreOffsetKHz); - //var delta2 = new PerformanceStates20ParameterDelta(0); - //var delta3 = new PerformanceStates20ParameterDelta(0); - //var single1 = new PerformanceStates20ClockDependentSingleFrequency(2670000); - //var single2 = new PerformanceStates20ClockDependentSingleFrequency(2760000); - //var single3 = new PerformanceStates20ClockDependentSingleFrequency(2775000); - - //var clockEntry1 = new PerformanceStates20ClockEntryV1(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics, delta, single1); - //var clockEntry2 = new PerformanceStates20ClockEntryV1(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics, delta2, single2); - //var clockEntry3 = new PerformanceStates20ClockEntryV1(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics, delta3, single3); - - var range = new PerformanceStates20ClockDependentFrequencyRange(2400000, 3000000, NvAPIWrapper.Native.GPU.PerformanceVoltageDomain.Core, 950000, 1050000); - var clockEntry = new PerformanceStates20ClockEntryV1(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics, delta, range); - - var memDelta = new PerformanceStates20ParameterDelta(memOffsetKHz); - var memClockEntry = new PerformanceStates20ClockEntryV1(NvAPIWrapper.Native.GPU.PublicClockDomain.Memory, memDelta); - - //var range2 = new PerformanceStates20ClockDependentFrequencyRange(2800001, 3000000, NvAPIWrapper.Native.GPU.PerformanceVoltageDomain.Core, 1000000, 1000000); - //var clockEntry2 = new PerformanceStates20ClockEntryV1(NvAPIWrapper.Native.GPU.PublicClockDomain.Graphics, delta2, range2); - - var deltaVoltage = new PerformanceStates20ParameterDelta(0); - var voltage = new PerformanceStates20BaseVoltageEntryV1(NvAPIWrapper.Native.GPU.PerformanceVoltageDomain.Core, deltaVoltage); - - var state = new PerformanceStates20InfoV1.PerformanceState20(NvAPIWrapper.Native.GPU.PerformanceStateId.P0_3DPerformance, new[] { clockEntry, memClockEntry }, new[] { voltage }); - - var newPerf = new PerformanceStates20InfoV3(new[] { state }, 2, 1); - - GPUApi.SetPerformanceStates20(handle, newPerf); + catch (Exception ex) + { + Logger.Error($"LoadConfig: {ex.Message}"); + } + Config ??= new NvServiceConfig(); } - public string GetGpuClocks(PhysicalGPU gpu) + private void SaveConfig() { - var handle = gpu.Handle; - - var perf = GPUApi.GetPerformanceStates20(handle); - var clock3D = perf.Clocks.FirstOrDefault(c => c.Key == NvAPIWrapper.Native.GPU.PerformanceStateId.P0_3DPerformance); - - var boostLock = GPUApi.GetClockBoostLock(handle); - - var values = new List(); - - foreach (var boostClock in boostLock.ClockBoostLocks.Where(l => l.LockMode == NvAPIWrapper.Native.GPU.ClockLockMode.Manual)) - { - var clock = clock3D.Value.FirstOrDefault(c => c.DomainId == boostClock.ClockDomain); - - var value = $"{boostClock.ClockDomain}: "; - - if (clock != null) - { - value += $"{clock.FrequencyDeltaInkHz.DeltaValue}KHz @ "; - } - - value += $"{boostClock.VoltageInMicroV}uv"; - - values.Add(value); - } - - if (!values.Any()) - { - values.Add("None"); - } - - return string.Join(", ", values); + Utils.WriteObject(_configFilename, Config); } } } diff --git a/ColorControl/Services/NVIDIA/NvServiceConfig.cs b/ColorControl/Services/NVIDIA/NvServiceConfig.cs new file mode 100644 index 0000000..9ab9780 --- /dev/null +++ b/ColorControl/Services/NVIDIA/NvServiceConfig.cs @@ -0,0 +1,11 @@ +namespace ColorControl.Services.NVIDIA +{ + class NvServiceConfig + { + public bool ShowOverclocking { get; set; } + + public NvServiceConfig() + { + } + } +} diff --git a/ColorControl/Services/NVIDIA/NvidiaML.cs b/ColorControl/Services/NVIDIA/NvidiaML.cs new file mode 100644 index 0000000..77bc075 --- /dev/null +++ b/ColorControl/Services/NVIDIA/NvidiaML.cs @@ -0,0 +1,400 @@ +// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// Copyright (C) LibreHardwareMonitor and Contributors. +// All Rights Reserved. + +using System; +using System.IO; +using System.Runtime.InteropServices; + +namespace ColorControl.Services.NVIDIA; + +internal static class NvidiaML +{ + private const string LinuxDllName = "nvidia-ml"; + private const string WindowsDllName = "nvml.dll"; + + private static readonly object _syncRoot = new(); + + private static IntPtr _windowsDll; + + private static WindowsNvmlGetHandleDelegate _windowsNvmlDeviceGetHandleByIndex; + private static WindowsNvmlGetHandleByPciBusIdDelegate _windowsNvmlDeviceGetHandleByPciBusId; + private static WindowsNvmlDeviceGetPcieThroughputDelegate _windowsNvmlDeviceGetPcieThroughputDelegate; + private static WindowsNvmlDeviceGetPciInfo _windowsNvmlDeviceGetPciInfo; + private static WindowsNvmlGetPowerUsageDelegate _windowsNvmlDeviceGetPowerUsage; + private static WindowsNvmlGetPowerManagementDefaultLimitDelegate _windowsNvmlDevicePowerManagementDefaultLimit; + private static WindowsNvmlDelegate _windowsNvmlInit; + private static WindowsNvmlDelegate _windowsNvmlShutdown; + + public enum NvmlPcieUtilCounter + { + TxBytes = 0, + RxBytes = 1 + } + + public enum NvmlReturn + { + /// + /// The operation was successful + /// + Success = 0, + + /// + /// NvidiaML was not first initialized with nvmlInit() + /// + Uninitialized = 1, + + /// + /// A supplied argument is invalid + /// + InvalidArgument = 2, + + /// + /// The requested operation is not available on target device + /// + NotSupported = 3, + + /// + /// The current user does not have permission for operation + /// + NoPermission = 4, + + /// + /// A query to find an object was unsuccessful + /// + NotFound = 6, + + /// + /// An input argument is not large enough + /// + InsufficientSize = 7, + + /// + /// A device's external power cables are not properly attached + /// + InsufficientPower = 8, + + /// + /// NVIDIA driver is not loaded + /// + DriverNotLoaded = 9, + + /// + /// User provided timeout passed + /// + TimeOut = 10, + + /// + /// NVIDIA Kernel detected an interrupt issue with a GPU + /// + IRQIssue = 11, + + /// + /// NvidiaML Shared Library couldn't be found or loaded + /// + LibraryNotFound = 12, + + /// + /// Local version of NvidiaML doesn't implement this function + /// + FunctionNotFound = 13, + + /// + /// infoROM is corrupted + /// + CorruptedInfoRom = 14, + + /// + /// The GPU has fallen off the bus or has otherwise become inaccessible + /// + GpuIsLost = 15, + + /// + /// The GPU requires a reset before it can be used again + /// + ResetRequired = 16, + + /// + /// The GPU control device has been blocked by the operating system/cgroups + /// + OperatingSystem = 17, + + /// + /// RM detects a driver/library version mismatch + /// + LibRmVersionMismatch = 18, + + /// + /// An operation cannot be performed because the GPU is currently in use + /// + InUse = 19, + + /// + /// An public driver error occurred + /// + Unknown = 999 + } + + public static bool IsAvailable { get; private set; } + + public static bool Initialize() + { + lock (_syncRoot) + { + if (IsAvailable) + { + return true; + } + + // Attempt to load the Nvidia Management Library from the + // windows standard search order for applications. This will + // help installations that either have the library in + // %windir%/system32 or provide their own library + _windowsDll = Kernel32.LoadLibrary(WindowsDllName); + + // If there is no dll in the path, then attempt to load it + // from program files + if (_windowsDll == IntPtr.Zero) + { + string programFilesDirectory = Environment.ExpandEnvironmentVariables("%ProgramW6432%"); + string dllPath = Path.Combine(programFilesDirectory, @"NVIDIA Corporation\NVSMI", WindowsDllName); + + _windowsDll = Kernel32.LoadLibrary(dllPath); + } + + IsAvailable = (_windowsDll != IntPtr.Zero) && InitialiseDelegates() && (_windowsNvmlInit() == NvmlReturn.Success); + + return IsAvailable; + } + } + + private static bool InitialiseDelegates() + { + IntPtr nvmlInit = Kernel32.GetProcAddress(_windowsDll, "nvmlInit_v2"); + + if (nvmlInit != IntPtr.Zero) + { + _windowsNvmlInit = (WindowsNvmlDelegate)Marshal.GetDelegateForFunctionPointer(nvmlInit, typeof(WindowsNvmlDelegate)); + } + else + { + nvmlInit = Kernel32.GetProcAddress(_windowsDll, "nvmlInit"); + if (nvmlInit != IntPtr.Zero) + _windowsNvmlInit = (WindowsNvmlDelegate)Marshal.GetDelegateForFunctionPointer(nvmlInit, typeof(WindowsNvmlDelegate)); + else + return false; + } + + IntPtr nvmlShutdown = Kernel32.GetProcAddress(_windowsDll, "nvmlShutdown"); + if (nvmlShutdown != IntPtr.Zero) + _windowsNvmlShutdown = (WindowsNvmlDelegate)Marshal.GetDelegateForFunctionPointer(nvmlShutdown, typeof(WindowsNvmlDelegate)); + else + return false; + + IntPtr nvmlGetHandle = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetHandleByIndex_v2"); + if (nvmlGetHandle != IntPtr.Zero) + _windowsNvmlDeviceGetHandleByIndex = (WindowsNvmlGetHandleDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetHandle, typeof(WindowsNvmlGetHandleDelegate)); + else + { + nvmlGetHandle = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetHandleByIndex"); + if (nvmlGetHandle != IntPtr.Zero) + _windowsNvmlDeviceGetHandleByIndex = (WindowsNvmlGetHandleDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetHandle, typeof(WindowsNvmlGetHandleDelegate)); + else + return false; + } + + IntPtr nvmlGetPowerUsage = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetPowerUsage"); + if (nvmlGetPowerUsage != IntPtr.Zero) + _windowsNvmlDeviceGetPowerUsage = (WindowsNvmlGetPowerUsageDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetPowerUsage, typeof(WindowsNvmlGetPowerUsageDelegate)); + else + return false; + + IntPtr nvmlGetPowerManagementDefaultLimit = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetPowerManagementDefaultLimit"); + if (nvmlGetPowerManagementDefaultLimit != IntPtr.Zero) + _windowsNvmlDevicePowerManagementDefaultLimit = (WindowsNvmlGetPowerManagementDefaultLimitDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetPowerManagementDefaultLimit, typeof(WindowsNvmlGetPowerManagementDefaultLimitDelegate)); + else + return false; + + IntPtr nvmlGetPcieThroughput = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetPcieThroughput"); + if (nvmlGetPcieThroughput != IntPtr.Zero) + _windowsNvmlDeviceGetPcieThroughputDelegate = (WindowsNvmlDeviceGetPcieThroughputDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetPcieThroughput, typeof(WindowsNvmlDeviceGetPcieThroughputDelegate)); + else + return false; + + IntPtr nvmlGetHandlePciBus = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetHandleByPciBusId_v2"); + if (nvmlGetHandlePciBus != IntPtr.Zero) + _windowsNvmlDeviceGetHandleByPciBusId = (WindowsNvmlGetHandleByPciBusIdDelegate)Marshal.GetDelegateForFunctionPointer(nvmlGetHandlePciBus, typeof(WindowsNvmlGetHandleByPciBusIdDelegate)); + else + return false; + + IntPtr nvmlDeviceGetPciInfo = Kernel32.GetProcAddress(_windowsDll, "nvmlDeviceGetPciInfo_v2"); + if (nvmlDeviceGetPciInfo != IntPtr.Zero) + _windowsNvmlDeviceGetPciInfo = (WindowsNvmlDeviceGetPciInfo)Marshal.GetDelegateForFunctionPointer(nvmlDeviceGetPciInfo, typeof(WindowsNvmlDeviceGetPciInfo)); + else + return false; + + return true; + } + + public static void Close() + { + lock (_syncRoot) + { + if (IsAvailable) + { + if (_windowsDll != IntPtr.Zero) + { + _windowsNvmlShutdown(); + Kernel32.FreeLibrary(_windowsDll); + } + + IsAvailable = false; + } + } + } + + public static NvmlDevice? NvmlDeviceGetHandleByIndex(int index) + { + if (IsAvailable) + { + NvmlDevice nvmlDevice; + if (_windowsNvmlDeviceGetHandleByIndex(index, out nvmlDevice) == NvmlReturn.Success) + return nvmlDevice; + } + + return null; + } + + public static NvmlDevice? NvmlDeviceGetHandleByPciBusId(string pciBusId) + { + if (IsAvailable) + { + NvmlDevice nvmlDevice; + if (_windowsNvmlDeviceGetHandleByPciBusId(pciBusId, out nvmlDevice) == NvmlReturn.Success) + return nvmlDevice; + } + + return null; + } + + public static int? NvmlDeviceGetPowerUsage(NvmlDevice nvmlDevice) + { + if (IsAvailable) + { + int powerUsage; + if (_windowsNvmlDeviceGetPowerUsage(nvmlDevice, out powerUsage) == NvmlReturn.Success) + return powerUsage; + } + + return null; + } + + public static int? NvmlDeviceGetPowerManagementDefaultLimit(NvmlDevice nvmlDevice) + { + if (IsAvailable) + { + int defaultLimit; + if (_windowsNvmlDevicePowerManagementDefaultLimit(nvmlDevice, out defaultLimit) == NvmlReturn.Success) + return defaultLimit; + } + + return null; + } + + public static uint? NvmlDeviceGetPcieThroughput(NvmlDevice nvmlDevice, NvmlPcieUtilCounter counter) + { + if (IsAvailable) + { + uint pcieThroughput; + if (_windowsNvmlDeviceGetPcieThroughputDelegate(nvmlDevice, counter, out pcieThroughput) == NvmlReturn.Success) + return pcieThroughput; + } + + return null; + } + + public static NvmlPciInfo? NvmlDeviceGetPciInfo(NvmlDevice nvmlDevice) + { + if (IsAvailable) + { + var pci = new NvmlPciInfo(); + + if (_windowsNvmlDeviceGetPciInfo(nvmlDevice, ref pci) == NvmlReturn.Success) + return pci; + } + + return null; + } + + [DllImport(LinuxDllName, EntryPoint = "nvmlInit_v2", ExactSpelling = true)] + private static extern NvmlReturn nvmlInit(); + + [DllImport(LinuxDllName, EntryPoint = "nvmlInit", ExactSpelling = true)] + private static extern NvmlReturn nvmlInitLegacy(); + + [DllImport(LinuxDllName, EntryPoint = "nvmlShutdown", ExactSpelling = true)] + private static extern NvmlReturn nvmlShutdown(); + + [DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetHandleByIndex_v2", ExactSpelling = true)] + private static extern NvmlReturn nvmlDeviceGetHandleByIndex(int index, out NvmlDevice device); + + [DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetHandleByPciBusId_v2", ExactSpelling = true)] + private static extern NvmlReturn nvmlDeviceGetHandleByPciBusId([MarshalAs(UnmanagedType.LPStr)] string pciBusId, out NvmlDevice device); + + [DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetHandleByIndex", ExactSpelling = true)] + private static extern NvmlReturn nvmlDeviceGetHandleByIndexLegacy(int index, out NvmlDevice device); + + [DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetPowerUsage", ExactSpelling = true)] + private static extern NvmlReturn nvmlDeviceGetPowerUsage(NvmlDevice device, out int power); + + [DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetPcieThroughput", ExactSpelling = true)] + private static extern NvmlReturn nvmlDeviceGetPcieThroughput(NvmlDevice device, NvmlPcieUtilCounter counter, out uint value); + + [DllImport(LinuxDllName, EntryPoint = "nvmlDeviceGetPciInfo_v2")] + private static extern NvmlReturn nvmlDeviceGetPciInfo(NvmlDevice device, ref NvmlPciInfo pci); + + private delegate NvmlReturn WindowsNvmlDelegate(); + + private delegate NvmlReturn WindowsNvmlGetHandleDelegate(int index, out NvmlDevice device); + + private delegate NvmlReturn WindowsNvmlGetHandleByPciBusIdDelegate([MarshalAs(UnmanagedType.LPStr)] string pciBusId, out NvmlDevice device); + + private delegate NvmlReturn WindowsNvmlGetPowerUsageDelegate(NvmlDevice device, out int power); + + private delegate NvmlReturn WindowsNvmlGetPowerManagementDefaultLimitDelegate(NvmlDevice device, out int defaultLimit); + + private delegate NvmlReturn WindowsNvmlDeviceGetPcieThroughputDelegate(NvmlDevice device, NvmlPcieUtilCounter counter, out uint value); + + private delegate NvmlReturn WindowsNvmlDeviceGetPciInfo(NvmlDevice device, ref NvmlPciInfo pci); + + [StructLayout(LayoutKind.Sequential)] + public struct NvmlDevice + { + public IntPtr Handle; + } + + [StructLayout(LayoutKind.Sequential)] + public struct NvmlPciInfo + { + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] + public string busId; + + public uint domain; + + public uint bus; + + public uint device; + + public ushort pciVendorId; + + public ushort pciDeviceId; + + public uint pciSubSystemId; + + public uint reserved0; + public uint reserved1; + public uint reserved2; + public uint reserved3; + } +} \ No newline at end of file diff --git a/ColorControl/Svc/ColorControlBackgroundService.cs b/ColorControl/Svc/ColorControlBackgroundService.cs index 095b5f1..24c0734 100644 --- a/ColorControl/Svc/ColorControlBackgroundService.cs +++ b/ColorControl/Svc/ColorControlBackgroundService.cs @@ -110,6 +110,7 @@ namespace ColorControl.Svc SvcMessageType.RestartAfterUpdate => HandleRestartAfterUpdateMessage(), SvcMessageType.ApplyNvidiaDriverSettings => HandleNvDriverSettingsMessage(JsonConvert.DeserializeObject(json)), SvcMessageType.RestoreNvidiaDriverSetting => HandleNvRestoreDriverSettingsMessage(JsonConvert.DeserializeObject(json)), + SvcMessageType.ApplyNvidiaOverclocking => HandleNvOverclockingMessage(JsonConvert.DeserializeObject(json)), _ => SvcResultMessage.FromResult(false, "Unexpected message type") }; @@ -197,6 +198,13 @@ namespace ColorControl.Svc return SvcResultMessage.FromResult(result); } + private SvcResultMessage HandleNvOverclockingMessage(SvcNvOverclockingMessage message) + { + NvService.CheckServiceInstance().ApplyOverclocking(message.OverclockingSettings); + + return SvcResultMessage.FromResult(true); + } + private async Task WakeDevicesAsync() { if (!UserSessionInfo.UserLocalSession) diff --git a/ColorControl/Svc/SvcMessage.cs b/ColorControl/Svc/SvcMessage.cs index fcb2504..7a58343 100644 --- a/ColorControl/Svc/SvcMessage.cs +++ b/ColorControl/Svc/SvcMessage.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using ColorControl.Services.NVIDIA; +using System.Collections.Generic; namespace ColorControl.Svc { @@ -12,6 +13,7 @@ namespace ColorControl.Svc RestartAfterUpdate = 21, ApplyNvidiaDriverSettings = 101, RestoreNvidiaDriverSetting = 102, + ApplyNvidiaOverclocking = 110, } public class SvcMessage @@ -43,4 +45,14 @@ namespace ColorControl.Svc public List> DriverSettings { get; set; } } + + public class SvcNvOverclockingMessage : SvcMessage + { + public SvcNvOverclockingMessage(SvcMessageType messageType = SvcMessageType.ApplyNvidiaOverclocking) + { + MessageType = messageType; + } + + public List OverclockingSettings { get; set; } + } } diff --git a/NvAPIWrapper/Display/ColorData.cs b/NvAPIWrapper/Display/ColorData.cs new file mode 100644 index 0000000..c856d81 --- /dev/null +++ b/NvAPIWrapper/Display/ColorData.cs @@ -0,0 +1,200 @@ +using System; +using NvAPIWrapper.Native.Display; +using NvAPIWrapper.Native.Display.Structures; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Display +{ + /// + public class ColorData : IColorData, IEquatable + { + /// + /// Creates an instance of to modify the color data + /// + /// The color data color format. + /// The color data color space. + /// The color data dynamic range. + /// The color data color depth. + /// The color data selection policy. + /// The color data desktop color depth. + public ColorData( + ColorDataFormat colorFormat = ColorDataFormat.Auto, + ColorDataColorimetry colorimetry = ColorDataColorimetry.Auto, + ColorDataDynamicRange? dynamicRange = null, + ColorDataDepth? colorDepth = null, + ColorDataSelectionPolicy? colorSelectionPolicy = null, + ColorDataDesktopDepth? desktopColorDepth = null + ) + { + ColorFormat = colorFormat; + Colorimetry = colorimetry; + DynamicRange = dynamicRange; + ColorDepth = colorDepth; + SelectionPolicy = colorSelectionPolicy; + DesktopColorDepth = desktopColorDepth; + } + + internal ColorData(IColorData colorData) + { + ColorDepth = colorData.ColorDepth; + DynamicRange = colorData.DynamicRange; + ColorFormat = colorData.ColorFormat; + Colorimetry = colorData.Colorimetry; + SelectionPolicy = colorData.SelectionPolicy; + DesktopColorDepth = colorData.DesktopColorDepth; + } + + /// + public ColorDataDepth? ColorDepth { get; } + + /// + public ColorDataFormat ColorFormat { get; } + + /// + public ColorDataColorimetry Colorimetry { get; } + + /// + public ColorDataDesktopDepth? DesktopColorDepth { get; } + + /// + public ColorDataDynamicRange? DynamicRange { get; } + + /// + public ColorDataSelectionPolicy? SelectionPolicy { get; } + + /// + public bool Equals(ColorData other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + return ColorDepth == other.ColorDepth && + ColorFormat == other.ColorFormat && + Colorimetry == other.Colorimetry && + DesktopColorDepth == other.DesktopColorDepth && + DynamicRange == other.DynamicRange && + SelectionPolicy == other.SelectionPolicy; + } + + /// + /// Compares two instances of for equality. + /// + /// The first instance. + /// The second instance. + /// true if two instances are equal; otherwise false. + public static bool operator ==(ColorData left, ColorData right) + { + return left?.Equals(right) == true; + } + + /// + /// Compares two instances of for inequality. + /// + /// The first instance. + /// The second instance. + /// true if two instances are not equal; otherwise false. + public static bool operator !=(ColorData left, ColorData right) + { + return !(left == right); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((ColorData) obj); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = ColorDepth.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) ColorFormat; + hashCode = (hashCode * 397) ^ (int) Colorimetry; + hashCode = (hashCode * 397) ^ DesktopColorDepth.GetHashCode(); + hashCode = (hashCode * 397) ^ DynamicRange.GetHashCode(); + hashCode = (hashCode * 397) ^ SelectionPolicy.GetHashCode(); + + return hashCode; + } + } + + internal ColorDataV1 AsColorDataV1(ColorDataCommand command) + { + return new ColorDataV1( + command, + ColorFormat, + Colorimetry + ); + } + + internal ColorDataV2 AsColorDataV2(ColorDataCommand command) + { + return new ColorDataV2( + command, + ColorFormat, + Colorimetry, + DynamicRange ?? ColorDataDynamicRange.Auto + ); + } + + internal ColorDataV3 AsColorDataV3(ColorDataCommand command) + { + return new ColorDataV3( + command, + ColorFormat, + Colorimetry, + DynamicRange ?? ColorDataDynamicRange.Auto, + ColorDepth ?? ColorDataDepth.Default + ); + } + + internal ColorDataV4 AsColorDataV4(ColorDataCommand command) + { + return new ColorDataV4( + command, + ColorFormat, + Colorimetry, + DynamicRange ?? ColorDataDynamicRange.Auto, + ColorDepth ?? ColorDataDepth.Default, + SelectionPolicy ?? ColorDataSelectionPolicy.Default + ); + } + + internal ColorDataV5 AsColorDataV5(ColorDataCommand command) + { + return new ColorDataV5( + command, + ColorFormat, + Colorimetry, + DynamicRange ?? ColorDataDynamicRange.Auto, + ColorDepth ?? ColorDataDepth.Default, + SelectionPolicy ?? ColorDataSelectionPolicy.Default, + DesktopColorDepth ?? ColorDataDesktopDepth.Default + ); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Display/CustomResolution.cs b/NvAPIWrapper/Display/CustomResolution.cs new file mode 100644 index 0000000..8dac9a4 --- /dev/null +++ b/NvAPIWrapper/Display/CustomResolution.cs @@ -0,0 +1,245 @@ +using System; +using NvAPIWrapper.Native.Display; +using NvAPIWrapper.Native.Display.Structures; + +namespace NvAPIWrapper.Display +{ + /// + /// Hold information about a custom display resolution + /// + public class CustomResolution : IEquatable + { + /// + /// Creates an instance of . + /// + /// The screen width. + /// The screen height. + /// The color format. + /// The resolution timing. + /// The horizontal scaling ratio. + /// The vertical scaling ratio. + public CustomResolution( + uint width, + uint height, + ColorFormat colorFormat, + Timing timing, + float xRatio = 1, + float yRatio = 1 + ) + { + if (xRatio <= 0) + { + throw new ArgumentOutOfRangeException(nameof(xRatio)); + } + + if (yRatio <= 0) + { + throw new ArgumentOutOfRangeException(nameof(yRatio)); + } + + Width = width; + Height = height; + ColorFormat = colorFormat; + XRatio = xRatio; + YRatio = yRatio; + Timing = timing; + + switch (ColorFormat) + { + case ColorFormat.P8: + ColorDepth = 8; + + break; + case ColorFormat.R5G6B5: + ColorDepth = 16; + + break; + case ColorFormat.A8R8G8B8: + ColorDepth = 24; + + break; + case ColorFormat.A16B16G16R16F: + ColorDepth = 32; + + break; + default: + throw new ArgumentException("Color format is invalid.", nameof(colorFormat)); + } + } + + /// + /// Creates an instance of . + /// + /// The screen width. + /// The screen height. + /// The color depth. + /// The resolution timing. + /// The horizontal scaling ratio. + /// The vertical scaling ratio. + public CustomResolution( + uint width, + uint height, + uint colorDepth, + Timing timing, + float xRatio = 1, + float yRatio = 1) + { + if (xRatio <= 0) + { + throw new ArgumentOutOfRangeException(nameof(xRatio)); + } + + if (yRatio <= 0) + { + throw new ArgumentOutOfRangeException(nameof(yRatio)); + } + + if (colorDepth != 0 && colorDepth != 8 && colorDepth != 16 && colorDepth != 24 && colorDepth != 32) + { + throw new ArgumentOutOfRangeException(nameof(colorDepth)); + } + + Width = width; + Height = height; + ColorDepth = colorDepth; + ColorFormat = ColorFormat.Unknown; + XRatio = xRatio; + YRatio = yRatio; + Timing = timing; + } + + internal CustomResolution(CustomDisplay customDisplay) + { + Width = customDisplay.Width; + Height = customDisplay.Height; + ColorDepth = customDisplay.Depth; + ColorFormat = customDisplay.ColorFormat; + Timing = customDisplay.Timing; + XRatio = customDisplay.XRatio; + YRatio = customDisplay.YRatio; + } + + /// + /// Gets the source surface color depth. "0" means all 8/16/32bpp. + /// + public uint ColorDepth { get; } + + /// + /// Gets the color format (optional) + /// + public ColorFormat ColorFormat { get; } + + /// + /// Gets the source surface (source mode) height. + /// + public uint Height { get; } + + /// + /// Gets the timing used to program TMDS/DAC/LVDS/HDMI/TVEncoder, etc. + /// + public Timing Timing { get; } + + /// + /// Gets the source surface (source mode) width. + /// + public uint Width { get; } + + /// + /// Gets the horizontal scaling ratio. + /// + public float XRatio { get; } + + /// + /// Gets the vertical scaling ratio. + /// + public float YRatio { get; } + + /// + public bool Equals(CustomResolution other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + return Width == other.Width && + Height == other.Height && + ColorDepth == other.ColorDepth && + Timing.Equals(other.Timing) && + ColorFormat == other.ColorFormat && + XRatio.Equals(other.XRatio) && + YRatio.Equals(other.YRatio); + } + + /// + /// Compares two instance of for equality. + /// + /// An first instance of to compare. + /// An Second instance of to compare. + /// True if both instances are equal, otherwise false. + public static bool operator ==(CustomResolution left, CustomResolution right) + { + return Equals(left, right); + } + + /// + /// Compares two instance of for inequality. + /// + /// An first instance of to compare. + /// An Second instance of to compare. + /// True if both instances are not equal, otherwise false. + public static bool operator !=(CustomResolution left, CustomResolution right) + { + return !Equals(left, right); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((CustomResolution) obj); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (int) Width; + hashCode = (hashCode * 397) ^ (int) Height; + hashCode = (hashCode * 397) ^ (int) ColorDepth; + hashCode = (hashCode * 397) ^ Timing.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) ColorFormat; + hashCode = (hashCode * 397) ^ XRatio.GetHashCode(); + hashCode = (hashCode * 397) ^ YRatio.GetHashCode(); + + return hashCode; + } + } + + internal CustomDisplay AsCustomDisplay(bool hardwareModeSetOnly) + { + return new CustomDisplay(Width, Height, ColorDepth, ColorFormat, XRatio, YRatio, Timing, + hardwareModeSetOnly); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Display/DVCInformation.cs b/NvAPIWrapper/Display/DVCInformation.cs new file mode 100644 index 0000000..c5a4da3 --- /dev/null +++ b/NvAPIWrapper/Display/DVCInformation.cs @@ -0,0 +1,325 @@ +using System; +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.Display.Structures; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Display +{ + /// + /// This class contains and provides a way to modify the Digital Vibrance Control information regarding the + /// saturation level of the display or the output + /// + public class DVCInformation : IDisplayDVCInfo + { + private readonly DisplayHandle _displayHandle = DisplayHandle.DefaultHandle; + private readonly OutputId _outputId = OutputId.Invalid; + private bool? _isLegacy; + + /// + /// Creates a new instance of the class using a DisplayHandle + /// + /// The handle of the display. + public DVCInformation(DisplayHandle displayHandle) + { + _displayHandle = displayHandle; + } + + /// + /// Creates a new instance of this class using a OutputId + /// + /// The output identification of a display or an output + public DVCInformation(OutputId outputId) + { + _outputId = outputId; + } + + /// + /// Gets and sets the normalized saturation level in the [-1,1] inclusive range. + /// a -1 value corresponds to the minimum saturation level and maximum under-saturation and the + /// a 1 value corresponds to the maximum saturation level and maximum over-saturation. + /// The value of 0 indicates the default saturation level. + /// + public double NormalizedLevel + { + get + { + var info = GetInfo(); + + if (info == null) + { + return double.NaN; + } + + var deviance = info.CurrentLevel - info.DefaultLevel; + var range = deviance >= 0 + ? info.MaximumLevel - info.DefaultLevel + : info.DefaultLevel - info.MinimumLevel; + + if (deviance == 0 || range == 0) + { + return 0; + } + + return Math.Max(Math.Min((double) deviance / range, 1), -1); + } + set + { + if (double.IsNaN(value) || double.IsInfinity(value)) + { + throw new ArgumentOutOfRangeException(nameof(value)); + } + + var info = GetInfo(); + + if (info == null) + { + return; + } + + var range = value >= 0 ? info.MaximumLevel - info.DefaultLevel : info.DefaultLevel - info.MinimumLevel; + var level = Math.Max(Math.Min((int) (value * range) + info.DefaultLevel, info.MaximumLevel), info.MinimumLevel); + + if (level == info.CurrentLevel) + { + return; + } + + SetLevel(level); + } + } + + /// + /// Gets and sets the current saturation level + /// + public int CurrentLevel + { + get => GetInfo()?.CurrentLevel ?? 0; + set + { + var info = GetInfo(); + + if (info == null) + { + return; + } + + value = Math.Max(Math.Min(value, info.MaximumLevel), info.MinimumLevel); + + if (info.CurrentLevel == value) + { + return; + } + + SetLevel(value); + } + } + + /// + public int DefaultLevel + { + get => GetInfo()?.DefaultLevel ?? 0; + } + + /// + public int MaximumLevel + { + get => GetInfo()?.MaximumLevel ?? 0; + } + + /// + public int MinimumLevel + { + get => GetInfo()?.MinimumLevel ?? 0; + } + + /// + public override string ToString() + { + return + $"{CurrentLevel:D} @ [{MinimumLevel:D} <= {DefaultLevel:D} <= {MaximumLevel:D}] = {NormalizedLevel:F2}"; + } + + private IDisplayDVCInfo GetInfo() + { + if (_isLegacy == true) + { + return GetLegacyInfo(); + } + + if (_isLegacy == false) + { + return GetModernInfo(); + } + + var info = GetModernInfo() ?? GetLegacyInfo(); + + if (info == null) + { + // exception occured on both, force a mode + _isLegacy = false; + + return GetInfo(); + } + + return info; + } + + private IDisplayDVCInfo GetLegacyInfo() + { + try + { + var info = _outputId == OutputId.Invalid + ? DisplayApi.GetDVCInfo(_displayHandle) + : DisplayApi.GetDVCInfo(_outputId); + + if (info.MaximumLevel == 0 && info.MinimumLevel == 0 && info.CurrentLevel == 0) + { + return null; + } + + if (!_isLegacy.HasValue) + { + _isLegacy = true; + } + + + return info; + } + catch (Exception) + { + if (_isLegacy == true) + { + throw; + } + + // ignore + } + + return null; + } + + private IDisplayDVCInfo GetModernInfo() + { + try + { + var info = _outputId == OutputId.Invalid + ? DisplayApi.GetDVCInfoEx(_displayHandle) + : DisplayApi.GetDVCInfoEx(_outputId); + + if (info.MaximumLevel == 0 && info.MinimumLevel == 0 && info.CurrentLevel == 0) + { + return null; + } + + if (!_isLegacy.HasValue) + { + _isLegacy = false; + } + + return info; + } + catch (Exception) + { + if (_isLegacy == false) + { + throw; + } + + // ignore + } + + return null; + } + + private bool SetLegacyLevel(int level) + { + try + { + if (_outputId == OutputId.Invalid) + { + DisplayApi.SetDVCLevel(_displayHandle, level); + } + else + { + DisplayApi.SetDVCLevel(_outputId, level); + } + + if (!_isLegacy.HasValue) + { + _isLegacy = true; + } + + return true; + } + catch (Exception) + { + if (_isLegacy == true) + { + throw; + } + + // ignore + } + + return false; + } + + private void SetLevel(int level) + { + if (_isLegacy == true) + { + SetLegacyLevel(level); + } + else if (_isLegacy == false) + { + SetModernLevel(level); + } + else + { + var success = SetModernLevel(level) || SetLegacyLevel(level); + + if (!success) + { + // exception occured on both, force a mode + _isLegacy = false; + + SetLevel(level); + } + } + } + + private bool SetModernLevel(int level) + { + try + { + if (_outputId == OutputId.Invalid) + { + DisplayApi.SetDVCLevelEx(_displayHandle, level); + } + else + { + DisplayApi.SetDVCLevelEx(_outputId, level); + } + + if (!_isLegacy.HasValue) + { + _isLegacy = false; + } + + return true; + } + catch (Exception) + { + if (_isLegacy == false) + { + throw; + } + + // ignore + } + + return false; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Display/Display.cs b/NvAPIWrapper/Display/Display.cs new file mode 100644 index 0000000..4da92f7 --- /dev/null +++ b/NvAPIWrapper/Display/Display.cs @@ -0,0 +1,232 @@ +using System; +using System.Linq; +using NvAPIWrapper.GPU; +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.Display; +using NvAPIWrapper.Native.Display.Structures; +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Display +{ + /// + /// Represents an attached display + /// + public class Display : IEquatable + { + /// + /// Creates a new Display + /// + /// Handle of the display device + public Display(DisplayHandle handle) + { + Handle = handle; + } + + /// + /// Creates a new Display + /// + /// Name of the display device + public Display(string displayName) + { + Handle = DisplayApi.GetAssociatedNvidiaDisplayHandle(displayName); + } + + /// + /// Gets the corresponding Digital Vibrance Control information + /// + public DVCInformation DigitalVibranceControl + { + get => new DVCInformation(Handle); + } + + /// + /// Gets corresponding DisplayDevice based on display name + /// + public DisplayDevice DisplayDevice + { + get => new DisplayDevice(Name); + } + + /// + /// Gets display driver build title + /// + public string DriverBuildTitle + { + get => DisplayApi.GetDisplayDriverBuildTitle(Handle); + } + + /// + /// Gets display handle + /// + public DisplayHandle Handle { get; } + + /// + /// Gets the display HDMI support information + /// + public IHDMISupportInfo HDMISupportInfo + { + get + { + var outputId = OutputId.Invalid; + try + { + outputId = DisplayApi.GetAssociatedDisplayOutputId(Handle); + } + catch (NVIDIAApiException) + { + // ignore + } + return DisplayApi.GetHDMISupportInfo(Handle, outputId); + } + } + + /// + /// Gets the corresponding HUE information + /// + public HUEInformation HUEControl + { + get => new HUEInformation(Handle); + } + + /// + /// Gets the driving logical GPU + /// + public LogicalGPU LogicalGPU + { + get => new LogicalGPU(GPUApi.GetLogicalGPUFromDisplay(Handle)); + } + + /// + /// Gets display name + /// + public string Name + { + get => DisplayApi.GetAssociatedNvidiaDisplayName(Handle); + } + + /// + /// Gets the connected GPU output + /// + public GPUOutput Output + { + get => new GPUOutput(DisplayApi.GetAssociatedDisplayOutputId(Handle), PhysicalGPUs.FirstOrDefault()); + } + + /// + /// Gets the list of all physical GPUs responsible for this display, with the first GPU returned as the one with the + /// attached active output. + /// + public PhysicalGPU[] PhysicalGPUs + { + get => GPUApi.GetPhysicalGPUsFromDisplay(Handle).Select(handle => new PhysicalGPU(handle)).ToArray(); + } + + /// + public bool Equals(Display other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + return Handle.Equals(other.Handle); + } + + /// + /// This function returns all NVIDIA displays + /// Note: Display handles can get invalidated on a modeset. + /// + /// An array of Display objects + public static Display[] GetDisplays() + { + return DisplayApi.EnumNvidiaDisplayHandle().Select(handle => new Display(handle)).ToArray(); + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(Display left, Display right) + { + return right?.Equals(left) ?? ReferenceEquals(left, null); + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(Display left, Display right) + { + return !(right == left); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((Display) obj); + } + + /// + public override int GetHashCode() + { + return Handle.GetHashCode(); + } + + /// + public override string ToString() + { + return Name; + } + + /// + /// Gets all the supported NVIDIA display views (nView and Dualview modes) for this display. + /// + /// + public TargetViewMode[] GetSupportedViews() + { + return DisplayApi.GetSupportedViews(Handle); + } + + /// + /// Overrides the refresh rate on this display. + /// The new refresh rate can be applied right away or deferred to be applied with the next OS + /// mode-set. + /// The override is good for only one mode-set (regardless whether it's deferred or immediate). + /// + /// The refresh rate to be applied. + /// + /// A boolean value indicating if the refresh rate override should be deferred to the next OS + /// mode-set. + /// + public void OverrideRefreshRate(float refreshRate, bool isDeferred = false) + { + DisplayApi.SetRefreshRateOverride(Handle, refreshRate, isDeferred); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Display/DisplayDevice.cs b/NvAPIWrapper/Display/DisplayDevice.cs new file mode 100644 index 0000000..5d404bf --- /dev/null +++ b/NvAPIWrapper/Display/DisplayDevice.cs @@ -0,0 +1,893 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NvAPIWrapper.GPU; +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.Display; +using NvAPIWrapper.Native.Display.Structures; +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; +using NvAPIWrapper.Native.Interfaces.Display; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Display +{ + /// + /// Represents an NVIDIA display device + /// + public class DisplayDevice : IEquatable + { + /// + /// Creates a new DisplayDevice + /// + /// Display identification of the device + public DisplayDevice(uint displayId) + { + DisplayId = displayId; + var extraInformation = PhysicalGPU.GetDisplayDevices().FirstOrDefault(ids => ids.DisplayId == DisplayId); + + if (extraInformation != null) + { + IsAvailable = true; + ScanOutInformation = new ScanOutInformation(this); + ConnectionType = extraInformation.ConnectionType; + IsDynamic = extraInformation.IsDynamic; + IsMultiStreamRootNode = extraInformation.IsMultiStreamRootNode; + IsActive = extraInformation.IsActive; + IsCluster = extraInformation.IsCluster; + IsOSVisible = extraInformation.IsOSVisible; + IsWFD = extraInformation.IsWFD; + IsConnected = extraInformation.IsConnected; + IsPhysicallyConnected = extraInformation.IsPhysicallyConnected; + } + } + + /// + /// Creates a new DisplayDevice + /// + /// Display identification and attributes of the display device + public DisplayDevice(IDisplayIds displayIds) + { + IsAvailable = true; + DisplayId = displayIds.DisplayId; + ScanOutInformation = new ScanOutInformation(this); + ConnectionType = displayIds.ConnectionType; + IsDynamic = displayIds.IsDynamic; + IsMultiStreamRootNode = displayIds.IsMultiStreamRootNode; + IsActive = displayIds.IsActive; + IsCluster = displayIds.IsCluster; + IsOSVisible = displayIds.IsOSVisible; + IsWFD = displayIds.IsWFD; + IsConnected = displayIds.IsConnected; + IsPhysicallyConnected = displayIds.IsPhysicallyConnected; + } + + /// + /// Creates a new DisplayDevice + /// + /// Display name of the display device + public DisplayDevice(string displayName) : this(DisplayApi.GetDisplayIdByDisplayName(displayName)) + { + } + + /// + /// Gets the display device connection type + /// + public MonitorConnectionType ConnectionType { get; } + + /// + /// Gets the current display color data + /// + public ColorData CurrentColorData + { + get + { + var instances = new IColorData[] + { + new ColorDataV5(ColorDataCommand.Get), + new ColorDataV4(ColorDataCommand.Get), + new ColorDataV3(ColorDataCommand.Get), + new ColorDataV2(ColorDataCommand.Get), + new ColorDataV1(ColorDataCommand.Get) + }; + + var instance = DisplayApi.ColorControl(DisplayId, instances); + + return new ColorData(instance); + } + } + + /// + /// Gets the current display device timing + /// + public Timing CurrentTiming + { + get => DisplayApi.GetTiming(DisplayId, new TimingInput(TimingOverride.Current)); + } + + /// + /// Gets the default display color data + /// + public ColorData DefaultColorData + { + get + { + var instances = new IColorData[] + { + new ColorDataV5(ColorDataCommand.GetDefault), + new ColorDataV4(ColorDataCommand.GetDefault), + new ColorDataV3(ColorDataCommand.GetDefault), + new ColorDataV2(ColorDataCommand.GetDefault), + new ColorDataV1(ColorDataCommand.GetDefault) + }; + + var instance = DisplayApi.ColorControl(DisplayId, instances); + + return new ColorData(instance); + } + } + + /// + /// Gets the NVIDIA display identification + /// + public uint DisplayId { get; } + + /// + /// Gets the monitor Display port capabilities + /// + public MonitorColorData[] DisplayPortColorCapabilities + { + get + { + if (ConnectionType != MonitorConnectionType.DisplayPort) + { + return null; + } + + return DisplayApi.GetMonitorColorCapabilities(DisplayId); + } + } + + /// + /// Gets the display driver EDID specified HDR capabilities + /// + public HDRCapabilitiesV1 DriverHDRCapabilities + { + get => DisplayApi.GetHDRCapabilities(DisplayId, true); + } + + /// + /// Gets the display currently effective HDR capabilities + /// + public HDRCapabilitiesV1 EffectiveHDRCapabilities + { + get => DisplayApi.GetHDRCapabilities(DisplayId, false); + } + + /// + /// Gets the HDMI audio info-frame current information + /// + public InfoFrameAudio? HDMIAudioFrameCurrentInformation + { + get + { + try + { + var infoFrame = new InfoFrameData(InfoFrameCommand.Get, InfoFrameDataType.AudioInformation); + DisplayApi.InfoFrameControl(DisplayId, ref infoFrame); + + return infoFrame.AudioInformation; + } + catch (NVIDIAApiException e) + { + if (e.Status == Status.NotSupported) + { + return null; + } + + throw; + } + } + } + + + /// + /// Gets the HDMI audio info-frame default information + /// + public InfoFrameAudio? HDMIAudioFrameDefaultInformation + { + get + { + try + { + var infoFrame = new InfoFrameData(InfoFrameCommand.GetDefault, InfoFrameDataType.AudioInformation); + DisplayApi.InfoFrameControl(DisplayId, ref infoFrame); + + return infoFrame.AudioInformation; + } + catch (NVIDIAApiException e) + { + if (e.Status == Status.NotSupported) + { + return null; + } + + throw; + } + } + } + + /// + /// Gets the HDMI audio info-frame override information + /// + public InfoFrameAudio? HDMIAudioFrameOverrideInformation + { + get + { + try + { + var infoFrame = new InfoFrameData(InfoFrameCommand.GetOverride, InfoFrameDataType.AudioInformation); + DisplayApi.InfoFrameControl(DisplayId, ref infoFrame); + + return infoFrame.AudioInformation; + } + catch (NVIDIAApiException e) + { + if (e.Status == Status.NotSupported) + { + return null; + } + + throw; + } + } + } + + /// + /// Gets the HDMI audio info-frame property information + /// + public InfoFrameProperty? HDMIAudioFramePropertyInformation + { + get + { + try + { + var infoFrame = new InfoFrameData(InfoFrameCommand.GetProperty, InfoFrameDataType.AudioInformation); + DisplayApi.InfoFrameControl(DisplayId, ref infoFrame); + + return infoFrame.PropertyInformation; + } + catch (NVIDIAApiException e) + { + if (e.Status == Status.NotSupported) + { + return null; + } + + throw; + } + } + } + + /// + /// Gets the device HDMI support information + /// + public IHDMISupportInfo HDMISupportInfo + { + get => DisplayApi.GetHDMISupportInfo(DisplayId); + } + + + /// + /// Gets the HDMI auxiliary video info-frame current information + /// + public InfoFrameVideo? HDMIVideoFrameCurrentInformation + { + get + { + try + { + var infoFrame = + new InfoFrameData(InfoFrameCommand.Get, InfoFrameDataType.AuxiliaryVideoInformation); + DisplayApi.InfoFrameControl(DisplayId, ref infoFrame); + + return infoFrame.AuxiliaryVideoInformation; + } + catch (NVIDIAApiException e) + { + if (e.Status == Status.NotSupported) + { + return null; + } + + throw; + } + } + } + + /// + /// Gets the HDMI auxiliary video info-frame default information + /// + public InfoFrameVideo? HDMIVideoFrameDefaultInformation + { + get + { + try + { + var infoFrame = new InfoFrameData(InfoFrameCommand.GetDefault, + InfoFrameDataType.AuxiliaryVideoInformation); + DisplayApi.InfoFrameControl(DisplayId, ref infoFrame); + + return infoFrame.AuxiliaryVideoInformation; + } + catch (NVIDIAApiException e) + { + if (e.Status == Status.NotSupported) + { + return null; + } + + throw; + } + } + } + + /// + /// Gets the HDMI auxiliary video info-frame override information + /// + public InfoFrameVideo? HDMIVideoFrameOverrideInformation + { + get + { + try + { + var infoFrame = new InfoFrameData(InfoFrameCommand.GetOverride, + InfoFrameDataType.AuxiliaryVideoInformation); + DisplayApi.InfoFrameControl(DisplayId, ref infoFrame); + + return infoFrame.AuxiliaryVideoInformation; + } + catch (NVIDIAApiException e) + { + if (e.Status == Status.NotSupported) + { + return null; + } + + throw; + } + } + } + + /// + /// Gets the HDMI auxiliary video info-frame property information + /// + public InfoFrameProperty? HDMIVideoFramePropertyInformation + { + get + { + try + { + var infoFrame = new InfoFrameData(InfoFrameCommand.GetProperty, + InfoFrameDataType.AuxiliaryVideoInformation); + DisplayApi.InfoFrameControl(DisplayId, ref infoFrame); + + return infoFrame.PropertyInformation; + } + catch (NVIDIAApiException e) + { + if (e.Status == Status.NotSupported) + { + return null; + } + + throw; + } + } + } + + /// + /// Gets the HDR color data, or null if the HDR is disabled or unavailable + /// + public HDRColorData HDRColorData + { + get + { + try + { + var instances = new IHDRColorData[] + { + new HDRColorDataV2(ColorDataHDRCommand.Get), + new HDRColorDataV1(ColorDataHDRCommand.Get) + }; + + var instance = DisplayApi.HDRColorControl(DisplayId, instances); + + if (instance.HDRMode == ColorDataHDRMode.Off) + { + return null; + } + + return new HDRColorData(instance); + } + catch (NVIDIAApiException e) + { + if (e.Status == Status.NotSupported) + { + return null; + } + + throw; + } + } + } + + /// + /// Indicates if the display is being actively driven + /// + public bool IsActive { get; } + + /// + /// Indicates if the display device is currently available + /// + public bool IsAvailable { get; } + + /// + /// Indicates if the display is the representative display + /// + public bool IsCluster { get; } + + /// + /// Indicates if the display is connected + /// + public bool IsConnected { get; } + + /// + /// Indicates if the display is part of MST topology and it's a dynamic + /// + public bool IsDynamic { get; } + + /// + /// Indicates if the display identification belongs to a multi stream enabled connector (root node). Note that when + /// multi stream is enabled and a single multi stream capable monitor is connected to it, the monitor will share the + /// display id with the RootNode. + /// When there is more than one monitor connected in a multi stream topology, then the root node will have a separate + /// displayId. + /// + public bool IsMultiStreamRootNode { get; } + + /// + /// Indicates if the display is reported to the OS + /// + public bool IsOSVisible { get; } + + /// + /// Indicates if the display is a physically connected display; Valid only when IsConnected is true + /// + public bool IsPhysicallyConnected { get; } + + /// + /// Indicates if the display is wireless + /// + public bool IsWFD { get; } + + /// + /// Gets the connected GPU output + /// + public GPUOutput Output + { + get + { + PhysicalGPUHandle handle; + var outputId = GPUApi.GetGPUAndOutputIdFromDisplayId(DisplayId, out handle); + + return new GPUOutput(outputId, new PhysicalGPU(handle)); + } + } + + /// + /// Gets the connected physical GPU + /// + public PhysicalGPU PhysicalGPU + { + get + { + try + { + var gpuHandle = GPUApi.GetPhysicalGPUFromDisplayId(DisplayId); + + return new PhysicalGPU(gpuHandle); + } + catch + { + // ignored + } + + return Output.PhysicalGPU; + } + } + + /// + /// Gets information regarding the scan-out settings of this display device + /// + public ScanOutInformation ScanOutInformation { get; } + + /// + /// Gets monitor capabilities from the Video Capability Data Block if available, otherwise null + /// + public MonitorVCDBCapabilities? VCDBMonitorCapabilities + { + get => DisplayApi.GetMonitorCapabilities(DisplayId, MonitorCapabilitiesType.VCDB)?.VCDBCapabilities; + } + + /// + /// Gets monitor capabilities from the Vendor Specific Data Block if available, otherwise null + /// + public MonitorVSDBCapabilities? VSDBMonitorCapabilities + { + get => DisplayApi.GetMonitorCapabilities(DisplayId, MonitorCapabilitiesType.VSDB)?.VSDBCapabilities; + } + + /// + public bool Equals(DisplayDevice other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + return DisplayId == other.DisplayId; + } + + /// + /// Deletes a custom resolution. + /// + /// The custom resolution to delete. + /// A list of display ids to remove the custom resolution from. + public static void DeleteCustomResolution(CustomResolution customResolution, uint[] displayIds) + { + var customDisplay = customResolution.AsCustomDisplay(false); + DisplayApi.DeleteCustomDisplay(displayIds, customDisplay); + } + + /// + /// Returns an instance of representing the primary GDI display device. + /// + /// An instance of . + public static DisplayDevice GetGDIPrimaryDisplayDevice() + { + var displayId = DisplayApi.GetGDIPrimaryDisplayId(); + + if (displayId == 0) + { + return null; + } + + return new DisplayDevice(displayId); + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(DisplayDevice left, DisplayDevice right) + { + return right?.Equals(left) ?? ReferenceEquals(left, null); + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(DisplayDevice left, DisplayDevice right) + { + return !(right == left); + } + + /// + /// Reverts the custom resolution currently on trial. + /// + /// A list of display ids to revert the custom resolution from. + public static void RevertCustomResolution(uint[] displayIds) + { + DisplayApi.RevertCustomDisplayTrial(displayIds); + } + + /// + /// Saves the custom resolution currently on trial. + /// + /// A list of display ids to save the custom resolution for. + /// + /// If set, the saved custom display will only be applied on the monitor with the same + /// outputId. + /// + /// + /// If set, the saved custom display will only be applied on the monitor with the same EDID + /// ID or the same TV connector in case of analog TV. + /// + public static void SaveCustomResolution(uint[] displayIds, bool isThisOutputIdOnly, bool isThisMonitorOnly) + { + DisplayApi.SaveCustomDisplay(displayIds, isThisOutputIdOnly, isThisMonitorOnly); + } + + /// + /// Applies a custom resolution into trial + /// + /// The custom resolution to apply. + /// A list of display ids to apply the custom resolution on. + /// + /// A boolean value indicating that a hardware mode-set without OS update should be + /// performed. + /// + public static void TrialCustomResolution( + CustomResolution customResolution, + uint[] displayIds, + bool hardwareModeSetOnly = true) + { + var customDisplay = customResolution.AsCustomDisplay(hardwareModeSetOnly); + DisplayApi.TryCustomDisplay(displayIds.ToDictionary(u => u, u => customDisplay)); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((DisplayDevice) obj); + } + + /// + public override int GetHashCode() + { + return (int) DisplayId; + } + + + /// + public override string ToString() + { + return $"Display #{DisplayId}"; + } + + /// + /// Calculates a valid timing based on the argument passed + /// + /// The preferred width. + /// The preferred height. + /// The preferred refresh rate. + /// The boolean value indicating if the preferred resolution is an interlaced resolution. + /// Returns a valid instance of . + public Timing CalculateTiming(uint width, uint height, float refreshRate, bool isInterlaced) + { + return DisplayApi.GetTiming( + DisplayId, + new TimingInput(width, height, refreshRate, TimingOverride.Auto, isInterlaced) + ); + } + + /// + /// Deletes a custom resolution. + /// + /// The custom resolution to delete. + public void DeleteCustomResolution(CustomResolution customResolution) + { + DeleteCustomResolution(customResolution, new[] {DisplayId}); + } + + /// + /// Retrieves the list of custom resolutions saved for this display device + /// + /// A list of instances. + public IEnumerable GetCustomResolutions() + { + return DisplayApi.EnumCustomDisplays(DisplayId).Select(custom => new CustomResolution(custom)); + } + + /// + /// Checks if a color data is supported on this display + /// + /// The color data to be checked. + /// true if the color data passed is supported; otherwise false + public bool IsColorDataSupported(ColorData colorData) + { + var instances = new IColorData[] + { + colorData.AsColorDataV5(ColorDataCommand.IsSupportedColor), + colorData.AsColorDataV4(ColorDataCommand.IsSupportedColor), + colorData.AsColorDataV3(ColorDataCommand.IsSupportedColor), + colorData.AsColorDataV2(ColorDataCommand.IsSupportedColor), + colorData.AsColorDataV1(ColorDataCommand.IsSupportedColor) + }; + + try + { + DisplayApi.ColorControl(DisplayId, instances); + + return true; + } + catch (NVIDIAApiException e) + { + if (e.Status == Status.NotSupported) + { + return false; + } + + throw; + } + } + + /// + /// Resets the HDMI audio info-frame information to default + /// + public void ResetHDMIAudioFrameInformation() + { + var infoFrame = new InfoFrameData( + InfoFrameCommand.Reset, + InfoFrameDataType.AudioInformation + ); + DisplayApi.InfoFrameControl(DisplayId, ref infoFrame); + } + + /// + /// Resets the HDMI auxiliary video info-frame information to default + /// + public void ResetHDMIVideoFrameInformation() + { + var infoFrame = new InfoFrameData( + InfoFrameCommand.Reset, + InfoFrameDataType.AuxiliaryVideoInformation + ); + DisplayApi.InfoFrameControl(DisplayId, ref infoFrame); + } + + /// + /// Reverts the custom resolution currently on trial. + /// + public void RevertCustomResolution() + { + RevertCustomResolution(new[] {DisplayId}); + } + + /// + /// Saves the custom resolution currently on trial. + /// + /// + /// If set, the saved custom display will only be applied on the monitor with the same + /// outputId. + /// + /// + /// If set, the saved custom display will only be applied on the monitor with the same EDID + /// ID or the same TV connector in case of analog TV. + /// + public void SaveCustomResolution(bool isThisOutputIdOnly = true, bool isThisMonitorOnly = true) + { + SaveCustomResolution(new[] {DisplayId}, isThisOutputIdOnly, isThisMonitorOnly); + } + + /// + /// Changes the display current color data configuration + /// + /// The color data to be set. + public void SetColorData(ColorData colorData) + { + var instances = new IColorData[] + { + colorData.AsColorDataV5(ColorDataCommand.Set), + colorData.AsColorDataV4(ColorDataCommand.Set), + colorData.AsColorDataV3(ColorDataCommand.Set), + colorData.AsColorDataV2(ColorDataCommand.Set), + colorData.AsColorDataV1(ColorDataCommand.Set) + }; + + DisplayApi.ColorControl(DisplayId, instances); + } + + /// + /// Sets the HDMI video info-frame current or override information + /// + /// The new information. + /// A boolean value indicating if the changes should persist mode-set and OS restart. + public void SetHDMIAudioFrameInformation(InfoFrameAudio audio, bool isOverride = false) + { + var infoFrame = new InfoFrameData( + isOverride ? InfoFrameCommand.SetOverride : InfoFrameCommand.Set, + audio + ); + DisplayApi.InfoFrameControl(DisplayId, ref infoFrame); + } + + /// + /// Sets the HDMI audio info-frame property information + /// + /// The new property information. + public void SetHDMIAudioFramePropertyInformation(InfoFrameProperty property) + { + var infoFrame = new InfoFrameData( + InfoFrameCommand.SetProperty, + InfoFrameDataType.AudioInformation, + property + ); + DisplayApi.InfoFrameControl(DisplayId, ref infoFrame); + } + + /// + /// Sets the HDMI auxiliary video info-frame current or override information + /// + /// The new information. + /// A boolean value indicating if the changes should persist mode-set and OS restart. + public void SetHDMIVideoFrameInformation(InfoFrameVideo video, bool isOverride = false) + { + var infoFrame = new InfoFrameData( + isOverride ? InfoFrameCommand.SetOverride : InfoFrameCommand.Set, + video + ); + DisplayApi.InfoFrameControl(DisplayId, ref infoFrame); + } + + /// + /// Sets the HDMI auxiliary video info-frame property information + /// + /// The new property information. + public void SetHDMIVideoFramePropertyInformation(InfoFrameProperty property) + { + var infoFrame = new InfoFrameData( + InfoFrameCommand.SetProperty, + InfoFrameDataType.AuxiliaryVideoInformation, + property + ); + DisplayApi.InfoFrameControl(DisplayId, ref infoFrame); + } + + /// + /// Changes the display HDR color data configuration + /// + /// The color data to be set. + public void SetHDRColorData(HDRColorData colorData) + { + var instances = new IHDRColorData[] + { + colorData.AsHDRColorDataV2(ColorDataHDRCommand.Set), + colorData.AsHDRColorDataV1(ColorDataHDRCommand.Set) + }; + + DisplayApi.HDRColorControl(DisplayId, instances); + } + + /// + /// Applies a custom resolution into trial. + /// + /// The custom resolution to apply. + /// + /// A boolean value indicating that a hardware mode-set without OS update should be + /// performed. + /// + public void TrialCustomResolution(CustomResolution customResolution, bool hardwareModeSetOnly = true) + { + TrialCustomResolution(customResolution, new[] {DisplayId}, hardwareModeSetOnly); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Display/FloatTexture.cs b/NvAPIWrapper/Display/FloatTexture.cs new file mode 100644 index 0000000..74ee552 --- /dev/null +++ b/NvAPIWrapper/Display/FloatTexture.cs @@ -0,0 +1,183 @@ +using System; +using System.Linq; + +namespace NvAPIWrapper.Display +{ + /// + /// Represents a texture of float values + /// + public class FloatTexture : IEquatable + { + /// + /// Underlying float array containing the values of all channels in all pixels + /// + protected readonly float[] UnderlyingArray; + + /// + /// Creates a new instance of . + /// + /// The texture width. + /// The texture height. + /// The number of texture channels. + public FloatTexture(int width, int height, int channels) : this(width, height, channels, null) + { + } + + /// + /// Creates a new instance of . + /// + /// The texture width. + /// The texture height. + /// The number of texture channels. + /// The underlying array containing all float values. + // ReSharper disable once TooManyDependencies + protected FloatTexture(int width, int height, int channels, float[] array) + { + Width = width; + Height = height; + Channels = channels; + UnderlyingArray = array ?? new float[width * height * channels]; + } + + /// + /// Gets the number of texture channels + /// + public int Channels { get; } + + /// + /// Gets the texture height in pixel + /// + public int Height { get; } + + /// + /// Gets the texture width in pixels + /// + public int Width { get; } + + /// + public bool Equals(FloatTexture other) + { + if (other == null) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.UnderlyingArray.Length != UnderlyingArray.Length) + { + return false; + } + + if (other.Width != Width || other.Height != Height || other.Channels != Channels) + { + return false; + } + + return !UnderlyingArray.Where((t, i) => Math.Abs(other.UnderlyingArray[i] - t) > 0.0001).Any(); + } + + /// + /// Returns a new instance of FloatTexture from the passed array of float values. + /// + /// The texture width. + /// The texture height. + /// The texture channels. + /// The array of float values. + /// A new instance of . + // ReSharper disable once TooManyArguments + public static FloatTexture FromFloatArray(int width, int height, int channels, float[] floats) + { + if (floats.Length != width * height * channels) + { + throw new ArgumentOutOfRangeException(nameof(floats)); + } + + return new FloatTexture(width, height, channels, floats.ToArray()); + } + + /// + /// Compares two instance of for equality. + /// + /// The first instance. + /// The second instance. + /// if both instances are equal, otherwise + public static bool operator ==(FloatTexture left, FloatTexture right) + { + return Equals(left, right) || left?.Equals(right) == true; + } + + /// + /// Compares two instance of for in-equality. + /// + /// The first instance. + /// The second instance. + /// if both instances are not equal, otherwise + public static bool operator !=(FloatTexture left, FloatTexture right) + { + return !(left == right); + } + + /// + public override bool Equals(object obj) + { + if (obj == null) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + return Equals(obj as FloatTexture); + } + + /// + public override int GetHashCode() + { + return UnderlyingArray.GetHashCode(); + } + + /// + /// Gets the values of each channel at a specific location + /// + /// The horizontal location. + /// The vertical location. + /// An array of float values each representing a channel value. + public float[] GetValues(int x, int y) + { + return UnderlyingArray.Skip(y * Width + x).Take(Channels).ToArray(); + } + + /// + /// Sets the value of each channel at a specific location + /// + /// The horizontal location. + /// The vertical location. + /// An array of float values each representing a channel value. + public void SetValues(int x, int y, params float[] floats) + { + var index = y * Width + x; + + for (var i = 0; i < Math.Min(Channels, floats.Length); i++) + { + UnderlyingArray[index + i] = floats[i]; + } + } + + /// + /// Returns this instance of as an array of float values. + /// + /// An array of float values representing this instance of . + public float[] ToFloatArray() + { + // Returns a copy of the underlying array + return UnderlyingArray.ToArray(); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Display/HDRColorData.cs b/NvAPIWrapper/Display/HDRColorData.cs new file mode 100644 index 0000000..935c260 --- /dev/null +++ b/NvAPIWrapper/Display/HDRColorData.cs @@ -0,0 +1,157 @@ +using System; +using NvAPIWrapper.Native.Display; +using NvAPIWrapper.Native.Display.Structures; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Display +{ + /// + public class HDRColorData : IHDRColorData, IEquatable + { + /// + /// Creates an instance of . + /// + /// The hdr mode. + /// The display color space configurations. + /// The color data color format. + /// The color data dynamic range. + /// The color data color depth. + public HDRColorData( + ColorDataHDRMode hdrMode, + MasteringDisplayColorData masteringDisplayData, + ColorDataFormat? colorFormat = null, + ColorDataDynamicRange? dynamicRange = null, + ColorDataDepth? colorDepth = null + ) + { + HDRMode = hdrMode; + MasteringDisplayData = masteringDisplayData; + ColorFormat = colorFormat; + DynamicRange = dynamicRange; + ColorDepth = colorDepth; + } + + internal HDRColorData(IHDRColorData colorData) + { + HDRMode = colorData.HDRMode; + MasteringDisplayData = colorData.MasteringDisplayData; + ColorDepth = colorData.ColorDepth; + ColorFormat = colorData.ColorFormat; + DynamicRange = colorData.DynamicRange; + } + + /// + public bool Equals(HDRColorData other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + return ColorDepth == other.ColorDepth && + ColorFormat == other.ColorFormat && + DynamicRange == other.DynamicRange && + HDRMode == other.HDRMode && + MasteringDisplayData.Equals(other.MasteringDisplayData); + } + + /// + public ColorDataDepth? ColorDepth { get; } + + /// + public ColorDataFormat? ColorFormat { get; } + + /// + public ColorDataDynamicRange? DynamicRange { get; } + + /// + public ColorDataHDRMode HDRMode { get; } + + /// + public MasteringDisplayColorData MasteringDisplayData { get; } + + /// + /// Compares two instances of for equality. + /// + /// The first instance. + /// The second instance. + /// true if two instances are equal; otherwise false. + public static bool operator ==(HDRColorData left, HDRColorData right) + { + return left?.Equals(right) == true; + } + + /// + /// Compares two instances of for inequality. + /// + /// The first instance. + /// The second instance. + /// true if two instances are not equal; otherwise false. + public static bool operator !=(HDRColorData left, HDRColorData right) + { + return !(left == right); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((HDRColorData) obj); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = ColorDepth.GetHashCode(); + hashCode = (hashCode * 397) ^ ColorFormat.GetHashCode(); + hashCode = (hashCode * 397) ^ DynamicRange.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) HDRMode; + hashCode = (hashCode * 397) ^ MasteringDisplayData.GetHashCode(); + + return hashCode; + } + } + + internal HDRColorDataV1 AsHDRColorDataV1(ColorDataHDRCommand command) + { + return new HDRColorDataV1( + command, + HDRMode, + MasteringDisplayData + ); + } + + internal HDRColorDataV2 AsHDRColorDataV2(ColorDataHDRCommand command) + { + return new HDRColorDataV2( + command, + HDRMode, + MasteringDisplayData, + ColorFormat ?? ColorDataFormat.Auto, + DynamicRange ?? ColorDataDynamicRange.Auto, + ColorDepth ?? ColorDataDepth.Default + ); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Display/HUEInformation.cs b/NvAPIWrapper/Display/HUEInformation.cs new file mode 100644 index 0000000..22ef2d7 --- /dev/null +++ b/NvAPIWrapper/Display/HUEInformation.cs @@ -0,0 +1,97 @@ +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.Display.Structures; +using NvAPIWrapper.Native.GPU; + +namespace NvAPIWrapper.Display +{ + /// + /// This class contains and provides a way to modify the HUE angle + /// + public class HUEInformation + { + private readonly DisplayHandle _displayHandle = DisplayHandle.DefaultHandle; + private readonly OutputId _outputId = OutputId.Invalid; + + /// + /// Creates a new instance of the class using a DisplayHandle + /// + /// The handle of the display. + public HUEInformation(DisplayHandle displayHandle) + { + _displayHandle = displayHandle; + } + + /// + /// Creates a new instance of this class using a OutputId + /// + /// The output identification of a display or an output + public HUEInformation(OutputId outputId) + { + _outputId = outputId; + } + + /// + /// Gets or sets the current HUE offset angle [0-359] + /// + public int CurrentAngle + { + get + { + PrivateDisplayHUEInfo? hueInfo = null; + + if (_displayHandle != DisplayHandle.DefaultHandle) + { + hueInfo = DisplayApi.GetHUEInfo(_displayHandle); + } + else if (_outputId != OutputId.Invalid) + { + hueInfo = DisplayApi.GetHUEInfo(_outputId); + } + + return hueInfo?.CurrentAngle ?? 0; + } + set + { + value %= 360; + + if (_displayHandle != DisplayHandle.DefaultHandle) + { + DisplayApi.SetHUEAngle(_displayHandle, value); + } + else if (_outputId != OutputId.Invalid) + { + DisplayApi.SetHUEAngle(_outputId, value); + } + } + } + + /// + /// Gets the default HUE offset angle [0-359] + /// + public int DefaultAngle + { + get + { + PrivateDisplayHUEInfo? hueInfo = null; + + if (_displayHandle != DisplayHandle.DefaultHandle) + { + hueInfo = DisplayApi.GetHUEInfo(_displayHandle); + } + else if (_outputId != OutputId.Invalid) + { + hueInfo = DisplayApi.GetHUEInfo(_outputId); + } + + return hueInfo?.DefaultAngle ?? 0; + } + } + + + /// + public override string ToString() + { + return $"{CurrentAngle:D}º [{DefaultAngle:D}º]"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Display/IntensityTexture.cs b/NvAPIWrapper/Display/IntensityTexture.cs new file mode 100644 index 0000000..0025f3c --- /dev/null +++ b/NvAPIWrapper/Display/IntensityTexture.cs @@ -0,0 +1,70 @@ +using System; +using System.Linq; + +namespace NvAPIWrapper.Display +{ + /// + /// Represents a texture of intensity values + /// + public class IntensityTexture : FloatTexture + { + /// + /// Creates a new instance of . + /// + /// The texture width. + /// The texture height. + public IntensityTexture(int width, int height) : base(width, height, 3) + { + } + + private IntensityTexture(int width, int height, float[] floats) : base(width, height, 3, floats) + { + } + + /// + /// Returns a new instance of FloatTexture from the passed array of float values. + /// + /// The texture width. + /// The texture height. + /// The array of float values. + /// A new instance of . + // ReSharper disable once TooManyArguments + public static IntensityTexture FromFloatArray(int width, int height, float[] floats) + { + if (floats.Length != width * height * 3) + { + throw new ArgumentOutOfRangeException(nameof(floats)); + } + + return new IntensityTexture(width, height, floats.ToArray()); + } + + /// + /// Gets the value of intensity pixel at a specific location. + /// + /// The horizontal location. + /// The vertical location. + /// An instance of . + public IntensityTexturePixel GetPixel(int x, int y) + { + return IntensityTexturePixel.FromFloatArray(UnderlyingArray, y * Width + x); + } + + /// + /// Sets the value of intensity pixel at a specific location + /// + /// The horizontal location. + /// The vertical location. + /// An instance of . + public void SetPixel(int x, int y, IntensityTexturePixel pixel) + { + var index = y * Width + x; + var floats = pixel.ToFloatArray(); + + for (var i = 0; i < Math.Min(Channels, floats.Length); i++) + { + UnderlyingArray[index + i] = floats[i]; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Display/IntensityTexturePixel.cs b/NvAPIWrapper/Display/IntensityTexturePixel.cs new file mode 100644 index 0000000..b357773 --- /dev/null +++ b/NvAPIWrapper/Display/IntensityTexturePixel.cs @@ -0,0 +1,117 @@ +using System; + +namespace NvAPIWrapper.Display +{ + /// + /// Represents a RGB intensity texture pixel + /// + public class IntensityTexturePixel : IEquatable + { + /// + /// Creates a new instance of . + /// + /// The intensity of the red light (0-1) + /// The intensity of the green light (0-1) + /// The intensity of the blue light (0-1) + public IntensityTexturePixel(float redIntensity, float greenIntensity, float blueIntensity) + { + RedIntensity = Math.Max(Math.Min(redIntensity, 1), 0); + GreenIntensity = Math.Max(Math.Min(greenIntensity, 1), 0); + BlueIntensity = Math.Max(Math.Min(blueIntensity, 1), 0); + } + + /// + /// Gets the intensity of the blue light (0-1) + /// + public float BlueIntensity { get; } + + /// + /// Gets the intensity of the green light (0-1) + /// + public float GreenIntensity { get; } + + /// + /// Gets the intensity of the red light (0-1) + /// + public float RedIntensity { get; } + + /// + public bool Equals(IntensityTexturePixel other) + { + if (other == null) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + return Math.Abs(RedIntensity - other.RedIntensity) < 0.0001 && + Math.Abs(GreenIntensity - other.GreenIntensity) < 0.0001 && + Math.Abs(BlueIntensity - other.BlueIntensity) < 0.0001; + } + + /// + /// Compares two instance of for equality. + /// + /// The first instance. + /// The second instance. + /// if both instances are equal, otherwise + public static bool operator ==(IntensityTexturePixel left, IntensityTexturePixel right) + { + return Equals(left, right) || left?.Equals(right) == true; + } + + /// + /// Compares two instance of for in-equality. + /// + /// The first instance. + /// The second instance. + /// if both instances are not equal, otherwise + public static bool operator !=(IntensityTexturePixel left, IntensityTexturePixel right) + { + return !(left == right); + } + + internal static IntensityTexturePixel FromFloatArray(float[] floats, int index) + { + return new IntensityTexturePixel(floats[index], floats[index + 1], floats[index + 2]); + } + + /// + public override bool Equals(object obj) + { + if (obj == null) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + return Equals(obj as IntensityTexturePixel); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = RedIntensity.GetHashCode(); + hashCode = (hashCode * 397) ^ GreenIntensity.GetHashCode(); + hashCode = (hashCode * 397) ^ BlueIntensity.GetHashCode(); + + return hashCode; + } + } + + internal float[] ToFloatArray() + { + return new[] {RedIntensity, GreenIntensity, BlueIntensity}; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Display/PathInfo.cs b/NvAPIWrapper/Display/PathInfo.cs new file mode 100644 index 0000000..02551a1 --- /dev/null +++ b/NvAPIWrapper/Display/PathInfo.cs @@ -0,0 +1,288 @@ +using System; +using System.Linq; +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.Display; +using NvAPIWrapper.Native.Display.Structures; +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Display +{ + /// + /// Represents a configuration path + /// + public class PathInfo : IEquatable + { + /// + /// Creates a new PathInfo + /// + /// Display resolution + /// Display color format + /// Target configuration informations + public PathInfo(Resolution resolution, ColorFormat colorFormat, PathTargetInfo[] targetInfos) + { + Resolution = resolution; + ColorFormat = colorFormat; + TargetsInfo = targetInfos; + } + + /// + /// Creates a new PathInfo + /// + /// IPathInfo implamented object + public PathInfo(IPathInfo info) + { + SourceId = info.SourceId; + Resolution = info.SourceModeInfo.Resolution; + ColorFormat = info.SourceModeInfo.ColorFormat; + Position = info.SourceModeInfo.Position; + SpanningOrientation = info.SourceModeInfo.SpanningOrientation; + IsGDIPrimary = info.SourceModeInfo.IsGDIPrimary; + IsSLIFocus = info.SourceModeInfo.IsSLIFocus; + TargetsInfo = + info.TargetsInfo.Select(targetInfo => new PathTargetInfo(targetInfo)).ToArray(); + + if (info is PathInfoV2) + { + OSAdapterLUID = ((PathInfoV2) info).OSAdapterLUID; + } + } + + /// + /// Gets or sets the display color format + /// + public ColorFormat ColorFormat { get; set; } + + /// + /// Gets or sets a boolean value indicating if the this is the primary GDI display + /// + public bool IsGDIPrimary { get; set; } + + /// + /// Gets or sets a boolean value indicating if the this is the SLI focus display + /// + public bool IsSLIFocus { get; set; } + + /// + /// Gets OS Adapter of LUID for Non-NVIDIA adapters + /// + public LUID? OSAdapterLUID { get; } + + /// + /// Gets or sets the display position + /// + public Position Position { get; set; } + + /// + /// Gets or sets the display resolution + /// + public Resolution Resolution { get; set; } + + /// + /// Gets or sets the Windows CCD display source identification. This can be optionally set. + /// + public uint SourceId { get; set; } + + /// + /// Gets or sets the display spanning orientation, valid for XP only + /// + public SpanningOrientation SpanningOrientation { get; set; } + + + /// + /// Gets information about path targets + /// + public PathTargetInfo[] TargetsInfo { get; } + + + /// + /// Checks for equality with a PathInfo instance + /// + /// The PathInfo object to check with + /// true if both objects are equal, otherwise false + public bool Equals(PathInfo other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + return Resolution.Equals(other.Resolution) && + ColorFormat == other.ColorFormat && + Position.Equals(other.Position) && + SpanningOrientation == other.SpanningOrientation && + IsGDIPrimary == other.IsGDIPrimary && + IsSLIFocus == other.IsSLIFocus && + TargetsInfo.SequenceEqual(other.TargetsInfo); + } + + + /// + /// Creates and fills a PathInfo object + /// + /// The newly created PathInfo object + public static PathInfo[] GetDisplaysConfig() + { + var configs = DisplayApi.GetDisplayConfig(); + var logicalDisplays = configs.Select(info => new PathInfo(info)).ToArray(); + configs.DisposeAll(); + + return logicalDisplays; + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(PathInfo left, PathInfo right) + { + return right?.Equals(left) ?? ReferenceEquals(left, null); + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(PathInfo left, PathInfo right) + { + return !(left == right); + } + + /// + /// Applies one or more path information configurations + /// + /// An array of path information configuration + /// DisplayConfigFlags flags + public static void SetDisplaysConfig(PathInfo[] pathInfos, DisplayConfigFlags flags) + { + try + { + var configsV2 = pathInfos.Select(config => config.GetPathInfoV2()).Cast().ToArray(); + DisplayApi.SetDisplayConfig(configsV2, flags); + configsV2.DisposeAll(); + } + catch (NVIDIAApiException ex) + { + if (ex.Status != Status.IncompatibleStructureVersion) + { + throw; + } + } + catch (NVIDIANotSupportedException) + { + // ignore + } + + var configsV1 = pathInfos.Select(config => config.GetPathInfoV1()).Cast().ToArray(); + DisplayApi.SetDisplayConfig(configsV1, flags); + configsV1.DisposeAll(); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((PathInfo) obj); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = Resolution.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) ColorFormat; + hashCode = (hashCode * 397) ^ Position.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) SpanningOrientation; + hashCode = (hashCode * 397) ^ IsGDIPrimary.GetHashCode(); + hashCode = (hashCode * 397) ^ IsSLIFocus.GetHashCode(); + hashCode = (hashCode * 397) ^ (TargetsInfo?.GetHashCode() ?? 0); + + return hashCode; + } + } + + + /// + public override string ToString() + { + return $"{Resolution} @ {Position} [{TargetsInfo.Length}]"; + } + + /// + /// Creates and fills a GetPathInfoV1 object + /// + /// The newly created GetPathInfoV1 object + public PathInfoV1 GetPathInfoV1() + { + var sourceModeInfo = GetSourceModeInfo(); + var pathTargetInfoV1 = GetPathTargetInfoV1Array(); + + return new PathInfoV1(pathTargetInfoV1, sourceModeInfo, SourceId); + } + + /// + /// Creates and fills a GetPathInfoV2 object + /// + /// The newly created GetPathInfoV2 object + public PathInfoV2 GetPathInfoV2() + { + var sourceModeInfo = GetSourceModeInfo(); + var pathTargetInfoV2 = GetPathTargetInfoV2Array(); + + return new PathInfoV2(pathTargetInfoV2, sourceModeInfo, SourceId); + } + + /// + /// Creates and fills an array of GetPathTargetInfoV1 object + /// + /// The newly created array of GetPathTargetInfoV1 objects + public PathTargetInfoV1[] GetPathTargetInfoV1Array() + { + return TargetsInfo.Select(config => config.GetPathTargetInfoV1()).ToArray(); + } + + /// + /// Creates and fills an array of GetPathTargetInfoV2 object + /// + /// The newly created array of GetPathTargetInfoV2 objects + public PathTargetInfoV2[] GetPathTargetInfoV2Array() + { + return TargetsInfo.Select(config => config.GetPathTargetInfoV2()).ToArray(); + } + + /// + /// Creates and fills a SourceModeInfo object + /// + /// The newly created SourceModeInfo object + public SourceModeInfo GetSourceModeInfo() + { + return new SourceModeInfo(Resolution, ColorFormat, Position, SpanningOrientation, IsGDIPrimary, IsSLIFocus); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Display/PathTargetInfo.cs b/NvAPIWrapper/Display/PathTargetInfo.cs new file mode 100644 index 0000000..dde14d1 --- /dev/null +++ b/NvAPIWrapper/Display/PathTargetInfo.cs @@ -0,0 +1,304 @@ +using System; +using System.Collections.Generic; +using NvAPIWrapper.Native.Display; +using NvAPIWrapper.Native.Display.Structures; +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Display +{ + /// + /// Represents a display configuration on a path + /// + public class PathTargetInfo : IEquatable + { + private TimingOverride _timingOverride; + + /// + /// Creates a new PathTargetInfo + /// + /// IPathTargetInfo implamented object + public PathTargetInfo(IPathTargetInfo info) + { + DisplayDevice = new DisplayDevice(info.DisplayId); + + if (info.Details.HasValue) + { + Rotation = info.Details.Value.Rotation; + Scaling = info.Details.Value.Scaling; + TVConnectorType = info.Details.Value.ConnectorType; + TVFormat = info.Details.Value.TVFormat; + RefreshRateInMillihertz = info.Details.Value.RefreshRateInMillihertz; + TimingOverride = info.Details.Value.TimingOverride; + IsInterlaced = info.Details.Value.IsInterlaced; + IsClonePrimary = info.Details.Value.IsClonePrimary; + IsClonePanAndScanTarget = info.Details.Value.IsClonePanAndScanTarget; + DisableVirtualModeSupport = info.Details.Value.DisableVirtualModeSupport; + IsPreferredUnscaledTarget = info.Details.Value.IsPreferredUnscaledTarget; + } + + if (info is PathTargetInfoV2) + { + WindowsCCDTargetId = ((PathTargetInfoV2) info).WindowsCCDTargetId; + } + } + + /// + /// Creates a new PathTargetInfo + /// + /// DisplayDevice object + public PathTargetInfo(DisplayDevice device) + { + DisplayDevice = device; + } + + /// + /// Gets or sets the virtual mode support + /// + public bool DisableVirtualModeSupport { get; set; } + + /// + /// Gets corresponding DisplayDevice + /// + public DisplayDevice DisplayDevice { get; } + + /// + /// Gets or sets the pan and scan is availability. Valid only when the target is part of clone + /// topology. + /// + public bool IsClonePanAndScanTarget { get; set; } + + /// + /// Gets or sets the primary display in clone configuration. This is *NOT* GDI Primary. + /// Only one target can be primary per source. If no primary is specified, the first target will automatically be + /// primary. + /// + public bool IsClonePrimary { get; set; } + + /// + /// Gets or sets the interlaced mode flag, ignored if refreshRate == 0 + /// + public bool IsInterlaced { get; set; } + + /// + /// Gets or sets the preferred unscaled mode of target + /// + public bool IsPreferredUnscaledTarget { get; set; } + + /// + /// Gets and sets the non-interlaced Refresh Rate of the mode, multiplied by 1000, 0 = ignored + /// This is the value which driver reports to the OS. + /// + public uint RefreshRateInMillihertz { get; set; } + + /// + /// Gets and sets the rotation setting + /// + public Rotate Rotation { get; set; } + + /// + /// Gets and sets the scaling setting + /// + public Scaling Scaling { get; set; } + + /// + /// Gets and sets the custom timing of display + /// Ignored if TimingOverride == TimingOverride.Current + /// + public TimingOverride TimingOverride + { + get => _timingOverride; + set + { + if (value == TimingOverride.Custom) + { + throw new NVIDIANotSupportedException("Custom timing is not supported yet."); + } + + _timingOverride = value; + } + } + + /// + /// Gets and sets the connector type. For TV only, ignored if TVFormat == TVFormat.None. + /// + public ConnectorType TVConnectorType { get; set; } + + /// + /// Gets and sets the TV format. For TV only, otherwise set to TVFormat.None + /// + public TVFormat TVFormat { get; set; } + + /// + /// Gets the Windows CCD target ID. Must be present only for non-NVIDIA adapter, for NVIDIA adapter this parameter is + /// ignored. + /// + public uint WindowsCCDTargetId { get; } + + /// + /// Checks for equality with a PathTargetInfo instance + /// + /// The PathTargetInfo object to check with + /// true if both objects are equal, otherwise false + public bool Equals(PathTargetInfo other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + return _timingOverride == other._timingOverride && + Rotation == other.Rotation && + Scaling == other.Scaling && + RefreshRateInMillihertz == other.RefreshRateInMillihertz && + (TVFormat == TVFormat.None || TVConnectorType == other.TVConnectorType) && + TVFormat == other.TVFormat && + DisplayDevice.Equals(other.DisplayDevice) && + IsInterlaced == other.IsInterlaced && + IsClonePrimary == other.IsClonePrimary && + IsClonePanAndScanTarget == other.IsClonePanAndScanTarget && + DisableVirtualModeSupport == other.DisableVirtualModeSupport && + IsPreferredUnscaledTarget == other.IsPreferredUnscaledTarget; + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(PathTargetInfo left, PathTargetInfo right) + { + return right?.Equals(left) ?? ReferenceEquals(left, null); + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(PathTargetInfo left, PathTargetInfo right) + { + return !(left == right); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((PathTargetInfo) obj); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (int) _timingOverride; + hashCode = (hashCode * 397) ^ (int) Rotation; + hashCode = (hashCode * 397) ^ (int) Scaling; + hashCode = (hashCode * 397) ^ (int) RefreshRateInMillihertz; + hashCode = (hashCode * 397) ^ (int) TVFormat; + hashCode = (hashCode * 397) ^ (TVFormat != TVFormat.None ? (int) TVConnectorType : 0); + hashCode = (hashCode * 397) ^ (DisplayDevice?.GetHashCode() ?? 0); + hashCode = (hashCode * 397) ^ IsInterlaced.GetHashCode(); + hashCode = (hashCode * 397) ^ IsClonePrimary.GetHashCode(); + hashCode = (hashCode * 397) ^ IsClonePanAndScanTarget.GetHashCode(); + hashCode = (hashCode * 397) ^ DisableVirtualModeSupport.GetHashCode(); + hashCode = (hashCode * 397) ^ IsPreferredUnscaledTarget.GetHashCode(); + + return hashCode; + } + } + + /// + public override string ToString() + { + var strs = new List + { + DisplayDevice.ToString() + }; + + if (RefreshRateInMillihertz > 0) + { + strs.Add($"@ {RefreshRateInMillihertz / 1000}hz"); + } + + if (TVFormat != TVFormat.None) + { + strs.Add($"- TV {TVFormat}"); + } + + strs.Add(IsInterlaced ? "Interlaced" : "Progressive"); + + if (Rotation != Rotate.Degree0) + { + strs.Add($"- Rotation: {Rotation}"); + } + + return string.Join(" ", strs); + } + + + /// + /// Creates and fills a PathAdvancedTargetInfo object + /// + /// The newly created PathAdvancedTargetInfo object + public PathAdvancedTargetInfo GetPathAdvancedTargetInfo() + { + if (TVFormat == TVFormat.None) + { + return new PathAdvancedTargetInfo(Rotation, Scaling, RefreshRateInMillihertz, TimingOverride, + IsInterlaced, IsClonePrimary, IsClonePanAndScanTarget, DisableVirtualModeSupport, + IsPreferredUnscaledTarget); + } + + return new PathAdvancedTargetInfo(Rotation, Scaling, TVFormat, TVConnectorType, RefreshRateInMillihertz, + TimingOverride, IsInterlaced, IsClonePrimary, IsClonePanAndScanTarget, DisableVirtualModeSupport, + IsPreferredUnscaledTarget); + } + + /// + /// Creates and fills a PathTargetInfoV1 object + /// + /// The newly created PathTargetInfoV1 object + public PathTargetInfoV1 GetPathTargetInfoV1() + { + var pathAdvancedTargetInfo = GetPathAdvancedTargetInfo(); + + return new PathTargetInfoV1(DisplayDevice.DisplayId, pathAdvancedTargetInfo); + } + + /// + /// Creates and fills a PathTargetInfoV2 object + /// + /// The newly created PathTargetInfoV2 object + public PathTargetInfoV2 GetPathTargetInfoV2() + { + var pathAdvancedTargetInfo = GetPathAdvancedTargetInfo(); + + return new PathTargetInfoV2(DisplayDevice.DisplayId, WindowsCCDTargetId, pathAdvancedTargetInfo); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Display/ScanOutInformation.cs b/NvAPIWrapper/Display/ScanOutInformation.cs new file mode 100644 index 0000000..4f338cd --- /dev/null +++ b/NvAPIWrapper/Display/ScanOutInformation.cs @@ -0,0 +1,217 @@ +using System.Linq; +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.Display; +using NvAPIWrapper.Native.Display.Structures; +using NvAPIWrapper.Native.General.Structures; + +namespace NvAPIWrapper.Display +{ + /// + /// Contains information regarding the scan-out buffer settings of a display device + /// + public class ScanOutInformation + { + internal ScanOutInformation(DisplayDevice displayDevice) + { + DisplayDevice = displayDevice; + } + + /// + /// Gets the clone importance assigned to the target if the target is a cloned view of the SourceDesktopRectangle + /// (0:primary,1 secondary,...). + /// + public uint CloneImportance + { + get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).CloneImportance; + } + + /// + /// Gets the display device that this instance describes + /// + public DisplayDevice DisplayDevice { get; } + + /// + /// Gets a boolean value indicating if the display device scan out output is warped + /// + public bool IsDisplayWarped + { + get => DisplayApi.GetScanOutWarpingState(DisplayDevice.DisplayId).IsEnabled; + } + + /// + /// Gets a boolean value indicating if the display device intensity is modified + /// + public bool IsIntensityModified + { + get => DisplayApi.GetScanOutIntensityState(DisplayDevice.DisplayId).IsEnabled; + } + + /// + /// Gets the operating system display device rectangle in desktop coordinates displayId is scanning out from. + /// + public Rectangle SourceDesktopRectangle + { + get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).SourceDesktopRectangle; + } + + /// + /// Gets the rotation performed between the SourceViewPortRectangle and the TargetViewPortRectangle. + /// + public Rotate SourceToTargetRotation + { + get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).SourceToTargetRotation; + } + + /// + /// Gets the area inside the SourceDesktopRectangle which is scanned out to the display. + /// + public Rectangle SourceViewPortRectangle + { + get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).SourceViewPortRectangle; + } + + /// + /// Gets the vertical size of the active resolution scanned out to the display. + /// + public uint TargetDisplayHeight + { + get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).TargetDisplayHeight; + } + + /// + /// Gets the horizontal size of the active resolution scanned out to the display. + /// + public uint TargetDisplayWidth + { + get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).TargetDisplayWidth; + } + + /// + /// Gets the area inside the rectangle described by targetDisplayWidth/Height SourceViewPortRectangle is scanned out + /// to. + /// + public Rectangle TargetViewPortRectangle + { + get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).TargetViewPortRectangle; + } + + /// + /// Disables the intensity modification on the display device scan-out buffer. + /// + /// A boolean value that indicates whether the settings will be kept over a reboot. + public void DisableIntensityModifications(out bool isSticky) + { + DisplayApi.SetScanOutIntensity(DisplayDevice.DisplayId, null, out isSticky); + } + + /// + /// Disables the warping of display device scan-out buffer. + /// + /// A boolean value that indicates whether the settings will be kept over a reboot. + public void DisableWarping(out bool isSticky) + { + var vorticesCount = 0; + DisplayApi.SetScanOutWarping(DisplayDevice.DisplayId, null, ref vorticesCount, out isSticky); + } + + /// + /// Enables the intensity modification on the display device scan-out buffer. + /// + /// The intensity texture to apply to the scan-out buffer. + /// A boolean value that indicates whether the settings will be kept over a reboot. + public void EnableIntensityModifications(IntensityTexture intensityTexture, out bool isSticky) + { + using ( + var intensity = new ScanOutIntensityV1( + (uint) intensityTexture.Width, + (uint) intensityTexture.Height, + intensityTexture.ToFloatArray() + ) + ) + { + DisplayApi.SetScanOutIntensity(DisplayDevice.DisplayId, intensity, out isSticky); + } + } + + /// + /// Enables the intensity modification on the display device scan-out buffer. + /// + /// The intensity texture to apply to the scan-out buffer. + /// The offset texture to apply to the scan-out buffer. + /// A boolean value that indicates whether the settings will be kept over a reboot. + public void EnableIntensityModifications( + IntensityTexture intensityTexture, + FloatTexture offsetTexture, + out bool isSticky) + { + using ( + var intensity = new ScanOutIntensityV2( + (uint) intensityTexture.Width, + (uint) intensityTexture.Height, + intensityTexture.ToFloatArray(), + (uint) offsetTexture.Channels, + offsetTexture.ToFloatArray() + ) + ) + { + DisplayApi.SetScanOutIntensity(DisplayDevice.DisplayId, intensity, out isSticky); + } + } + + /// + /// Enables the warping of display device scan-out buffer + /// + /// The type of warping vortexes. + /// An array of warping vortexes. + /// The rectangle in desktop coordinates describing the source area for the warping. + /// A boolean value that indicates whether the settings will be kept over a reboot. + // ReSharper disable once TooManyArguments + public void EnableWarping( + WarpingVerticeFormat warpingVerticeFormat, + XYUVRQVortex[] vortices, + Rectangle textureRectangle, + out bool isSticky) + { + using ( + var warping = new ScanOutWarpingV1( + warpingVerticeFormat, + vortices.SelectMany(vortex => vortex.AsFloatArray()).ToArray(), + textureRectangle + ) + ) + { + var vorticesCount = vortices.Length; + DisplayApi.SetScanOutWarping(DisplayDevice.DisplayId, warping, ref vorticesCount, out isSticky); + } + } + + /// + /// Queries the current state of one of the various scan-out composition parameters. + /// + /// The scan-out composition parameter. + /// The additional value included with the parameter value. + /// The scan-out composition parameter value. + public ScanOutCompositionParameterValue GetCompositionParameterValue( + ScanOutCompositionParameter parameter, + out float additionalValue) + { + return DisplayApi.GetScanOutCompositionParameter(DisplayDevice.DisplayId, parameter, out additionalValue); + } + + + /// + /// Sets the current state of one of the various scan-out composition parameters. + /// + /// The scan-out composition parameter. + /// The scan-out composition parameter value. + /// The additional value included with the parameter value. + public void SetCompositionParameterValue( + ScanOutCompositionParameter parameter, + ScanOutCompositionParameterValue parameterValue, + float additionalValue) + { + DisplayApi.SetScanOutCompositionParameter(DisplayDevice.DisplayId, parameter, parameterValue, + ref additionalValue); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Display/UnAttachedDisplay.cs b/NvAPIWrapper/Display/UnAttachedDisplay.cs new file mode 100644 index 0000000..1af2c33 --- /dev/null +++ b/NvAPIWrapper/Display/UnAttachedDisplay.cs @@ -0,0 +1,150 @@ +using System; +using System.Linq; +using NvAPIWrapper.GPU; +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.Display.Structures; + +namespace NvAPIWrapper.Display +{ + /// + /// Represents an unattached display + /// + public class UnAttachedDisplay : IEquatable + { + /// + /// Creates a new UnAttachedDisplay + /// + /// Handle of the unattached display device + public UnAttachedDisplay(UnAttachedDisplayHandle handle) + { + Handle = handle; + } + + /// + /// Creates a new UnAttachedDisplay + /// + /// Name of the unattached display device + public UnAttachedDisplay(string displayName) + { + Handle = DisplayApi.GetAssociatedUnAttachedNvidiaDisplayHandle(displayName); + } + + /// + /// Gets display handle + /// + public UnAttachedDisplayHandle Handle { get; } + + /// + /// Gets display name + /// + public string Name + { + get => DisplayApi.GetUnAttachedAssociatedDisplayName(Handle); + } + + /// + /// Gets corresponding physical GPU + /// + public PhysicalGPU PhysicalGPU + { + get => new PhysicalGPU(GPUApi.GetPhysicalGPUFromUnAttachedDisplay(Handle)); + } + + /// + /// Checks for equality with a UnAttachedDisplay instance + /// + /// The Display object to check with + /// true if both objects are equal, otherwise false + public bool Equals(UnAttachedDisplay other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + return Handle.Equals(other.Handle); + } + + /// + /// This function returns all unattached NVIDIA displays + /// Note: Display handles can get invalidated on a modeset. + /// + /// An array of Display objects + public static UnAttachedDisplay[] GetUnAttachedDisplays() + { + return + DisplayApi.EnumNvidiaUnAttachedDisplayHandle().Select(handle => new UnAttachedDisplay(handle)) + .ToArray(); + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(UnAttachedDisplay left, UnAttachedDisplay right) + { + return right?.Equals(left) ?? ReferenceEquals(left, null); + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(UnAttachedDisplay left, UnAttachedDisplay right) + { + return !(left == right); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((UnAttachedDisplay) obj); + } + + /// + public override int GetHashCode() + { + return Handle.GetHashCode(); + } + + /// + public override string ToString() + { + return Name; + } + + /// + /// Creates a new active attached display from this unattached display + /// At least one GPU must be present in the system and running an NVIDIA display driver. + /// + /// An active attached display + public Display CreateDisplay() + { + return new Display(DisplayApi.CreateDisplayFromUnAttachedDisplay(Handle)); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Display/XYUVRQVortex.cs b/NvAPIWrapper/Display/XYUVRQVortex.cs new file mode 100644 index 0000000..f90a955 --- /dev/null +++ b/NvAPIWrapper/Display/XYUVRQVortex.cs @@ -0,0 +1,165 @@ +using System; +using System.Collections.Generic; + +namespace NvAPIWrapper.Display +{ + /// + /// Represents a XYUVRQ scan-out warping vortex + /// + public class XYUVRQVortex : IEquatable + { + /// + /// Creates a new instance of . + /// + /// The target view port mesh horizontal coordinate + /// The target view port mesh vertical coordinate + /// The desktop view port texture horizontal coordinate + /// The desktop view port texture vertical coordinate + /// The 3D warp perspective R factor + /// The 3D warp perspective Q factor + // ReSharper disable once TooManyDependencies + public XYUVRQVortex(int x, int y, int u, int v, float r, float q) + { + X = x; + Y = y; + U = u; + V = v; + R = r; + Q = q; + } + + /// + /// 3D warp perspective Q factor + /// + public float Q { get; } + + /// + /// 3D warp perspective R factor + /// + public float R { get; } + + /// + /// Desktop view port texture horizontal coordinate + /// + public int U { get; } + + /// + /// Desktop view port texture vertical coordinate + /// + public int V { get; } + + /// + /// Target view port mesh horizontal coordinate + /// + public int X { get; } + + /// + /// Target view port mesh vertical coordinate + /// + public int Y { get; } + + /// + public bool Equals(XYUVRQVortex other) + { + if (other == null) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + return Math.Abs(Q - other.Q) < 0.0001 && + Math.Abs(R - other.R) < 0.0001 && + U == other.U && + V == other.V && + X == other.X && + Y == other.Y; + } + + /// + /// Parses an array of floats and returns the corresponding s. + /// + /// The array of float representing one or more s. + /// Instances of . + public static IEnumerable FromFloatArray(float[] floats) + { + for (var i = 0; i + 6 <= floats.Length; i += 6) + { + yield return new XYUVRQVortex( + (int) floats[i], + (int) floats[i + 1], + (int) floats[i + 2], + (int) floats[i + 3], + floats[i + 4], + floats[i + 5] + ); + } + } + + /// + /// Compares two instance of for equality. + /// + /// The first instance. + /// The second instance. + /// if both instances are equal, otherwise + public static bool operator ==(XYUVRQVortex left, XYUVRQVortex right) + { + return Equals(left, right) || left?.Equals(right) == true; + } + + /// + /// Compares two instance of for in-equality. + /// + /// The first instance. + /// The second instance. + /// if both instances are not equal, otherwise + public static bool operator !=(XYUVRQVortex left, XYUVRQVortex right) + { + return !(left == right); + } + + /// + public override bool Equals(object obj) + { + if (obj == null) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + return Equals(obj as XYUVRQVortex); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = Q.GetHashCode(); + hashCode = (hashCode * 397) ^ R.GetHashCode(); + hashCode = (hashCode * 397) ^ U; + hashCode = (hashCode * 397) ^ V; + hashCode = (hashCode * 397) ^ X; + hashCode = (hashCode * 397) ^ Y; + + return hashCode; + } + } + + /// + /// Returns this instance of as a float array. + /// + /// An array of float values representing this instance of . + public float[] AsFloatArray() + { + return new[] {X, Y, U, V, R, Q}; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/AGPInformation.cs b/NvAPIWrapper/GPU/AGPInformation.cs new file mode 100644 index 0000000..25a8084 --- /dev/null +++ b/NvAPIWrapper/GPU/AGPInformation.cs @@ -0,0 +1,30 @@ +namespace NvAPIWrapper.GPU +{ + /// + /// Contains information about the accelerated graphics connection + /// + public class AGPInformation + { + internal AGPInformation(int aperture, int currentRate) + { + ApertureInMB = aperture; + CurrentRate = currentRate; + } + + /// + /// Gets AGP aperture in megabytes + /// + public int ApertureInMB { get; } + + /// + /// Gets current AGP Rate (0 = AGP not present, 1 = 1x, 2 = 2x, etc.) + /// + public int CurrentRate { get; } + + /// + public override string ToString() + { + return $"AGP Aperture: {ApertureInMB}MB, Current Rate: {CurrentRate}x"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/ECCMemoryInformation.cs b/NvAPIWrapper/GPU/ECCMemoryInformation.cs new file mode 100644 index 0000000..486182d --- /dev/null +++ b/NvAPIWrapper/GPU/ECCMemoryInformation.cs @@ -0,0 +1,201 @@ +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.GPU; + +namespace NvAPIWrapper.GPU +{ + /// + /// Contains information about the ECC memory + /// + public class ECCMemoryInformation + { + internal ECCMemoryInformation(PhysicalGPU physicalGPU) + { + PhysicalGPU = physicalGPU; + } + + /// + /// Gets the number of aggregated ECC memory double bit errors + /// + public ulong AggregatedDoubleBitErrors + { + get + { + if (!IsSupported || !IsEnabled) + { + return 0; + } + + return GPUApi.GetECCErrorInfo(PhysicalGPU.Handle).AggregatedErrors.DoubleBitErrors; + } + } + + + /// + /// Gets the number of aggregated ECC memory single bit errors + /// + public ulong AggregatedSingleBitErrors + { + get + { + if (!IsSupported || !IsEnabled) + { + return 0; + } + + return GPUApi.GetECCErrorInfo(PhysicalGPU.Handle).AggregatedErrors.SingleBitErrors; + } + } + + /// + /// Gets the ECC memory configuration in regard to how changes are applied + /// + public ECCConfiguration Configuration + { + get + { + try + { + return GPUApi.GetECCStatusInfo(PhysicalGPU.Handle).ConfigurationOptions; + } + catch + { + return ECCConfiguration.NotSupported; + } + } + } + + /// + /// Gets the number of current ECC memory double bit errors + /// + public ulong CurrentDoubleBitErrors + { + get + { + if (!IsSupported || !IsEnabled) + { + return 0; + } + + return GPUApi.GetECCErrorInfo(PhysicalGPU.Handle).CurrentErrors.DoubleBitErrors; + } + } + + /// + /// Gets the number of current ECC memory single bit errors + /// + public ulong CurrentSingleBitErrors + { + get + { + if (!IsSupported || !IsEnabled) + { + return 0; + } + + return GPUApi.GetECCErrorInfo(PhysicalGPU.Handle).CurrentErrors.SingleBitErrors; + } + } + + /// + /// Gets a boolean value indicating if ECC memory error correction is enabled + /// + + public bool IsEnabled + { + get => IsSupported && + GPUApi.GetECCStatusInfo(PhysicalGPU.Handle).IsEnabled && + GPUApi.GetECCConfigurationInfo(PhysicalGPU.Handle).IsEnabled; + } + + /// + /// Gets a boolean value indicating if ECC memory is enabled by default + /// + public bool IsEnabledByDefault + { + get => IsSupported && + GPUApi.GetECCConfigurationInfo(PhysicalGPU.Handle).IsEnabledByDefault; + } + + /// + /// Gets a boolean value indicating if ECC memory is supported and available + /// + public bool IsSupported + { + get + { + try + { + return GPUApi.GetECCStatusInfo(PhysicalGPU.Handle).IsSupported; + } + catch + { + return false; + } + } + } + + /// + /// Gets the physical GPU that this instance describes + /// + public PhysicalGPU PhysicalGPU { get; } + + /// + public override string ToString() + { + if (!IsSupported) + { + return "[Not Supported]"; + } + + if (!IsEnabled) + { + return "[Disabled]"; + } + + return + $"{CurrentSingleBitErrors}, {CurrentDoubleBitErrors} ({AggregatedSingleBitErrors}, {AggregatedDoubleBitErrors})"; + } + + /// + /// Clears aggregated error counters. + /// + public void ClearAggregatedErrors() + { + GPUApi.ResetECCErrorInfo(PhysicalGPU.Handle, false, true); + } + + /// + /// Clears current error counters. + /// + public void ClearCurrentErrors() + { + GPUApi.ResetECCErrorInfo(PhysicalGPU.Handle, true, false); + } + + /// + /// Clears all error counters. + /// + public void ClearErrors() + { + GPUApi.ResetECCErrorInfo(PhysicalGPU.Handle, true, true); + } + + /// + /// Disables ECC memory error correction. + /// + /// A boolean value to indicate if this change should get applied immediately + public void Disable(bool immediate) + { + GPUApi.SetECCConfiguration(PhysicalGPU.Handle, false, immediate); + } + + /// + /// Enables ECC memory error correction. + /// + /// A boolean value to indicate if this change should get applied immediately + public void Enable(bool immediate) + { + GPUApi.SetECCConfiguration(PhysicalGPU.Handle, true, immediate); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUArchitectInformation.cs b/NvAPIWrapper/GPU/GPUArchitectInformation.cs new file mode 100644 index 0000000..c489e25 --- /dev/null +++ b/NvAPIWrapper/GPU/GPUArchitectInformation.cs @@ -0,0 +1,115 @@ +using NvAPIWrapper.Native; + +namespace NvAPIWrapper.GPU +{ + /// + /// Contains physical GPU architect information + /// + public class GPUArchitectInformation + { + internal GPUArchitectInformation(PhysicalGPU physicalGPU) + { + PhysicalGPU = physicalGPU; + } + + /// + /// Gets total number of cores defined for this GPU, or zero for older architectures + /// + public int NumberOfCores + { + get => (int) GPUApi.GetGPUCoreCount(PhysicalGPU.Handle); + } + + /// + /// Gets the number of graphics processing clusters (aka GPU Partitions) + /// + public int NumberOfGPC + { + get => (int) GPUApi.GetPartitionCount(PhysicalGPU.Handle); + } + + /// + /// Gets the number of render output units + /// + public int NumberOfROPs + { + get => (int) GPUApi.GetROPCount(PhysicalGPU.Handle); + } + + /// + /// Gets the number of shader pipelines + /// + public int NumberOfShaderPipelines + { + get => (int) GPUApi.GetShaderPipeCount(PhysicalGPU.Handle); + } + + /// + /// Gets the number of shader sub pipelines + /// + public int NumberOfShaderSubPipelines + { + get => (int) GPUApi.GetShaderSubPipeCount(PhysicalGPU.Handle); + } + + /// + /// Gets the number of video processing engines + /// + public int NumberOfVPEs + { + get => (int) GPUApi.GetVPECount(PhysicalGPU.Handle); + } + + /// + /// Gets the physical GPU that this instance describes + /// + public PhysicalGPU PhysicalGPU { get; } + + /// + /// Gets the GPU revision number (should be displayed as a hex string) + /// + public int Revision + { + get => (int) GPUApi.GetArchitectInfo(PhysicalGPU.Handle).Revision; + } + + /// + /// Gets the GPU short name (aka Codename) + /// + public string ShortName + { + get => GPUApi.GetShortName(PhysicalGPU.Handle); + } + + /// + /// Gets the total number of streaming multiprocessors + /// + public int TotalNumberOfSMs + { + get => (int) GPUApi.GetTotalSMCount(PhysicalGPU.Handle); + } + + + /// + /// Gets the total number of streaming processors + /// + public int TotalNumberOfSPs + { + get => (int) GPUApi.GetTotalSPCount(PhysicalGPU.Handle); + } + + /// + /// Gets the total number of texture processing clusters + /// + public int TotalNumberOfTPCs + { + get => (int) GPUApi.GetTotalTPCCount(PhysicalGPU.Handle); + } + + /// + public override string ToString() + { + return $"[{ShortName} REV{Revision:X}] Cores: {NumberOfCores}"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUBusInformation.cs b/NvAPIWrapper/GPU/GPUBusInformation.cs new file mode 100644 index 0000000..4e47776 --- /dev/null +++ b/NvAPIWrapper/GPU/GPUBusInformation.cs @@ -0,0 +1,118 @@ +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.GPU; + +namespace NvAPIWrapper.GPU +{ + /// + /// Contains information about the GPU bus + /// + public class GPUBusInformation + { + internal GPUBusInformation(PhysicalGPU physicalGPU) + { + PhysicalGPU = physicalGPU; + } + + /// + /// Gets accelerated graphics port information + /// + public AGPInformation AGPInformation + { + get + { + if (BusType != GPUBusType.AGP) + { + return null; + } + + return new AGPInformation( + GPUApi.GetAGPAperture(PhysicalGPU.Handle), + GPUApi.GetCurrentAGPRate(PhysicalGPU.Handle) + ); + } + } + + /// + /// Gets the bus identification + /// + public int BusId + { + get => GPUApi.GetBusId(PhysicalGPU.Handle); + } + + /// + /// Gets the bus slot identification + /// + public int BusSlot + { + get => GPUApi.GetBusSlotId(PhysicalGPU.Handle); + } + + /// + /// Gets the the bus type + /// + public GPUBusType BusType + { + get => GPUApi.GetBusType(PhysicalGPU.Handle); + } + + /// + /// Gets number of PCIe lanes being used for the PCIe interface downstream + /// + public int CurrentPCIeLanes + { + get + { + if (BusType == GPUBusType.PCIExpress) + { + return GPUApi.GetCurrentPCIEDownStreamWidth(PhysicalGPU.Handle); + } + + return 0; + } + } + + /// + /// Gets GPU interrupt number + /// + public int IRQ + { + get => GPUApi.GetIRQ(PhysicalGPU.Handle); + } + + /// + /// Gets the PCI identifiers + /// + public PCIIdentifiers PCIIdentifiers + { + get + { + if (BusType == GPUBusType.FPCI || BusType == GPUBusType.PCI || BusType == GPUBusType.PCIExpress) + { + GPUApi.GetPCIIdentifiers( + PhysicalGPU.Handle, + out var deviceId, + out var subSystemId, + out var revisionId, + out var extDeviceId + ); + + return new PCIIdentifiers(deviceId, subSystemId, revisionId, (int) extDeviceId); + } + + return null; + } + } + + /// + /// Gets the physical GPU that this instance describes + /// + public PhysicalGPU PhysicalGPU { get; } + + /// + public override string ToString() + { + return $"[{BusType}] Bus #{BusId}, Slot #{BusSlot}"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUCooler.cs b/NvAPIWrapper/GPU/GPUCooler.cs new file mode 100644 index 0000000..86d6816 --- /dev/null +++ b/NvAPIWrapper/GPU/GPUCooler.cs @@ -0,0 +1,130 @@ +using System; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; + +namespace NvAPIWrapper.GPU +{ + /// + /// Holds information regarding a GPU cooler entry + /// + public class GPUCooler + { + internal GPUCooler(int coolerId, PrivateCoolerSettingsV1.CoolerSetting coolerSetting, int currentRPM = -1) + { + CoolerId = coolerId; + CurrentLevel = (int) coolerSetting.CurrentLevel; + DefaultMinimumLevel = (int) coolerSetting.DefaultMinimumLevel; + DefaultMaximumLevel = (int) coolerSetting.DefaultMaximumLevel; + CurrentMinimumLevel = (int) coolerSetting.CurrentMinimumLevel; + CurrentMaximumLevel = (int) coolerSetting.CurrentMaximumLevel; + CoolerType = coolerSetting.CoolerType; + CoolerController = coolerSetting.CoolerController; + DefaultPolicy = coolerSetting.DefaultPolicy; + CurrentPolicy = coolerSetting.CurrentPolicy; + Target = coolerSetting.Target; + ControlMode = coolerSetting.ControlMode; + CurrentFanSpeedInRPM = currentRPM; + } + + // ReSharper disable once TooManyDependencies + internal GPUCooler( + PrivateFanCoolersInfoV1.FanCoolersInfoEntry infoEntry, + PrivateFanCoolersStatusV1.FanCoolersStatusEntry statusEntry, + PrivateFanCoolersControlV1.FanCoolersControlEntry controlEntry) + { + if (infoEntry.CoolerId != statusEntry.CoolerId || statusEntry.CoolerId != controlEntry.CoolerId) + { + throw new ArgumentException("Passed arguments are meant to be for different coolers."); + } + + CoolerId = (int) statusEntry.CoolerId; + CurrentLevel = (int) statusEntry.CurrentLevel; + DefaultMinimumLevel = (int) statusEntry.CurrentMinimumLevel; + DefaultMaximumLevel = (int) statusEntry.CurrentMaximumLevel; + CurrentMinimumLevel = (int) statusEntry.CurrentMinimumLevel; + CurrentMaximumLevel = (int) statusEntry.CurrentMaximumLevel; + CoolerType = CoolerType.Fan; + CoolerController = CoolerController.Internal; + DefaultPolicy = CoolerPolicy.None; + CurrentPolicy = controlEntry.ControlMode == FanCoolersControlMode.Manual + ? CoolerPolicy.Manual + : CoolerPolicy.None; + Target = CoolerTarget.All; + ControlMode = CoolerControlMode.Variable; + CurrentFanSpeedInRPM = (int) statusEntry.CurrentRPM; + } + + /// + /// Gets the cooler control mode + /// + public CoolerControlMode ControlMode { get; } + + /// + /// Gets the cooler controller + /// + public CoolerController CoolerController { get; } + + /// + /// Gets the cooler identification number or index + /// + public int CoolerId { get; } + + /// + /// Gets the cooler type + /// + public CoolerType CoolerType { get; } + + /// + /// Gets the GPU fan speed in revolutions per minute + /// + public int CurrentFanSpeedInRPM { get; } + + /// + /// Gets the cooler current level in percentage + /// + public int CurrentLevel { get; } + + + /// + /// Gets the cooler current maximum level in percentage + /// + public int CurrentMaximumLevel { get; } + + + /// + /// Gets the cooler current minimum level in percentage + /// + public int CurrentMinimumLevel { get; } + + /// + /// Gets the cooler current policy + /// + public CoolerPolicy CurrentPolicy { get; } + + /// + /// Gets the cooler default maximum level in percentage + /// + public int DefaultMaximumLevel { get; } + + /// + /// Gets the cooler default minimum level in percentage + /// + public int DefaultMinimumLevel { get; } + + /// + /// Gets the cooler default policy + /// + public CoolerPolicy DefaultPolicy { get; } + + /// + /// Gets the cooler target + /// + public CoolerTarget Target { get; } + + /// + public override string ToString() + { + return $"[{CoolerId} @ {CoolerController}] {Target}: {CurrentLevel}%"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUCoolerInformation.cs b/NvAPIWrapper/GPU/GPUCoolerInformation.cs new file mode 100644 index 0000000..9be8cc8 --- /dev/null +++ b/NvAPIWrapper/GPU/GPUCoolerInformation.cs @@ -0,0 +1,340 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; + +namespace NvAPIWrapper.GPU +{ + /// + /// Contains information about the GPU coolers and current fan speed + /// + public class GPUCoolerInformation + { + internal GPUCoolerInformation(PhysicalGPU physicalGPU) + { + PhysicalGPU = physicalGPU; + + // TODO: Add Support For Pascal Only Policy Table Method + // TODO: GPUApi.GetCoolerPolicyTable & GPUApi.SetCoolerPolicyTable & GPUApi.RestoreCoolerPolicyTable + // TODO: Better support of ClientFanCoolers set of APIs + } + + /// + /// Gets a list of all available coolers along with their current settings and status + /// + public IEnumerable Coolers + { + get + { + PrivateCoolerSettingsV1? settings = null; + + try + { + settings = GPUApi.GetCoolerSettings(PhysicalGPU.Handle); + } + catch (NVIDIAApiException e) + { + if (e.Status != Status.NotSupported) + { + throw; + } + } + + if (settings != null) + { + for (var i = 0; i < settings.Value.CoolerSettings.Length; i++) + { + if (i == 0) + { + var currentRPM = -1; + try + { + currentRPM = (int)GPUApi.GetTachReading(PhysicalGPU.Handle); + } + catch (NVIDIAApiException) + { + // ignored + } + + if (currentRPM >= 0) + { + yield return new GPUCooler( + i, + settings.Value.CoolerSettings[i], + currentRPM + ); + continue; + } + } + + yield return new GPUCooler( + i, + settings.Value.CoolerSettings[i] + ); + } + + yield break; + } + + PrivateFanCoolersStatusV1? status = null; + PrivateFanCoolersInfoV1? info = null; + PrivateFanCoolersControlV1? control = null; + + try + { + status = GPUApi.GetClientFanCoolersStatus(PhysicalGPU.Handle); + info = GPUApi.GetClientFanCoolersInfo(PhysicalGPU.Handle); + control = GPUApi.GetClientFanCoolersControl(PhysicalGPU.Handle); + } + catch (NVIDIAApiException e) + { + if (e.Status != Status.NotSupported) + { + throw; + } + } + + if (status != null && info != null && control != null) + { + for (var i = 0; i < status.Value.FanCoolersStatusEntries.Length; i++) + { + if (info.Value.FanCoolersInfoEntries.Length > i && + control.Value.FanCoolersControlEntries.Length > i) + { + yield return new GPUCooler( + info.Value.FanCoolersInfoEntries[i], + status.Value.FanCoolersStatusEntries[i], + control.Value.FanCoolersControlEntries[i] + ); + } + } + + yield break; + } + + throw new NVIDIAApiException(Status.NotSupported); + } + } + + /// + /// Gets the GPU fan speed in revolutions per minute + /// + public int CurrentFanSpeedInRPM + { + get + { + try + { + return (int) GPUApi.GetTachReading(PhysicalGPU.Handle); + } + catch + { + return Coolers.FirstOrDefault(cooler => cooler.Target == CoolerTarget.All)?.CurrentFanSpeedInRPM ?? + 0; + } + } + } + + /// + /// Gets the current fan speed in percentage if available + /// + public int CurrentFanSpeedLevel + { + get + { + try + { + return (int) GPUApi.GetCurrentFanSpeedLevel(PhysicalGPU.Handle); + } + catch + { + return Coolers.FirstOrDefault(cooler => cooler.Target == CoolerTarget.All)?.CurrentLevel ?? 0; + } + } + } + + /// + /// Gets the physical GPU that this instance describes + /// + public PhysicalGPU PhysicalGPU { get; } + + /// + public override string ToString() + { + return $"{CurrentFanSpeedInRPM} RPM ({CurrentFanSpeedLevel}%)"; + } + + /// + /// Resets all cooler settings to default. + /// + public void RestoreCoolerSettingsToDefault() + { + RestoreCoolerSettingsToDefault(Coolers.Select(cooler => cooler.CoolerId).ToArray()); + } + + /// + /// Resets one or more cooler settings to default. + /// + /// The cooler identification numbers (indexes) to reset their settings to default. + public void RestoreCoolerSettingsToDefault(params int[] coolerIds) + { + var availableCoolerIds = Coolers.Select(cooler => cooler.CoolerId).ToArray(); + + if (coolerIds.Any(i => !availableCoolerIds.Contains(i))) + { + throw new ArgumentException("Invalid cooler identification number provided.", nameof(coolerIds)); + } + + try + { + GPUApi.RestoreCoolerSettings(PhysicalGPU.Handle, coolerIds.Select(i => (uint) i).ToArray()); + + return; + } + catch (NVIDIAApiException e) + { + if (e.Status != Status.NotSupported) + { + throw; + } + } + + var currentControl = GPUApi.GetClientFanCoolersControl(PhysicalGPU.Handle); + var newControl = new PrivateFanCoolersControlV1( + currentControl.FanCoolersControlEntries.Select( + entry => coolerIds.Contains((int) entry.CoolerId) + ? new PrivateFanCoolersControlV1.FanCoolersControlEntry( + entry.CoolerId, + FanCoolersControlMode.Auto + ) + : entry + ) + .ToArray(), + currentControl.UnknownUInt + ); + GPUApi.SetClientFanCoolersControl(PhysicalGPU.Handle, newControl); + } + + /// + /// Changes a cooler settings by modifying the policy and the current level + /// + /// The cooler identification number (index) to change the settings. + /// The new cooler policy. + /// The new cooler level. Valid only if policy is set to manual. + // ReSharper disable once TooManyDeclarations + public void SetCoolerSettings(int coolerId, CoolerPolicy policy, int newLevel) + { + if (Coolers.All(cooler => cooler.CoolerId != coolerId)) + { + throw new ArgumentException("Invalid cooler identification number provided.", nameof(coolerId)); + } + + try + { + GPUApi.SetCoolerLevels( + PhysicalGPU.Handle, + (uint) coolerId, + new PrivateCoolerLevelsV1(new[] + { + new PrivateCoolerLevelsV1.CoolerLevel(policy, (uint) newLevel) + } + ), + 1 + ); + + return; + } + catch (NVIDIAApiException e) + { + if (e.Status != Status.NotSupported) + { + throw; + } + } + + var currentControl = GPUApi.GetClientFanCoolersControl(PhysicalGPU.Handle); + var newControl = new PrivateFanCoolersControlV1( + currentControl.FanCoolersControlEntries.Select( + entry => entry.CoolerId == coolerId + ? new PrivateFanCoolersControlV1.FanCoolersControlEntry( + entry.CoolerId, + policy == CoolerPolicy.Manual + ? FanCoolersControlMode.Manual + : FanCoolersControlMode.Auto, + policy == CoolerPolicy.Manual ? (uint)newLevel : 0u) + : entry + ) + .ToArray(), + currentControl.UnknownUInt + ); + GPUApi.SetClientFanCoolersControl(PhysicalGPU.Handle, newControl); + } + + /// + /// Changes a cooler setting by modifying the policy + /// + /// The cooler identification number (index) to change the settings. + /// The new cooler policy. + // ReSharper disable once TooManyDeclarations + public void SetCoolerSettings(int coolerId, CoolerPolicy policy) + { + if (Coolers.All(cooler => cooler.CoolerId != coolerId)) + { + throw new ArgumentException("Invalid cooler identification number provided.", nameof(coolerId)); + } + + try + { + GPUApi.SetCoolerLevels( + PhysicalGPU.Handle, + (uint) coolerId, + new PrivateCoolerLevelsV1(new[] + { + new PrivateCoolerLevelsV1.CoolerLevel(policy) + } + ), + 1 + ); + + return; + } + catch (NVIDIAApiException e) + { + if (e.Status != Status.NotSupported) + { + throw; + } + } + + var currentControl = GPUApi.GetClientFanCoolersControl(PhysicalGPU.Handle); + var newControl = new PrivateFanCoolersControlV1( + currentControl.FanCoolersControlEntries.Select( + entry => entry.CoolerId == coolerId + ? new PrivateFanCoolersControlV1.FanCoolersControlEntry( + entry.CoolerId, + policy == CoolerPolicy.Manual + ? FanCoolersControlMode.Manual + : FanCoolersControlMode.Auto) + : entry + ) + .ToArray(), + currentControl.UnknownUInt + ); + GPUApi.SetClientFanCoolersControl(PhysicalGPU.Handle, newControl); + } + + /// + /// Changes a cooler settings by modifying the policy to manual and sets a new level + /// + /// The cooler identification number (index) to change the settings. + /// The new cooler level. + public void SetCoolerSettings(int coolerId, int newLevel) + { + SetCoolerSettings(coolerId, CoolerPolicy.Manual, newLevel); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUMemoryInformation.cs b/NvAPIWrapper/GPU/GPUMemoryInformation.cs new file mode 100644 index 0000000..468b1e2 --- /dev/null +++ b/NvAPIWrapper/GPU/GPUMemoryInformation.cs @@ -0,0 +1,232 @@ +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.Interfaces.GPU; +using System; + +namespace NvAPIWrapper.GPU +{ + /// + /// Contains information regarding the available and total memory as well as the type of memory and other information + /// regarding the GPU RAM and frame buffer + /// + public class GPUMemoryInformation : IDisplayDriverMemoryInfo + { + internal GPUMemoryInformation(PhysicalGPU physicalGPU) + { + PhysicalGPU = physicalGPU; + } + + /// + /// Gets the frame buffer bandwidth + /// + + public int FrameBufferBandwidth + { + get + { + GPUApi.GetFrameBufferWidthAndLocation(PhysicalGPU.Handle, out var width, out _); + + return (int)width; + } + } + + /// + /// Gets the frame buffer location index + /// + public int FrameBufferLocation + { + get + { + GPUApi.GetFrameBufferWidthAndLocation(PhysicalGPU.Handle, out _, out var location); + + return (int)location; + } + } + + /// + /// Gets the internal clock to bus clock factor based on the type of RAM + /// + public int InternalClockToBusClockFactor + { + get => GetMemoryBusClockFactor(RAMType); + } + + /// + /// Gets the internal clock to transfer rate factor based on the type of RAM + /// + public int InternalClockToTransferRateFactor + { + get => GetMemoryTransferRateFactor(RAMType); + } + + /// + /// Gets GPU physical frame buffer size in KB. This does NOT include any system RAM that may be dedicated for use by + /// the GPU. + /// + public int PhysicalFrameBufferSizeInkB + { + get => GPUApi.GetPhysicalFrameBufferSize(PhysicalGPU.Handle); + } + + /// + /// Gets the physical GPU that this instance describes + /// + public PhysicalGPU PhysicalGPU { get; } + + /// + /// Gets the number of memory banks + /// + public uint RAMBanks + { + get => GPUApi.GetRAMBankCount(PhysicalGPU.Handle); + } + + /// + /// Gets the memory bus width + /// + public uint RAMBusWidth + { + get => GPUApi.GetRAMBusWidth(PhysicalGPU.Handle); + } + + /// + /// Gets the memory maker (brand) + /// + public GPUMemoryMaker RAMMaker + { + get => GPUApi.GetRAMMaker(PhysicalGPU.Handle); + } + + /// + /// Gets the memory type + /// + public GPUMemoryType RAMType + { + get => GPUApi.GetRAMType(PhysicalGPU.Handle); + } + + /// + /// Gets virtual size of frame-buffer in KB for this GPU. This includes the physical RAM plus any system RAM that has + /// been dedicated for use by the GPU. + /// + public int VirtualFrameBufferSizeInkB + { + get => GPUApi.GetVirtualFrameBufferSize(PhysicalGPU.Handle); + } + + /// + public uint AvailableDedicatedVideoMemoryInkB + { + get => GPUApi.GetMemoryInfo(PhysicalGPU.Handle).AvailableDedicatedVideoMemoryInkB; + } + + /// + public uint CurrentAvailableDedicatedVideoMemoryInkB + { + get => GPUApi.GetMemoryInfo(PhysicalGPU.Handle).CurrentAvailableDedicatedVideoMemoryInkB; + } + + /// + public uint DedicatedVideoMemoryInkB + { + get => GPUApi.GetMemoryInfo(PhysicalGPU.Handle).DedicatedVideoMemoryInkB; + } + + /// + public uint SharedSystemMemoryInkB + { + get => GPUApi.GetMemoryInfo(PhysicalGPU.Handle).SharedSystemMemoryInkB; + } + + /// + public uint SystemVideoMemoryInkB + { + get => GPUApi.GetMemoryInfo(PhysicalGPU.Handle).SystemVideoMemoryInkB; + } + + /// + /// Gets the memory bus clock to internal memory clock factor + /// + /// + /// The value of X in X(InternalMemoryClock)=(BusMemoryClock) + public static int GetMemoryBusClockFactor(GPUMemoryType memoryType) + { + switch (memoryType) + { + case GPUMemoryType.SDRAM: + + // Bus Clocks Per Internal Clock = 1 + return 1; + case GPUMemoryType.DDR1: + case GPUMemoryType.DDR2: + case GPUMemoryType.DDR3: + case GPUMemoryType.GDDR2: + case GPUMemoryType.GDDR3: + case GPUMemoryType.GDDR4: + case GPUMemoryType.LPDDR2: + case GPUMemoryType.GDDR5: + case GPUMemoryType.GDDR5X: + case GPUMemoryType.GDDR6: + case GPUMemoryType.GDDR6X: + + // Bus Clocks Per Internal Clock = 2 + return 2; + default: + + throw new ArgumentOutOfRangeException(nameof(memoryType)); + } + } + + /// + /// Gets the number of transfers per internal memory clock factor + /// + /// + /// The value of X in X(InternalMemoryClock)=(OperationsPerSecond) + public static int GetMemoryTransferRateFactor(GPUMemoryType memoryType) + { + switch (memoryType) + { + case GPUMemoryType.SDRAM: + + // Transfers Per Internal Clock = 1 + return 1; + case GPUMemoryType.DDR1: + case GPUMemoryType.DDR2: + case GPUMemoryType.DDR3: + case GPUMemoryType.GDDR2: + case GPUMemoryType.GDDR3: + case GPUMemoryType.GDDR4: + case GPUMemoryType.LPDDR2: + + // Transfers Per Internal Clock = 1 + return 2; + case GPUMemoryType.GDDR5: + + // Transfers Per Internal Clock = 2 + return 4; + case GPUMemoryType.GDDR5X: + + // Transfers Per Internal Clock = 4 + return 8; + case GPUMemoryType.GDDR6: + + // Transfers Per Internal Clock = 2 + return 4; + case GPUMemoryType.GDDR6X: + + // Transfers Per Internal Clock = 4 + return 8; + default: + + throw new ArgumentOutOfRangeException(nameof(memoryType)); + } + } + + /// + public override string ToString() + { + return + $"[{RAMMaker} {RAMType}] Total: {AvailableDedicatedVideoMemoryInkB:N0} kB - Available: {CurrentAvailableDedicatedVideoMemoryInkB:N0} kB"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUOutput.cs b/NvAPIWrapper/GPU/GPUOutput.cs new file mode 100644 index 0000000..c9fb3b0 --- /dev/null +++ b/NvAPIWrapper/GPU/GPUOutput.cs @@ -0,0 +1,264 @@ +using System; +using NvAPIWrapper.Display; +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; + +namespace NvAPIWrapper.GPU +{ + /// + /// Represents a single GPU output + /// + public class GPUOutput : IEquatable + { + internal GPUOutput(OutputId outputId, PhysicalGPUHandle gpuHandle) + { + OutputId = outputId; + OutputType = !gpuHandle.IsNull ? GPUApi.GetOutputType(gpuHandle, outputId) : OutputType.Unknown; + PhysicalGPU = new PhysicalGPU(gpuHandle); + } + + internal GPUOutput(OutputId outputId, PhysicalGPU gpu) + : this(outputId, gpu?.Handle ?? PhysicalGPUHandle.DefaultHandle) + { + PhysicalGPU = gpu; + } + + /// + /// Gets the corresponding Digital Vibrance Control information + /// + public DVCInformation DigitalVibranceControl + { + get => new DVCInformation(OutputId); + } + + /// + /// Gets the corresponding HUE information + /// + public HUEInformation HUEControl + { + get => new HUEInformation(OutputId); + } + + /// + /// Gets the output identification as a single bit unsigned integer + /// + public OutputId OutputId { get; } + + /// + /// Gets the output type + /// + public OutputType OutputType { get; } + + /// + /// Gets the corresponding physical GPU + /// + public PhysicalGPU PhysicalGPU { get; } + + /// + public bool Equals(GPUOutput other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + return PhysicalGPU.Equals(other.PhysicalGPU) && OutputId == other.OutputId; + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(GPUOutput left, GPUOutput right) + { + return right?.Equals(left) ?? ReferenceEquals(left, null); + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(GPUOutput left, GPUOutput right) + { + return !(left == right); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((GPUOutput) obj); + } + + /// + public override int GetHashCode() + { + unchecked + { + return ((PhysicalGPU != null ? PhysicalGPU.GetHashCode() : 0) * 397) ^ (int) OutputId; + } + } + + /// + public override string ToString() + { + return $"{OutputId} {OutputType} @ {PhysicalGPU}"; + } + + /// + /// Overrides the refresh rate on this output. + /// The new refresh rate can be applied right away or deferred to be applied with the next OS + /// mode-set. + /// The override is good for only one mode-set (regardless whether it's deferred or immediate). + /// + /// The refresh rate to be applied. + /// + /// A boolean value indicating if the refresh rate override should be deferred to the next OS + /// mode-set. + /// + public void OverrideRefreshRate(float refreshRate, bool isDeferred = false) + { + DisplayApi.SetRefreshRateOverride(OutputId, refreshRate, isDeferred); + } + + /// + /// Reads data from the I2C bus + /// + /// The port id on which device is connected + /// A boolean value indicating that the DDC port should be used instead of the communication port + /// The device I2C slave address + /// The target I2C register address + /// The length of the buffer to allocate for the read operation. + /// The target speed of the transaction in kHz + public byte[] ReadI2C( + byte? portId, + bool useDDCPort, + byte deviceAddress, + byte[] registerAddress, + uint readDataLength, + I2CSpeed speed = I2CSpeed.Default + ) + { + try + { + // ReSharper disable once InconsistentNaming + var i2cInfoV3 = new I2CInfoV3( + OutputId, + portId, + useDDCPort, + deviceAddress, + registerAddress, + readDataLength, + speed + ); + + return PhysicalGPU.ReadI2C(i2cInfoV3); + } + catch (NVIDIAApiException e) + { + if (e.Status != Status.IncompatibleStructureVersion || portId != null) + { + throw; + } + + // ignore + } + + // ReSharper disable once InconsistentNaming + var i2cInfoV2 = new I2CInfoV2( + OutputId, + useDDCPort, + deviceAddress, + registerAddress, + readDataLength, + speed + ); + + return PhysicalGPU.ReadI2C(i2cInfoV2); + } + + /// + /// Writes data to the I2C bus + /// + /// The port id on which device is connected + /// A boolean value indicating that the DDC port should be used instead of the communication port + /// The device I2C slave address + /// The target I2C register address + /// The payload data + /// The target speed of the transaction in kHz + public void WriteI2C( + byte? portId, + bool useDDCPort, + byte deviceAddress, + byte[] registerAddress, + byte[] data, + I2CSpeed speed = I2CSpeed.Default + ) + { + try + { + // ReSharper disable once InconsistentNaming + var i2cInfoV3 = new I2CInfoV3( + OutputId, + portId, + useDDCPort, + deviceAddress, + registerAddress, + data, + speed + ); + + PhysicalGPU.WriteI2C(i2cInfoV3); + + return; + } + catch (NVIDIAApiException e) + { + if (e.Status != Status.IncompatibleStructureVersion || portId != null) + { + throw; + } + + // ignore + } + + // ReSharper disable once InconsistentNaming + var i2cInfoV2 = new I2CInfoV2( + OutputId, + useDDCPort, + deviceAddress, + registerAddress, + data, + speed + ); + + PhysicalGPU.WriteI2C(i2cInfoV2); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUPerformanceControl.cs b/NvAPIWrapper/GPU/GPUPerformanceControl.cs new file mode 100644 index 0000000..6174cf8 --- /dev/null +++ b/NvAPIWrapper/GPU/GPUPerformanceControl.cs @@ -0,0 +1,124 @@ +using System.Collections.Generic; +using System.Linq; +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.GPU; + +namespace NvAPIWrapper.GPU +{ + /// + /// Contains information regarding the GPU performance control and limitations + /// + public class GPUPerformanceControl + { + internal GPUPerformanceControl(PhysicalGPU physicalGPU) + { + PhysicalGPU = physicalGPU; + } + + /// + /// Gets the current active performance limitation + /// + public PerformanceLimit CurrentActiveLimit + { + get => GPUApi.PerformancePoliciesGetStatus(PhysicalGPU.Handle).PerformanceLimit; + } + + /// + /// Gets the current performance decrease reason + /// + public PerformanceDecreaseReason CurrentPerformanceDecreaseReason + { + get => GPUApi.GetPerformanceDecreaseInfo(PhysicalGPU.Handle); + } + + + /// + /// Gets a boolean value indicating if no load limit is supported with this GPU + /// + public bool IsNoLoadLimitSupported + { + get => GPUApi.PerformancePoliciesGetInfo(PhysicalGPU.Handle).IsNoLoadLimitSupported; + } + + + /// + /// Gets a boolean value indicating if power limit is supported with this GPU + /// + public bool IsPowerLimitSupported + { + get => GPUApi.PerformancePoliciesGetInfo(PhysicalGPU.Handle).IsPowerLimitSupported; + } + + + /// + /// Gets a boolean value indicating if temperature limit is supported with this GPU + /// + public bool IsTemperatureLimitSupported + { + get => GPUApi.PerformancePoliciesGetInfo(PhysicalGPU.Handle).IsTemperatureLimitSupported; + } + + /// + /// Gets a boolean value indicating if voltage limit is supported with this GPU + /// + public bool IsVoltageLimitSupported + { + get => GPUApi.PerformancePoliciesGetInfo(PhysicalGPU.Handle).IsVoltageLimitSupported; + } + + /// + /// Gets the physical GPU that this instance describes + /// + public PhysicalGPU PhysicalGPU { get; } + + /// + /// Gets information regarding possible power limit policies and their acceptable range + /// + public IEnumerable PowerLimitInformation + { + get + { + return GPUApi.ClientPowerPoliciesGetInfo(PhysicalGPU.Handle).PowerPolicyInfoEntries + .Select(entry => new GPUPowerLimitInfo(entry)); + } + } + + /// + /// Gets the current active power limit policies + /// + public IEnumerable PowerLimitPolicies + { + get + { + // TODO: GPUApi.ClientPowerPoliciesSetStatus(); + return GPUApi.ClientPowerPoliciesGetStatus(PhysicalGPU.Handle).PowerPolicyStatusEntries + .Select(entry => new GPUPowerLimitPolicy(entry)); + } + } + + /// + /// Gets information regarding possible thermal limit policies and their acceptable range + /// + public IEnumerable ThermalLimitInformation + { + get + { + return GPUApi.GetThermalPoliciesInfo(PhysicalGPU.Handle).ThermalPoliciesInfoEntries + .Select(entry => new GPUThermalLimitInfo(entry)); + } + } + + /// + /// Gets the current active thermal limit policies + /// + public IEnumerable ThermalLimitPolicies + { + get + { + // TODO: GPUApi.SetThermalPoliciesStatus(); + return GPUApi.GetThermalPoliciesStatus(PhysicalGPU.Handle).ThermalPoliciesStatusEntries + .Select(entry => new GPUThermalLimitPolicy(entry)); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUPerformanceState.cs b/NvAPIWrapper/GPU/GPUPerformanceState.cs new file mode 100644 index 0000000..8344dad --- /dev/null +++ b/NvAPIWrapper/GPU/GPUPerformanceState.cs @@ -0,0 +1,70 @@ +using System.Linq; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.GPU +{ + /// + /// Represents a performance state + /// + public class GPUPerformanceState + { + // ReSharper disable once TooManyDependencies + internal GPUPerformanceState( + int index, + IPerformanceState20 performanceState, + IPerformanceStates20ClockEntry[] statesClockEntries, + IPerformanceStates20VoltageEntry[] baseVoltageEntries, + PCIeInformation pcieInformation) + { + StateIndex = index; + StateId = performanceState.StateId; + IsReadOnly = !performanceState.IsEditable; + Clocks = statesClockEntries.Select(entry => new GPUPerformanceStateClock(entry)).ToArray(); + Voltages = baseVoltageEntries.Select(entry => new GPUPerformanceStateVoltage(entry)).ToArray(); + PCIeInformation = pcieInformation; + } + + /// + /// Gets a list of clocks associated with this performance state + /// + + public GPUPerformanceStateClock[] Clocks { get; } + + /// + /// Gets a boolean value indicating if this performance state is readonly + /// + public bool IsReadOnly { get; } + + /// + /// Gets the PCI-e information regarding this performance state. + /// + public PCIeInformation PCIeInformation { get; } + + /// + /// Gets the performance state identification + /// + public PerformanceStateId StateId { get; } + + /// + /// Gets the state index + /// + public int StateIndex { get; } + + /// + /// Gets a list of voltages associated with this performance state + /// + public GPUPerformanceStateVoltage[] Voltages { get; } + + /// + public override string ToString() + { + if (IsReadOnly) + { + return $"{StateId} (ReadOnly)"; + } + + return StateId.ToString(); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUPerformanceStateClock.cs b/NvAPIWrapper/GPU/GPUPerformanceStateClock.cs new file mode 100644 index 0000000..e8afe07 --- /dev/null +++ b/NvAPIWrapper/GPU/GPUPerformanceStateClock.cs @@ -0,0 +1,99 @@ +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.GPU +{ + /// + /// Represents a performance state clock settings + /// + public class GPUPerformanceStateClock + { + internal GPUPerformanceStateClock(IPerformanceStates20ClockEntry states20ClockEntry) + { + ClockDomain = states20ClockEntry.DomainId; + IsReadOnly = !states20ClockEntry.IsEditable; + ClockDeltaInkHz = states20ClockEntry.FrequencyDeltaInkHz.DeltaValue; + ClockDeltaRangeInkHz = new GPUPerformanceStateValueRange( + states20ClockEntry.FrequencyDeltaInkHz.DeltaRange.Minimum, + states20ClockEntry.FrequencyDeltaInkHz.DeltaRange.Maximum + ); + + if (states20ClockEntry.ClockType == PerformanceStates20ClockType.Range) + { + CurrentClockInkHz = new GPUPerformanceStateValueRange( + states20ClockEntry.FrequencyRange.MinimumFrequencyInkHz, + states20ClockEntry.FrequencyRange.MaximumFrequencyInkHz + ); + BaseClockInkHz = new GPUPerformanceStateValueRange( + CurrentClockInkHz.Minimum - ClockDeltaInkHz, + CurrentClockInkHz.Maximum - ClockDeltaInkHz + ); + DependentVoltageDomain = states20ClockEntry.FrequencyRange.VoltageDomainId; + DependentVoltageRangeInMicroVolt = new GPUPerformanceStateValueRange( + states20ClockEntry.FrequencyRange.MinimumVoltageInMicroVolt, + states20ClockEntry.FrequencyRange.MaximumVoltageInMicroVolt + ); + } + else + { + CurrentClockInkHz = new GPUPerformanceStateValueRange( + states20ClockEntry.SingleFrequency.FrequencyInkHz + ); + BaseClockInkHz = new GPUPerformanceStateValueRange( + CurrentClockInkHz.Minimum - ClockDeltaInkHz + ); + DependentVoltageDomain = PerformanceVoltageDomain.Undefined; + DependentVoltageRangeInMicroVolt = null; + } + } + + /// + /// Gets the base clock frequency in kHz + /// + public GPUPerformanceStateValueRange BaseClockInkHz { get; } + + /// + /// Gets the clock frequency delta in kHz + /// + public int ClockDeltaInkHz { get; } + + /// + /// Gets the clock frequency delta range in kHz + /// + public GPUPerformanceStateValueRange ClockDeltaRangeInkHz { get; } + + /// + /// Gets the clock domain + /// + public PublicClockDomain ClockDomain { get; } + + /// + /// Gets the current clock frequency in kHz + /// + public GPUPerformanceStateValueRange CurrentClockInkHz { get; } + + /// + /// Gets the dependent voltage domain + /// + public PerformanceVoltageDomain DependentVoltageDomain { get; } + + /// + /// Gets the dependent voltage range in uV + /// + public GPUPerformanceStateValueRange DependentVoltageRangeInMicroVolt { get; } + + /// + /// Gets a boolean value indicating if this clock setting is readonly + /// + public bool IsReadOnly { get; } + + /// + public override string ToString() + { + var title = IsReadOnly ? $"{ClockDomain} (ReadOnly)" : ClockDomain.ToString(); + + return + $"{title}: {BaseClockInkHz} + ({ClockDeltaInkHz}) = {CurrentClockInkHz}"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUPerformanceStateValueRange.cs b/NvAPIWrapper/GPU/GPUPerformanceStateValueRange.cs new file mode 100644 index 0000000..c396575 --- /dev/null +++ b/NvAPIWrapper/GPU/GPUPerformanceStateValueRange.cs @@ -0,0 +1,115 @@ +using System; + +namespace NvAPIWrapper.GPU +{ + /// + /// Represents an integer value range + /// + public class GPUPerformanceStateValueRange : IEquatable + { + /// + /// Creates a new instance of . + /// + /// The lower bound of the range. + /// The upper bound of the range. + public GPUPerformanceStateValueRange(long min, long max) + { + Minimum = min; + Maximum = max; + } + + /// + /// Creates a new single value instance of . + /// + /// The only value in the range + public GPUPerformanceStateValueRange(long value) + { + Minimum = value; + Maximum = value; + } + + /// + /// Gets the upper bound of the inclusive range + /// + public long Maximum { get; } + + /// + /// Gets the lower bound of the inclusive range + /// + public long Minimum { get; } + + /// + public bool Equals(GPUPerformanceStateValueRange other) + { + if (other == null) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + return Maximum == other.Maximum && Minimum == other.Minimum; + } + + /// + /// Checks two instances of for equality. + /// + /// The left side of the comparison. + /// The right side of the comparison. + /// true if instances are equal, otherwise false + public static bool operator ==(GPUPerformanceStateValueRange left, GPUPerformanceStateValueRange right) + { + return Equals(left, right) || left?.Equals(right) == true; + } + + /// + /// Checks two instances of for inequality. + /// + /// The left side of the comparison. + /// The right side of the comparison. + /// true if instances are in-equal, otherwise false + public static bool operator !=(GPUPerformanceStateValueRange left, GPUPerformanceStateValueRange right) + { + return !(left == right); + } + + /// + public override bool Equals(object obj) + { + if (obj == null) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + return Equals(obj as GPUPerformanceStateValueRange); + } + + /// + public override int GetHashCode() + { + unchecked + { + return ((int) Maximum * 397) ^ (int) Minimum; + } + } + + /// + public override string ToString() + { + if (Minimum == Maximum) + { + return $"({Minimum})"; + } + + return $"[({Minimum}) - ({Maximum})]"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUPerformanceStateVoltage.cs b/NvAPIWrapper/GPU/GPUPerformanceStateVoltage.cs new file mode 100644 index 0000000..97257b9 --- /dev/null +++ b/NvAPIWrapper/GPU/GPUPerformanceStateVoltage.cs @@ -0,0 +1,65 @@ +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.GPU +{ + /// + /// Represents a performance state voltage settings + /// + public class GPUPerformanceStateVoltage + { + internal GPUPerformanceStateVoltage(IPerformanceStates20VoltageEntry states20BaseVoltageEntry) + { + VoltageDomain = states20BaseVoltageEntry.DomainId; + IsReadOnly = !states20BaseVoltageEntry.IsEditable; + + CurrentVoltageInMicroVolt = states20BaseVoltageEntry.ValueInMicroVolt; + VoltageDeltaInMicroVolt = states20BaseVoltageEntry.ValueDeltaInMicroVolt.DeltaValue; + BaseVoltageInMicroVolt = (int) (CurrentVoltageInMicroVolt - VoltageDeltaInMicroVolt); + + VoltageDeltaRangeInMicroVolt = new GPUPerformanceStateValueRange( + states20BaseVoltageEntry.ValueDeltaInMicroVolt.DeltaRange.Minimum, + states20BaseVoltageEntry.ValueDeltaInMicroVolt.DeltaRange.Maximum + ); + } + + /// + /// Gets the base voltage in uV + /// + public int BaseVoltageInMicroVolt { get; } + + /// + /// Gets the current voltage in uV + /// + public uint CurrentVoltageInMicroVolt { get; } + + /// + /// Gets a boolean value indicating if this voltage is readonly + /// + public bool IsReadOnly { get; } + + /// + /// Gets the voltage delta in uV + /// + public int VoltageDeltaInMicroVolt { get; } + + /// + /// Gets the voltage delta range in uV + /// + public GPUPerformanceStateValueRange VoltageDeltaRangeInMicroVolt { get; } + + /// + /// Gets the voltage domain + /// + public PerformanceVoltageDomain VoltageDomain { get; } + + /// + public override string ToString() + { + var title = IsReadOnly ? $"{VoltageDomain} (ReadOnly)" : VoltageDomain.ToString(); + + return + $"{title}: ({BaseVoltageInMicroVolt}) + ({VoltageDeltaInMicroVolt}) = ({CurrentVoltageInMicroVolt})"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUPerformanceStatesInfo.cs b/NvAPIWrapper/GPU/GPUPerformanceStatesInfo.cs new file mode 100644 index 0000000..7c26789 --- /dev/null +++ b/NvAPIWrapper/GPU/GPUPerformanceStatesInfo.cs @@ -0,0 +1,107 @@ +using System.Collections.Generic; +using System.Linq; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.GPU +{ + /// + /// Holds the retrieved performance states information + /// + public class GPUPerformanceStatesInformation + { + internal GPUPerformanceStatesInformation( + IPerformanceStates20Info states20Info, + PerformanceStateId currentPerformanceStateId, + PrivatePCIeInfoV2? pciInformation) + { + IsReadOnly = !states20Info.IsEditable; + + GlobalVoltages = states20Info.GeneralVoltages + .Select(entry => new GPUPerformanceStateVoltage(entry)) + .ToArray(); + + var clocks = states20Info.Clocks; + var baseVoltages = states20Info.Voltages; + + PerformanceStates = states20Info.PerformanceStates.Select((state20, i) => + { + PCIeInformation statePCIeInfo = null; + + if (pciInformation != null && pciInformation.Value.PCIePerformanceStateInfos.Length > i) + { + statePCIeInfo = new PCIeInformation(pciInformation.Value.PCIePerformanceStateInfos[i]); + } + + return new GPUPerformanceState( + i, + state20, + clocks[state20.StateId], + baseVoltages[state20.StateId], + statePCIeInfo + ); + }).ToArray(); + + CurrentPerformanceState = + PerformanceStates.FirstOrDefault(performanceState => + performanceState.StateId == currentPerformanceStateId); + } + + /// + /// Gets the currently active performance state + /// + public GPUPerformanceState CurrentPerformanceState { get; } + + /// + /// Gets a list of global voltage settings + /// + public GPUPerformanceStateVoltage[] GlobalVoltages { get; } + + /// + /// Gets a boolean value indicating if performance states are readonly + /// + public bool IsReadOnly { get; } + + /// + /// Gets a list of all available performance states + /// + public GPUPerformanceState[] PerformanceStates { get; } + + /// + public override string ToString() + { + if (PerformanceStates.Length == 0) + { + return "No Performance State Available"; + } + + return string.Join( + ", ", + PerformanceStates + .Select( + state => + { + var attributes = new List(); + + if (state.IsReadOnly) + { + attributes.Add("ReadOnly"); + } + + if (CurrentPerformanceState.StateId == state.StateId) + { + attributes.Add("Active"); + } + + if (attributes.Any()) + { + return $"{state.StateId} ({string.Join(" - ", attributes)})"; + } + + return state.StateId.ToString(); + }) + ); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUPowerLimitInfo.cs b/NvAPIWrapper/GPU/GPUPowerLimitInfo.cs new file mode 100644 index 0000000..41a0173 --- /dev/null +++ b/NvAPIWrapper/GPU/GPUPowerLimitInfo.cs @@ -0,0 +1,70 @@ +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; + +namespace NvAPIWrapper.GPU +{ + /// + /// Holds information regarding a possible power limit policy and its acceptable range + /// + public class GPUPowerLimitInfo + { + internal GPUPowerLimitInfo(PrivatePowerPoliciesInfoV1.PowerPolicyInfoEntry powerPolicyInfoEntry) + { + PerformanceStateId = powerPolicyInfoEntry.PerformanceStateId; + MinimumPowerInPCM = powerPolicyInfoEntry.MinimumPowerInPCM; + DefaultPowerInPCM = powerPolicyInfoEntry.DefaultPowerInPCM; + MaximumPowerInPCM = powerPolicyInfoEntry.MaximumPowerInPCM; + } + + /// + /// Gets the default policy target power in per cent mille (PCM) + /// + public uint DefaultPowerInPCM { get; } + + /// + /// Gets the default policy target power in percentage + /// + public float DefaultPowerInPercent + { + get => DefaultPowerInPCM / 1000f; + } + + /// + /// Gets the maximum possible policy target power in per cent mille (PCM) + /// + public uint MaximumPowerInPCM { get; } + + /// + /// Gets the maximum possible policy target power in percentage + /// + public float MaximumPowerInPercent + { + get => MaximumPowerInPCM / 1000f; + } + + /// + /// Gets the minimum possible policy target power in per cent mille (PCM) + /// + public uint MinimumPowerInPCM { get; } + + /// + /// Gets the minimum possible policy target power in percentage + /// + public float MinimumPowerInPercent + { + get => MinimumPowerInPCM / 1000f; + } + + /// + /// Gets the corresponding performance state identification + /// + public PerformanceStateId PerformanceStateId { get; } + + /// + public override string ToString() + { + return + $"[{PerformanceStateId}] Default: {DefaultPowerInPercent}% - Range: ({MinimumPowerInPercent}% - {MaximumPowerInPercent}%)"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUPowerLimitPolicy.cs b/NvAPIWrapper/GPU/GPUPowerLimitPolicy.cs new file mode 100644 index 0000000..3b18cdd --- /dev/null +++ b/NvAPIWrapper/GPU/GPUPowerLimitPolicy.cs @@ -0,0 +1,41 @@ +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; + +namespace NvAPIWrapper.GPU +{ + /// + /// Holds information regarding a currently active power limit policy + /// + public class GPUPowerLimitPolicy + { + internal GPUPowerLimitPolicy(PrivatePowerPoliciesStatusV1.PowerPolicyStatusEntry powerPolicyStatusEntry) + { + PerformanceStateId = powerPolicyStatusEntry.PerformanceStateId; + PowerTargetInPCM = powerPolicyStatusEntry.PowerTargetInPCM; + } + + /// + /// Gets the corresponding performance state identification + /// + public PerformanceStateId PerformanceStateId { get; } + + /// + /// Gets the current policy target power in per cent mille (PCM) + /// + public uint PowerTargetInPCM { get; } + + /// + /// Gets the current policy target power in percentage + /// + public float PowerTargetInPercent + { + get => PowerTargetInPCM / 1000f; + } + + /// + public override string ToString() + { + return $"{PerformanceStateId} Target: {PowerTargetInPercent}%"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUPowerTopologyInformation.cs b/NvAPIWrapper/GPU/GPUPowerTopologyInformation.cs new file mode 100644 index 0000000..9c61385 --- /dev/null +++ b/NvAPIWrapper/GPU/GPUPowerTopologyInformation.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using System.Linq; +using NvAPIWrapper.Native; + +namespace NvAPIWrapper.GPU +{ + /// + /// Holds information regarding current power topology and their current power usage + /// + public class GPUPowerTopologyInformation + { + internal GPUPowerTopologyInformation(PhysicalGPU physicalGPU) + { + PhysicalGPU = physicalGPU; + } + + /// + /// Gets the physical GPU that this instance describes + /// + public PhysicalGPU PhysicalGPU { get; } + + /// + /// Gets the current power topology entries + /// + public IEnumerable PowerTopologyEntries + { + get + { + return GPUApi.ClientPowerTopologyGetStatus(PhysicalGPU.Handle).PowerPolicyStatusEntries + .Select(entry => new GPUPowerTopologyStatus(entry)); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUPowerTopologyStatus.cs b/NvAPIWrapper/GPU/GPUPowerTopologyStatus.cs new file mode 100644 index 0000000..54849ca --- /dev/null +++ b/NvAPIWrapper/GPU/GPUPowerTopologyStatus.cs @@ -0,0 +1,42 @@ +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; + +namespace NvAPIWrapper.GPU +{ + /// + /// Contains information about a power domain usage + /// + public class GPUPowerTopologyStatus + { + internal GPUPowerTopologyStatus( + PrivatePowerTopologiesStatusV1.PowerTopologiesStatusEntry powerTopologiesStatusEntry) + { + Domain = powerTopologiesStatusEntry.Domain; + PowerUsageInPCM = powerTopologiesStatusEntry.PowerUsageInPCM; + } + + /// + /// Gets the power usage domain + /// + public PowerTopologyDomain Domain { get; } + + /// + /// Gets the current power usage in per cent mille (PCM) + /// + public uint PowerUsageInPCM { get; } + + /// + /// Gets the current power usage in percentage + /// + public float PowerUsageInPercent + { + get => PowerUsageInPCM / 1000f; + } + + /// + public override string ToString() + { + return $"[{Domain}] {PowerUsageInPercent}%"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUThermalInformation.cs b/NvAPIWrapper/GPU/GPUThermalInformation.cs new file mode 100644 index 0000000..ea20cb7 --- /dev/null +++ b/NvAPIWrapper/GPU/GPUThermalInformation.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using System.Linq; +using NvAPIWrapper.Native; + +namespace NvAPIWrapper.GPU +{ + /// + /// Holds information regarding the available thermal sensors and current thermal level of a GPU + /// + public class GPUThermalInformation + { + internal GPUThermalInformation(PhysicalGPU physicalGPU) + { + PhysicalGPU = physicalGPU; + } + + /// + /// Gets the current thermal level of the GPU + /// + public int CurrentThermalLevel + { + get => (int) GPUApi.GetCurrentThermalLevel(PhysicalGPU.Handle); + } + + /// + /// Gets the physical GPU that this instance describes + /// + public PhysicalGPU PhysicalGPU { get; } + + /// + /// Gets the list of available thermal sensors + /// + public IEnumerable ThermalSensors + { + get + { + return GPUApi.GetThermalSettings(PhysicalGPU.Handle).Sensors + .Select((sensor, i) => new GPUThermalSensor(i, sensor)); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUThermalLimitInfo.cs b/NvAPIWrapper/GPU/GPUThermalLimitInfo.cs new file mode 100644 index 0000000..510c80b --- /dev/null +++ b/NvAPIWrapper/GPU/GPUThermalLimitInfo.cs @@ -0,0 +1,47 @@ +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; + +namespace NvAPIWrapper.GPU +{ + /// + /// Holds information regarding a possible thermal limit policy and its acceptable range + /// + public class GPUThermalLimitInfo + { + internal GPUThermalLimitInfo(PrivateThermalPoliciesInfoV2.ThermalPoliciesInfoEntry policiesInfoEntry) + { + Controller = policiesInfoEntry.Controller; + MinimumTemperature = policiesInfoEntry.MinimumTemperature; + DefaultTemperature = policiesInfoEntry.DefaultTemperature; + MaximumTemperature = policiesInfoEntry.MaximumTemperature; + } + + /// + /// Gets the policy's thermal controller + /// + public ThermalController Controller { get; } + + /// + /// Gets the default policy target temperature in degree Celsius + /// + public int DefaultTemperature { get; } + + + /// + /// Gets the maximum possible policy target temperature in degree Celsius + /// + public int MaximumTemperature { get; } + + /// + /// Gets the minimum possible policy target temperature in degree Celsius + /// + public int MinimumTemperature { get; } + + /// + public override string ToString() + { + return + $"[{Controller}] Default: {DefaultTemperature}°C - Range: ({MinimumTemperature}°C - {MaximumTemperature}°C)"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUThermalLimitPolicy.cs b/NvAPIWrapper/GPU/GPUThermalLimitPolicy.cs new file mode 100644 index 0000000..9ad502c --- /dev/null +++ b/NvAPIWrapper/GPU/GPUThermalLimitPolicy.cs @@ -0,0 +1,40 @@ +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; + +namespace NvAPIWrapper.GPU +{ + /// + /// Holds information regarding a currently active temperature limit policy + /// + public class GPUThermalLimitPolicy + { + internal GPUThermalLimitPolicy(PrivateThermalPoliciesStatusV2.ThermalPoliciesStatusEntry thermalPoliciesEntry) + { + Controller = thermalPoliciesEntry.Controller; + PerformanceStateId = thermalPoliciesEntry.PerformanceStateId; + TargetTemperature = thermalPoliciesEntry.TargetTemperature; + } + + /// + /// Gets the policy's thermal controller + /// + public ThermalController Controller { get; } + + /// + /// Gets the corresponding performance state identification + /// + public PerformanceStateId PerformanceStateId { get; } + + /// + /// Gets the current policy target temperature in degree Celsius + /// + public int TargetTemperature { get; } + + /// + public override string ToString() + { + return + $"{PerformanceStateId} [{Controller}] Target: {TargetTemperature}°C"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUThermalSensor.cs b/NvAPIWrapper/GPU/GPUThermalSensor.cs new file mode 100644 index 0000000..a1a8c48 --- /dev/null +++ b/NvAPIWrapper/GPU/GPUThermalSensor.cs @@ -0,0 +1,48 @@ +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.GPU +{ + /// + /// Represents a thermal sensor + /// + public class GPUThermalSensor : IThermalSensor + { + internal GPUThermalSensor(int sensorId, IThermalSensor thermalSensor) + { + SensorId = sensorId; + Controller = thermalSensor.Controller; + DefaultMinimumTemperature = thermalSensor.DefaultMinimumTemperature; + DefaultMaximumTemperature = thermalSensor.DefaultMaximumTemperature; + CurrentTemperature = thermalSensor.CurrentTemperature; + Target = thermalSensor.Target; + } + + /// + /// Gets the sensor identification number or index + /// + public int SensorId { get; set; } + + /// + public ThermalController Controller { get; } + + /// + public int CurrentTemperature { get; } + + /// + public int DefaultMaximumTemperature { get; } + + /// + public int DefaultMinimumTemperature { get; } + + /// + public ThermalSettingsTarget Target { get; } + + /// + public override string ToString() + { + return + $"[{Target} @ {Controller}] Current: {CurrentTemperature}°C - Default Range: [({DefaultMinimumTemperature}°C) , ({DefaultMaximumTemperature}°C)]"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUUsageDomainStatus.cs b/NvAPIWrapper/GPU/GPUUsageDomainStatus.cs new file mode 100644 index 0000000..21d4c0f --- /dev/null +++ b/NvAPIWrapper/GPU/GPUUsageDomainStatus.cs @@ -0,0 +1,33 @@ +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.GPU +{ + /// + /// Holds information about a utilization domain + /// + public class GPUUsageDomainStatus + { + internal GPUUsageDomainStatus(UtilizationDomain domain, IUtilizationDomainInfo utilizationDomainInfo) + { + Domain = domain; + Percentage = (int) utilizationDomainInfo.Percentage; + } + + /// + /// Gets the utilization domain that this instance describes + /// + public UtilizationDomain Domain { get; } + + /// + /// Gets the percentage of time where the domain is considered busy in the last 1 second interval. + /// + public int Percentage { get; } + + /// + public override string ToString() + { + return $"[{Domain}] {Percentage}%"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/GPUUsageInformation.cs b/NvAPIWrapper/GPU/GPUUsageInformation.cs new file mode 100644 index 0000000..1d6b687 --- /dev/null +++ b/NvAPIWrapper/GPU/GPUUsageInformation.cs @@ -0,0 +1,99 @@ +using System.Collections.Generic; +using System.Linq; +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.GPU; + +namespace NvAPIWrapper.GPU +{ + /// + /// Holds information about the GPU utilization domains + /// + public class GPUUsageInformation + { + internal GPUUsageInformation(PhysicalGPU physicalGPU) + { + PhysicalGPU = physicalGPU; + } + + /// + /// Gets the Bus interface (BUS) utilization + /// + public GPUUsageDomainStatus BusInterface + { + get => UtilizationDomainsStatus.FirstOrDefault(status => status.Domain == UtilizationDomain.BusInterface); + } + + /// + /// Gets the frame buffer (FB) utilization + /// + public GPUUsageDomainStatus FrameBuffer + { + get => UtilizationDomainsStatus.FirstOrDefault(status => status.Domain == UtilizationDomain.FrameBuffer); + } + + /// + /// Gets the graphic engine (GPU) utilization + /// + public GPUUsageDomainStatus GPU + { + get => UtilizationDomainsStatus.FirstOrDefault(status => status.Domain == UtilizationDomain.GPU); + } + + /// + /// Gets a boolean value indicating if the dynamic performance states is enabled + /// + public bool IsDynamicPerformanceStatesEnabled + { + get => GPUApi.GetDynamicPerformanceStatesInfoEx(PhysicalGPU.Handle).IsDynamicPerformanceStatesEnabled; + } + + /// + /// Gets the physical GPU that this instance describes + /// + public PhysicalGPU PhysicalGPU { get; } + + /// + /// Gets all valid utilization domains and information + /// + public IEnumerable UtilizationDomainsStatus + { + get + { + try + { + var dynamicPerformanceStates = GPUApi.GetDynamicPerformanceStatesInfoEx(PhysicalGPU.Handle); + + if (dynamicPerformanceStates.IsDynamicPerformanceStatesEnabled) + { + return dynamicPerformanceStates.Domains + .Select(pair => new GPUUsageDomainStatus(pair.Key, pair.Value)); + } + } + catch + { + // ignored + } + + return GPUApi.GetUsages(PhysicalGPU.Handle).Domains + .Select(pair => new GPUUsageDomainStatus(pair.Key, pair.Value)); + } + } + + + /// + /// Gets the Video engine (VID) utilization + /// + public GPUUsageDomainStatus VideoEngine + { + get => UtilizationDomainsStatus.FirstOrDefault(status => status.Domain == UtilizationDomain.VideoEngine); + } + + /// + /// Enables dynamic performance states + /// + public void EnableDynamicPerformanceStates() + { + GPUApi.EnableDynamicPStates(PhysicalGPU.Handle); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/LogicalGPU.cs b/NvAPIWrapper/GPU/LogicalGPU.cs new file mode 100644 index 0000000..6f15666 --- /dev/null +++ b/NvAPIWrapper/GPU/LogicalGPU.cs @@ -0,0 +1,119 @@ +using System; +using System.Linq; +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.GPU.Structures; + +namespace NvAPIWrapper.GPU +{ + /// + /// Represents a logical NVIDIA GPU + /// + public class LogicalGPU : IEquatable + { + /// + /// Creates a new LogicalGPU + /// + /// Logical GPU handle + public LogicalGPU(LogicalGPUHandle handle) + { + Handle = handle; + } + + /// + /// Gets a list of all corresponding physical GPUs + /// + public PhysicalGPU[] CorrespondingPhysicalGPUs + { + get + { + return GPUApi.GetPhysicalGPUsFromLogicalGPU(Handle).Select(handle => new PhysicalGPU(handle)).ToArray(); + } + } + + /// + /// Gets the logical GPU handle + /// + public LogicalGPUHandle Handle { get; } + + /// + public bool Equals(LogicalGPU other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + return Handle.Equals(other.Handle); + } + + /// + /// Gets all logical GPUs + /// + /// An array of logical GPUs + public static LogicalGPU[] GetLogicalGPUs() + { + return GPUApi.EnumLogicalGPUs().Select(handle => new LogicalGPU(handle)).ToArray(); + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(LogicalGPU left, LogicalGPU right) + { + return right?.Equals(left) ?? ReferenceEquals(left, null); + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(LogicalGPU left, LogicalGPU right) + { + return !(left == right); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((LogicalGPU) obj); + } + + /// + public override int GetHashCode() + { + return Handle.GetHashCode(); + } + + /// + public override string ToString() + { + return + $"Logical GPU [{CorrespondingPhysicalGPUs.Length}] {{{string.Join(", ", CorrespondingPhysicalGPUs.Select(gpu => gpu.FullName).ToArray())}}}"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/PCIIdentifiers.cs b/NvAPIWrapper/GPU/PCIIdentifiers.cs new file mode 100644 index 0000000..0076a86 --- /dev/null +++ b/NvAPIWrapper/GPU/PCIIdentifiers.cs @@ -0,0 +1,114 @@ +using System; + +namespace NvAPIWrapper.GPU +{ + /// + /// Contains information about the PCI connection + /// + public class PCIIdentifiers : IEquatable + { + // ReSharper disable once TooManyDependencies + internal PCIIdentifiers(uint deviceId, uint subSystemId, uint revisionId, int externalDeviceId = 0) + { + DeviceId = deviceId; + SubSystemId = subSystemId; + RevisionId = revisionId; + + if (externalDeviceId > 0) + { + ExternalDeviceId = (ushort) externalDeviceId; + } + else + { + ExternalDeviceId = (ushort) (deviceId >> 16); + } + + VendorId = (ushort) ((DeviceId << 16) >> 16); + } + + /// + /// Gets the internal PCI device identifier + /// + public uint DeviceId { get; } + + /// + /// Gets the external PCI device identifier + /// + public ushort ExternalDeviceId { get; } + + /// + /// Gets the internal PCI device-specific revision identifier + /// + public uint RevisionId { get; } + + /// + /// Gets the internal PCI subsystem identifier + /// + public uint SubSystemId { get; } + + /// + /// Gets the vendor identification calculated from internal device identification + /// + public ushort VendorId { get; } + + /// + public bool Equals(PCIIdentifiers other) + { + return DeviceId == other.DeviceId && + SubSystemId == other.SubSystemId && + RevisionId == other.RevisionId; + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(PCIIdentifiers left, PCIIdentifiers right) + { + return left.Equals(right); + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(PCIIdentifiers left, PCIIdentifiers right) + { + return !left.Equals(right); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is PCIIdentifiers identifiers && Equals(identifiers); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (int) DeviceId; + hashCode = (hashCode * 397) ^ (int) SubSystemId; + hashCode = (hashCode * 397) ^ (int) RevisionId; + + return hashCode; + } + } + + /// + public override string ToString() + { + return $"PCI\\VEN_{VendorId:X}&DEV_{ExternalDeviceId:X}&SUBSYS_{SubSystemId:X}&REV_{RevisionId:X}"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/PCIeInformation.cs b/NvAPIWrapper/GPU/PCIeInformation.cs new file mode 100644 index 0000000..b585577 --- /dev/null +++ b/NvAPIWrapper/GPU/PCIeInformation.cs @@ -0,0 +1,67 @@ +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; + +namespace NvAPIWrapper.GPU +{ + /// + /// Contains information about the PCI-e connection + /// + public class PCIeInformation + { + internal PCIeInformation(PrivatePCIeInfoV2.PCIePerformanceStateInfo stateInfo) + { + TransferRateInMTps = stateInfo.TransferRateInMTps; + Generation = stateInfo.Generation; + Lanes = stateInfo.Lanes; + Version = stateInfo.Version; + } + + /// + /// Gets the PCI-e generation + /// + public PCIeGeneration Generation { get; } + + /// + /// Gets the PCI-e down stream lanes + /// + public uint Lanes { get; } + + /// + /// Gets the PCIe transfer rate in Mega Transfers per Second + /// + public uint TransferRateInMTps { get; } + + /// + /// Gets the PCI-e version + /// + public PCIeGeneration Version { get; } + + /// + public override string ToString() + { + var v = "Unknown"; + + switch (Version) + { + case PCIeGeneration.PCIe1: + v = "PCIe 1.0"; + + break; + case PCIeGeneration.PCIe1Minor1: + v = "PCIe 1.1"; + + break; + case PCIeGeneration.PCIe2: + v = "PCIe 2.0"; + + break; + case PCIeGeneration.PCIe3: + v = "PCIe 3.0"; + + break; + } + + return $"{v} x{Lanes} - {TransferRateInMTps} MTps"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/PhysicalGPU.cs b/NvAPIWrapper/GPU/PhysicalGPU.cs new file mode 100644 index 0000000..cb8f62a --- /dev/null +++ b/NvAPIWrapper/GPU/PhysicalGPU.cs @@ -0,0 +1,559 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using NvAPIWrapper.Display; +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.GPU +{ + /// + /// Represents a physical NVIDIA GPU + /// + public class PhysicalGPU : IEquatable + { + /// + /// Creates a new PhysicalGPU + /// + /// Physical GPU handle + public PhysicalGPU(PhysicalGPUHandle handle) + { + Handle = handle; + UsageInformation = new GPUUsageInformation(this); + ThermalInformation = new GPUThermalInformation(this); + BusInformation = new GPUBusInformation(this); + ArchitectInformation = new GPUArchitectInformation(this); + MemoryInformation = new GPUMemoryInformation(this); + CoolerInformation = new GPUCoolerInformation(this); + ECCMemoryInformation = new ECCMemoryInformation(this); + PerformanceControl = new GPUPerformanceControl(this); + PowerTopologyInformation = new GPUPowerTopologyInformation(this); + } + + /// + /// Gets all active outputs of this GPU + /// + public GPUOutput[] ActiveOutputs + { + get + { + var outputs = new List(); + var allOutputs = GPUApi.GetActiveOutputs(Handle); + + foreach (OutputId outputId in Enum.GetValues(typeof(OutputId))) + { + if (outputId != OutputId.Invalid && allOutputs.HasFlag(outputId)) + { + outputs.Add(new GPUOutput(outputId, this)); + } + } + + return outputs.ToArray(); + } + } + + /// + /// Gets GPU architect information + /// + public GPUArchitectInformation ArchitectInformation { get; } + + /// + /// Gets GPU base clock frequencies + /// + public IClockFrequencies BaseClockFrequencies + { + get => GPUApi.GetAllClockFrequencies(Handle, new ClockFrequenciesV2(ClockType.BaseClock)); + } + + /// + /// Gets GPU video BIOS information + /// + public VideoBIOS Bios + { + get => new VideoBIOS( + GPUApi.GetVBIOSRevision(Handle), + (int) GPUApi.GetVBIOSOEMRevision(Handle), + GPUApi.GetVBIOSVersionString(Handle) + ); + } + + /// + /// Gets the board information + /// + public BoardInfo Board + { + get + { + try + { + return GPUApi.GetBoardInfo(Handle); + } + catch (NVIDIAApiException ex) + { + if (ex.Status == Status.NotSupported) + { + return default; + } + + throw; + } + } + } + + /// + /// Gets GPU boost clock frequencies + /// + public IClockFrequencies BoostClockFrequencies + { + get => GPUApi.GetAllClockFrequencies(Handle, new ClockFrequenciesV2(ClockType.BoostClock)); + } + + /// + /// Gets GPU bus information + /// + public GPUBusInformation BusInformation { get; } + + /// + /// Gets GPU coolers information + /// + public GPUCoolerInformation CoolerInformation { get; } + + /// + /// Gets corresponding logical GPU + /// + public LogicalGPU CorrespondingLogicalGPU + { + get => new LogicalGPU(GPUApi.GetLogicalGPUFromPhysicalGPU(Handle)); + } + + /// + /// Gets GPU current clock frequencies + /// + public IClockFrequencies CurrentClockFrequencies + { + get => GPUApi.GetAllClockFrequencies(Handle, new ClockFrequenciesV2(ClockType.CurrentClock)); + } + + /// + /// Gets the driver model number for this GPU + /// + public uint DriverModel + { + get => GPUApi.GetDriverModel(Handle); + } + + /// + /// Gets GPU ECC memory information + /// + public ECCMemoryInformation ECCMemoryInformation { get; } + + /// + /// Gets the chipset foundry + /// + public GPUFoundry Foundry + { + get => GPUApi.GetFoundry(Handle); + } + + /// + /// Gets GPU full name + /// + public string FullName + { + get => GPUApi.GetFullName(Handle); + } + + /// + /// Gets the GPU identification number + /// + public uint GPUId + { + get => GPUApi.GetGPUIDFromPhysicalGPU(Handle); + } + + /// + /// Gets GPU type + /// + public GPUType GPUType + { + get => GPUApi.GetGPUType(Handle); + } + + /// + /// Gets the physical GPU handle + /// + public PhysicalGPUHandle Handle { get; } + + /// + /// Gets a boolean value indicating the Quadro line of products + /// + public bool IsQuadro + { + get => GPUApi.GetQuadroStatus(Handle); + } + + /// + /// Gets GPU memory and RAM information as well as frame-buffer information + /// + public GPUMemoryInformation MemoryInformation { get; } + + /// + /// Gets GPU performance control status and configurations + /// + public GPUPerformanceControl PerformanceControl { get; } + + + /// + /// Gets the GPU performance states information and configurations + /// + public GPUPerformanceStatesInformation PerformanceStatesInfo + { + get + { + var performanceStates20Info = GPUApi.GetPerformanceStates20(Handle); + var currentPerformanceState = GPUApi.GetCurrentPerformanceState(Handle); + PrivatePCIeInfoV2? pcieInformation = null; + + if (BusInformation.BusType == GPUBusType.PCIExpress) + { + try + { + pcieInformation = GPUApi.GetPCIEInfo(Handle); + } + catch + { + // ignore + } + } + + return new GPUPerformanceStatesInformation(performanceStates20Info, currentPerformanceState, + pcieInformation); + } + } + + /// + /// Gets GPU coolers information + /// + public GPUPowerTopologyInformation PowerTopologyInformation { get; } + + /// + /// Gets GPU system type + /// + public SystemType SystemType + { + get => GPUApi.GetSystemType(Handle); + } + + /// + /// Gets GPU thermal sensors information + /// + public GPUThermalInformation ThermalInformation { get; } + + /// + /// Gets the GPU utilization domains and usages + /// + public GPUUsageInformation UsageInformation { get; } + + /// + public bool Equals(PhysicalGPU other) + { + if (other == null) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + return Handle.Equals(other.Handle); + } + + /// + /// Gets the corresponding instance from a GPU identification number. + /// + /// The GPU identification number. + /// An instance of or if operation failed. + public static PhysicalGPU FromGPUId(uint gpuId) + { + var handle = GPUApi.GetPhysicalGPUFromGPUID(gpuId); + + if (handle.IsNull) + { + return null; + } + + return new PhysicalGPU(handle); + } + + /// + /// Gets all physical GPUs + /// + /// An array of physical GPUs + public static PhysicalGPU[] GetPhysicalGPUs() + { + return GPUApi.EnumPhysicalGPUs().Select(handle => new PhysicalGPU(handle)).ToArray(); + } + + /// + /// Gets all physical GPUs in TCC state + /// + /// An array of physical GPUs + public static PhysicalGPU[] GetTCCPhysicalGPUs() + { + return GPUApi.EnumTCCPhysicalGPUs().Select(handle => new PhysicalGPU(handle)).ToArray(); + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(PhysicalGPU left, PhysicalGPU right) + { + return Equals(left, right) || left?.Equals(right) == true; + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(PhysicalGPU left, PhysicalGPU right) + { + return !(left == right); + } + + /// + public override bool Equals(object obj) + { + if (obj == null) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + return Equals(obj as PhysicalGPU); + } + + /// + public override int GetHashCode() + { + return Handle.GetHashCode(); + } + + /// + public override string ToString() + { + return FullName; + } + + /// + /// Get a list of all active applications for this GPU + /// + /// An array of processes + public Process[] GetActiveApplications() + { + return GPUApi.QueryActiveApps(Handle).Select(app => Process.GetProcessById(app.ProcessId)).ToArray(); + } + + /// + /// Get a list of all connected display devices on this GPU + /// + /// ConnectedIdsFlag flag + /// An array of display devices + public DisplayDevice[] GetConnectedDisplayDevices(ConnectedIdsFlag flags) + { + return GPUApi.GetConnectedDisplayIds(Handle, flags).Select(display => new DisplayDevice(display)).ToArray(); + } + + /// + /// Get the display device connected to a specific GPU output + /// + /// The GPU output to get connected display device for + /// DisplayDevice connected to the specified GPU output + public DisplayDevice GetDisplayDeviceByOutput(GPUOutput output) + { + return new DisplayDevice(GPUApi.GetDisplayIdFromGPUAndOutputId(Handle, output.OutputId)); + } + + /// + /// Get a list of all display devices on any possible output + /// + /// An array of display devices + public DisplayDevice[] GetDisplayDevices() + { + return GPUApi.GetAllDisplayIds(Handle).Select(display => new DisplayDevice(display)).ToArray(); + } + + /// + /// Reads EDID data of an output + /// + /// The GPU output to read EDID information for + /// A byte array containing EDID data + public byte[] ReadEDIDData(GPUOutput output) + { + try + { + var data = new byte[0]; + var identification = 0; + var totalSize = EDIDV3.MaxDataSize; + + for (var offset = 0; offset < totalSize; offset += EDIDV3.MaxDataSize) + { + var edid = GPUApi.GetEDID(Handle, output.OutputId, offset, identification); + identification = edid.Identification; + totalSize = edid.TotalSize; + + var edidData = edid.Data; + Array.Resize(ref data, data.Length + edidData.Length); + Array.Copy(edidData, 0, data, data.Length - edidData.Length, edidData.Length); + } + + return data; + } + catch (NVIDIAApiException ex) + { + if (ex.Status == Status.IncompatibleStructureVersion) + { + return GPUApi.GetEDID(Handle, output.OutputId).Data; + } + + throw; + } + } + + /// + /// Reads data from the I2C bus + /// + /// Information required to read from the I2C bus. + /// The returned payload. + // ReSharper disable once InconsistentNaming + public byte[] ReadI2C(II2CInfo i2cInfo) + { + GPUApi.I2CRead(Handle, ref i2cInfo); + + return i2cInfo.Data; + } + + /// + /// Validates a set of GPU outputs to check if they can be active simultaneously + /// + /// GPU outputs to check + /// true if all specified outputs can be active simultaneously, otherwise false + public bool ValidateOutputCombination(GPUOutput[] outputs) + { + var gpuOutpudIds = + outputs.Aggregate(OutputId.Invalid, (current, gpuOutput) => current | gpuOutput.OutputId); + + return GPUApi.ValidateOutputCombination(Handle, gpuOutpudIds); + } + + /// + /// Writes EDID data of an output + /// + /// The GPU output to write EDID information for + /// A byte array containing EDID data + public void WriteEDIDData(GPUOutput output, byte[] edidData) + { + WriteEDIDData((uint) output.OutputId, edidData); + } + + /// + /// Writes EDID data of an display + /// + /// The display device to write EDID information for + /// A byte array containing EDID data + public void WriteEDIDData(DisplayDevice display, byte[] edidData) + { + WriteEDIDData(display.DisplayId, edidData); + } + + /// + /// Writes data to the I2C bus + /// + /// Information required to write to the I2C bus including data payload. + // ReSharper disable once InconsistentNaming + public void WriteI2C(II2CInfo i2cInfo) + { + GPUApi.I2CWrite(Handle, i2cInfo); + } + + private void WriteEDIDData(uint displayOutputId, byte[] edidData) + { + try + { + if (edidData.Length == 0) + { + var instance = typeof(EDIDV3).Instantiate(); + GPUApi.SetEDID(Handle, displayOutputId, instance); + } + + for (var offset = 0; offset < edidData.Length; offset += EDIDV3.MaxDataSize) + { + var array = new byte[Math.Min(EDIDV3.MaxDataSize, edidData.Length - offset)]; + Array.Copy(edidData, offset, array, 0, array.Length); + var instance = EDIDV3.CreateWithData(0, (uint) offset, array, edidData.Length); + GPUApi.SetEDID(Handle, displayOutputId, instance); + } + + return; + } + catch (NVIDIAApiException ex) + { + if (ex.Status != Status.IncompatibleStructureVersion) + { + throw; + } + } + catch (NVIDIANotSupportedException) + { + // ignore + } + + try + { + if (edidData.Length == 0) + { + var instance = typeof(EDIDV2).Instantiate(); + GPUApi.SetEDID(Handle, displayOutputId, instance); + } + + for (var offset = 0; offset < edidData.Length; offset += EDIDV2.MaxDataSize) + { + var array = new byte[Math.Min(EDIDV2.MaxDataSize, edidData.Length - offset)]; + Array.Copy(edidData, offset, array, 0, array.Length); + GPUApi.SetEDID(Handle, displayOutputId, EDIDV2.CreateWithData(array, edidData.Length)); + } + + return; + } + catch (NVIDIAApiException ex) + { + if (ex.Status != Status.IncompatibleStructureVersion) + { + throw; + } + } + catch (NVIDIANotSupportedException) + { + // ignore + } + + GPUApi.SetEDID(Handle, displayOutputId, EDIDV1.CreateWithData(edidData)); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/GPU/VideoBIOS.cs b/NvAPIWrapper/GPU/VideoBIOS.cs new file mode 100644 index 0000000..72b522d --- /dev/null +++ b/NvAPIWrapper/GPU/VideoBIOS.cs @@ -0,0 +1,52 @@ +using System; + +namespace NvAPIWrapper.GPU +{ + /// + /// Contains information about the GPU Video BIOS + /// + public class VideoBIOS + { + internal VideoBIOS(uint revision, int oemRevision, string versionString) + { + Revision = revision; + OEMRevision = oemRevision; + VersionString = versionString.ToUpper(); + } + + /// + /// Gets the the OEM revision of the video BIOS + /// + public int OEMRevision { get; } + + /// + /// Gets the revision of the video BIOS + /// + public uint Revision { get; } + + /// + /// Gets the full video BIOS version string + /// + public string VersionString { get; } + + /// + public override string ToString() + { + return AsVersion().ToString(); + } + + /// + /// Returns the video BIOS version as a .Net Version object + /// + /// A Version object representing the video BIOS version + public Version AsVersion() + { + return new Version( + (int) ((Revision >> 28) + ((Revision << 4) >> 28) * 16), // 8 bit little endian + (int) (((Revision << 8) >> 28) + ((Revision << 12) >> 28) * 16), // 8 bit little endian + (int) ((Revision << 16) >> 16), // 16 bit big endian + OEMRevision // 8 bit integer + ); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Icon.png b/NvAPIWrapper/Icon.png new file mode 100644 index 0000000..43914ec Binary files /dev/null and b/NvAPIWrapper/Icon.png differ diff --git a/NvAPIWrapper/NVIDIA.cs b/NvAPIWrapper/NVIDIA.cs new file mode 100644 index 0000000..5fd5825 --- /dev/null +++ b/NvAPIWrapper/NVIDIA.cs @@ -0,0 +1,81 @@ +using NvAPIWrapper.Native; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces.General; + +namespace NvAPIWrapper +{ + /// + /// .Net friendly version of system and general functions of NVAPI library + /// + public static class NVIDIA + { + /// + /// Gets information about the system's chipset. + /// + public static IChipsetInfo ChipsetInfo + { + get => GeneralApi.GetChipsetInfo(); + } + + /// + /// Gets NVIDIA driver branch version as string + /// + public static string DriverBranchVersion + { + get + { + GeneralApi.GetDriverAndBranchVersion(out var branchVersion); + + return branchVersion; + } + } + + /// + /// Gets NVIDIA driver version + /// + public static uint DriverVersion + { + get => GeneralApi.GetDriverAndBranchVersion(out _); + } + + /// + /// Gets NVAPI interface version as string + /// + public static string InterfaceVersionString + { + get => GeneralApi.GetInterfaceVersionString(); + } + + /// + /// Gets the current lid and dock information. + /// + public static LidDockParameters LidAndDockParameters + { + get => GeneralApi.GetLidAndDockInfo(); + } + + /// + /// Initializes the NvAPI library (if not already initialized) but always increments the ref-counter. + /// + public static void Initialize() + { + GeneralApi.Initialize(); + } + + /// + /// PRIVATE - Requests to restart the display driver + /// + public static void RestartDisplayDriver() + { + GeneralApi.RestartDisplayDriver(); + } + + /// + /// Decrements the ref-counter and when it reaches ZERO, unloads NVAPI library. + /// + public static void Unload() + { + GeneralApi.Unload(); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Attributes/AcceptsAttribute.cs b/NvAPIWrapper/Native/Attributes/AcceptsAttribute.cs new file mode 100644 index 0000000..7df15fb --- /dev/null +++ b/NvAPIWrapper/Native/Attributes/AcceptsAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace NvAPIWrapper.Native.Attributes +{ + [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Delegate)] + internal class AcceptsAttribute : Attribute + { + public AcceptsAttribute(params Type[] types) + { + Types = types; + } + + public Type[] Types { get; set; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Attributes/FunctionIdAttribute.cs b/NvAPIWrapper/Native/Attributes/FunctionIdAttribute.cs new file mode 100644 index 0000000..260da7d --- /dev/null +++ b/NvAPIWrapper/Native/Attributes/FunctionIdAttribute.cs @@ -0,0 +1,16 @@ +using System; +using NvAPIWrapper.Native.Helpers; + +namespace NvAPIWrapper.Native.Attributes +{ + [AttributeUsage(AttributeTargets.Delegate)] + internal class FunctionIdAttribute : Attribute + { + public FunctionIdAttribute(FunctionId functionId) + { + FunctionId = functionId; + } + + public FunctionId FunctionId { get; set; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Attributes/StructureVersionAttribute.cs b/NvAPIWrapper/Native/Attributes/StructureVersionAttribute.cs new file mode 100644 index 0000000..9752e65 --- /dev/null +++ b/NvAPIWrapper/Native/Attributes/StructureVersionAttribute.cs @@ -0,0 +1,19 @@ +using System; + +namespace NvAPIWrapper.Native.Attributes +{ + [AttributeUsage(AttributeTargets.Struct)] + internal class StructureVersionAttribute : Attribute + { + public StructureVersionAttribute() + { + } + + public StructureVersionAttribute(int versionNumber) + { + VersionNumber = versionNumber; + } + + public int VersionNumber { get; set; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Constants/Display.cs b/NvAPIWrapper/Native/Constants/Display.cs new file mode 100644 index 0000000..c7a01b8 --- /dev/null +++ b/NvAPIWrapper/Native/Constants/Display.cs @@ -0,0 +1,8 @@ +namespace NvAPIWrapper.Native.Constants +{ + internal static class Display + { + public const int AdvancedDisplayHeads = 4; + public const int MaxDisplayHeads = 2; + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Constants/General.cs b/NvAPIWrapper/Native/Constants/General.cs new file mode 100644 index 0000000..20468c7 --- /dev/null +++ b/NvAPIWrapper/Native/Constants/General.cs @@ -0,0 +1,8 @@ +namespace NvAPIWrapper.Native.Constants +{ + internal static class General + { + public const int BinaryDataMax = 4096; + public const int UnicodeStringLength = 2048; + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Delegates/Display.cs b/NvAPIWrapper/Native/Delegates/Display.cs new file mode 100644 index 0000000..fb04283 --- /dev/null +++ b/NvAPIWrapper/Native/Delegates/Display.cs @@ -0,0 +1,327 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.Display; +using NvAPIWrapper.Native.Display.Structures; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; + +// ReSharper disable InconsistentNaming + +namespace NvAPIWrapper.Native.Delegates +{ + internal static class Display + { + [FunctionId(FunctionId.NvAPI_CreateDisplayFromUnAttachedDisplay)] + public delegate Status NvAPI_CreateDisplayFromUnAttachedDisplay( + [In] UnAttachedDisplayHandle display, + [Out] out DisplayHandle newDisplay + ); + + [FunctionId(FunctionId.NvAPI_Disp_ColorControl)] + public delegate Status NvAPI_Disp_ColorControl( + [In] uint displayId, + [In] + [Out] + [Accepts( + typeof(ColorDataV5), + typeof(ColorDataV4), + typeof(ColorDataV3), + typeof(ColorDataV2), + typeof(ColorDataV1) + )] + ValueTypeReference colorData + ); + + [FunctionId(FunctionId.NvAPI_DISP_DeleteCustomDisplay)] + public delegate Status NvAPI_DISP_DeleteCustomDisplay( + [In] [Accepts(typeof(uint))] ValueTypeArray displayIds, + [In] uint count, + [In] [Accepts(typeof(CustomDisplay))] ValueTypeReference customDisplay + ); + + [FunctionId(FunctionId.NvAPI_DISP_EnumCustomDisplay)] + public delegate Status NvAPI_DISP_EnumCustomDisplay( + [In] uint displayId, + [In] uint index, + [In] [Accepts(typeof(CustomDisplay))] ValueTypeReference customDisplay + ); + + [FunctionId(FunctionId.NvAPI_DISP_GetAssociatedUnAttachedNvidiaDisplayHandle)] + public delegate Status NvAPI_DISP_GetAssociatedUnAttachedNvidiaDisplayHandle( + [In] [MarshalAs(UnmanagedType.LPStr)] string displayName, + [Out] out UnAttachedDisplayHandle display + ); + + [FunctionId(FunctionId.NvAPI_DISP_GetDisplayConfig)] + public delegate Status NvAPI_DISP_GetDisplayConfig( + [In] [Out] ref uint pathInfoCount, + [In] [Accepts(typeof(PathInfoV2), typeof(PathInfoV1))] + ValueTypeArray pathInfos + ); + + [FunctionId(FunctionId.NvAPI_DISP_GetDisplayIdByDisplayName)] + public delegate Status NvAPI_DISP_GetDisplayIdByDisplayName([In] string displayName, [Out] out uint displayId); + + [FunctionId(FunctionId.NvAPI_DISP_GetGDIPrimaryDisplayId)] + public delegate Status NvAPI_DISP_GetGDIPrimaryDisplayId([Out] out uint displayId); + + [FunctionId(FunctionId.NvAPI_Disp_GetHdrCapabilities)] + public delegate Status NvAPI_Disp_GetHdrCapabilities( + [In] uint displayId, + [In] [Out] [Accepts(typeof(HDRCapabilitiesV1))] + ValueTypeReference hdrCapabilities + ); + + [FunctionId(FunctionId.NvAPI_DISP_GetMonitorCapabilities)] + public delegate Status NvAPI_DISP_GetMonitorCapabilities( + [In] uint displayId, + [In] [Accepts(typeof(MonitorCapabilities))] + ValueTypeReference capabilities + ); + + [FunctionId(FunctionId.NvAPI_DISP_GetMonitorColorCapabilities)] + public delegate Status NvAPI_DISP_GetMonitorColorCapabilities( + [In] uint displayId, + [In] [Accepts(typeof(MonitorColorData))] + ValueTypeArray capabilities, + [In] [Out] ref uint count + ); + + [FunctionId(FunctionId.NvAPI_DISP_GetTiming)] + public delegate Status NvAPI_DISP_GetTiming( + [In] uint displayId, + [In] [Accepts(typeof(TimingInput))] ValueTypeReference timingInput, + [In] [Accepts(typeof(Timing))] ValueTypeReference timing + ); + + [FunctionId(FunctionId.NvAPI_Disp_HdrColorControl)] + public delegate Status NvAPI_Disp_HdrColorControl( + [In] uint displayId, + [In] [Out] [Accepts(typeof(HDRColorDataV2), typeof(HDRColorDataV1))] + ValueTypeReference hdrColorData + ); + + [FunctionId(FunctionId.NvAPI_Disp_InfoFrameControl)] + public delegate Status NvAPI_Disp_InfoFrameControl( + [In] uint displayId, + [In] [Accepts(typeof(InfoFrameData))] ValueTypeReference infoFrameData + ); + + [FunctionId(FunctionId.NvAPI_DISP_RevertCustomDisplayTrial)] + public delegate Status NvAPI_DISP_RevertCustomDisplayTrial( + [In] [Accepts(typeof(uint))] ValueTypeArray displayIds, + [In] uint count + ); + + [FunctionId(FunctionId.NvAPI_DISP_SaveCustomDisplay)] + public delegate Status NvAPI_DISP_SaveCustomDisplay( + [In] [Accepts(typeof(uint))] ValueTypeArray displayIds, + [In] uint count, + [In] uint isThisOutputIdOnly, + [In] uint isThisMonitorIdOnly + ); + + [FunctionId(FunctionId.NvAPI_DISP_SetDisplayConfig)] + public delegate Status NvAPI_DISP_SetDisplayConfig( + [In] uint pathInfoCount, + [In] [Accepts(typeof(PathInfoV2), typeof(PathInfoV1))] + ValueTypeArray pathInfos, + [In] DisplayConfigFlags flags + ); + + [FunctionId(FunctionId.NvAPI_DISP_TryCustomDisplay)] + public delegate Status NvAPI_DISP_TryCustomDisplay( + [In] [Accepts(typeof(uint))] ValueTypeArray displayIds, + [In] uint count, + [In] [Accepts(typeof(CustomDisplay))] ValueTypeArray customDisplays + ); + + [FunctionId(FunctionId.NvAPI_EnumNvidiaDisplayHandle)] + public delegate Status NvAPI_EnumNvidiaDisplayHandle( + [In] uint enumId, + [Out] out DisplayHandle display + ); + + [FunctionId(FunctionId.NvAPI_EnumNvidiaUnAttachedDisplayHandle)] + public delegate Status NvAPI_EnumNvidiaUnAttachedDisplayHandle( + [In] uint enumId, + [Out] out UnAttachedDisplayHandle display + ); + + [FunctionId(FunctionId.NvAPI_GetAssociatedDisplayOutputId)] + public delegate Status NvAPI_GetAssociatedDisplayOutputId( + [In] DisplayHandle display, + [Out] out OutputId outputId + ); + + [FunctionId(FunctionId.NvAPI_GetAssociatedNvidiaDisplayHandle)] + public delegate Status NvAPI_GetAssociatedNvidiaDisplayHandle( + [In] [MarshalAs(UnmanagedType.LPStr)] string displayName, + [Out] out DisplayHandle display + ); + + [FunctionId(FunctionId.NvAPI_GetAssociatedNvidiaDisplayName)] + public delegate Status NvAPI_GetAssociatedNvidiaDisplayName( + [In] DisplayHandle display, + [Out] out ShortString displayName + ); + + [FunctionId(FunctionId.NvAPI_GetDisplayDriverBuildTitle)] + public delegate Status NvAPI_GetDisplayDriverBuildTitle( + [In] DisplayHandle displayHandle, + [Out] out ShortString name + ); + + [FunctionId(FunctionId.NvAPI_GetDisplayDriverMemoryInfo)] + public delegate Status NvAPI_GetDisplayDriverMemoryInfo( + [In] DisplayHandle displayHandle, + [In] + [Accepts( + typeof(DisplayDriverMemoryInfoV3), + typeof(DisplayDriverMemoryInfoV2), + typeof(DisplayDriverMemoryInfoV1) + )] + ValueTypeReference memoryInfo + ); + + [FunctionId(FunctionId.NvAPI_GetDVCInfo)] + public delegate Status NvAPI_GetDVCInfo( + [In] DisplayHandle displayHandle, + [In] OutputId displayId, + [In] [Accepts(typeof(PrivateDisplayDVCInfo))] + ValueTypeReference dvcInfo + ); + + [FunctionId(FunctionId.NvAPI_GetDVCInfoEx)] + public delegate Status NvAPI_GetDVCInfoEx( + [In] DisplayHandle displayHandle, + [In] OutputId displayId, + [In] [Accepts(typeof(PrivateDisplayDVCInfoEx))] + ValueTypeReference dvcInfo + ); + + [FunctionId(FunctionId.NvAPI_GetHDMISupportInfo)] + public delegate Status NvAPI_GetHDMISupportInfo( + [In] DisplayHandle displayHandle, + [In] uint displayIdOrOutputId, + [In] [Accepts(typeof(HDMISupportInfoV2), typeof(HDMISupportInfoV1))] + ValueTypeReference supportInfo + ); + + [FunctionId(FunctionId.NvAPI_GetHUEInfo)] + public delegate Status NvAPI_GetHUEInfo( + [In] DisplayHandle displayHandle, + [In] OutputId displayId, + [In] [Accepts(typeof(PrivateDisplayHUEInfo))] + ValueTypeReference hueInfo + ); + + [FunctionId(FunctionId.NvAPI_GetSupportedViews)] + public delegate Status NvAPI_GetSupportedViews( + [In] DisplayHandle display, + [In] [Accepts(typeof(TargetViewMode))] ValueTypeArray viewModes, + [Out] [In] ref uint viewCount + ); + + [FunctionId(FunctionId.NvAPI_GetUnAttachedAssociatedDisplayName)] + public delegate Status NvAPI_GetUnAttachedAssociatedDisplayName( + [In] UnAttachedDisplayHandle display, + [Out] out ShortString displayName + ); + + [FunctionId(FunctionId.NvAPI_GPU_GetScanoutCompositionParameter)] + public delegate Status NvAPI_GPU_GetScanOutCompositionParameter( + [In] uint displayId, + [In] ScanOutCompositionParameter parameter, + [Out] out ScanOutCompositionParameterValue parameterValue, + [Out] out float container + ); + + [FunctionId(FunctionId.NvAPI_GPU_GetScanoutConfiguration)] + public delegate Status NvAPI_GPU_GetScanOutConfiguration( + [In] uint displayId, + [In] [Accepts(typeof(Rectangle))] ValueTypeReference desktopRectangle, + [In] [Accepts(typeof(Rectangle))] ValueTypeReference scanOutRectangle + ); + + [FunctionId(FunctionId.NvAPI_GPU_GetScanoutConfigurationEx)] + public delegate Status NvAPI_GPU_GetScanOutConfigurationEx( + [In] uint displayId, + [In] [Accepts(typeof(ScanOutInformationV1))] + ValueTypeReference scanOutInformation + ); + + [FunctionId(FunctionId.NvAPI_GPU_GetScanoutIntensityState)] + public delegate Status NvAPI_GPU_GetScanOutIntensityState( + [In] uint displayId, + [In] [Accepts(typeof(ScanOutIntensityStateV1))] + ValueTypeReference scanOutIntensityState + ); + + [FunctionId(FunctionId.NvAPI_GPU_GetScanoutWarpingState)] + public delegate Status NvAPI_GPU_GetScanOutWarpingState( + [In] uint displayId, + [In] [Accepts(typeof(ScanOutWarpingStateV1))] + ValueTypeReference scanOutWarpingState + ); + + [FunctionId(FunctionId.NvAPI_GPU_SetScanoutCompositionParameter)] + public delegate Status NvAPI_GPU_SetScanOutCompositionParameter( + [In] uint displayId, + [In] ScanOutCompositionParameter parameter, + [In] ScanOutCompositionParameterValue parameterValue, + [In] ref float container + ); + + [FunctionId(FunctionId.NvAPI_GPU_SetScanoutIntensity)] + public delegate Status NvAPI_GPU_SetScanOutIntensity( + [In] uint displayId, + [In] [Accepts(typeof(ScanOutIntensityV2), typeof(ScanOutIntensityV1))] + ValueTypeReference scanOutIntensityData, + [Out] out int isSticky + ); + + [FunctionId(FunctionId.NvAPI_GPU_SetScanoutWarping)] + public delegate Status NvAPI_GPU_SetScanOutWarping( + [In] uint displayId, + [In] [Accepts(typeof(ScanOutWarpingV1))] + ValueTypeReference scanOutWarping, + [In] [Out] ref int maximumNumberOfVertices, + [Out] out int isSticky + ); + + [FunctionId(FunctionId.NvAPI_SetDVCLevel)] + public delegate Status NvAPI_SetDVCLevel( + [In] DisplayHandle displayHandle, + [In] OutputId displayId, + [In] int dvcLevel + ); + + [FunctionId(FunctionId.NvAPI_SetDVCLevelEx)] + public delegate Status NvAPI_SetDVCLevelEx( + [In] DisplayHandle displayHandle, + [In] OutputId displayId, + [In] [Accepts(typeof(PrivateDisplayDVCInfoEx))] + ValueTypeReference dvcInfo + ); + + [FunctionId(FunctionId.NvAPI_SetHUEAngle)] + public delegate Status NvAPI_SetHUEAngle( + [In] DisplayHandle displayHandle, + [In] OutputId displayId, + [In] int hueAngle + ); + + [FunctionId(FunctionId.NvAPI_SetRefreshRateOverride)] + public delegate Status NvAPI_SetRefreshRateOverride( + [In] DisplayHandle displayHandle, + [In] OutputId outputMask, + [In] float refreshRate, + [In] uint isDeferred + ); + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Delegates/GPU.cs b/NvAPIWrapper/Native/Delegates/GPU.cs new file mode 100644 index 0000000..e445f3f --- /dev/null +++ b/NvAPIWrapper/Native/Delegates/GPU.cs @@ -0,0 +1,733 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.Display.Structures; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; + +// ReSharper disable InconsistentNaming + +namespace NvAPIWrapper.Native.Delegates +{ + internal static class GPU + { + [FunctionId(FunctionId.NvAPI_EnumLogicalGPUs)] + public delegate Status NvAPI_EnumLogicalGPUs( + [In] [Out] [MarshalAs(UnmanagedType.LPArray, SizeConst = LogicalGPUHandle.MaxLogicalGPUs)] + LogicalGPUHandle[] + gpuHandles, + [Out] out uint gpuCount); + + [FunctionId(FunctionId.NvAPI_EnumPhysicalGPUs)] + public delegate Status NvAPI_EnumPhysicalGPUs( + [In] [Out] [MarshalAs(UnmanagedType.LPArray, SizeConst = PhysicalGPUHandle.MaxPhysicalGPUs)] + PhysicalGPUHandle[] + gpuHandles, + [Out] out uint gpuCount); + + [FunctionId(FunctionId.NvAPI_EnumTCCPhysicalGPUs)] + public delegate Status NvAPI_EnumTCCPhysicalGPUs( + [In] [Out] [MarshalAs(UnmanagedType.LPArray, SizeConst = PhysicalGPUHandle.MaxPhysicalGPUs)] + PhysicalGPUHandle[] + gpuHandles, + [Out] out uint gpuCount); + + [FunctionId(FunctionId.NvAPI_GPU_QueryThermalSensors)] + public delegate Status NvAPI_GPU_QueryThermalSensors( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(PrivateThermalSensorsV2))] [In] + ValueTypeReference thermal + ); + + [FunctionId(FunctionId.NvAPI_GetDriverModel)] + public delegate Status NvAPI_GetDriverModel( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint model); + + [FunctionId(FunctionId.NvAPI_GetGPUIDfromPhysicalGPU)] + public delegate Status NvAPI_GetGPUIDFromPhysicalGPU( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint gpuId); + + [FunctionId(FunctionId.NvAPI_GetLogicalGPUFromDisplay)] + public delegate Status NvAPI_GetLogicalGPUFromDisplay( + [In] DisplayHandle displayHandle, + [Out] out LogicalGPUHandle gpuHandle); + + [FunctionId(FunctionId.NvAPI_GetLogicalGPUFromPhysicalGPU)] + public delegate Status NvAPI_GetLogicalGPUFromPhysicalGPU( + [In] PhysicalGPUHandle physicalGPUHandle, + [Out] out LogicalGPUHandle logicalGPUHandle); + + [FunctionId(FunctionId.NvAPI_GetPhysicalGPUFromGPUID)] + public delegate Status NvAPI_GetPhysicalGPUFromGPUID( + [In] uint gpuId, + [Out] out PhysicalGPUHandle physicalGpu); + + [FunctionId(FunctionId.NvAPI_GetPhysicalGPUFromUnAttachedDisplay)] + public delegate Status NvAPI_GetPhysicalGPUFromUnAttachedDisplay( + [In] UnAttachedDisplayHandle displayHandle, + [Out] out PhysicalGPUHandle gpuHandle); + + [FunctionId(FunctionId.NvAPI_GetPhysicalGPUsFromDisplay)] + public delegate Status NvAPI_GetPhysicalGPUsFromDisplay( + [In] DisplayHandle displayHandle, + [In] [Out] [MarshalAs(UnmanagedType.LPArray, SizeConst = PhysicalGPUHandle.MaxPhysicalGPUs)] + PhysicalGPUHandle[] + gpuHandles, + [Out] out uint gpuCount); + + [FunctionId(FunctionId.NvAPI_GetPhysicalGPUsFromLogicalGPU)] + public delegate Status NvAPI_GetPhysicalGPUsFromLogicalGPU( + [In] LogicalGPUHandle logicalGPUHandle, + [In] [Out] [MarshalAs(UnmanagedType.LPArray, SizeConst = PhysicalGPUHandle.MaxPhysicalGPUs)] + PhysicalGPUHandle[] + gpuHandles, + [Out] out uint gpuCount); + + [FunctionId(FunctionId.NvAPI_GPU_ClientFanCoolersGetControl)] + public delegate Status NvAPI_GPU_ClientFanCoolersGetControl( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(PrivateFanCoolersControlV1))] [In] + ValueTypeReference control); + + [FunctionId(FunctionId.NvAPI_GPU_ClientFanCoolersGetInfo)] + public delegate Status NvAPI_GPU_ClientFanCoolersGetInfo( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(PrivateFanCoolersInfoV1))] [In] + ValueTypeReference info); + + [FunctionId(FunctionId.NvAPI_GPU_ClientFanCoolersGetStatus)] + public delegate Status NvAPI_GPU_ClientFanCoolersGetStatus( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(PrivateFanCoolersStatusV1))] [In] + ValueTypeReference status); + + [FunctionId(FunctionId.NvAPI_GPU_ClientFanCoolersSetControl)] + public delegate Status NvAPI_GPU_ClientFanCoolersSetControl( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(PrivateFanCoolersControlV1))] [In] + ValueTypeReference control); + + [FunctionId(FunctionId.NvAPI_GPU_ClientIllumDevicesGetControl)] + public delegate Status NvAPI_GPU_ClientIlluminationDevicesGetControl( + [In] PhysicalGPUHandle gpu, + [Accepts(typeof(IlluminationDeviceControlParametersV1))] [In] + ValueTypeReference illuminationDeviceControlInfo + ); + + [FunctionId(FunctionId.NvAPI_GPU_ClientIllumDevicesGetInfo)] + public delegate Status NvAPI_GPU_ClientIlluminationDevicesGetInfo( + [In] PhysicalGPUHandle gpu, + [Accepts(typeof(IlluminationDeviceInfoParametersV1))] [In] + ValueTypeReference illuminationDevicesInfo + ); + + [FunctionId(FunctionId.NvAPI_GPU_ClientIllumDevicesSetControl)] + public delegate Status NvAPI_GPU_ClientIlluminationDevicesSetControl( + [In] PhysicalGPUHandle gpu, + [Accepts(typeof(IlluminationDeviceControlParametersV1))] [In] + ValueTypeReference illuminationDeviceControlInfo + ); + + [FunctionId(FunctionId.NvAPI_GPU_ClientIllumZonesGetControl)] + public delegate Status NvAPI_GPU_ClientIlluminationZonesGetControl( + [In] PhysicalGPUHandle gpu, + [Accepts(typeof(IlluminationZoneControlParametersV1))] [In] + ValueTypeReference illuminationZoneControlInfo + ); + + [FunctionId(FunctionId.NvAPI_GPU_ClientIllumZonesGetInfo)] + public delegate Status NvAPI_GPU_ClientIlluminationZonesGetInfo( + [In] PhysicalGPUHandle gpu, + [Accepts(typeof(IlluminationZoneInfoParametersV1))] [In] + ValueTypeReference illuminationZoneInfo + ); + + [FunctionId(FunctionId.NvAPI_GPU_ClientIllumZonesSetControl)] + public delegate Status NvAPI_GPU_ClientIlluminationZonesSetControl( + [In] PhysicalGPUHandle gpu, + [Accepts(typeof(IlluminationZoneControlParametersV1))] [In] + ValueTypeReference illuminationZoneControlInfo + ); + + [FunctionId(FunctionId.NvAPI_GPU_ClientPowerPoliciesGetInfo)] + public delegate Status NvAPI_GPU_ClientPowerPoliciesGetInfo( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(PrivatePowerPoliciesInfoV1))] [In] + ValueTypeReference powerInfo); + + [FunctionId(FunctionId.NvAPI_GPU_ClientPowerPoliciesGetStatus)] + public delegate Status NvAPI_GPU_ClientPowerPoliciesGetStatus( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(PrivatePowerPoliciesStatusV1))] [In] + ValueTypeReference status); + + [FunctionId(FunctionId.NvAPI_GPU_ClientPowerPoliciesSetStatus)] + public delegate Status NvAPI_GPU_ClientPowerPoliciesSetStatus( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(PrivatePowerPoliciesStatusV1))] [In] + ValueTypeReference status); + + [FunctionId(FunctionId.NvAPI_GPU_ClientPowerTopologyGetStatus)] + public delegate Status NvAPI_GPU_ClientPowerTopologyGetStatus( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(PrivatePowerTopologiesStatusV1))] [In] + ValueTypeReference status); + + [FunctionId(FunctionId.NvAPI_GPU_EnableDynamicPstates)] + public delegate Status NvAPI_GPU_EnableDynamicPStates([In] PhysicalGPUHandle physicalGpu); + + [FunctionId(FunctionId.NvAPI_GPU_EnableOverclockedPstates)] + public delegate Status NvAPI_GPU_EnableOverclockedPStates([In] PhysicalGPUHandle physicalGpu); + + [FunctionId(FunctionId.NvAPI_GPU_GetActiveOutputs)] + public delegate Status NvAPI_GPU_GetActiveOutputs( + [In] PhysicalGPUHandle physicalGpu, + [Out] out OutputId outputMask); + + [FunctionId(FunctionId.NvAPI_GPU_GetAGPAperture)] + public delegate Status NvAPI_GPU_GetAGPAperture( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint size); + + [FunctionId(FunctionId.NvAPI_GPU_GetAllClockFrequencies)] + public delegate Status NvAPI_GPU_GetAllClockFrequencies( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(ClockFrequenciesV3), typeof(ClockFrequenciesV2), typeof(ClockFrequenciesV1))] + ValueTypeReference nvClocks); + + [FunctionId(FunctionId.NvAPI_GPU_GetAllDisplayIds)] + public delegate Status NvAPI_GPU_GetAllDisplayIds( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(DisplayIdsV2))] [In] [Out] + ValueTypeArray pDisplayIds, + [In] [Out] ref uint displayIdCount); + + [FunctionId(FunctionId.NvAPI_GPU_GetArchInfo)] + public delegate Status NvAPI_GPU_GetArchInfo( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(PrivateArchitectInfoV2))] [In] + ValueTypeReference info); + + [FunctionId(FunctionId.NvAPI_GPU_GetBoardInfo)] + public delegate Status NvAPI_GPU_GetBoardInfo( + [In] PhysicalGPUHandle physicalGpu, + [Out] [In] ref BoardInfo info); + + [FunctionId(FunctionId.NvAPI_GPU_GetBusId)] + public delegate Status NvAPI_GPU_GetBusId( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint gpuBusId); + + [FunctionId(FunctionId.NvAPI_GPU_GetBusSlotId)] + public delegate Status NvAPI_GPU_GetBusSlotId( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint gpuBusSlotId); + + [FunctionId(FunctionId.NvAPI_GPU_GetBusType)] + public delegate Status NvAPI_GPU_GetBusType( + [In] PhysicalGPUHandle physicalGpu, + [Out] out GPUBusType gpuBusType); + + [FunctionId(FunctionId.NvAPI_GPU_GetClockBoostLock)] + public delegate Status NvAPI_GPU_GetClockBoostLock( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(PrivateClockBoostLockV2))] + ValueTypeReference clockLocks); + + [FunctionId(FunctionId.NvAPI_GPU_GetClockBoostMask)] + public delegate Status NvAPI_GPU_GetClockBoostMask( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(PrivateClockBoostMasksV1))] + ValueTypeReference clockMasks); + + [FunctionId(FunctionId.NvAPI_GPU_GetClockBoostRanges)] + public delegate Status NvAPI_GPU_GetClockBoostRanges( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(PrivateClockBoostRangesV1))] + ValueTypeReference clockRanges); + + [FunctionId(FunctionId.NvAPI_GPU_GetClockBoostTable)] + public delegate Status NvAPI_GPU_GetClockBoostTable( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(PrivateClockBoostTableV1))] + ValueTypeReference boostTable); + + [FunctionId(FunctionId.NvAPI_GPU_GetConnectedDisplayIds)] + public delegate Status NvAPI_GPU_GetConnectedDisplayIds( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(DisplayIdsV2))] [In] [Out] + ValueTypeArray pDisplayIds, + [In] [Out] ref uint displayIdCount, + [In] ConnectedIdsFlag flags); + + [FunctionId(FunctionId.NvAPI_GPU_GetCoolerPolicyTable)] + public delegate Status NvAPI_GPU_GetCoolerPolicyTable( + [In] PhysicalGPUHandle physicalGpu, + [In] uint index, + [In] [Accepts(typeof(PrivateCoolerPolicyTableV1))] + ValueTypeReference coolerPolicyTable, + [Out] out uint count); + + [FunctionId(FunctionId.NvAPI_GPU_GetCoolerSettings)] + public delegate Status NvAPI_GPU_GetCoolerSettings( + [In] PhysicalGPUHandle physicalGpu, + [In] CoolerTarget coolerIndex, + [In] [Accepts(typeof(PrivateCoolerSettingsV1))] + ValueTypeReference coolerSettings); + + [FunctionId(FunctionId.NvAPI_GPU_GetCoreVoltageBoostPercent)] + public delegate Status NvAPI_GPU_GetCoreVoltageBoostPercent( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(PrivateVoltageBoostPercentV1))] + ValueTypeReference voltageBoostPercent); + + [FunctionId(FunctionId.NvAPI_GPU_GetCurrentAGPRate)] + public delegate Status NvAPI_GPU_GetCurrentAGPRate( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint rate); + + [FunctionId(FunctionId.NvAPI_GPU_GetCurrentFanSpeedLevel)] + public delegate Status NvAPI_GPU_GetCurrentFanSpeedLevel( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint fanLevel); + + [FunctionId(FunctionId.NvAPI_GPU_GetCurrentPCIEDownstreamWidth)] + public delegate Status NvAPI_GPU_GetCurrentPCIEDownstreamWidth( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint width); + + [FunctionId(FunctionId.NvAPI_GPU_GetCurrentPstate)] + public delegate Status NvAPI_GPU_GetCurrentPState( + [In] PhysicalGPUHandle physicalGpu, + [Out] out PerformanceStateId performanceStateId); + + [FunctionId(FunctionId.NvAPI_GPU_GetCurrentThermalLevel)] + public delegate Status NvAPI_GPU_GetCurrentThermalLevel( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint thermalLevel); + + [FunctionId(FunctionId.NvAPI_GPU_GetCurrentVoltage)] + public delegate Status NvAPI_GPU_GetCurrentVoltage( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(PrivateVoltageStatusV1))] + ValueTypeReference voltageStatus); + + [FunctionId(FunctionId.NvAPI_GPU_GetDynamicPstatesInfoEx)] + public delegate Status NvAPI_GPU_GetDynamicPStatesInfoEx( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(DynamicPerformanceStatesInfoV1))] + ValueTypeReference performanceStatesInfoEx); + + [FunctionId(FunctionId.NvAPI_GPU_GetECCConfigurationInfo)] + public delegate Status NvAPI_GPU_GetECCConfigurationInfo( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(ECCConfigurationInfoV1))] + ValueTypeReference eccConfigurationInfo); + + [FunctionId(FunctionId.NvAPI_GPU_GetECCErrorInfo)] + public delegate Status NvAPI_GPU_GetECCErrorInfo( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(ECCErrorInfoV1))] ValueTypeReference eccErrorInfo); + + [FunctionId(FunctionId.NvAPI_GPU_GetECCStatusInfo)] + public delegate Status NvAPI_GPU_GetECCStatusInfo( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(ECCStatusInfoV1))] + ValueTypeReference eccStatusInfo); + + [FunctionId(FunctionId.NvAPI_GPU_GetEDID)] + public delegate Status NvAPI_GPU_GetEDID( + [In] PhysicalGPUHandle physicalGpu, + [In] OutputId outputId, + [Accepts(typeof(EDIDV3), typeof(EDIDV2), typeof(EDIDV1))] [In] + ValueTypeReference edid); + + [FunctionId(FunctionId.NvAPI_GPU_GetFBWidthAndLocation)] + public delegate Status NvAPI_GPU_GetFBWidthAndLocation( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint width, + [Out] out uint location); + + [FunctionId(FunctionId.NvAPI_GPU_GetFoundry)] + public delegate Status NvAPI_GPU_GetFoundry( + [In] PhysicalGPUHandle physicalGpu, + [Out] out GPUFoundry pFoundry); + + [FunctionId(FunctionId.NvAPI_GPU_GetFullName)] + public delegate Status NvAPI_GPU_GetFullName( + [In] PhysicalGPUHandle physicalGpu, + [Out] out ShortString name); + + [FunctionId(FunctionId.NvAPI_GPU_GetGpuCoreCount)] + public delegate Status NvAPI_GPU_GetGpuCoreCount( + [In] PhysicalGPUHandle gpuHandle, + [Out] out uint count); + + [FunctionId(FunctionId.NvAPI_GPU_GetGPUType)] + public delegate Status NvAPI_GPU_GetGPUType( + [In] PhysicalGPUHandle physicalGpu, + [Out] out GPUType gpuType); + + [FunctionId(FunctionId.NvAPI_GPU_GetIllumination)] + public delegate Status NvAPI_GPU_GetIllumination( + [Accepts(typeof(GetIlluminationParameterV1))] [In] + ValueTypeReference illuminationInfo); + + [FunctionId(FunctionId.NvAPI_GPU_GetIRQ)] + public delegate Status NvAPI_GPU_GetIRQ( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint gpuIRQ); + + [FunctionId(FunctionId.NvAPI_GPU_GetLogicalFBWidthAndLocation)] + public delegate Status NvAPI_GPU_GetLogicalFBWidthAndLocation( + [In] LogicalGPUHandle logicalGpu, + [Out] out uint width, + [Out] out uint location); + + [FunctionId(FunctionId.NvAPI_GPU_GetMemoryInfo)] + public delegate Status NvAPI_GPU_GetMemoryInfo( + [In] PhysicalGPUHandle physicalGpu, + [In] + [Accepts(typeof(DisplayDriverMemoryInfoV3), typeof(DisplayDriverMemoryInfoV2), + typeof(DisplayDriverMemoryInfoV1))] + ValueTypeReference memoryInfo); + + [FunctionId(FunctionId.NvAPI_GPU_GetOutputType)] + public delegate Status NvAPI_GPU_GetOutputType( + [In] PhysicalGPUHandle physicalGpu, + [In] uint outputId, + [Out] out OutputType outputType); + + + [FunctionId(FunctionId.NvAPI_GPU_GetPartitionCount)] + public delegate Status NvAPI_GPU_GetPartitionCount( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint count); + + [FunctionId(FunctionId.NvAPI_GPU_GetPCIEInfo)] + public delegate Status NvAPI_GPU_GetPCIEInfo( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(PrivatePCIeInfoV2))] [In] + ValueTypeReference pcieInfo); + + [FunctionId(FunctionId.NvAPI_GPU_GetPCIIdentifiers)] + public delegate Status NvAPI_GPU_GetPCIIdentifiers( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint deviceId, + [Out] out uint subSystemId, + [Out] out uint revisionId, + [Out] out uint extDeviceId); + + [FunctionId(FunctionId.NvAPI_GPU_GetPerfDecreaseInfo)] + public delegate Status NvAPI_GPU_GetPerfDecreaseInfo( + [In] PhysicalGPUHandle gpu, + [Out] out PerformanceDecreaseReason performanceDecreaseReason); + + [FunctionId(FunctionId.NvAPI_GPU_GetPhysicalFrameBufferSize)] + public delegate Status NvAPI_GPU_GetPhysicalFrameBufferSize( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint size); + + [FunctionId(FunctionId.NvAPI_GPU_GetPstates20)] + public delegate Status NvAPI_GPU_GetPStates20( + [In] PhysicalGPUHandle physicalGpu, + [Accepts( + typeof(PerformanceStates20InfoV3), + typeof(PerformanceStates20InfoV2), + typeof(PerformanceStates20InfoV1) + )] + [In] + ValueTypeReference performanceStatesInfo); + + [FunctionId(FunctionId.NvAPI_GPU_GetPstatesInfoEx)] + public delegate Status NvAPI_GPU_GetPStatesInfoEx( + [In] PhysicalGPUHandle physicalGpu, + [Accepts( + typeof(PerformanceStatesInfoV3), + typeof(PerformanceStatesInfoV2), + typeof(PerformanceStatesInfoV1) + )] + [In] + ValueTypeReference performanceStatesInfo, + [In] GetPerformanceStatesInfoFlags flags); + + [FunctionId(FunctionId.NvAPI_GPU_GetQuadroStatus)] + public delegate Status NvAPI_GPU_GetQuadroStatus( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint isQuadro); + + [FunctionId(FunctionId.NvAPI_GPU_GetRamBankCount)] + public delegate Status NvAPI_GPU_GetRamBankCount( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint count); + + [FunctionId(FunctionId.NvAPI_GPU_GetRamBusWidth)] + public delegate Status NvAPI_GPU_GetRamBusWidth( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint busWidth); + + [FunctionId(FunctionId.NvAPI_GPU_GetRamMaker)] + public delegate Status NvAPI_GPU_GetRamMaker( + [In] PhysicalGPUHandle physicalGpu, + [Out] out GPUMemoryMaker maker); + + [FunctionId(FunctionId.NvAPI_GPU_GetRamType)] + public delegate Status NvAPI_GPU_GetRamType( + [In] PhysicalGPUHandle physicalGpu, + [Out] out GPUMemoryType type); + + [FunctionId(FunctionId.NvAPI_GPU_GetROPCount)] + public delegate Status NvAPI_GPU_GetROPCount( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint count); + + [FunctionId(FunctionId.NvAPI_GPU_GetShaderPipeCount)] + public delegate Status NvAPI_GPU_GetShaderPipeCount( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint count); + + [FunctionId(FunctionId.NvAPI_GPU_GetShaderSubPipeCount)] + public delegate Status NvAPI_GPU_GetShaderSubPipeCount( + [In] PhysicalGPUHandle gpuHandle, + [Out] out uint count); + + [FunctionId(FunctionId.NvAPI_GPU_GetShortName)] + public delegate Status NvAPI_GPU_GetShortName( + [In] PhysicalGPUHandle physicalGpu, + [Out] out ShortString name); + + [FunctionId(FunctionId.NvAPI_GPU_GetSystemType)] + public delegate Status NvAPI_GPU_GetSystemType( + [In] PhysicalGPUHandle physicalGpu, + [Out] out SystemType systemType); + + [FunctionId(FunctionId.NvAPI_GPU_GetTachReading)] + public delegate Status NvAPI_GPU_GetTachReading( + [In] PhysicalGPUHandle gpuHandle, + [Out] out uint value); + + [FunctionId(FunctionId.NvAPI_GPU_GetThermalPoliciesInfo)] + public delegate Status NvAPI_GPU_GetThermalPoliciesInfo( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(PrivateThermalPoliciesInfoV2))] [In] + ValueTypeReference info); + + [FunctionId(FunctionId.NvAPI_GPU_GetThermalPoliciesStatus)] + public delegate Status NvAPI_GPU_GetThermalPoliciesStatus( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(PrivateThermalPoliciesStatusV2))] [In] + ValueTypeReference info); + + [FunctionId(FunctionId.NvAPI_GPU_GetThermalSettings)] + public delegate Status NvAPI_GPU_GetThermalSettings( + [In] PhysicalGPUHandle physicalGpu, + [In] ThermalSettingsTarget sensorIndex, + [In] [Accepts(typeof(ThermalSettingsV2), typeof(ThermalSettingsV1))] + ValueTypeReference thermalSettings); + + [FunctionId(FunctionId.NvAPI_GPU_GetTotalSMCount)] + public delegate Status NvAPI_GPU_GetTotalSMCount( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint count); + + [FunctionId(FunctionId.NvAPI_GPU_GetTotalSPCount)] + public delegate Status NvAPI_GPU_GetTotalSPCount( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint count); + + [FunctionId(FunctionId.NvAPI_GPU_GetTotalTPCCount)] + public delegate Status NvAPI_GPU_GetTotalTPCCount( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint count); + + [FunctionId(FunctionId.NvAPI_GPU_GetUsages)] + public delegate Status NvAPI_GPU_GetUsages( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(PrivateUsagesInfoV1))] + ValueTypeReference usageInfo); + + [FunctionId(FunctionId.NvAPI_GPU_GetVbiosOEMRevision)] + public delegate Status NvAPI_GPU_GetVbiosOEMRevision( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint biosOEMRevision); + + [FunctionId(FunctionId.NvAPI_GPU_GetVbiosRevision)] + public delegate Status NvAPI_GPU_GetVbiosRevision( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint biosRevision); + + [FunctionId(FunctionId.NvAPI_GPU_GetVbiosVersionString)] + public delegate Status NvAPI_GPU_GetVbiosVersionString( + [In] PhysicalGPUHandle physicalGpu, + [Out] out ShortString biosVersion); + + [FunctionId(FunctionId.NvAPI_GPU_GetVFPCurve)] + public delegate Status NvAPI_GPU_GetVFPCurve( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(PrivateVFPCurveV1))] + ValueTypeReference vfpCurve); + + [FunctionId(FunctionId.NvAPI_GPU_GetVirtualFrameBufferSize)] + public delegate Status NvAPI_GPU_GetVirtualFrameBufferSize( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint size); + + [FunctionId(FunctionId.NvAPI_GPU_GetVPECount)] + public delegate Status NvAPI_GPU_GetVPECount( + [In] PhysicalGPUHandle physicalGpu, + [Out] out uint count); + + [FunctionId(FunctionId.NvAPI_GPU_PerfPoliciesGetInfo)] + public delegate Status NvAPI_GPU_PerfPoliciesGetInfo( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(PrivatePerformanceInfoV1))] + ValueTypeReference performanceInfo); + + [FunctionId(FunctionId.NvAPI_GPU_PerfPoliciesGetStatus)] + public delegate Status NvAPI_GPU_PerfPoliciesGetStatus( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(PrivatePerformanceStatusV1))] + ValueTypeReference performanceStatus); + + [FunctionId(FunctionId.NvAPI_GPU_QueryActiveApps)] + public delegate Status NvAPI_GPU_QueryActiveApps( + [In] PhysicalGPUHandle gpu, + [In] [Accepts(typeof(PrivateActiveApplicationV2))] + ValueTypeArray applications, + [In] [Out] ref uint numberOfApplications + ); + + + [FunctionId(FunctionId.NvAPI_GPU_QueryIlluminationSupport)] + public delegate Status NvAPI_GPU_QueryIlluminationSupport( + [Accepts(typeof(QueryIlluminationSupportParameterV1))] [In] + ValueTypeReference illuminationSupportInfo); + + [FunctionId(FunctionId.NvAPI_GPU_ResetECCErrorInfo)] + public delegate Status NvAPI_GPU_ResetECCErrorInfo( + [In] PhysicalGPUHandle physicalGpu, + [In] byte resetCurrent, + [In] byte resetAggregated + ); + + [FunctionId(FunctionId.NvAPI_GPU_RestoreCoolerPolicyTable)] + public delegate Status NvAPI_GPU_RestoreCoolerPolicyTable( + [In] PhysicalGPUHandle physicalGpu, + [In] uint[] indexes, + [In] uint indexesCount, + [In] CoolerPolicy policy); + + [FunctionId(FunctionId.NvAPI_GPU_RestoreCoolerSettings)] + public delegate Status NvAPI_GPU_RestoreCoolerSettings( + [In] PhysicalGPUHandle physicalGpu, + [In] uint[] indexes, + [In] uint indexesCount); + + [FunctionId(FunctionId.NvAPI_GPU_SetClockBoostLock)] + public delegate Status NvAPI_GPU_SetClockBoostLock( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(PrivateClockBoostLockV2))] + ValueTypeReference clockLocks); + + [FunctionId(FunctionId.NvAPI_GPU_SetClockBoostTable)] + public delegate Status NvAPI_GPU_SetClockBoostTable( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(PrivateClockBoostTableV1))] + ValueTypeReference boostTable); + + [FunctionId(FunctionId.NvAPI_GPU_SetCoolerLevels)] + public delegate Status NvAPI_GPU_SetCoolerLevels( + [In] PhysicalGPUHandle physicalGpu, + [In] uint index, + [In] [Accepts(typeof(PrivateCoolerLevelsV1))] + ValueTypeReference coolerLevels, + [In] uint count); + + [FunctionId(FunctionId.NvAPI_GPU_SetCoolerPolicyTable)] + public delegate Status NvAPI_GPU_SetCoolerPolicyTable( + [In] PhysicalGPUHandle physicalGpu, + [In] uint index, + [In] [Accepts(typeof(PrivateCoolerPolicyTableV1))] + ValueTypeReference coolerLevels, + [In] uint count); + + [FunctionId(FunctionId.NvAPI_GPU_SetCoreVoltageBoostPercent)] + public delegate Status NvAPI_GPU_SetCoreVoltageBoostPercent( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(PrivateVoltageBoostPercentV1))] + ValueTypeReference voltageBoostPercent); + + [FunctionId(FunctionId.NvAPI_GPU_SetECCConfiguration)] + public delegate Status NvAPI_GPU_SetECCConfiguration( + [In] PhysicalGPUHandle physicalGpu, + [In] byte isEnable, + [In] byte isEnableImmediately + ); + + [FunctionId(FunctionId.NvAPI_GPU_SetEDID)] + public delegate Status NvAPI_GPU_SetEDID( + [In] PhysicalGPUHandle physicalGpu, + [In] uint outputId, + [Accepts(typeof(EDIDV3), typeof(EDIDV2), typeof(EDIDV1))] [In] + ValueTypeReference edid); + + + [FunctionId(FunctionId.NvAPI_GPU_SetIllumination)] + public delegate Status NvAPI_GPU_SetIllumination( + [Accepts(typeof(SetIlluminationParameterV1))] [In] + ValueTypeReference illuminationInfo); + + [FunctionId(FunctionId.NvAPI_GPU_SetPstates20)] + public delegate Status NvAPI_GPU_SetPStates20( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(PerformanceStates20InfoV3), typeof(PerformanceStates20InfoV2), + typeof(PerformanceStates20InfoV1))] + [In] + ValueTypeReference performanceStatesInfo); + + [FunctionId(FunctionId.NvAPI_GPU_SetThermalPoliciesStatus)] + public delegate Status NvAPI_GPU_SetThermalPoliciesStatus( + [In] PhysicalGPUHandle physicalGpu, + [Accepts(typeof(PrivateThermalPoliciesStatusV2))] [In] + ValueTypeReference info); + + [FunctionId(FunctionId.NvAPI_GPU_ValidateOutputCombination)] + public delegate Status NvAPI_GPU_ValidateOutputCombination( + [In] PhysicalGPUHandle physicalGpu, + [In] OutputId outputMask); + + [FunctionId(FunctionId.NvAPI_I2CRead)] + public delegate Status NvAPI_I2CRead( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(I2CInfoV3), typeof(I2CInfoV2))] ValueTypeReference i2cInfo + ); + + [FunctionId(FunctionId.NvAPI_I2CWrite)] + public delegate Status NvAPI_I2CWrite( + [In] PhysicalGPUHandle physicalGpu, + [In] [Accepts(typeof(I2CInfoV3), typeof(I2CInfoV2))] ValueTypeReference i2cInfo + ); + + [FunctionId(FunctionId.NvAPI_SYS_GetDisplayIdFromGpuAndOutputId)] + public delegate Status NvAPI_SYS_GetDisplayIdFromGpuAndOutputId( + [In] PhysicalGPUHandle gpu, + [In] OutputId outputId, + [Out] out uint displayId); + + [FunctionId(FunctionId.NvAPI_SYS_GetGpuAndOutputIdFromDisplayId)] + public delegate Status NvAPI_SYS_GetGpuAndOutputIdFromDisplayId( + [In] uint displayId, + [Out] out PhysicalGPUHandle gpu, + [Out] out OutputId outputId); + + [FunctionId(FunctionId.NvAPI_SYS_GetPhysicalGpuFromDisplayId)] + public delegate Status NvAPI_SYS_GetPhysicalGpuFromDisplayId( + [In] uint displayId, + [Out] out PhysicalGPUHandle gpu); + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Delegates/General.cs b/NvAPIWrapper/Native/Delegates/General.cs new file mode 100644 index 0000000..ab5e2cd --- /dev/null +++ b/NvAPIWrapper/Native/Delegates/General.cs @@ -0,0 +1,43 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; + +// ReSharper disable InconsistentNaming + +namespace NvAPIWrapper.Native.Delegates +{ + internal static class General + { + [FunctionId(FunctionId.NvAPI_GetErrorMessage)] + public delegate Status NvAPI_GetErrorMessage([In] Status status, out ShortString message); + + [FunctionId(FunctionId.NvAPI_GetInterfaceVersionString)] + public delegate Status NvAPI_GetInterfaceVersionString(out ShortString version); + + [FunctionId(FunctionId.NvAPI_Initialize)] + public delegate Status NvAPI_Initialize(); + + + [FunctionId(FunctionId.NvAPI_RestartDisplayDriver)] + public delegate Status NvAPI_RestartDisplayDriver(); + + [FunctionId(FunctionId.NvAPI_SYS_GetChipSetInfo)] + public delegate Status NvAPI_SYS_GetChipSetInfo( + [In] [Accepts(typeof(ChipsetInfoV4), typeof(ChipsetInfoV3), typeof(ChipsetInfoV2), typeof(ChipsetInfoV1))] + ValueTypeReference chipsetInfo); + + [FunctionId(FunctionId.NvAPI_SYS_GetDriverAndBranchVersion)] + public delegate Status NvAPI_SYS_GetDriverAndBranchVersion( + out uint driverVersion, + out ShortString buildBranchString); + + [FunctionId(FunctionId.NvAPI_SYS_GetLidAndDockInfo)] + public delegate Status NvAPI_SYS_GetLidAndDockInfo([In] [Out] ref LidDockParameters lidAndDock); + + [FunctionId(FunctionId.NvAPI_Unload)] + public delegate Status NvAPI_Unload(); + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/ColorDataColorimetry.cs b/NvAPIWrapper/Native/Display/ColorDataColorimetry.cs new file mode 100644 index 0000000..e87908a --- /dev/null +++ b/NvAPIWrapper/Native/Display/ColorDataColorimetry.cs @@ -0,0 +1,74 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible values for color data color space + /// + public enum ColorDataColorimetry : uint + { + /// + /// RGB color space + /// + RGB = 0, + + /// + /// YCC601 color space + /// + YCC601, + + /// + /// YCC709 color space + /// + YCC709, + + /// + /// XVYCC601 color space + /// + XVYCC601, + + /// + /// XVYCC709 color space + /// + XVYCC709, + + /// + /// SYCC601 color space + /// + SYCC601, + + /// + /// ADOBEYCC601 color space + /// + ADOBEYCC601, + + /// + /// ADOBERGB color space + /// + ADOBERGB, + + /// + /// BT2020RGB color space + /// + BT2020RGB, + + /// + /// BT2020YCC color space + /// + BT2020YCC, + + /// + /// BT2020cYCC color space + /// + // ReSharper disable once InconsistentNaming + BT2020cYCC, + + /// + /// Default color space + /// + Default = 0xFE, + + /// + /// Automatically select color space + /// + Auto = 0xFF + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/ColorDataCommand.cs b/NvAPIWrapper/Native/Display/ColorDataCommand.cs new file mode 100644 index 0000000..cf1761f --- /dev/null +++ b/NvAPIWrapper/Native/Display/ColorDataCommand.cs @@ -0,0 +1,28 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible values for the color data command + /// + public enum ColorDataCommand : uint + { + /// + /// Get the current color data + /// + Get = 1, + + /// + /// Set the current color data + /// + Set, + + /// + /// Check if the passed color data is supported + /// + IsSupportedColor, + + /// + /// Get the default color data + /// + GetDefault + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/ColorDataDepth.cs b/NvAPIWrapper/Native/Display/ColorDataDepth.cs new file mode 100644 index 0000000..e77eb89 --- /dev/null +++ b/NvAPIWrapper/Native/Display/ColorDataDepth.cs @@ -0,0 +1,38 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible values for the color data depth + /// + public enum ColorDataDepth : uint + { + /// + /// Default color depth meaning that the current setting should be kept + /// + Default = 0, + + /// + /// 6bit per color depth + /// + BPC6 = 1, + + /// + /// 8bit per color depth + /// + BPC8 = 2, + + /// + /// 10bit per color depth + /// + BPC10 = 3, + + /// + /// 12bit per color depth + /// + BPC12 = 4, + + /// + /// 16bit per color depth + /// + BPC16 = 5 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/ColorDataDesktopDepth.cs b/NvAPIWrapper/Native/Display/ColorDataDesktopDepth.cs new file mode 100644 index 0000000..7d5673d --- /dev/null +++ b/NvAPIWrapper/Native/Display/ColorDataDesktopDepth.cs @@ -0,0 +1,38 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible values for the color data desktop color depth + /// + public enum ColorDataDesktopDepth : uint + { + /// + /// Default color depth meaning that the current setting should be kept + /// + Default = 0x0, + + /// + /// 8bit per integer color component + /// + BPC8 = 0x1, + + /// + /// 10bit integer per color component + /// + BPC10 = 0x2, + + /// + /// 16bit float per color component + /// + BPC16Float = 0x3, + + /// + /// 16bit float per color component wide color gamut + /// + BPC16FloatWcg = 0x4, + + /// + /// 16bit float per color component HDR + /// + BPC16FloatHDR = 0x5 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/ColorDataDynamicRange.cs b/NvAPIWrapper/Native/Display/ColorDataDynamicRange.cs new file mode 100644 index 0000000..16dee35 --- /dev/null +++ b/NvAPIWrapper/Native/Display/ColorDataDynamicRange.cs @@ -0,0 +1,23 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible values for color data dynamic range + /// + public enum ColorDataDynamicRange : uint + { + /// + /// VESA standard progress signal + /// + VESA = 0, + + /// + /// CEA interlaced signal + /// + CEA, + + /// + /// Automatically select the best value + /// + Auto + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/ColorDataFormat.cs b/NvAPIWrapper/Native/Display/ColorDataFormat.cs new file mode 100644 index 0000000..42f26e2 --- /dev/null +++ b/NvAPIWrapper/Native/Display/ColorDataFormat.cs @@ -0,0 +1,38 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible color data color format values + /// + public enum ColorDataFormat : uint + { + /// + /// RGB color format + /// + RGB = 0, + + /// + /// YUV422 color format + /// + YUV422, + + /// + /// YUV444 color format + /// + YUV444, + + /// + /// YUV420 color format + /// + YUV420, + + /// + /// Default color format + /// + Default = 0xFE, + + /// + /// Automatically select the best color format + /// + Auto = 0xFF + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/ColorDataHDRCommand.cs b/NvAPIWrapper/Native/Display/ColorDataHDRCommand.cs new file mode 100644 index 0000000..9cb1fd3 --- /dev/null +++ b/NvAPIWrapper/Native/Display/ColorDataHDRCommand.cs @@ -0,0 +1,18 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible values for the HDR color data command + /// + public enum ColorDataHDRCommand : uint + { + /// + /// Get the current HDR color data + /// + Get = 0, + + /// + /// Set the current HDR color data + /// + Set = 1 + } +} diff --git a/NvAPIWrapper/Native/Display/ColorDataHDRMode.cs b/NvAPIWrapper/Native/Display/ColorDataHDRMode.cs new file mode 100644 index 0000000..7d49042 --- /dev/null +++ b/NvAPIWrapper/Native/Display/ColorDataHDRMode.cs @@ -0,0 +1,61 @@ +using System; + +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible color data HDR modes + /// + public enum ColorDataHDRMode : uint + { + /// + /// Turn off HDR. + /// + Off = 0, + + /// + /// Source: CCCS [a.k.a FP16 scRGB, linear, sRGB primaries, [-65504,0, 65504] range, RGB(1,1,1) = 80nits] + /// Output: UHDA HDR [a.k.a HDR10, RGB/YCC 10/12bpc ST2084(PQ) EOTF RGB(1,1,1) = 10000 nits, Rec2020 color primaries, + /// ST2086 static HDR metadata]. + /// This is the only supported production HDR mode. + /// + UHDA = 2, + + /// + /// Source: CCCS (a.k.a FP16 scRGB) + /// Output: EDR (Extended Dynamic Range) - HDR content is tone-mapped and gamut mapped to output on regular SDR display + /// set to max luminance ( ~300 nits ). + /// + [Obsolete("Do not use! Internal test mode only, to be removed.", false)] + EDR = 3, + + /// + /// Source: any + /// Output: SDR (Standard Dynamic Range), we continuously send SDR EOTF InfoFrame signaling, HDMI compliance testing. + /// + [Obsolete("Do not use! Internal test mode only, to be removed.", false)] + SDR = 4, + + /// + /// Source: HDR10 RGB 10bpc + /// Output: HDR10 RGB 10 colorDepth - signal UHDA HDR mode (PQ + Rec2020) to the sink but send source pixel values + /// unmodified (no PQ or Rec2020 conversions) - assumes source is already in HDR10 format. + /// + [Obsolete("Experimental mode only, not for production!", false)] + UHDAPassthrough = 5, + + /// + /// Source: CCCS (a.k.a FP16 scRGB) + /// Output: notebook HDR + /// + [Obsolete("Do not use! Internal test mode only, to be removed.", false)] + UHDANB = 6, + + /// + /// Source: RGB8 Dolby Vision encoded (12 colorDepth YCbCr422 packed into RGB8) + /// Output: Dolby Vision encoded : Application is to encoded frames in DV format and embed DV dynamic metadata as + /// described in Dolby Vision specification. + /// + [Obsolete("Experimental mode only, not for production!", false)] + DolbyVision = 7 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/ColorDataSelectionPolicy.cs b/NvAPIWrapper/Native/Display/ColorDataSelectionPolicy.cs new file mode 100644 index 0000000..86468b2 --- /dev/null +++ b/NvAPIWrapper/Native/Display/ColorDataSelectionPolicy.cs @@ -0,0 +1,28 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Possible values for the color data selection policy + /// + public enum ColorDataSelectionPolicy : uint + { + /// + /// Application or the Nvidia Control Panel user configuration are used to decide the best color format + /// + User = 0, + + /// + /// Driver or the Operating System decides the best color format + /// + BestQuality = 1, + + /// + /// Default value, + /// + Default = BestQuality, + + /// + /// Unknown policy + /// + Unknown = 0xFF + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/ColorFormat.cs b/NvAPIWrapper/Native/Display/ColorFormat.cs new file mode 100644 index 0000000..56d436f --- /dev/null +++ b/NvAPIWrapper/Native/Display/ColorFormat.cs @@ -0,0 +1,33 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Possible color formats + /// + public enum ColorFormat + { + /// + /// Unknown, driver will choose one automatically. + /// + Unknown = 0, + + /// + /// 8bpp mode + /// + P8 = 41, + + /// + /// 16bpp mode + /// + R5G6B5 = 23, + + /// + /// 32bpp mode + /// + A8R8G8B8 = 21, + + /// + /// 64bpp (floating point) + /// + A16B16G16R16F = 113 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/DisplayConfigFlags.cs b/NvAPIWrapper/Native/Display/DisplayConfigFlags.cs new file mode 100644 index 0000000..f92ed18 --- /dev/null +++ b/NvAPIWrapper/Native/Display/DisplayConfigFlags.cs @@ -0,0 +1,41 @@ +using System; + +namespace NvAPIWrapper.Native.Display +{ + /// + /// Flags for applying settings, used by NvAPI_DISP_SetDisplayConfig() + /// + [Flags] + public enum DisplayConfigFlags + { + /// + /// None + /// + None = 0, + + /// + /// Do not apply + /// + ValidateOnly = 0x00000001, + + /// + /// Save to the persistence storage + /// + SaveToPersistence = 0x00000002, + + /// + /// Driver reload is permitted if necessary + /// + DriverReloadAllowed = 0x00000004, + + /// + /// Refresh OS mode list. + /// + ForceModeEnumeration = 0x00000008, + + /// + /// Tell OS to avoid optimizing CommitVidPn call during a modeset + /// + ForceCommitVideoPresentNetwork = 0x00000010 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/DisplayPortColorDepth.cs b/NvAPIWrapper/Native/Display/DisplayPortColorDepth.cs new file mode 100644 index 0000000..a8ad307 --- /dev/null +++ b/NvAPIWrapper/Native/Display/DisplayPortColorDepth.cs @@ -0,0 +1,34 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Possible display port color depths + /// + public enum DisplayPortColorDepth : uint + { + /// + /// Default color depth + /// + Default = 0, + /// + /// 6 bit per color color depth + /// + BPC6, + /// + /// 8 bit per color color depth + /// + BPC8, + /// + /// 10 bit per color color depth + /// + BPC10, + /// + /// 12 bit per color color depth + /// + BPC12, + + /// + /// 16 bit per color color depth + /// + BPC16, + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/DisplayPortColorFormat.cs b/NvAPIWrapper/Native/Display/DisplayPortColorFormat.cs new file mode 100644 index 0000000..8ab1367 --- /dev/null +++ b/NvAPIWrapper/Native/Display/DisplayPortColorFormat.cs @@ -0,0 +1,23 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Possible display port color formats + /// + public enum DisplayPortColorFormat : uint + { + /// + /// RGB color format + /// + RGB = 0, + + /// + /// YCbCr422 color format + /// + YCbCr422 = 1, + + /// + /// YCbCr444 color format + /// + YCbCr444 = 2 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameAudioChannelAllocation.cs b/NvAPIWrapper/Native/Display/InfoFrameAudioChannelAllocation.cs new file mode 100644 index 0000000..0704a12 --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameAudioChannelAllocation.cs @@ -0,0 +1,300 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible audio channel allocations (speaker placements) + /// + public enum InfoFrameAudioChannelAllocation : uint + { + /// + /// [0] Empty [1] Empty [2] Empty [3] Empty [4] Empty [5] Empty [6] Front Right [7] Front Left + /// + FrFl = 0, + + /// + /// [0] Empty [1] Empty [2] Empty [3] Empty [4] Empty [5] Low Frequency Effects [6] Front Right [7] Front Left + /// + LfeFrFl, + + /// + /// [0] Empty [1] Empty [2] Empty [3] Empty [4] Front Center [5] Empty [6] Front Right [7] Front Left + /// + FcFrFl, + + /// + /// [0] Empty [1] Empty [2] Empty [3] Empty [4] Front Center [5] Low Frequency Effects [6] Front Right [7] Front Left + /// + FcLfeFrFl, + + /// + /// [0] Empty [1] Empty [2] Empty [3] Rear Center [4] Empty [5] Empty [6] Front Right [7] Front Left + /// + RcFrFl, + + /// + /// [0] Empty [1] Empty [2] Empty [3] Rear Center [4] Empty [5] Low Frequency Effects [6] Front Right [7] Front Left + /// + RcLfeFrFl, + + /// + /// [0] Empty [1] Empty [2] Empty [3] Rear Center [4] Front Center [5] Empty [6] Front Right [7] Front Left + /// + RcFcFrFl, + + /// + /// [0] Empty [1] Empty [2] Empty [3] Rear Center [4] Front Center [5] Low Frequency Effects [6] Front Right [7] Front + /// Left + /// + RcFcLfeFrFl, + + /// + /// [0] Empty [1] Empty [2] Rear Right [3] Rear Left [4] Empty [5] Empty [6] Front Right [7] Front Left + /// + RrRlFrFl, + + /// + /// [0] Empty [1] Empty [2] Rear Right [3] Rear Left [4] Empty [5] Low Frequency Effects [6] Front Right [7] Front Left + /// + RrRlLfeFrFl, + + /// + /// [0] Empty [1] Empty [2] Rear Right [3] Rear Left [4] Front Center [5] Empty [6] Front Right [7] Front Left + /// + RrRlFcFrFl, + + /// + /// [0] Empty [1] Empty [2] Rear Right [3] Rear Left [4] Front Center [5] Low Frequency Effects [6] Front Right [7] + /// Front Left + /// + RrRlFcLfeFrFl, + + /// + /// [0] Empty [1] Rear Center [2] Rear Right [3] Rear Left [4] Empty [5] Empty [6] Front Right [7] Front Left + /// + RcRrRlFrFl, + + /// + /// [0] Empty [1] Rear Center [2] Rear Right [3] Rear Left [4] Empty [5] Low Frequency Effects [6] Front Right [7] + /// Front Left + /// + RcRrRlLfeFrFl, + + /// + /// [0] Empty [1] Rear Center [2] Rear Right [3] Rear Left [4] Front Center [5] Empty [6] Front Right [7] Front Left + /// + RcRrRlFcFrFl, + + /// + /// [0] Empty [1] Rear Center [2] Rear Right [3] Rear Left [4] Front Center [5] Low Frequency Effects [6] Front Right + /// [7] Front Left + /// + RcRrRlFcLfeFrFl, + + /// + /// [0] Rear Right Of Center [1] Rear Left Of Center [2] Rear Right [3] Rear Left [4] Empty [5] Empty [6] Front Right + /// [7] Front Left + /// + RrcRlcRrRlFrFl, + + /// + /// [0] Rear Right Of Center [1] Rear Left Of Center [2] Rear Right [3] Rear Left [4] Empty [5] Low Frequency Effects + /// [6] Front Right [7] Front Left + /// + RrcRlcRrRlLfeFrFl, + + /// + /// [0] Rear Right Of Center [1] Rear Left Of Center [2] Rear Right [3] Rear Left [4] Front Center [5] Empty [6] Front + /// Right [7] Front Left + /// + RrcRlcRrRlFcFrFl, + + /// + /// [0] Rear Right Of Center [1] Rear Left Of Center [2] Rear Right [3] Rear Left [4] Front Center [5] Low Frequency + /// Effects [6] Front Right [7] Front Left + /// + RrcRlcRrRlFcLfeFrFl, + + /// + /// [0] Front Right Of Center [1] Front Left Of Center [2] Empty [3] Empty [4] Empty [5] Empty [6] Front Right [7] + /// Front Left + /// + FrcFlcFrFl, + + /// + /// [0] Front Right Of Center [1] Front Left Of Center [2] Empty [3] Empty [4] Empty [5] Low Frequency Effects [6] + /// Front Right [7] Front Left + /// + FrcFlcLfeFrFl, + + /// + /// [0] Front Right Of Center [1] Front Left Of Center [2] Empty [3] Empty [4] Front Center [5] Empty [6] Front Right + /// [7] Front Left + /// + FrcFlcFcFrFl, + + /// + /// [0] Front Right Of Center [1] Front Left Of Center [2] Empty [3] Empty [4] Front Center [5] Low Frequency Effects + /// [6] Front Right [7] Front Left + /// + FrcFlcFcLfeFrFl, + + /// + /// [0] Front Right Of Center [1] Front Left Of Center [2] Empty [3] Rear Center [4] Empty [5] Empty [6] Front Right + /// [7] Front Left + /// + FrcFlcRcFrFl, + + /// + /// [0] Front Right Of Center [1] Front Left Of Center [2] Empty [3] Rear Center [4] Empty [5] Low Frequency Effects + /// [6] Front Right [7] Front Left + /// + FrcFlcRcLfeFrFl, + + /// + /// [0] Front Right Of Center [1] Front Left Of Center [2] Empty [3] Rear Center [4] Front Center [5] Empty [6] Front + /// Right [7] Front Left + /// + FrcFlcRcFcFrFl, + + /// + /// [0] Front Right Of Center [1] Front Left Of Center [2] Empty [3] Rear Center [4] Front Center [5] Low Frequency + /// Effects [6] Front Right [7] Front Left + /// + FrcFlcRcFcLfeFrFl, + + /// + /// [0] Front Right Of Center [1] Front Left Of Center [2] Rear Right [3] Rear Left [4] Empty [5] Empty [6] Front Right + /// [7] Front Left + /// + FrcFlcRrRlFrFl, + + /// + /// [0] Front Right Of Center [1] Front Left Of Center [2] Rear Right [3] Rear Left [4] Empty [5] Low Frequency Effects + /// [6] Front Right [7] Front Left + /// + FrcFlcRrRlLfeFrFl, + + /// + /// [0] Front Right Of Center [1] Front Left Of Center [2] Rear Right [3] Rear Left [4] Front Center [5] Empty [6] + /// Front Right [7] Front Left + /// + FrcFlcRrRlFcFrFl, + + /// + /// [0] Front Right Of Center [1] Front Left Of Center [2] Rear Right [3] Rear Left [4] Front Center [5] Low Frequency + /// Effects [6] Front Right [7] Front Left + /// + FrcFlcRrRlFcLfeFrFl, + + /// + /// [0] Empty [1] Front Center High [2] Rear Right [3] Rear Left [4] Front Center [5] Empty [6] Front Right [7] Front + /// Left + /// + FchRrRlFcFrFl, + + /// + /// [0] Empty [1] Front Center High [2] Rear Right [3] Rear Left [4] Front Center [5] Low Frequency Effects [6] Front + /// Right [7] Front Left + /// + FchRrRlFcLfeFrFl, + + /// + /// [0] TopCenter [1] Empty [2] Rear Right [3] Rear Left [4] Front Center [5] Empty [6] Front Right [7] Front Left + /// + TcRrRlFcFrFl, + + /// + /// [0] TopCenter [1] Empty [2] Rear Right [3] Rear Left [4] Front Center [5] Low Frequency Effects [6] Front Right [7] + /// Front Left + /// + TcRrRlFcLfeFrFl, + + /// + /// [0] Front Right High [1] Front Left High [2] Rear Right [3] Rear Left [4] Empty [5] Empty [6] Front Right [7] Front + /// Left + /// + FrhFlhRrRlFrFl, + + /// + /// [0] Front Right High [1] Front Left High [2] Rear Right [3] Rear Left [4] Empty [5] Low Frequency Effects [6] Front + /// Right [7] Front Left + /// + FrhFlhRrRlLfeFrFl, + + /// + /// [0] Front Right Wide [1] Front Left Wide [2] Rear Right [3] Rear Left [4] Empty [5] Empty [6] Front Right [7] Front + /// Left + /// + FrwFlwRrRlFrFl, + + /// + /// [0] Front Right Wide [1] Front Left Wide [2] Rear Right [3] Rear Left [4] Empty [5] Low Frequency Effects [6] Front + /// Right [7] Front Left + /// + FrwFlwRrRlLfeFrFl, + + /// + /// [0] TopCenter [1] Rear Center [2] Rear Right [3] Rear Left [4] Front Center [5] Empty [6] Front Right [7] Front + /// Left + /// + TcRcRrRlFcFrFl, + + /// + /// [0] TopCenter [1] Rear Center [2] Rear Right [3] Rear Left [4] Front Center [5] Low Frequency Effects [6] Front + /// Right [7] Front Left + /// + TcRcRrRlFcLfeFrFl, + + /// + /// [0] Front Center High [1] Rear Center [2] Rear Right [3] Rear Left [4] Front Center [5] Empty [6] Front Right [7] + /// Front Left + /// + FchRcRrRlFcFrFl, + + /// + /// [0] Front Center High [1] Rear Center [2] Rear Right [3] Rear Left [4] Front Center [5] Low Frequency Effects [6] + /// Front Right [7] Front Left + /// + FchRcRrRlFcLfeFrFl, + + /// + /// [0] TopCenter [1] Front Center High [2] Rear Right [3] Rear Left [4] Front Center [5] Empty [6] Front Right [7] + /// Front Left + /// + TcFcRrRlFcFrFl, + + /// + /// [0] TopCenter [1] Front Center High [2] Rear Right [3] Rear Left [4] Front Center [5] Low Frequency Effects [6] + /// Front Right [7] Front Left + /// + TcFchRrRlFcLfeFrFl, + + /// + /// [0] Front Right High [1] Front Left High [2] Rear Right [3] Rear Left [4] Front Center [5] Empty [6] Front Right + /// [7] Front Left + /// + FrhFlhRrRlFcFrFl, + + /// + /// [0] Front Right High [1] Front Left High [2] Rear Right [3] Rear Left [4] Front Center [5] Low Frequency Effects + /// [6] Front Right [7] Front Left + /// + FrhFlhRrRlFcLfeFrFl, + + /// + /// [0] Front Right Wide [1] Front Left Wide [2] Rear Right [3] Rear Left [4] Front Center [5] Empty [6] Front Right + /// [7] Front Left + /// + FrwFlwRrRlFcFeFl, + + /// + /// [0] Front Right Wide [1] Front Left Wide [2] Rear Right [3] Rear Left [4] Front Center [5] Low Frequency Effects + /// [6] Front Right [7] Front Left + /// + FrwFlwRrRlFcLfeFrFl, + + /// + /// Auto (Unspecified) + /// + Auto = 511 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameAudioChannelCount.cs b/NvAPIWrapper/Native/Display/InfoFrameAudioChannelCount.cs new file mode 100644 index 0000000..71e76c8 --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameAudioChannelCount.cs @@ -0,0 +1,53 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible audio channels + /// + public enum InfoFrameAudioChannelCount : uint + { + /// + /// Data is available in the header of source data + /// + InHeader = 0, + + /// + /// Two channels + /// + Two, + + /// + /// Three channels + /// + Three, + + /// + /// Four channels + /// + Four, + + /// + /// Five channels + /// + Five, + + /// + /// Six channels + /// + Six, + + /// + /// Seven channels + /// + Seven, + + /// + /// Eight channels + /// + Eight, + + /// + /// Auto (Unspecified) + /// + Auto = 15 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameAudioCodec.cs b/NvAPIWrapper/Native/Display/InfoFrameAudioCodec.cs new file mode 100644 index 0000000..0db6fcf --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameAudioCodec.cs @@ -0,0 +1,93 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible audio codecs + /// + public enum InfoFrameAudioCodec : uint + { + /// + /// Data is available in the header of source data + /// + InHeader = 0, + + /// + /// Pulse-code modulation + /// + PCM, + + /// + /// Dolby AC-3 + /// + AC3, + + /// + /// MPEG1 + /// + MPEG1, + + /// + /// MP3 (MPEG-2 Audio Layer III) + /// + MP3, + + /// + /// MPEG2 + /// + MPEG2, + + /// + /// Advanced Audio Coding + /// + AACLC, + + /// + /// DTS + /// + DTS, + + /// + /// Adaptive Transform Acoustic Coding + /// + ATRAC, + + /// + /// Direct Stream Digital + /// + DSD, + + /// + /// Dolby Digital Plus + /// + EAC3, + + /// + /// DTS High Definition + /// + DTSHD, + + /// + /// Meridian Lossless Packing + /// + MLP, + + /// + /// DST + /// + DST, + + /// + /// Windows Media Audio Pro + /// + WMAPRO, + + /// + /// Extended audio codec value should be used to get information regarding audio codec + /// + UseExtendedCodecType, + + /// + /// Auto (Unspecified) + /// + Auto = 31 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameAudioExtendedCodec.cs b/NvAPIWrapper/Native/Display/InfoFrameAudioExtendedCodec.cs new file mode 100644 index 0000000..82dfdde --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameAudioExtendedCodec.cs @@ -0,0 +1,33 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible extended audio codecs + /// + public enum InfoFrameAudioExtendedCodec : uint + { + /// + /// Use the primary audio codec type, data not available + /// + UseCodecType = 0, + + /// + /// High-Efficiency Advanced Audio Coding + /// + HEAAC, + + /// + /// High-Efficiency Advanced Audio Coding 2 + /// + HEAACVersion2, + + /// + /// MPEG Surround + /// + MPEGSurround, + + /// + /// Auto (Unspecified) + /// + Auto = 63 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameAudioLFEPlaybackLevel.cs b/NvAPIWrapper/Native/Display/InfoFrameAudioLFEPlaybackLevel.cs new file mode 100644 index 0000000..7988db3 --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameAudioLFEPlaybackLevel.cs @@ -0,0 +1,28 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible audio low frequency effects channel playback level + /// + public enum InfoFrameAudioLFEPlaybackLevel : uint + { + /// + /// Data not available + /// + NoData = 0, + + /// + /// No change to the source audio + /// + Plus0Decibel, + + /// + /// Adds 10 decibel + /// + Plus10Decibel, + + /// + /// Auto (Unspecified) + /// + Auto = 7 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameAudioLevelShift.cs b/NvAPIWrapper/Native/Display/InfoFrameAudioLevelShift.cs new file mode 100644 index 0000000..64e3b21 --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameAudioLevelShift.cs @@ -0,0 +1,93 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible audio channel level shift values + /// + public enum InfoFrameAudioLevelShift : uint + { + /// + /// No change to the source audio + /// + Shift0Decibel = 0, + + /// + /// Shifts 1 decibel + /// + Shift1Decibel, + + /// + /// Shifts 2 decibel + /// + Shift2Decibel, + + /// + /// Shifts 3 decibel + /// + Shift3Decibel, + + /// + /// Shifts 4 decibel + /// + Shift4Decibel, + + /// + /// Shifts 5 decibel + /// + Shift5Decibel, + + /// + /// Shifts 6 decibel + /// + Shift6Decibel, + + /// + /// Shifts 7 decibel + /// + Shift7Decibel, + + /// + /// Shifts 8 decibel + /// + Shift8Decibel, + + /// + /// Shifts 9 decibel + /// + Shift9Decibel, + + /// + /// Shifts 10 decibel + /// + Shift10Decibel, + + /// + /// Shifts 11 decibel + /// + Shift11Decibel, + + /// + /// Shifts 12 decibel + /// + Shift12Decibel, + + /// + /// Shifts 13 decibel + /// + Shift13Decibel, + + /// + /// Shifts 14 decibel + /// + Shift14Decibel, + + /// + /// Shifts 15 decibel + /// + Shift15Decibel, + + /// + /// Auto (Unspecified) + /// + Auto = 31 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameAudioSampleRate.cs b/NvAPIWrapper/Native/Display/InfoFrameAudioSampleRate.cs new file mode 100644 index 0000000..f283e1c --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameAudioSampleRate.cs @@ -0,0 +1,53 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible audio sample rates (sampling frequency) + /// + public enum InfoFrameAudioSampleRate : uint + { + /// + /// Data is available in the header of source data + /// + InHeader = 0, + + /// + /// 31kHz sampling frequency + /// + F32000Hz, + + /// + /// 44.1kHz sampling frequency + /// + F44100Hz, + + /// + /// 48kHz sampling frequency + /// + F48000Hz, + + /// + /// 88.2kHz sampling frequency + /// + F88200Hz, + + /// + /// 96kHz sampling frequency + /// + F96000Hz, + + /// + /// 176.4kHz sampling frequency + /// + F176400Hz, + + /// + /// 192kHz sampling frequency + /// + F192000Hz, + + /// + /// Auto (Unspecified) + /// + Auto = 15 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameAudioSampleSize.cs b/NvAPIWrapper/Native/Display/InfoFrameAudioSampleSize.cs new file mode 100644 index 0000000..361279c --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameAudioSampleSize.cs @@ -0,0 +1,33 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible audio sample size (bit depth) + /// + public enum InfoFrameAudioSampleSize : uint + { + /// + /// Data is available in the header of source data + /// + InHeader = 0, + + /// + /// 16bit audio sample size + /// + B16, + + /// + /// 20bit audio sample size + /// + B20, + + /// + /// 24bit audio sample size + /// + B24, + + /// + /// Auto (Unspecified) + /// + Auto = 7 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameBoolean.cs b/NvAPIWrapper/Native/Display/InfoFrameBoolean.cs new file mode 100644 index 0000000..0aa0e45 --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameBoolean.cs @@ -0,0 +1,23 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible values for info-frame properties that accept or return a boolean value + /// + public enum InfoFrameBoolean : uint + { + /// + /// False + /// + False = 0, + + /// + /// True + /// + True, + + /// + /// Auto (Unspecified) + /// + Auto = 3 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameCommand.cs b/NvAPIWrapper/Native/Display/InfoFrameCommand.cs new file mode 100644 index 0000000..578bb59 --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameCommand.cs @@ -0,0 +1,50 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Possible commands for info-frame operations + /// + public enum InfoFrameCommand : uint + { + /// + /// Returns the fields in the info-frame with values set by the manufacturer (NVIDIA or OEM) + /// + GetDefault = 0, + + /// + /// Sets the fields in the info-frame to auto, and info-frame to the default info-frame for use in a set. + /// + Reset, + + /// + /// Get the current info-frame state. + /// + Get, + + /// + /// Set the current info-frame state (flushed to the monitor), the values are one time and do not persist. + /// + Set, + + /// + /// Get the override info-frame state, non-override fields will be set to value = AUTO, overridden fields will have the + /// current override values. + /// + GetOverride, + + /// + /// Set the override info-frame state, non-override fields will be set to value = AUTO, other values indicate override; + /// persist across mode-set and reboot. + /// + SetOverride, + + /// + /// Get properties associated with info-frame (each of the info-frame type will have properties). + /// + GetProperty, + + /// + /// Set properties associated with info-frame. + /// + SetProperty + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameDataType.cs b/NvAPIWrapper/Native/Display/InfoFrameDataType.cs new file mode 100644 index 0000000..50db98f --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameDataType.cs @@ -0,0 +1,18 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible info-frame data type + /// + public enum InfoFrameDataType : uint + { + /// + /// Auxiliary Video data + /// + AuxiliaryVideoInformation = 2, + + /// + /// Audio data + /// + AudioInformation = 4, + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFramePropertyMode.cs b/NvAPIWrapper/Native/Display/InfoFramePropertyMode.cs new file mode 100644 index 0000000..93ac83b --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFramePropertyMode.cs @@ -0,0 +1,28 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible info-frame property modes + /// + public enum InfoFramePropertyMode : uint + { + /// + /// Driver determines whether to send info-frames. + /// + Auto = 0, + + /// + /// Driver always sends info-frame. + /// + Enable, + + /// + /// Driver never sends info-frame. + /// + Disable, + + /// + /// Driver only sends info-frame when client requests it via info-frame escape call. + /// + AllowOverride + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameVideoAspectRatioActivePortion.cs b/NvAPIWrapper/Native/Display/InfoFrameVideoAspectRatioActivePortion.cs new file mode 100644 index 0000000..5c0ffe7 --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameVideoAspectRatioActivePortion.cs @@ -0,0 +1,58 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible values for AVI aspect ratio portions + /// + public enum InfoFrameVideoAspectRatioActivePortion : uint + { + /// + /// Disabled or not available + /// + Disabled = 0, + + /// + /// Letter box 16x9 + /// + LetterboxGreaterThan16X9 = 4, + + /// + /// Equal to the source frame size + /// + EqualCodedFrame = 8, + + /// + /// Centered 4x3 ratio + /// + Center4X3 = 9, + + /// + /// Centered 16x9 ratio + /// + Center16X9 = 10, + + /// + /// Centered 14x9 ratio + /// + Center14X9 = 11, + + /// + /// Bordered 4x3 on 14x9 + /// + Bordered4X3On14X9 = 13, + + /// + /// Bordered 16x9 on 14x9 + /// + Bordered16X9On14X9 = 14, + + /// + /// Bordered 16x9 on 4x3 + /// + Bordered16X9On4X3 = 15, + + /// + /// Auto (Unspecified) + /// + Auto = 31 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameVideoAspectRatioCodedFrame.cs b/NvAPIWrapper/Native/Display/InfoFrameVideoAspectRatioCodedFrame.cs new file mode 100644 index 0000000..246853d --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameVideoAspectRatioCodedFrame.cs @@ -0,0 +1,28 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Gets the possible values for AVI source aspect ratio + /// + public enum InfoFrameVideoAspectRatioCodedFrame : uint + { + /// + /// No data available + /// + NoData = 0, + + /// + /// The 4x3 aspect ratio + /// + Aspect4X3, + + /// + /// The 16x9 aspect ratio + /// + Aspect16X9, + + /// + /// Auto (Unspecified) + /// + Auto = 7 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameVideoBarData.cs b/NvAPIWrapper/Native/Display/InfoFrameVideoBarData.cs new file mode 100644 index 0000000..16f3e09 --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameVideoBarData.cs @@ -0,0 +1,33 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible AVI bar data that are available and should be used + /// + public enum InfoFrameVideoBarData : uint + { + /// + /// No bar data present + /// + NotPresent = 0, + + /// + /// Vertical bar + /// + Vertical, + + /// + /// Horizontal bar + /// + Horizontal, + + /// + /// Both sides have bars + /// + Both, + + /// + /// Auto (Unspecified) + /// + Auto = 7 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameVideoColorFormat.cs b/NvAPIWrapper/Native/Display/InfoFrameVideoColorFormat.cs new file mode 100644 index 0000000..b3c2fae --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameVideoColorFormat.cs @@ -0,0 +1,28 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible AVI color formats + /// + public enum InfoFrameVideoColorFormat : uint + { + /// + /// The RGB color format + /// + RGB = 0, + + /// + /// The YCbCr422 color format + /// + YCbCr422, + + /// + /// The YCbCr444 color format + /// + YCbCr444, + + /// + /// Auto (Unspecified) + /// + Auto = 7 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameVideoColorimetry.cs b/NvAPIWrapper/Native/Display/InfoFrameVideoColorimetry.cs new file mode 100644 index 0000000..9beccb9 --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameVideoColorimetry.cs @@ -0,0 +1,33 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible values for the AVI color space + /// + public enum InfoFrameVideoColorimetry : uint + { + /// + /// No data available + /// + NoData = 0, + + /// + /// The SMPTE170M color space + /// + SMPTE170M, + + /// + /// The ITURBT709 color space + /// + ITURBT709, + + /// + /// Extended colorimetry value should be used to get information regarding AVI color space + /// + UseExtendedColorimetry, + + /// + /// Auto (Unspecified) + /// + Auto = 7 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameVideoContentType.cs b/NvAPIWrapper/Native/Display/InfoFrameVideoContentType.cs new file mode 100644 index 0000000..2d51155 --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameVideoContentType.cs @@ -0,0 +1,33 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible AVI content type + /// + public enum InfoFrameVideoContentType : uint + { + /// + /// Graphics content + /// + Graphics = 0, + + /// + /// Photo content + /// + Photo, + + /// + /// Cinematic content + /// + Cinema, + + /// + /// Gaming content + /// + Game, + + /// + /// Auto (Unspecified) + /// + Auto = 7 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameVideoExtendedColorimetry.cs b/NvAPIWrapper/Native/Display/InfoFrameVideoExtendedColorimetry.cs new file mode 100644 index 0000000..dbb374a --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameVideoExtendedColorimetry.cs @@ -0,0 +1,41 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible values for the AVI extended color space + /// + public enum InfoFrameVideoExtendedColorimetry : uint + { + /// + /// The xvYCC601 color space + /// + // ReSharper disable once InconsistentNaming + xvYCC601 = 0, + + /// + /// The xvYCC709 color space + /// + // ReSharper disable once InconsistentNaming + xvYCC709, + + /// + /// The sYCC601 color space + /// + // ReSharper disable once InconsistentNaming + sYCC601, + + /// + /// The AdobeYCC601 color space + /// + AdobeYCC601, + + /// + /// The AdobeRGB color space + /// + AdobeRGB, + + /// + /// Auto (Unspecified) + /// + Auto = 15 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameVideoITC.cs b/NvAPIWrapper/Native/Display/InfoFrameVideoITC.cs new file mode 100644 index 0000000..ca2cba4 --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameVideoITC.cs @@ -0,0 +1,23 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible AVI video content modes + /// + public enum InfoFrameVideoITC : uint + { + /// + /// Normal video content (Consumer Electronics) + /// + VideoContent = 0, + + /// + /// Information Technology content + /// + ITContent, + + /// + /// Auto (Unspecified) + /// + Auto = 3 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameVideoNonUniformPictureScaling.cs b/NvAPIWrapper/Native/Display/InfoFrameVideoNonUniformPictureScaling.cs new file mode 100644 index 0000000..63a95c8 --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameVideoNonUniformPictureScaling.cs @@ -0,0 +1,33 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible values for the AVI non uniform picture scaling + /// + public enum InfoFrameVideoNonUniformPictureScaling : uint + { + /// + /// No data available + /// + NoData = 0, + + /// + /// Horizontal scaling + /// + Horizontal, + + /// + /// Vertical scaling + /// + Vertical, + + /// + /// Scaling in both directions + /// + Both, + + /// + /// Auto (Unspecified) + /// + Auto = 7 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameVideoPixelRepetition.cs b/NvAPIWrapper/Native/Display/InfoFrameVideoPixelRepetition.cs new file mode 100644 index 0000000..bb725d6 --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameVideoPixelRepetition.cs @@ -0,0 +1,63 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible AVI pixel repetition values + /// + public enum InfoFrameVideoPixelRepetition : uint + { + /// + /// No pixel repetition + /// + None = 0, + + /// + /// Two pixel repetition + /// + X2, + + /// + /// Three pixel repetition + /// + X3, + + /// + /// Four pixel repetition + /// + X4, + + /// + /// Five pixel repetition + /// + X5, + + /// + /// Six pixel repetition + /// + X6, + + /// + /// Seven pixel repetition + /// + X7, + + /// + /// Eight pixel repetition + /// + X8, + + /// + /// Nine pixel repetition + /// + X9, + + /// + /// Ten pixel repetition + /// + X10, + + /// + /// Auto (Unspecified) + /// + Auto = 31 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameVideoRGBQuantization.cs b/NvAPIWrapper/Native/Display/InfoFrameVideoRGBQuantization.cs new file mode 100644 index 0000000..64b613f --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameVideoRGBQuantization.cs @@ -0,0 +1,28 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible values for the AVI RGB quantization + /// + public enum InfoFrameVideoRGBQuantization : uint + { + /// + /// Default setting + /// + Default = 0, + + /// + /// Limited RGB range [16-235] (86%) + /// + LimitedRange, + + /// + /// Full RGB range [0-255] (100%) + /// + FullRange, + + /// + /// Auto (Unspecified) + /// + Auto = 7 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameVideoScanInfo.cs b/NvAPIWrapper/Native/Display/InfoFrameVideoScanInfo.cs new file mode 100644 index 0000000..fbed2f3 --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameVideoScanInfo.cs @@ -0,0 +1,28 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible values for AVI scan information + /// + public enum InfoFrameVideoScanInfo : uint + { + /// + /// No data available + /// + NoData = 0, + + /// + /// Overscan + /// + OverScan, + + /// + /// Underscan + /// + UnderScan, + + /// + /// Auto (Unspecified) + /// + Auto = 7 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/InfoFrameVideoYCCQuantization.cs b/NvAPIWrapper/Native/Display/InfoFrameVideoYCCQuantization.cs new file mode 100644 index 0000000..5b8238b --- /dev/null +++ b/NvAPIWrapper/Native/Display/InfoFrameVideoYCCQuantization.cs @@ -0,0 +1,23 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible AVI YCC quantization + /// + public enum InfoFrameVideoYCCQuantization : uint + { + /// + /// Limited YCC range + /// + LimitedRange = 0, + + /// + /// Full YCC range + /// + FullRange, + + /// + /// Auto (Unspecified) + /// + Auto = 7 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/MonitorCapabilitiesConnectorType.cs b/NvAPIWrapper/Native/Display/MonitorCapabilitiesConnectorType.cs new file mode 100644 index 0000000..15c45d7 --- /dev/null +++ b/NvAPIWrapper/Native/Display/MonitorCapabilitiesConnectorType.cs @@ -0,0 +1,38 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Possible values for the monitor capabilities connector type + /// + public enum MonitorCapabilitiesConnectorType : uint + { + /// + /// Unknown or invalid connector + /// + Unknown = 0, + + /// + /// VGA connector + /// + VGA, + + /// + /// Composite connector (TV) + /// + TV, + + /// + /// DVI connector + /// + DVI, + + /// + /// HDMI connector + /// + HDMI, + + /// + /// Display Port connector + /// + DisplayPort + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/MonitorCapabilitiesType.cs b/NvAPIWrapper/Native/Display/MonitorCapabilitiesType.cs new file mode 100644 index 0000000..0b6958d --- /dev/null +++ b/NvAPIWrapper/Native/Display/MonitorCapabilitiesType.cs @@ -0,0 +1,18 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible values for the monitor capabilities type + /// + public enum MonitorCapabilitiesType : uint + { + /// + /// The Vendor Specific Data Block + /// + VSDB = 0x1000, + + /// + /// The Video Capability Data Block + /// + VCDB = 0x1001 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Rotate.cs b/NvAPIWrapper/Native/Display/Rotate.cs new file mode 100644 index 0000000..171d4d3 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Rotate.cs @@ -0,0 +1,33 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Possible rotate modes + /// + public enum Rotate : uint + { + /// + /// No rotation + /// + Degree0 = 0, + + /// + /// 90 degree rotation + /// + Degree90 = 1, + + /// + /// 180 degree rotation + /// + Degree180 = 2, + + /// + /// 270 degree rotation + /// + Degree270 = 3, + + /// + /// This value is ignored + /// + Ignored = 4 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Scaling.cs b/NvAPIWrapper/Native/Display/Scaling.cs new file mode 100644 index 0000000..7c4e15d --- /dev/null +++ b/NvAPIWrapper/Native/Display/Scaling.cs @@ -0,0 +1,48 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Possible scaling modes + /// + public enum Scaling + { + /// + /// No change + /// + Default = 0, + + /// + /// Balanced - Full Screen + /// + ToClosest = 1, + + /// + /// Force GPU - Full Screen + /// + ToNative = 2, + + /// + /// Force GPU - Centered\No Scaling + /// + GPUScanOutToNative = 3, + + /// + /// Force GPU - Aspect Ratio + /// + ToAspectScanOutToNative = 5, + + /// + /// Balanced - Aspect Ratio + /// + ToAspectScanOutToClosest = 6, + + /// + /// Balanced - Centered\No Scaling + /// + GPUScanOutToClosest = 7, + + /// + /// Customized scaling - For future use + /// + Customized = 255 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/ScanOutCompositionParameter.cs b/NvAPIWrapper/Native/Display/ScanOutCompositionParameter.cs new file mode 100644 index 0000000..4d76256 --- /dev/null +++ b/NvAPIWrapper/Native/Display/ScanOutCompositionParameter.cs @@ -0,0 +1,13 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Holds a list of possible scan out composition configurable parameters + /// + public enum ScanOutCompositionParameter : uint + { + /// + /// Warping re-sampling method parameter + /// + WarpingReSamplingMethod = 0 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/ScanOutCompositionParameterValue.cs b/NvAPIWrapper/Native/Display/ScanOutCompositionParameterValue.cs new file mode 100644 index 0000000..e1ae328 --- /dev/null +++ b/NvAPIWrapper/Native/Display/ScanOutCompositionParameterValue.cs @@ -0,0 +1,48 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Holds a list of possible scan out composition parameter values + /// + public enum ScanOutCompositionParameterValue : uint + { + /// + /// Default parameter value + /// + Default = 0, + + /// + /// BiLinear value for the warping re-sampling method parameter + /// + WarpingReSamplingMethodBiLinear = 0x100, + + /// + /// Bicubic Triangular value for the warping re-sampling method parameter + /// + WarpingReSamplingMethodBicubicTriangular = 0x101, + + /// + /// Bicubic Bell Shaped value for the warping re-sampling method parameter + /// + WarpingReSamplingMethodBicubicBellShaped = 0x102, + + /// + /// Bicubic B-Spline value for the warping re-sampling method parameter + /// + WarpingReSamplingMethodBicubicBSpline = 0x103, + + /// + /// Bicubic Adaptive Triangular value for the warping re-sampling method parameter + /// + WarpingReSamplingMethodBicubicAdaptiveTriangular = 0x104, + + /// + /// Bicubic Adaptive Bell Shaped value for the warping re-sampling method parameter + /// + WarpingReSamplingMethodBicubicAdaptiveBellShaped = 0x105, + + /// + /// Bicubic Adaptive B-Spline value for the warping re-sampling method parameter + /// + WarpingReSamplingMethodBicubicAdaptiveBSpline = 0x106 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/SpanningOrientation.cs b/NvAPIWrapper/Native/Display/SpanningOrientation.cs new file mode 100644 index 0000000..ee4b265 --- /dev/null +++ b/NvAPIWrapper/Native/Display/SpanningOrientation.cs @@ -0,0 +1,23 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Display spanning for Windows XP + /// + public enum SpanningOrientation + { + /// + /// No spanning + /// + None = 0, + + /// + /// Horizontal spanning + /// + Horizontal = 1, + + /// + /// Vertical spanning + /// + Vertical = 2 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/StaticMetadataDescriptorId.cs b/NvAPIWrapper/Native/Display/StaticMetadataDescriptorId.cs new file mode 100644 index 0000000..4a02f72 --- /dev/null +++ b/NvAPIWrapper/Native/Display/StaticMetadataDescriptorId.cs @@ -0,0 +1,13 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Contains possible values for the type of the Static Metadata Descriptor block structure + /// + public enum StaticMetadataDescriptorId : uint + { + /// + /// Type 1 Static Metadata Descriptor block structure + /// + StaticMetadataType1 = 0 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/ColorDataColorCoordinate.cs b/NvAPIWrapper/Native/Display/Structures/ColorDataColorCoordinate.cs new file mode 100644 index 0000000..40cef00 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/ColorDataColorCoordinate.cs @@ -0,0 +1,100 @@ +using System; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Holds coordinates of a color in the color space + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct ColorDataColorCoordinate : IEquatable + { + private readonly ushort _X; + private readonly ushort _Y; + + /// + /// Gets the color space's X coordinate + /// + public float X + { + get => (float) _X / 0xC350; + } + + /// + /// Gets the color space's Y coordinate + /// + public float Y + { + get => (float) _Y / 0xC350; + } + + /// + /// Creates an instance of . + /// + /// The color space's X coordinate. + /// The color space's Y coordinate. + public ColorDataColorCoordinate(float x, float y) + { + _X = (ushort) (Math.Min(Math.Max(x, 0), 1) * 0xC350); + _Y = (ushort) (Math.Min(Math.Max(y, 0), 1) * 0xC350); + } + + /// + /// Creates an instance of . + /// + /// The color space's coordinates. + public ColorDataColorCoordinate(PointF coordinate) : this(coordinate.X, coordinate.Y) + { + } + + /// + public override string ToString() + { + return $"({X:F3}, {Y:F3})"; + } + + /// + public bool Equals(ColorDataColorCoordinate other) + { + return _X == other._X && _Y == other._Y; + } + + /// + public override bool Equals(object obj) + { + return obj is ColorDataColorCoordinate other && Equals(other); + } + + /// + public override int GetHashCode() + { + unchecked + { + return (_X.GetHashCode() * 397) ^ _Y.GetHashCode(); + } + } + + /// + /// Checks two instance of for equality. + /// + /// The first instance. + /// The second instance. + /// true if both instances are equal, otherwise false. + public static bool operator ==(ColorDataColorCoordinate left, ColorDataColorCoordinate right) + { + return left.Equals(right); + } + + /// + /// Checks two instance of for inequality. + /// + /// The first instance. + /// The second instance. + /// true if both instances are not equal, otherwise false. + public static bool operator !=(ColorDataColorCoordinate left, ColorDataColorCoordinate right) + { + return !left.Equals(right); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/ColorDataV1.cs b/NvAPIWrapper/Native/Display/Structures/ColorDataV1.cs new file mode 100644 index 0000000..f2c6eef --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/ColorDataV1.cs @@ -0,0 +1,113 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct ColorDataV1 : IInitializable, IColorData + { + internal StructureVersion _Version; + internal ushort _Size; + + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly byte _Command; + private readonly ColorDataBag _Data; + + [StructLayout(LayoutKind.Sequential, Pack = 8)] + private struct ColorDataBag + { + public readonly byte ColorFormat; + public readonly byte Colorimetry; + + public ColorDataBag(ColorDataFormat colorFormat, ColorDataColorimetry colorimetry) + { + ColorFormat = (byte)colorFormat; + Colorimetry = (byte)colorimetry; + } + } + + /// + /// Creates an instance of to retrieve color data information + /// + /// The command to be executed. + public ColorDataV1(ColorDataCommand command) + { + this = typeof(ColorDataV1).Instantiate(); + _Size = (ushort)_Version.StructureSize; + + if (command != ColorDataCommand.Get && command != ColorDataCommand.GetDefault) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = (byte)command; + } + + /// + /// Creates an instance of to modify the color data + /// + /// The command to be executed. + /// The color data color format. + /// The color data color space. + public ColorDataV1( + ColorDataCommand command, + ColorDataFormat colorFormat, + ColorDataColorimetry colorimetry + ) + { + this = typeof(ColorDataV1).Instantiate(); + _Size = (ushort)_Version.StructureSize; + + if (command != ColorDataCommand.Set && command != ColorDataCommand.IsSupportedColor) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = (byte)command; + _Data = new ColorDataBag(colorFormat, colorimetry); + } + + /// + public ColorDataFormat ColorFormat + { + get => (ColorDataFormat)_Data.ColorFormat; + } + + /// + public ColorDataColorimetry Colorimetry + { + get => (ColorDataColorimetry)_Data.Colorimetry; + } + + /// + public ColorDataDynamicRange? DynamicRange + { + get => null; + } + + /// + public ColorDataDepth? ColorDepth + { + get => null; + } + + /// + public ColorDataSelectionPolicy? SelectionPolicy + { + get => null; + } + + /// + public ColorDataDesktopDepth? DesktopColorDepth + { + get => null; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/ColorDataV2.cs b/NvAPIWrapper/Native/Display/Structures/ColorDataV2.cs new file mode 100644 index 0000000..4a8c7cb --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/ColorDataV2.cs @@ -0,0 +1,121 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + public struct ColorDataV2 : IInitializable, IColorData + { + internal StructureVersion _Version; + internal ushort _Size; + + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly byte _Command; + private readonly ColorDataBag _Data; + + [StructLayout(LayoutKind.Sequential, Pack = 8)] + private struct ColorDataBag + { + public readonly byte ColorFormat; + public readonly byte Colorimetry; + public readonly byte ColorDynamicRange; + + public ColorDataBag( + ColorDataFormat colorFormat, + ColorDataColorimetry colorimetry, + ColorDataDynamicRange colorDynamicRange + ) + { + ColorFormat = (byte) colorFormat; + Colorimetry = (byte) colorimetry; + ColorDynamicRange = (byte) colorDynamicRange; + } + } + + /// + /// Creates an instance of to retrieve color data information + /// + /// The command to be executed. + public ColorDataV2(ColorDataCommand command) + { + this = typeof(ColorDataV2).Instantiate(); + _Size = (ushort) _Version.StructureSize; + + if (command != ColorDataCommand.Get && command != ColorDataCommand.GetDefault) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = (byte) command; + } + + /// + /// Creates an instance of to modify the color data + /// + /// The command to be executed. + /// The color data color format. + /// The color data color space. + /// The color data dynamic range. + public ColorDataV2( + ColorDataCommand command, + ColorDataFormat colorFormat, + ColorDataColorimetry colorimetry, + ColorDataDynamicRange colorDynamicRange + ) + { + this = typeof(ColorDataV2).Instantiate(); + _Size = (ushort) _Version.StructureSize; + + if (command != ColorDataCommand.Set && command != ColorDataCommand.IsSupportedColor) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = (byte) command; + _Data = new ColorDataBag(colorFormat, colorimetry, colorDynamicRange); + } + + /// + public ColorDataFormat ColorFormat + { + get => (ColorDataFormat) _Data.ColorFormat; + } + + /// + public ColorDataColorimetry Colorimetry + { + get => (ColorDataColorimetry) _Data.Colorimetry; + } + + /// + public ColorDataDynamicRange? DynamicRange + { + get => (ColorDataDynamicRange) _Data.ColorDynamicRange; + } + + /// + public ColorDataDepth? ColorDepth + { + get => null; + } + + /// + public ColorDataSelectionPolicy? SelectionPolicy + { + get => null; + } + + /// + public ColorDataDesktopDepth? DesktopColorDepth + { + get => null; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/ColorDataV3.cs b/NvAPIWrapper/Native/Display/Structures/ColorDataV3.cs new file mode 100644 index 0000000..9757c07 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/ColorDataV3.cs @@ -0,0 +1,143 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(3)] + public struct ColorDataV3 : IInitializable, IColorData + { + internal StructureVersion _Version; + internal ushort _Size; + + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly byte _Command; + private readonly ColorDataBag _Data; + + [StructLayout(LayoutKind.Sequential, Pack = 8)] + private struct ColorDataBag + { + public readonly byte ColorFormat; + public readonly byte Colorimetry; + public readonly byte ColorDynamicRange; + public readonly ColorDataDepth ColorDepth; + + public ColorDataBag( + ColorDataFormat colorFormat, + ColorDataColorimetry colorimetry, + ColorDataDynamicRange colorDynamicRange, + ColorDataDepth colorDepth + ) + { + ColorFormat = (byte) colorFormat; + Colorimetry = (byte) colorimetry; + ColorDynamicRange = (byte) colorDynamicRange; + ColorDepth = colorDepth; + } + } + + /// + /// Creates an instance of to retrieve color data information + /// + /// The command to be executed. + public ColorDataV3(ColorDataCommand command) + { + this = typeof(ColorDataV3).Instantiate(); + _Size = (ushort) _Version.StructureSize; + + if (command != ColorDataCommand.Get && command != ColorDataCommand.GetDefault) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = (byte) command; + } + + /// + /// Creates an instance of to modify the color data + /// + /// The command to be executed. + /// The color data color format. + /// The color data color space. + /// The color data dynamic range. + /// The color data color depth. + public ColorDataV3( + ColorDataCommand command, + ColorDataFormat colorFormat, + ColorDataColorimetry colorimetry, + ColorDataDynamicRange colorDynamicRange, + ColorDataDepth colorDepth + ) + { + this = typeof(ColorDataV3).Instantiate(); + _Size = (ushort) _Version.StructureSize; + + if (command != ColorDataCommand.Set && command != ColorDataCommand.IsSupportedColor) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = (byte) command; + _Data = new ColorDataBag(colorFormat, colorimetry, colorDynamicRange, colorDepth); + } + + /// + public ColorDataFormat ColorFormat + { + get => (ColorDataFormat) _Data.ColorFormat; + } + + /// + public ColorDataColorimetry Colorimetry + { + get => (ColorDataColorimetry) _Data.Colorimetry; + } + + /// + public ColorDataDynamicRange? DynamicRange + { + get => (ColorDataDynamicRange) _Data.ColorDynamicRange; + } + + /// + public ColorDataDepth? ColorDepth + { + get + { + switch ((int) _Data.ColorDepth) + { + case 6: + return ColorDataDepth.BPC6; + case 8: + return ColorDataDepth.BPC8; + case 10: + return ColorDataDepth.BPC10; + case 12: + return ColorDataDepth.BPC12; + case 16: + return ColorDataDepth.BPC16; + default: + return _Data.ColorDepth; + } + } + } + + /// + public ColorDataSelectionPolicy? SelectionPolicy + { + get => null; + } + + /// + public ColorDataDesktopDepth? DesktopColorDepth + { + get => null; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/ColorDataV4.cs b/NvAPIWrapper/Native/Display/Structures/ColorDataV4.cs new file mode 100644 index 0000000..c7a8a0e --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/ColorDataV4.cs @@ -0,0 +1,148 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(4)] + public struct ColorDataV4 : IInitializable, IColorData + { + internal StructureVersion _Version; + internal ushort _Size; + + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly byte _Command; + private readonly ColorDataBag _Data; + + [StructLayout(LayoutKind.Sequential, Pack = 8)] + private struct ColorDataBag + { + public readonly byte ColorFormat; + public readonly byte Colorimetry; + public readonly byte ColorDynamicRange; + public readonly ColorDataDepth ColorDepth; + public readonly ColorDataSelectionPolicy ColorSelectionPolicy; + + public ColorDataBag( + ColorDataFormat colorFormat, + ColorDataColorimetry colorimetry, + ColorDataDynamicRange colorDynamicRange, + ColorDataDepth colorDepth, + ColorDataSelectionPolicy colorSelectionPolicy + ) + { + ColorFormat = (byte) colorFormat; + Colorimetry = (byte) colorimetry; + ColorDynamicRange = (byte) colorDynamicRange; + ColorDepth = colorDepth; + ColorSelectionPolicy = colorSelectionPolicy; + } + } + + /// + /// Creates an instance of to retrieve color data information + /// + /// The command to be executed. + public ColorDataV4(ColorDataCommand command) + { + this = typeof(ColorDataV4).Instantiate(); + _Size = (ushort) _Version.StructureSize; + + if (command != ColorDataCommand.Get && command != ColorDataCommand.GetDefault) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = (byte) command; + } + + /// + /// Creates an instance of to modify the color data + /// + /// The command to be executed. + /// The color data color format. + /// The color data color space. + /// The color data dynamic range. + /// The color data color depth. + /// The color data selection policy. + public ColorDataV4( + ColorDataCommand command, + ColorDataFormat colorFormat, + ColorDataColorimetry colorimetry, + ColorDataDynamicRange colorDynamicRange, + ColorDataDepth colorDepth, + ColorDataSelectionPolicy colorSelectionPolicy + ) + { + this = typeof(ColorDataV4).Instantiate(); + _Size = (ushort) _Version.StructureSize; + + if (command != ColorDataCommand.Set && command != ColorDataCommand.IsSupportedColor) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = (byte) command; + _Data = new ColorDataBag(colorFormat, colorimetry, colorDynamicRange, colorDepth, colorSelectionPolicy); + } + + /// + public ColorDataFormat ColorFormat + { + get => (ColorDataFormat) _Data.ColorFormat; + } + + /// + public ColorDataColorimetry Colorimetry + { + get => (ColorDataColorimetry) _Data.Colorimetry; + } + + /// + public ColorDataDynamicRange? DynamicRange + { + get => (ColorDataDynamicRange) _Data.ColorDynamicRange; + } + + /// + public ColorDataDepth? ColorDepth + { + get + { + switch ((int) _Data.ColorDepth) + { + case 6: + return ColorDataDepth.BPC6; + case 8: + return ColorDataDepth.BPC8; + case 10: + return ColorDataDepth.BPC10; + case 12: + return ColorDataDepth.BPC12; + case 16: + return ColorDataDepth.BPC16; + default: + return _Data.ColorDepth; + } + } + } + + /// + public ColorDataSelectionPolicy? SelectionPolicy + { + get => _Data.ColorSelectionPolicy; + } + + /// + public ColorDataDesktopDepth? DesktopColorDepth + { + get => null; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/ColorDataV5.cs b/NvAPIWrapper/Native/Display/Structures/ColorDataV5.cs new file mode 100644 index 0000000..919a44e --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/ColorDataV5.cs @@ -0,0 +1,160 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(5)] + public struct ColorDataV5 : IInitializable, IColorData + { + internal StructureVersion _Version; + internal ushort _Size; + + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly byte _Command; + private readonly ColorDataBag _Data; + + [StructLayout(LayoutKind.Sequential, Pack = 8)] + private struct ColorDataBag + { + public readonly byte ColorFormat; + public readonly byte Colorimetry; + public readonly byte ColorDynamicRange; + public readonly ColorDataDepth ColorDepth; + public readonly ColorDataSelectionPolicy ColorSelectionPolicy; + public readonly ColorDataDesktopDepth DesktopColorDepth; + + public ColorDataBag( + ColorDataFormat colorFormat, + ColorDataColorimetry colorimetry, + ColorDataDynamicRange colorDynamicRange, + ColorDataDepth colorDepth, + ColorDataSelectionPolicy colorSelectionPolicy, + ColorDataDesktopDepth desktopColorDepth + ) + { + ColorFormat = (byte) colorFormat; + Colorimetry = (byte) colorimetry; + ColorDynamicRange = (byte) colorDynamicRange; + ColorDepth = colorDepth; + ColorSelectionPolicy = colorSelectionPolicy; + DesktopColorDepth = desktopColorDepth; + } + } + + /// + /// Creates an instance of to retrieve color data information + /// + /// The command to be executed. + public ColorDataV5(ColorDataCommand command) + { + this = typeof(ColorDataV5).Instantiate(); + _Size = (ushort) _Version.StructureSize; + + if (command != ColorDataCommand.Get && command != ColorDataCommand.GetDefault) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = (byte) command; + } + + /// + /// Creates an instance of to modify the color data + /// + /// The command to be executed. + /// The color data color format. + /// The color data color space. + /// The color data dynamic range. + /// The color data color depth. + /// The color data selection policy. + /// The color data desktop color depth. + public ColorDataV5( + ColorDataCommand command, + ColorDataFormat colorFormat, + ColorDataColorimetry colorimetry, + ColorDataDynamicRange dynamicRange, + ColorDataDepth colorDepth, + ColorDataSelectionPolicy colorSelectionPolicy, + ColorDataDesktopDepth desktopColorDepth + ) + { + this = typeof(ColorDataV5).Instantiate(); + _Size = (ushort) _Version.StructureSize; + + if (command != ColorDataCommand.Set && command != ColorDataCommand.IsSupportedColor) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = (byte) command; + _Data = new ColorDataBag( + colorFormat, + colorimetry, + dynamicRange, + colorDepth, + colorSelectionPolicy, + desktopColorDepth + ); + } + + /// + public ColorDataFormat ColorFormat + { + get => (ColorDataFormat) _Data.ColorFormat; + } + + /// + public ColorDataColorimetry Colorimetry + { + get => (ColorDataColorimetry) _Data.Colorimetry; + } + + /// + public ColorDataDynamicRange? DynamicRange + { + get => (ColorDataDynamicRange) _Data.ColorDynamicRange; + } + + /// + public ColorDataDepth? ColorDepth + { + get + { + switch ((int) _Data.ColorDepth) + { + case 6: + return ColorDataDepth.BPC6; + case 8: + return ColorDataDepth.BPC8; + case 10: + return ColorDataDepth.BPC10; + case 12: + return ColorDataDepth.BPC12; + case 16: + return ColorDataDepth.BPC16; + default: + return _Data.ColorDepth; + } + } + } + + /// + public ColorDataSelectionPolicy? SelectionPolicy + { + get => _Data.ColorSelectionPolicy; + } + + /// + public ColorDataDesktopDepth? DesktopColorDepth + { + get => _Data.DesktopColorDepth; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/CustomDisplay.cs b/NvAPIWrapper/Native/Display/Structures/CustomDisplay.cs new file mode 100644 index 0000000..a668934 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/CustomDisplay.cs @@ -0,0 +1,135 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Hold information about a custom display resolution + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct CustomDisplay : IInitializable + { + internal StructureVersion _Version; + internal uint _Width; + internal uint _Height; + internal uint _Depth; + internal ColorFormat _ColorFormat; + internal ViewPortF _SourcePartition; + internal float _XRatio; + internal float _YRatio; + internal Timing _Timing; + internal uint _Flags; + + /// + /// Gets the source surface (source mode) width. + /// + public uint Width + { + get => _Width; + } + + /// + /// Gets the source surface (source mode) height. + /// + public uint Height + { + get => _Height; + } + + /// + /// Gets the source surface color depth. "0" means all 8/16/32bpp. + /// + public uint Depth + { + get => _Depth; + } + + /// + /// Gets the color format (optional) + /// + public ColorFormat ColorFormat + { + get => _ColorFormat; + } + + /// + /// Gets the source partition viewport. All values are between [0, 1]. For multi-mon support, should be set to + /// (0,0,1.0,1.0) for now. + /// + public ViewPortF SourcePartition + { + get => _SourcePartition; + } + + /// + /// Gets the horizontal scaling ratio. + /// + public float XRatio + { + get => _XRatio; + } + + /// + /// Gets the vertical scaling ratio. + /// + public float YRatio + { + get => _YRatio; + } + + /// + /// Gets the timing used to program TMDS/DAC/LVDS/HDMI/TVEncoder, etc. + /// + public Timing Timing + { + get => _Timing; + } + + /// + /// Gets a boolean value indicating that a hardware mode-set without OS update should be performed. + /// + public bool HardwareModeSetOnly + { + get => _Flags.GetBit(0); + } + + /// + /// Creates an instance of + /// + /// The source surface (source mode) width. + /// The source surface (source mode) height. + /// The source surface color depth. "0" means all 8/16/32bpp. + /// The color format (optional) + /// The horizontal scaling ratio. + /// The vertical scaling ratio. + /// The timing used to program TMDS/DAC/LVDS/HDMI/TVEncoder, etc. + /// A boolean value indicating that a hardware mode-set without OS update should be performed. + public CustomDisplay( + uint width, + uint height, + uint depth, + ColorFormat colorFormat, + float xRatio, + float yRatio, + Timing timing, + bool hwModeSetOnly + ) + { + this = typeof(CustomDisplay).Instantiate(); + + _Width = width; + _Height = height; + _Depth = depth; + _ColorFormat = colorFormat; + _SourcePartition = new ViewPortF(0, 0, 1, 1); + _XRatio = xRatio; + _YRatio = yRatio; + _Timing = timing; + _Flags = _Flags.SetBit(0, hwModeSetOnly); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/DisplayColorData.cs b/NvAPIWrapper/Native/Display/Structures/DisplayColorData.cs new file mode 100644 index 0000000..3a59071 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/DisplayColorData.cs @@ -0,0 +1,70 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct DisplayColorData : IDisplayColorData + { + private readonly ColorDataColorCoordinate _FirstColorCoordinate; + private readonly ColorDataColorCoordinate _SecondColorCoordinate; + private readonly ColorDataColorCoordinate _ThirdColorCoordinate; + private readonly ColorDataColorCoordinate _WhiteColorCoordinate; + private readonly ushort _MaximumDesiredContentLuminance; + private readonly ushort _MinimumDesiredContentLuminance; + private readonly ushort _MaximumDesiredFrameAverageLightLevel; + + /// + // ReSharper disable once ConvertToAutoProperty + public ColorDataColorCoordinate FirstColorCoordinate + { + get => _FirstColorCoordinate; + } + + /// + // ReSharper disable once ConvertToAutoProperty + public ColorDataColorCoordinate SecondColorCoordinate + { + get => _SecondColorCoordinate; + } + + /// + // ReSharper disable once ConvertToAutoProperty + public ColorDataColorCoordinate ThirdColorCoordinate + { + get => _ThirdColorCoordinate; + } + + /// + // ReSharper disable once ConvertToAutoProperty + public ColorDataColorCoordinate WhiteColorCoordinate + { + get => _WhiteColorCoordinate; + } + + /// + /// Gets the maximum desired content luminance [1.0-65535] in cd/m^2 + /// + public float MaximumDesiredContentLuminance + { + get => _MaximumDesiredContentLuminance; + } + + /// + /// Gets the maximum desired content frame average light level (a.k.a MaxFALL) [1.0-65535] in cd/m^2 + /// + public float MaximumDesiredContentFrameAverageLightLevel + { + get => _MaximumDesiredFrameAverageLightLevel; + } + + /// + /// Gets the maximum desired content luminance [1.0-6.5535] in cd/m^2 + /// + public float MinimumDesiredContentLuminance + { + get => _MinimumDesiredContentLuminance / 10000f; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/DisplayHandle.cs b/NvAPIWrapper/Native/Display/Structures/DisplayHandle.cs new file mode 100644 index 0000000..c19e6cb --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/DisplayHandle.cs @@ -0,0 +1,87 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// DisplayHandle is a one-to-one map to the GDI handle of an attached display in the Windows Display Properties + /// Settings page. + /// + [StructLayout(LayoutKind.Sequential)] + public struct DisplayHandle : IHandle, IEquatable + { + internal readonly IntPtr _MemoryAddress; + + /// + public IntPtr MemoryAddress + { + get => _MemoryAddress; + } + + /// + public bool IsNull + { + get => _MemoryAddress == IntPtr.Zero; + } + + /// + public bool Equals(DisplayHandle other) + { + return _MemoryAddress.Equals(other._MemoryAddress); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is DisplayHandle handle && Equals(handle); + } + + /// + public override int GetHashCode() + { + return _MemoryAddress.GetHashCode(); + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(DisplayHandle left, DisplayHandle right) + { + return left.Equals(right); + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(DisplayHandle left, DisplayHandle right) + { + return !left.Equals(right); + } + + /// + public override string ToString() + { + return $"DisplayHandle #{MemoryAddress.ToInt64()}"; + } + + /// + /// Gets default DisplayHandle with a null pointer + /// + public static DisplayHandle DefaultHandle + { + get => default(DisplayHandle); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/HDMISupportInfoV1.cs b/NvAPIWrapper/Native/Display/Structures/HDMISupportInfoV1.cs new file mode 100644 index 0000000..2da5ea0 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/HDMISupportInfoV1.cs @@ -0,0 +1,94 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + [StructLayout(LayoutKind.Explicit, Pack = 8)] + [StructureVersion(1)] + public struct HDMISupportInfoV1 : IInitializable, IHDMISupportInfo + { + [FieldOffset(0)] internal StructureVersion _Version; + [FieldOffset(4)] private readonly uint _Flags; + [FieldOffset(8)] private readonly uint _EDID861ExtensionRevision; + + /// + public bool IsGPUCapableOfHDMIOutput + { + get => _Flags.GetBit(0); + } + + /// + public bool? IsMonitorCapableOfsYCC601 + { + get => null; + } + + /// + public bool IsMonitorCapableOfUnderscan + { + get => _Flags.GetBit(1); + } + + /// + public bool? IsMonitorCapableOfAdobeYCC601 + { + get => null; + } + + /// + public bool IsMonitorCapableOfBasicAudio + { + get => _Flags.GetBit(2); + } + + /// + public bool IsMonitorCapableOfYCbCr444 + { + get => _Flags.GetBit(3); + } + + /// + public bool IsMonitorCapableOfYCbCr422 + { + get => _Flags.GetBit(4); + } + + /// + // ReSharper disable once IdentifierTypo + public bool IsMonitorCapableOfxvYCC601 + { + get => _Flags.GetBit(5); + } + + /// + // ReSharper disable once IdentifierTypo + public bool IsMonitorCapableOfxvYCC709 + { + get => _Flags.GetBit(6); + } + + /// + public bool IsHDMIMonitor + { + get => _Flags.GetBit(7); + } + + /// + public bool? IsMonitorCapableOfAdobeRGB + { + get => null; + } + + /// + // ReSharper disable once ConvertToAutoProperty + public uint EDID861ExtensionRevision + { + get => _EDID861ExtensionRevision; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/HDMISupportInfoV2.cs b/NvAPIWrapper/Native/Display/Structures/HDMISupportInfoV2.cs new file mode 100644 index 0000000..5072ad7 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/HDMISupportInfoV2.cs @@ -0,0 +1,94 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + [StructLayout(LayoutKind.Explicit, Pack = 8)] + [StructureVersion(2)] + public struct HDMISupportInfoV2 : IInitializable, IHDMISupportInfo + { + [FieldOffset(0)] internal StructureVersion _Version; + [FieldOffset(4)] private readonly uint _Flags; + [FieldOffset(8)] private readonly uint _EDID861ExtensionRevision; + + /// + public bool IsGPUCapableOfHDMIOutput + { + get => _Flags.GetBit(0); + } + + /// + public bool IsMonitorCapableOfUnderscan + { + get => _Flags.GetBit(1); + } + + /// + public bool IsMonitorCapableOfBasicAudio + { + get => _Flags.GetBit(2); + } + + /// + public bool IsMonitorCapableOfYCbCr444 + { + get => _Flags.GetBit(3); + } + + /// + public bool IsMonitorCapableOfYCbCr422 + { + get => _Flags.GetBit(4); + } + + /// + // ReSharper disable once IdentifierTypo + public bool IsMonitorCapableOfxvYCC601 + { + get => _Flags.GetBit(5); + } + + /// + // ReSharper disable once IdentifierTypo + public bool IsMonitorCapableOfxvYCC709 + { + get => _Flags.GetBit(6); + } + + /// + public bool IsHDMIMonitor + { + get => _Flags.GetBit(7); + } + + /// + public bool? IsMonitorCapableOfsYCC601 + { + get => _Flags.GetBit(8); + } + + /// + public bool? IsMonitorCapableOfAdobeYCC601 + { + get => _Flags.GetBit(9); + } + + /// + public bool? IsMonitorCapableOfAdobeRGB + { + get => _Flags.GetBit(10); + } + + /// + // ReSharper disable once ConvertToAutoProperty + public uint EDID861ExtensionRevision + { + get => _EDID861ExtensionRevision; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/HDRCapabilitiesV1.cs b/NvAPIWrapper/Native/Display/Structures/HDRCapabilitiesV1.cs new file mode 100644 index 0000000..cda5283 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/HDRCapabilitiesV1.cs @@ -0,0 +1,80 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Contains information regarding HDR capabilities of a display + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct HDRCapabilitiesV1 : IInitializable + { + internal StructureVersion _Version; + private readonly uint _RawReserved; + + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly StaticMetadataDescriptorId _StaticMetadataDescriptorId; + private readonly DisplayColorData _DisplayData; + + internal HDRCapabilitiesV1(bool expandDriverDefaultHDRParameters) + { + this = typeof(HDRCapabilitiesV1).Instantiate(); + _RawReserved = 0u.SetBit(3, expandDriverDefaultHDRParameters); + _StaticMetadataDescriptorId = StaticMetadataDescriptorId.StaticMetadataType1; + } + + /// + /// Gets the display color space configurations + /// + // ReSharper disable once ConvertToAutoProperty + public DisplayColorData DisplayData + { + get => _DisplayData; + } + + /// + /// Gets a boolean value indicating if the HDMI2.0a UHDA HDR with ST2084 EOTF (CEA861.3) is supported. + /// + public bool IsST2084EOTFSupported + { + get => _RawReserved.GetBit(0); + } + + /// + /// Gets a boolean value indicating if the HDMI2.0a traditional HDR gamma (CEA861.3) is supported. + /// + public bool IsTraditionalHDRGammaSupported + { + get => _RawReserved.GetBit(1); + } + + /// + /// Gets a boolean value indicating if the Extended Dynamic Range on SDR displays is supported. + /// + public bool IsEDRSupported + { + get => _RawReserved.GetBit(2); + } + + /// + /// Gets a boolean value indicating if the default EDID HDR parameters is expanded; + /// otherwise false if this instance contains actual HDR parameters. + /// + public bool IsDriverDefaultHDRParametersExpanded + { + get => _RawReserved.GetBit(3); + } + + /// + /// Gets a boolean value indicating if the HDMI2.0a traditional SDR gamma is supported. + /// + public bool IsTraditionalSDRGammaSupported + { + get => _RawReserved.GetBit(4); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/HDRColorDataV1.cs b/NvAPIWrapper/Native/Display/Structures/HDRColorDataV1.cs new file mode 100644 index 0000000..2a37132 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/HDRColorDataV1.cs @@ -0,0 +1,107 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct HDRColorDataV1 : IInitializable, IHDRColorData + { + internal StructureVersion _Version; + private readonly ColorDataHDRCommand _Command; + private readonly ColorDataHDRMode _HDRMode; + + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly StaticMetadataDescriptorId _StaticMetadataDescriptorId; + private readonly MasteringDisplayColorData _MasteringDisplayData; + + /// + /// Creates an instance of . + /// + /// The command to be executed. + /// The hdr mode. + /// The display color space configurations. + public HDRColorDataV1( + ColorDataHDRCommand command, + ColorDataHDRMode hdrMode, + MasteringDisplayColorData masteringDisplayData = default + ) + { + this = typeof(HDRColorDataV1).Instantiate(); + + if (command != ColorDataHDRCommand.Set) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = command; + _HDRMode = hdrMode; + _MasteringDisplayData = masteringDisplayData; + _StaticMetadataDescriptorId = StaticMetadataDescriptorId.StaticMetadataType1; + } + + + /// + /// Creates an instance of . + /// + /// The command to be executed. + public HDRColorDataV1(ColorDataHDRCommand command) + { + this = typeof(HDRColorDataV1).Instantiate(); + + if (command != ColorDataHDRCommand.Get) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = command; + } + + /// + public ColorDataDepth? ColorDepth + { + get => null; + } + + /// + public ColorDataFormat? ColorFormat + { + get => null; + } + + /// + /// Gets the color data command + /// + // ReSharper disable once ConvertToAutoProperty + public ColorDataHDRCommand Command + { + get => _Command; + } + + /// + public ColorDataDynamicRange? DynamicRange + { + get => null; + } + + /// + // ReSharper disable once ConvertToAutoProperty + public ColorDataHDRMode HDRMode + { + get => _HDRMode; + } + + /// + // ReSharper disable once ConvertToAutoProperty + public MasteringDisplayColorData MasteringDisplayData + { + get => _MasteringDisplayData; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/HDRColorDataV2.cs b/NvAPIWrapper/Native/Display/Structures/HDRColorDataV2.cs new file mode 100644 index 0000000..2f9c9d6 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/HDRColorDataV2.cs @@ -0,0 +1,135 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + public struct HDRColorDataV2 : IInitializable, IHDRColorData + { + internal StructureVersion _Version; + private readonly ColorDataHDRCommand _Command; + private readonly ColorDataHDRMode _HDRMode; + + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly StaticMetadataDescriptorId _StaticMetadataDescriptorId; + private readonly MasteringDisplayColorData _MasteringDisplayData; + private readonly ColorDataFormat _ColorFormat; + private readonly ColorDataDynamicRange _DynamicRange; + private readonly ColorDataDepth _ColorDepth; + + /// + /// Creates an instance of . + /// + /// The command to be executed. + /// The hdr mode. + /// The display color space configurations. + /// The color data color format. + /// The color data dynamic range. + /// The color data color depth. + public HDRColorDataV2( + ColorDataHDRCommand command, + ColorDataHDRMode hdrMode, + MasteringDisplayColorData masteringDisplayData = default, + ColorDataFormat colorFormat = ColorDataFormat.Default, + ColorDataDynamicRange dynamicRange = ColorDataDynamicRange.Auto, + ColorDataDepth colorDepth = ColorDataDepth.Default + ) + { + this = typeof(HDRColorDataV2).Instantiate(); + + if (command != ColorDataHDRCommand.Set) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = command; + _HDRMode = hdrMode; + _MasteringDisplayData = masteringDisplayData; + _ColorFormat = colorFormat; + _DynamicRange = dynamicRange; + _ColorDepth = colorDepth; + _StaticMetadataDescriptorId = StaticMetadataDescriptorId.StaticMetadataType1; + } + + /// + /// Creates an instance of . + /// + /// The command to be executed. + public HDRColorDataV2(ColorDataHDRCommand command) + { + this = typeof(HDRColorDataV2).Instantiate(); + + if (command != ColorDataHDRCommand.Get) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = command; + } + + /// + /// Gets the color data command + /// + // ReSharper disable once ConvertToAutoProperty + public ColorDataHDRCommand Command + { + get => _Command; + } + + /// + // ReSharper disable once ConvertToAutoProperty + public ColorDataHDRMode HDRMode + { + get => _HDRMode; + } + + /// + // ReSharper disable once ConvertToAutoProperty + public MasteringDisplayColorData MasteringDisplayData + { + get => _MasteringDisplayData; + } + + /// + public ColorDataFormat? ColorFormat + { + get => _ColorFormat; + } + + /// + public ColorDataDynamicRange? DynamicRange + { + get => _DynamicRange; + } + + /// + public ColorDataDepth? ColorDepth + { + get + { + switch ((uint) _ColorDepth) + { + case 6: + return ColorDataDepth.BPC6; + case 8: + return ColorDataDepth.BPC8; + case 10: + return ColorDataDepth.BPC10; + case 12: + return ColorDataDepth.BPC12; + case 16: + return ColorDataDepth.BPC16; + default: + return _ColorDepth; + } + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/InfoFrameAudio.cs b/NvAPIWrapper/Native/Display/Structures/InfoFrameAudio.cs new file mode 100644 index 0000000..5389707 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/InfoFrameAudio.cs @@ -0,0 +1,142 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Contains info-frame audio information + /// + [StructLayout(LayoutKind.Explicit, Pack = 8)] + public struct InfoFrameAudio + { + [FieldOffset(0)] private readonly uint _WordAt0; + + [FieldOffset(4)] private readonly uint _WordAt4; + + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + [FieldOffset(8)] private readonly uint _WordAt8; + + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + [FieldOffset(12)] private readonly byte _ByteAt12; + + /// + /// Creates an instance of . + /// + /// The audio coding type (codec) + /// The audio codec from codec extension + /// The audio sample size (depth) + /// The audio sample rate (sampling frequency) + /// The number of audio channels + /// The audio channel allocation (speaker placements) + /// A value indicating if down-mix is prohibited + /// The Low Frequency Effects playback level value + /// The audio level shift value + public InfoFrameAudio( + InfoFrameAudioCodec codec, + InfoFrameAudioExtendedCodec codecExtension, + InfoFrameAudioSampleSize sampleSize, + InfoFrameAudioSampleRate sampleRate, + InfoFrameAudioChannelCount channelCount, + InfoFrameAudioChannelAllocation channelAllocation, + InfoFrameBoolean isDownMixProhibited, + InfoFrameAudioLFEPlaybackLevel lfePlaybackLevel, + InfoFrameAudioLevelShift levelShift + ) + { + _WordAt0 = 0u + .SetBits(0, 5, (uint) codec) + .SetBits(5, 6, (uint) codecExtension) + .SetBits(11, 3, (uint) sampleSize) + .SetBits(14, 4, (uint) sampleRate) + .SetBits(18, 4, (uint) channelCount) + .SetBits(22, 9, (uint) channelAllocation); + _WordAt4 = 0u + .SetBits(0, 2, (uint) isDownMixProhibited) + .SetBits(2, 3, (uint) lfePlaybackLevel) + .SetBits(5, 5, (uint) levelShift); + _WordAt8 = 0; + _ByteAt12 = 0; + } + + /// + /// Gets the audio coding type (codec) + /// + public InfoFrameAudioCodec Codec + { + get => (InfoFrameAudioCodec) _WordAt0.GetBits(0, 5); + } + + /// + /// Gets the audio codec from codec extension; only valid when + /// == + /// + public InfoFrameAudioExtendedCodec? ExtendedCodec + { + get + { + if (Codec != InfoFrameAudioCodec.UseExtendedCodecType) + { + return null; + } + + return (InfoFrameAudioExtendedCodec) _WordAt0.GetBits(5, 6); + } + } + + /// + /// Gets the audio sample size (depth) + /// + public InfoFrameAudioSampleSize SampleSize + { + get => (InfoFrameAudioSampleSize) _WordAt0.GetBits(11, 3); + } + + /// + /// Gets the audio sample rate (sampling frequency) + /// + public InfoFrameAudioSampleRate SampleRate + { + get => (InfoFrameAudioSampleRate) _WordAt0.GetBits(14, 4); + } + + /// + /// Gets the number of audio channels + /// + public InfoFrameAudioChannelCount ChannelCount + { + get => (InfoFrameAudioChannelCount) _WordAt0.GetBits(18, 4); + } + + /// + /// Gets the audio channel allocation (speaker placements) + /// + public InfoFrameAudioChannelAllocation ChannelAllocation + { + get => (InfoFrameAudioChannelAllocation) _WordAt0.GetBits(22, 9); + } + + /// + /// Gets a value indicating if down-mix is prohibited + /// + public InfoFrameBoolean IsDownMixProhibited + { + get => (InfoFrameBoolean) _WordAt4.GetBits(0, 2); + } + + /// + /// Gets the Low Frequency Effects playback level value + /// + public InfoFrameAudioLFEPlaybackLevel LFEPlaybackLevel + { + get => (InfoFrameAudioLFEPlaybackLevel) _WordAt4.GetBits(2, 3); + } + + /// + /// Gets the audio level shift value + /// + public InfoFrameAudioLevelShift LevelShift + { + get => (InfoFrameAudioLevelShift) _WordAt4.GetBits(5, 5); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/InfoFrameData.cs b/NvAPIWrapper/Native/Display/Structures/InfoFrameData.cs new file mode 100644 index 0000000..d90ded1 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/InfoFrameData.cs @@ -0,0 +1,199 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Contains info-frame requested information or information to be overriden + /// + [StructLayout(LayoutKind.Explicit, Pack = 8)] + [StructureVersion(1)] + public struct InfoFrameData : IInitializable + { + [FieldOffset(0)] internal StructureVersion _Version; + + [FieldOffset(4)] + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly ushort _Size; + + [FieldOffset(6)] + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly byte _Command; + + [FieldOffset(7)] private readonly byte _Type; + + [FieldOffset(8)] private readonly InfoFrameProperty _Property; + [FieldOffset(8)] private readonly InfoFrameAudio _Audio; + [FieldOffset(8)] private readonly InfoFrameVideo _Video; + + /// + /// Creates a new instance of . + /// + /// + /// The operation to be done. Can be used for information retrieval or to reset configurations to + /// default. + /// + /// The type of information. + public InfoFrameData(InfoFrameCommand command, InfoFrameDataType dataType) + { + this = typeof(InfoFrameData).Instantiate(); + _Size = (ushort) _Version.StructureSize; + + if (command != InfoFrameCommand.Get && + command != InfoFrameCommand.GetDefault && + command != InfoFrameCommand.GetOverride && + command != InfoFrameCommand.GetProperty && + command != InfoFrameCommand.Reset) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = (byte) command; + _Type = (byte) dataType; + } + + /// + /// Creates a new instance of . + /// + /// The operation to be done. Can only be used to change property information. + /// The type of information. + /// The new property information to be set. + public InfoFrameData( + InfoFrameCommand command, + InfoFrameDataType dataType, + InfoFrameProperty propertyInformation) + { + this = typeof(InfoFrameData).Instantiate(); + _Size = (ushort) _Version.StructureSize; + + if (command != InfoFrameCommand.SetProperty) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = (byte) command; + _Type = (byte) dataType; + _Property = propertyInformation; + } + + /// + /// Creates a new instance of . + /// + /// The operation to be done. Can only be used to change current or default audio information. + /// The new audio information to be set. + public InfoFrameData(InfoFrameCommand command, InfoFrameAudio audioInformation) + { + this = typeof(InfoFrameData).Instantiate(); + _Size = (ushort) _Version.StructureSize; + + if (command != InfoFrameCommand.Set && + command != InfoFrameCommand.SetOverride) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = (byte) command; + _Type = (byte) InfoFrameDataType.AudioInformation; + _Audio = audioInformation; + } + + /// + /// Creates a new instance of . + /// + /// The operation to be done. Can only be used to change current or default video information. + /// The new video information to be set. + public InfoFrameData(InfoFrameCommand command, InfoFrameVideo videoInformation) + { + this = typeof(InfoFrameData).Instantiate(); + _Size = (ushort) _Version.StructureSize; + + if (command != InfoFrameCommand.Set && + command != InfoFrameCommand.SetOverride) + { + throw new ArgumentOutOfRangeException(nameof(command)); + } + + _Command = (byte) command; + _Type = (byte) InfoFrameDataType.AuxiliaryVideoInformation; + _Video = videoInformation; + } + + /// + /// Gets the type of data contained in this instance + /// + public InfoFrameDataType Type + { + get => (InfoFrameDataType) _Type; + } + + /// + /// Gets the operation type + /// + public InfoFrameCommand Command + { + get => (InfoFrameCommand) _Command; + } + + /// + /// Gets the info-frame audio information if available; otherwise null + /// + public InfoFrameAudio? AudioInformation + { + get + { + if (Command == InfoFrameCommand.GetProperty || Command == InfoFrameCommand.SetProperty) + { + return null; + } + + if (Type == InfoFrameDataType.AudioInformation) + { + return _Audio; + } + + return null; + } + } + + /// + /// Gets the info-frame auxiliary video information (AVI) if available; otherwise null + /// + public InfoFrameVideo? AuxiliaryVideoInformation + { + get + { + if (Command == InfoFrameCommand.GetProperty || Command == InfoFrameCommand.SetProperty) + { + return null; + } + + if (Type == InfoFrameDataType.AuxiliaryVideoInformation) + { + return _Video; + } + + return null; + } + } + + /// + /// Gets the info-frame property information if available; otherwise null + /// + public InfoFrameProperty? PropertyInformation + { + get + { + if (Command != InfoFrameCommand.GetProperty && Command != InfoFrameCommand.SetProperty) + { + return null; + } + + return _Property; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/InfoFrameProperty.cs b/NvAPIWrapper/Native/Display/Structures/InfoFrameProperty.cs new file mode 100644 index 0000000..1489be5 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/InfoFrameProperty.cs @@ -0,0 +1,58 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Contains info-frame property information + /// + [StructLayout(LayoutKind.Explicit, Pack = 8)] + public struct InfoFrameProperty + { + [FieldOffset(0)] private readonly uint _Word; + + /// + /// Creates an instance of . + /// + /// The info-frame operation mode + /// A value indicating if this display (monitor) is blacklisted + public InfoFrameProperty(InfoFramePropertyMode mode, InfoFrameBoolean isBlackListed) + { + _Word = 0u + .SetBits(0, 4, (uint) mode) + .SetBits(4, 2, (uint) isBlackListed); + } + + /// + /// Gets the info-frame operation mode + /// + public InfoFramePropertyMode Mode + { + get => (InfoFramePropertyMode) _Word.GetBits(0, 4); + } + + /// + /// Gets a value indicating if this display (monitor) is blacklisted + /// + public InfoFrameBoolean IsBlackListed + { + get => (InfoFrameBoolean) _Word.GetBits(4, 2); + } + + /// + /// Gets the info-frame version + /// + public byte Version + { + get => (byte) _Word.GetBits(16, 8); + } + + /// + /// Gets the info-frame length + /// + public byte Length + { + get => (byte) _Word.GetBits(24, 8); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/InfoFrameVideo.cs b/NvAPIWrapper/Native/Display/Structures/InfoFrameVideo.cs new file mode 100644 index 0000000..a366bda --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/InfoFrameVideo.cs @@ -0,0 +1,320 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Contains info-frame video information + /// + [StructLayout(LayoutKind.Explicit, Pack = 8)] + public struct InfoFrameVideo + { + [FieldOffset(0)] private readonly uint _WordAt0; + [FieldOffset(4)] private readonly uint _WordAt4; + [FieldOffset(8)] private readonly uint _WordAt8; + [FieldOffset(12)] private readonly uint _WordAt12; + [FieldOffset(16)] private readonly uint _WordAt16; + [FieldOffset(20)] private readonly uint _WordAt20; + + /// + /// Creates an instance of . + /// + /// The video identification code (VIC) + /// The video pixel repetition + /// The video color format + /// The video color space + /// The extended video color space + /// The RGB quantization configuration + /// The YCC quantization configuration + /// The video content mode + /// The video content type + /// The video scan information + /// A value indicating if the active format information is present + /// The active format aspect ratio + /// The picture aspect ratio + /// The non uniform picture scaling direction + /// The video bar information + /// The top bar value if not auto and present; otherwise null + /// The bottom bar value if not auto and present; otherwise null + /// The left bar value if not auto and present; otherwise null + /// The right bar value if not auto and present; otherwise null + public InfoFrameVideo( + byte videoIdentificationCode, + InfoFrameVideoPixelRepetition pixelRepetition, + InfoFrameVideoColorFormat colorFormat, + InfoFrameVideoColorimetry colorimetry, + InfoFrameVideoExtendedColorimetry extendedColorimetry, + InfoFrameVideoRGBQuantization rgbQuantization, + InfoFrameVideoYCCQuantization yccQuantization, + InfoFrameVideoITC contentMode, + InfoFrameVideoContentType contentType, + InfoFrameVideoScanInfo scanInfo, + InfoFrameBoolean isActiveFormatInfoPresent, + InfoFrameVideoAspectRatioActivePortion activeFormatAspectRatio, + InfoFrameVideoAspectRatioCodedFrame pictureAspectRatio, + InfoFrameVideoNonUniformPictureScaling nonUniformPictureScaling, + InfoFrameVideoBarData barInfo, + uint? topBar, + uint? bottomBar, + uint? leftBar, + uint? rightBar + ) + { + _WordAt0 = 0u + .SetBits(0, 8, videoIdentificationCode) + .SetBits(8, 5, (uint) pixelRepetition) + .SetBits(13, 3, (uint) colorFormat) + .SetBits(16, 3, (uint) colorimetry) + .SetBits(19, 4, (uint) extendedColorimetry) + .SetBits(23, 3, (uint) rgbQuantization) + .SetBits(26, 3, (uint) yccQuantization) + .SetBits(29, 2, (uint) contentMode); + + _WordAt4 = 0u + .SetBits(0, 3, (uint) contentType) + .SetBits(3, 3, (uint) scanInfo) + .SetBits(6, 2, (uint) isActiveFormatInfoPresent) + .SetBits(8, 5, (uint) activeFormatAspectRatio) + .SetBits(13, 3, (uint) pictureAspectRatio) + .SetBits(16, 3, (uint) nonUniformPictureScaling) + .SetBits(19, 3, (uint) barInfo); + + _WordAt8 = topBar == null ? 0x1FFFF : 0u.SetBits(0, 17, topBar.Value); + _WordAt12 = bottomBar == null ? 0x1FFFF : 0u.SetBits(0, 17, bottomBar.Value); + _WordAt16 = leftBar == null ? 0x1FFFF : 0u.SetBits(0, 17, leftBar.Value); + _WordAt20 = rightBar == null ? 0x1FFFF : 0u.SetBits(0, 17, rightBar.Value); + } + + /// + /// Gets the video identification code (VIC) + /// + // ReSharper disable once ConvertToAutoProperty + public byte? VideoIdentificationCode + { + get + { + var value = (byte) _WordAt0.GetBits(0, 8); + + if (value == 0xFF) + { + return null; + } + + return value; + } + } + + /// + /// Gets the video pixel repetition + /// + public InfoFrameVideoPixelRepetition PixelRepetition + { + get => (InfoFrameVideoPixelRepetition) _WordAt0.GetBits(8, 5); + } + + /// + /// Gets the video color format + /// + public InfoFrameVideoColorFormat ColorFormat + { + get => (InfoFrameVideoColorFormat) _WordAt0.GetBits(13, 3); + } + + /// + /// Gets the video color space + /// + public InfoFrameVideoColorimetry Colorimetry + { + get => (InfoFrameVideoColorimetry) _WordAt0.GetBits(16, 3); + } + + /// + /// Gets the extended video color space; only valid when == + /// + /// + public InfoFrameVideoExtendedColorimetry? ExtendedColorimetry + { + get + { + if (Colorimetry != InfoFrameVideoColorimetry.UseExtendedColorimetry) + { + return null; + } + + return (InfoFrameVideoExtendedColorimetry) _WordAt0.GetBits(19, 4); + } + } + + /// + /// Gets the RGB quantization configuration + /// + public InfoFrameVideoRGBQuantization RGBQuantization + { + get => (InfoFrameVideoRGBQuantization) _WordAt0.GetBits(23, 3); + } + + /// + /// Gets the YCC quantization configuration + /// + public InfoFrameVideoYCCQuantization YCCQuantization + { + get => (InfoFrameVideoYCCQuantization) _WordAt0.GetBits(26, 3); + } + + /// + /// Gets the video content mode + /// + public InfoFrameVideoITC ContentMode + { + get => (InfoFrameVideoITC) _WordAt0.GetBits(29, 2); + } + + /// + /// Gets the video content type + /// + public InfoFrameVideoContentType ContentType + { + get => (InfoFrameVideoContentType) _WordAt4.GetBits(0, 3); + } + + /// + /// Gets the video scan information + /// + public InfoFrameVideoScanInfo ScanInfo + { + get => (InfoFrameVideoScanInfo) _WordAt4.GetBits(3, 3); + } + + /// + /// Gets a value indicating if the active format information is present + /// + public InfoFrameBoolean IsActiveFormatInfoPresent + { + get => (InfoFrameBoolean) _WordAt4.GetBits(6, 2); + } + + /// + /// Gets the active format aspect ratio + /// + public InfoFrameVideoAspectRatioActivePortion ActiveFormatAspectRatio + { + get => (InfoFrameVideoAspectRatioActivePortion) _WordAt4.GetBits(8, 5); + } + + /// + /// Gets the picture aspect ratio + /// + public InfoFrameVideoAspectRatioCodedFrame PictureAspectRatio + { + get => (InfoFrameVideoAspectRatioCodedFrame) _WordAt4.GetBits(13, 3); + } + + /// + /// Gets the non uniform picture scaling direction + /// + public InfoFrameVideoNonUniformPictureScaling NonUniformPictureScaling + { + get => (InfoFrameVideoNonUniformPictureScaling) _WordAt4.GetBits(16, 3); + } + + /// + /// Gets the video bar information + /// + public InfoFrameVideoBarData BarInfo + { + get => (InfoFrameVideoBarData) _WordAt4.GetBits(19, 3); + } + + /// + /// Gets the top bar value if not auto and present; otherwise null + /// + public uint? TopBar + { + get + { + if (BarInfo == InfoFrameVideoBarData.NotPresent || BarInfo == InfoFrameVideoBarData.Horizontal) + { + return null; + } + + var val = _WordAt8.GetBits(0, 17); + + if (val == 0x1FFFF) + { + return null; + } + + return (uint) val; + } + } + + /// + /// Gets the bottom bar value if not auto and present; otherwise null + /// + public uint? BottomBar + { + get + { + if (BarInfo == InfoFrameVideoBarData.NotPresent || BarInfo == InfoFrameVideoBarData.Horizontal) + { + return null; + } + + var val = _WordAt12.GetBits(0, 17); + + if (val == 0x1FFFF) + { + return null; + } + + return (uint) val; + } + } + + /// + /// Gets the left bar value if not auto and present; otherwise null + /// + public uint? LeftBar + { + get + { + if (BarInfo == InfoFrameVideoBarData.NotPresent || BarInfo == InfoFrameVideoBarData.Vertical) + { + return null; + } + + var val = _WordAt16.GetBits(0, 17); + + if (val == 0x1FFFF) + { + return null; + } + + return (uint) val; + } + } + + /// + /// Gets the right bar value if not auto and present; otherwise null + /// + public uint? RightBar + { + get + { + if (BarInfo == InfoFrameVideoBarData.NotPresent || BarInfo == InfoFrameVideoBarData.Vertical) + { + return null; + } + + var val = _WordAt20.GetBits(0, 17); + + if (val == 0x1FFFF) + { + return null; + } + + return (uint) val; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/LUID.cs b/NvAPIWrapper/Native/Display/Structures/LUID.cs new file mode 100644 index 0000000..1af8cae --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/LUID.cs @@ -0,0 +1,76 @@ +using System; +using System.Runtime.InteropServices; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Locally unique identifier is a 64-bit value guaranteed to be unique only on the system on which it was generated. + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct LUID : IEquatable + { + /// + /// 32Bit unsigned integer, low + /// + public readonly uint LowPart; + + /// + /// 32Bit signed integer, high + /// + public readonly int HighPart; + + /// + public override string ToString() + { + return $"{{{LowPart:X}-{HighPart:X}}}"; + } + + /// + public bool Equals(LUID other) + { + return LowPart == other.LowPart && HighPart == other.HighPart; + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is LUID luid && Equals(luid); + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(LUID left, LUID right) + { + return left.Equals(right); + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(LUID left, LUID right) + { + return !left.Equals(right); + } + + /// + public override int GetHashCode() + { + unchecked + { + return ((int) LowPart * 397) ^ HighPart; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/MasteringDisplayColorData.cs b/NvAPIWrapper/Native/Display/Structures/MasteringDisplayColorData.cs new file mode 100644 index 0000000..0a0f2da --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/MasteringDisplayColorData.cs @@ -0,0 +1,120 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct MasteringDisplayColorData : IDisplayColorData + { + private readonly ColorDataColorCoordinate _FirstColorCoordinate; + private readonly ColorDataColorCoordinate _SecondColorCoordinate; + private readonly ColorDataColorCoordinate _ThirdColorCoordinate; + private readonly ColorDataColorCoordinate _WhiteColorCoordinate; + private readonly ushort _MaximumMasteringLuminance; + private readonly ushort _MinimumMasteringLuminance; + private readonly ushort _MaximumContentLightLevel; + private readonly ushort _MaximumFrameAverageLightLevel; + + /// + /// Creates an instance of . + /// + /// The first primary color coordinate. + /// The second primary color coordinate. + /// The third primary color coordinate. + /// The white color coordinate. + /// The maximum mastering display luminance [1.0-65535] in cd/m^2 + /// The maximum mastering display luminance [1.0-6.5535] in cd/m^2 + /// + /// The maximum mastering display content light level (a.k.a MaxCLL) [1.0-65535] in + /// cd/m^2 + /// + /// + /// The maximum mastering display frame average light level (a.k.a MaxFALL) + /// [1.0-65535] in cd/m^2 + /// + public MasteringDisplayColorData( + ColorDataColorCoordinate firstColorCoordinate, + ColorDataColorCoordinate secondColorCoordinate, + ColorDataColorCoordinate thirdColorCoordinate, + ColorDataColorCoordinate whiteColorCoordinate, + float maximumMasteringLuminance, + float minimumMasteringLuminance, + float maximumContentLightLevel, + float maximumFrameAverageLightLevel + ) + { + _FirstColorCoordinate = firstColorCoordinate; + _SecondColorCoordinate = secondColorCoordinate; + _ThirdColorCoordinate = thirdColorCoordinate; + _WhiteColorCoordinate = whiteColorCoordinate; + _MaximumMasteringLuminance = (ushort) Math.Max(Math.Min(maximumMasteringLuminance, uint.MaxValue), 1); + _MinimumMasteringLuminance = + (ushort) Math.Max(Math.Min(minimumMasteringLuminance * 10000, uint.MaxValue), 1); + _MaximumContentLightLevel = (ushort) Math.Max(Math.Min(maximumContentLightLevel, uint.MaxValue), 1); + _MaximumFrameAverageLightLevel = + (ushort) Math.Max(Math.Min(maximumFrameAverageLightLevel, uint.MaxValue), 1); + } + + /// + // ReSharper disable once ConvertToAutoProperty + public ColorDataColorCoordinate FirstColorCoordinate + { + get => _FirstColorCoordinate; + } + + /// + // ReSharper disable once ConvertToAutoProperty + public ColorDataColorCoordinate SecondColorCoordinate + { + get => _SecondColorCoordinate; + } + + /// + // ReSharper disable once ConvertToAutoProperty + public ColorDataColorCoordinate ThirdColorCoordinate + { + get => _ThirdColorCoordinate; + } + + /// + // ReSharper disable once ConvertToAutoProperty + public ColorDataColorCoordinate WhiteColorCoordinate + { + get => _WhiteColorCoordinate; + } + + /// + /// Gets the maximum mastering display luminance [1.0-65535] in cd/m^2 + /// + public float MaximumMasteringLuminance + { + get => _MaximumMasteringLuminance; + } + + /// + /// Gets the maximum mastering display frame average light level (a.k.a MaxFALL) [1.0-65535] in cd/m^2 + /// + public float MaximumFrameAverageLightLevel + { + get => _MaximumFrameAverageLightLevel; + } + + /// + /// Gets the maximum mastering display content light level (a.k.a MaxCLL) [1.0-65535] in cd/m^2 + /// + public float MaximumContentLightLevel + { + get => _MaximumContentLightLevel; + } + + /// + /// Gets the maximum mastering display luminance [1.0-6.5535] in cd/m^2 + /// + public float MinimumMasteringLuminance + { + get => _MinimumMasteringLuminance / 10000f; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/MonitorCapabilities.cs b/NvAPIWrapper/Native/Display/Structures/MonitorCapabilities.cs new file mode 100644 index 0000000..8d38851 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/MonitorCapabilities.cs @@ -0,0 +1,96 @@ +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Contains the monitor capabilities read from the Vendor Specific Data Block or the Video Capability Data Block + /// + [StructureVersion(1)] + [StructLayout(LayoutKind.Explicit, Pack = 8)] + public struct MonitorCapabilities : IInitializable + { + [FieldOffset(0)] internal StructureVersion _Version; + + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + [FieldOffset(4)] private readonly ushort _Size; + [FieldOffset(8)] private readonly MonitorCapabilitiesType _Type; + [FieldOffset(12)] private readonly MonitorCapabilitiesConnectorType _ConnectorType; + + [FieldOffset(16)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)] + private readonly byte[] _Data; + + /// + /// Creates a new instance of . + /// + /// The type of information to be retrieved. + public MonitorCapabilities(MonitorCapabilitiesType type) + { + this = typeof(MonitorCapabilities).Instantiate(); + _Size = (ushort) _Version.StructureSize; + _Type = type; + } + + /// + /// Gets a boolean value indicating if this instance contains valid information + /// + public bool IsValid + { + get => _Data[0].GetBit(0); + } + + /// + /// Gets the monitor capability type + /// + // ReSharper disable once ConvertToAutoPropertyWhenPossible + public MonitorCapabilitiesType Type + { + get => _Type; + } + + /// + /// Gets the monitor connector type + /// + // ReSharper disable once ConvertToAutoProperty + public MonitorCapabilitiesConnectorType ConnectorType + { + get => _ConnectorType; + } + + /// + /// Gets the monitor VCDB capabilities information + /// + public MonitorVCDBCapabilities? VCDBCapabilities + { + get + { + if (IsValid && _Type == MonitorCapabilitiesType.VCDB) + { + return new MonitorVCDBCapabilities(_Data.Skip(1).ToArray()); + } + + return null; + } + } + + /// + /// Gets the monitor VSDB capabilities information + /// + public MonitorVSDBCapabilities? VSDBCapabilities + { + get + { + if (IsValid && _Type == MonitorCapabilitiesType.VSDB) + { + return new MonitorVSDBCapabilities(_Data.Skip(1).ToArray()); + } + + return null; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/MonitorColorData.cs b/NvAPIWrapper/Native/Display/Structures/MonitorColorData.cs new file mode 100644 index 0000000..4cfe3a5 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/MonitorColorData.cs @@ -0,0 +1,57 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Contains information about a monitor color data + /// + [StructureVersion(1)] + [StructLayout(LayoutKind.Explicit, Pack = 8, Size = 12)] + public struct MonitorColorData : IInitializable + { + [FieldOffset(0)] + internal StructureVersion _Version; + [FieldOffset(4)] + private readonly DisplayPortColorFormat _ColorFormat; + [FieldOffset(8)] + private readonly DisplayPortColorDepth _ColorDepth; + + /// + ///Gets the monitor display port color format + /// + // ReSharper disable once ConvertToAutoProperty + public DisplayPortColorFormat ColorFormat + { + get => _ColorFormat; + } + + /// + /// Gets the monitor display port color depth + /// + // ReSharper disable once ConvertToAutoProperty + public DisplayPortColorDepth ColorDepth + { + get + { + switch ((uint) _ColorDepth) + { + case 6: + return DisplayPortColorDepth.BPC6; + case 8: + return DisplayPortColorDepth.BPC8; + case 10: + return DisplayPortColorDepth.BPC10; + case 12: + return DisplayPortColorDepth.BPC12; + case 16: + return DisplayPortColorDepth.BPC16; + default: + return _ColorDepth; + } + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/MonitorVCDBCapabilities.cs b/NvAPIWrapper/Native/Display/Structures/MonitorVCDBCapabilities.cs new file mode 100644 index 0000000..7305b7a --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/MonitorVCDBCapabilities.cs @@ -0,0 +1,54 @@ +using System; +using NvAPIWrapper.Native.Helpers; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Contains monitor VCDB capabilities + /// + public struct MonitorVCDBCapabilities + { + private readonly byte[] _data; + + internal MonitorVCDBCapabilities(byte[] data) + { + if (data.Length != 49) + { + throw new ArgumentOutOfRangeException(nameof(data)); + } + + _data = data; + } + + /// + /// Gets a boolean value indicating RGB range quantization + /// + public bool QuantizationRangeRGB + { + get => _data[0].GetBit(1); + } + + /// + /// Gets a boolean value indicating Ycc range quantization + /// + public bool QuantizationRangeYcc + { + get => _data[0].GetBit(0); + } + + public byte ScanInfoConsumerElectronicsVideoFormats + { + get => (byte)_data[0].GetBits(6, 2); + } + + public byte ScanInfoInformationTechnologyVideoFormats + { + get => (byte)_data[0].GetBits(4, 2); + } + + public byte ScanInfoPreferredVideoFormat + { + get => (byte)_data[0].GetBits(2, 2); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/MonitorVSDBCapabilities.cs b/NvAPIWrapper/Native/Display/Structures/MonitorVSDBCapabilities.cs new file mode 100644 index 0000000..b81cdfd --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/MonitorVSDBCapabilities.cs @@ -0,0 +1,254 @@ +using System; +using System.Linq; +using NvAPIWrapper.Native.Helpers; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Contains monitor VSDB capabilities + /// + public struct MonitorVSDBCapabilities + { + private readonly byte[] _data; + + internal MonitorVSDBCapabilities(byte[] data) + { + if (data.Length != 49) + { + throw new ArgumentOutOfRangeException(nameof(data)); + } + + _data = data; + } + + /// + /// Gets the audio latency if available or null + /// + public byte? AudioLatency + { + get + { + if (!_data[4].GetBit(7)) + { + return null; + } + + return _data[6]; + } + } + + public byte[] HDMI3D + { + get + { + if (!_data[9].GetBit(7)) + { + return new byte[0]; + } + + return _data.Skip(18).Take(31).Take((int)_data[10].GetBits(0, 5)).ToArray(); + } + } + + public byte[] HDMIVideoImageCompositors + { + get + { + if (!_data[4].GetBit(5)) + { + return new byte[0]; + } + + return _data.Skip(11).Take(7).Take((int)_data[10].GetBits(5, 3)).ToArray(); + } + } + + /// + /// Gets the interlaced audio latency if available or null + /// + public byte? InterlacedAudioLatency + { + get + { + if (!_data[4].GetBit(6)) + { + return null; + } + + return _data[8]; + } + } + + /// + /// Gets the interlaced video latency if available or null + /// + public byte? InterlacedVideoLatency + { + get + { + if (!_data[4].GetBit(6)) + { + return null; + } + + return _data[7]; + } + } + + public bool IsAISupported + { + get => _data[2].GetBit(7); + } + + /// + /// Returns a boolean value indicating if the cinematic content is supported by the monitor or the connection + /// + public bool IsCinemaContentSupported + { + get => _data[4].GetBit(2); + } + + /// + /// Returns a boolean value indicating if the 30bit deep color is supported by the monitor or the connection + /// + public bool IsDeepColor30BitsSupported + { + get => _data[2].GetBit(4); + } + + /// + /// Returns a boolean value indicating if the 36bit deep color is supported by the monitor or the connection + /// + public bool IsDeepColor36BitsSupported + { + get => _data[2].GetBit(5); + } + + /// + /// Returns a boolean value indicating if the 48bit deep color is supported by the monitor or the connection + /// + public bool IsDeepColor48BitsSupported + { + get => _data[2].GetBit(6); + } + + + /// + /// Returns a boolean value indicating if the YCbCr444 deep color is supported by the monitor or the connection + /// + public bool IsDeepColorYCbCr444Supported + { + get => _data[2].GetBit(3); + } + + /// + /// Returns a boolean value indicating if the dual DVI operation is supported by the monitor or the connection + /// + public bool IsDualDVIOperationSupported + { + get => _data[2].GetBit(0); + } + + /// + /// Returns a boolean value indicating if the gaming content is supported by the monitor or the connection + /// + public bool IsGameContentSupported + { + get => _data[4].GetBit(3); + } + + /// + /// Returns a boolean value indicating if the graphics text content is supported by the monitor or the connection + /// + public bool IsGraphicsTextContentSupported + { + get => _data[4].GetBit(0); + } + + /// + /// Returns a boolean value indicating if the photo content is supported by monitor or the connection + /// + public bool IsPhotoContentSupported + { + get => _data[4].GetBit(1); + } + + /// + /// Gets the connection max TMDS clock supported by the monitor or the connection + /// + public byte MaxTMDSClock + { + get => _data[3]; + } + + /// + /// Gets the monitor physical address on port + /// + public MonitorPhysicalAddress PhysicalAddress + { + get => new MonitorPhysicalAddress( + (byte)_data[0].GetBits(4, 4), + (byte)_data[0].GetBits(0, 4), + (byte)_data[1].GetBits(4, 4), + (byte)_data[1].GetBits(0, 4) + ); + } + + /// + /// Gets the video latency if available or null + /// + public byte? VideoLatency + { + get + { + if (!_data[4].GetBit(7)) + { + return null; + } + + return _data[5]; + } + } + + /// + /// Represents a monitor physical address + /// + public class MonitorPhysicalAddress + { + internal MonitorPhysicalAddress(byte a, byte b, byte c, byte d) + { + A = a; + B = b; + C = c; + D = d; + } + + /// + /// Gets the first part of a monitor physical address + /// + public byte A { get; set; } + + /// + /// Gets the second part of a monitor physical address + /// + public byte B { get; set; } + + + /// + /// Gets the third part of a monitor physical address + /// + public byte C { get; set; } + + /// + /// Gets the forth part of a monitor physical address + /// + public byte D { get; set; } + + /// + public override string ToString() + { + return $"{A:D}.{B:D}.{C:D}.{D:D}"; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/PathAdvancedTargetInfo.cs b/NvAPIWrapper/Native/Display/Structures/PathAdvancedTargetInfo.cs new file mode 100644 index 0000000..73e649a --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/PathAdvancedTargetInfo.cs @@ -0,0 +1,268 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Holds advanced information about a PathTargetInfo + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PathAdvancedTargetInfo : IInitializable, IEquatable + { + internal StructureVersion _Version; + internal readonly Rotate _Rotation; + internal readonly Scaling _Scaling; + internal readonly uint _RefreshRateInMillihertz; + internal uint _RawReserved; + internal readonly ConnectorType _ConnectorType; + internal readonly TVFormat _TVFormat; + internal readonly TimingOverride _TimingOverride; + internal readonly Timing _Timing; + + /// + /// Creates a new PathAdvancedTargetInfo for monitors + /// + /// Screen rotation + /// Screen scaling + /// Screen refresh rate + /// Timing override + /// Indicates if the mode is interlaced + /// Indicates if the display is the primary display of a clone topology + /// Indicates if the target Pan and Scan is enabled + /// + /// + /// + public PathAdvancedTargetInfo( + Rotate rotation, + Scaling scale, + uint refreshRateInMillihertz = 0, + TimingOverride timingOverride = TimingOverride.Current, + bool isInterlaced = false, + bool isClonePrimary = false, + bool isClonePanAndScanTarget = false, + bool disableVirtualModeSupport = false, + bool isPreferredUnscaledTarget = false) + { + if (timingOverride == TimingOverride.Custom) + { + throw new NVIDIANotSupportedException("Custom timing is not supported yet."); + } + + this = typeof(PathAdvancedTargetInfo).Instantiate(); + _Rotation = rotation; + _Scaling = scale; + _RefreshRateInMillihertz = refreshRateInMillihertz; + _TimingOverride = timingOverride; + IsInterlaced = isInterlaced; + IsClonePrimary = isClonePrimary; + IsClonePanAndScanTarget = isClonePanAndScanTarget; + DisableVirtualModeSupport = disableVirtualModeSupport; + IsPreferredUnscaledTarget = isPreferredUnscaledTarget; + } + + /// + /// Creates a new PathAdvancedTargetInfo for TVs + /// + /// Screen rotation + /// Screen scaling + /// The TV format to apply + /// Specify connector type. For TV only + /// Screen refresh rate + /// Timing override + /// Indicates if the mode is interlaced + /// Indicates if the display is the primary display of a clone topology + /// Indicates if the target Pan and Scan is enabled + /// + /// + /// + public PathAdvancedTargetInfo( + Rotate rotation, + Scaling scale, + TVFormat tvFormat, + ConnectorType connectorType, + uint refreshRateInMillihertz = 0, + TimingOverride timingOverride = TimingOverride.Current, + bool isInterlaced = false, + bool isClonePrimary = false, + bool isClonePanAndScanTarget = false, + bool disableVirtualModeSupport = false, + bool isPreferredUnscaledTarget = false) + : this( + rotation, scale, refreshRateInMillihertz, timingOverride, isInterlaced, isClonePrimary, + isClonePanAndScanTarget, + disableVirtualModeSupport, isPreferredUnscaledTarget) + { + if (tvFormat == TVFormat.None) + { + throw new NVIDIANotSupportedException( + "This overload is for TV displays, use the other overload(s) if the display is not a TV."); + } + + this = typeof(PathAdvancedTargetInfo).Instantiate(); + _TVFormat = tvFormat; + _ConnectorType = connectorType; + } + + /// + public bool Equals(PathAdvancedTargetInfo other) + { + return _Rotation == other._Rotation && + _Scaling == other._Scaling && + _RefreshRateInMillihertz == other._RefreshRateInMillihertz && + (TVFormat == TVFormat.None || _ConnectorType == other._ConnectorType) && + _TVFormat == other._TVFormat && + _TimingOverride == other._TimingOverride && + _Timing.Equals(other._Timing) && + _RawReserved == other._RawReserved; + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is PathAdvancedTargetInfo info && Equals(info); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (int) _Rotation; + hashCode = (hashCode * 397) ^ (int) _Scaling; + hashCode = (hashCode * 397) ^ (int) _RefreshRateInMillihertz; + // ReSharper disable once NonReadonlyMemberInGetHashCode + hashCode = (hashCode * 397) ^ (int) _RawReserved; + hashCode = (hashCode * 397) ^ (int) _ConnectorType; + hashCode = (hashCode * 397) ^ (int) _TVFormat; + hashCode = (hashCode * 397) ^ (int) _TimingOverride; + hashCode = (hashCode * 397) ^ _Timing.GetHashCode(); + + return hashCode; + } + } + + /// + /// Rotation setting + /// + public Rotate Rotation + { + get => _Rotation; + } + + /// + /// Scaling setting + /// + public Scaling Scaling + { + get => _Scaling; + } + + /// + /// Non-interlaced Refresh Rate of the mode, multiplied by 1000, 0 = ignored + /// This is the value which driver reports to the OS. + /// + public uint RefreshRateInMillihertz + { + get => _RefreshRateInMillihertz; + } + + /// + /// Specify connector type. For TV only, ignored if TVFormat == TVFormat.None. + /// + public ConnectorType ConnectorType + { + get => _ConnectorType; + } + + /// + /// To choose the last TV format set this value to TVFormat.None + /// In case of NvAPI_DISP_GetDisplayConfig(), this field will indicate the currently applied TV format; + /// if no TV format is applied, this field will have TVFormat.None value. + /// In case of NvAPI_DISP_SetDisplayConfig(), this field should only be set in case of TVs; + /// for other displays this field will be ignored and resolution & refresh rate specified in input will be used to + /// apply the TV format. + /// + public TVFormat TVFormat + { + get => _TVFormat; + } + + /// + /// Ignored if TimingOverride == TimingOverride.Current + /// + public TimingOverride TimingOverride + { + get => _TimingOverride; + } + + /// + /// Scan out timing, valid only if TimingOverride == TimingOverride.Custom + /// The value Timing.PixelClockIn10KHertz is obtained from the EDID. The driver may tweak this value for HDTV, stereo, + /// etc., before reporting it to the OS. + /// + public Timing Timing + { + get => _Timing; + } + + /// + /// Interlaced mode flag, ignored if refreshRate == 0 + /// + public bool IsInterlaced + { + get => _RawReserved.GetBit(0); + private set => _RawReserved = _RawReserved.SetBit(0, value); + } + + /// + /// Declares primary display in clone configuration. This is *NOT* GDI Primary. + /// Only one target can be primary per source. If no primary is specified, the first target will automatically be + /// primary. + /// + public bool IsClonePrimary + { + get => _RawReserved.GetBit(1); + private set => _RawReserved = _RawReserved.SetBit(1, value); + } + + /// + /// Whether on this target Pan and Scan is enabled or has to be enabled. Valid only when the target is part of clone + /// topology. + /// + public bool IsClonePanAndScanTarget + { + get => _RawReserved.GetBit(2); + private set => _RawReserved = _RawReserved.SetBit(2, value); + } + + /// + /// Indicates if virtual mode support is disabled + /// + public bool DisableVirtualModeSupport + { + get => _RawReserved.GetBit(3); + private set => _RawReserved = _RawReserved.SetBit(3, value); + } + + /// + /// Indicates if the target is in preferred unscaled mode + /// + public bool IsPreferredUnscaledTarget + { + get => _RawReserved.GetBit(4); + private set => _RawReserved = _RawReserved.SetBit(4, value); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/PathInfoV1.cs b/NvAPIWrapper/Native/Display/Structures/PathInfoV1.cs new file mode 100644 index 0000000..ec49742 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/PathInfoV1.cs @@ -0,0 +1,163 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Holds information about a path + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + // ReSharper disable once RedundantExtendsListEntry + public struct PathInfoV1 : IPathInfo, IInitializable, IAllocatable, IEquatable + { + internal StructureVersion _Version; + internal readonly uint _ReservedSourceId; + internal readonly uint _TargetInfoCount; + internal ValueTypeArray _TargetsInfo; + internal ValueTypeReference _SourceModeInfo; + + /// + public uint SourceId + { + get => _ReservedSourceId; + } + + /// + public IEnumerable TargetsInfo + { + get => _TargetsInfo.ToArray((int) _TargetInfoCount)?.Cast() ?? new IPathTargetInfo[0]; + } + + /// + public SourceModeInfo SourceModeInfo + { + get => _SourceModeInfo.ToValueType() ?? default(SourceModeInfo); + } + + /// + /// Creates a new PathInfoV1 + /// + /// Information about path targets + /// Source mode information + /// Source Id, can be zero + public PathInfoV1( + PathTargetInfoV1[] targetsInformation, + SourceModeInfo sourceModeInformation, + uint sourceId = 0) + { + this = typeof(PathInfoV1).Instantiate(); + _TargetInfoCount = (uint) targetsInformation.Length; + _TargetsInfo = ValueTypeArray.FromArray(targetsInformation); + _SourceModeInfo = ValueTypeReference.FromValueType(sourceModeInformation); + _ReservedSourceId = sourceId; + } + + /// + public bool Equals(PathInfoV1 other) + { + return _TargetInfoCount == other._TargetInfoCount && + _TargetsInfo.Equals(other._TargetsInfo) && + _SourceModeInfo.Equals(other._SourceModeInfo); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is PathInfoV1 && Equals((PathInfoV1) obj); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (int) _TargetInfoCount; + // ReSharper disable once NonReadonlyMemberInGetHashCode + hashCode = (hashCode * 397) ^ _TargetsInfo.GetHashCode(); + // ReSharper disable once NonReadonlyMemberInGetHashCode + hashCode = (hashCode * 397) ^ _SourceModeInfo.GetHashCode(); + + return hashCode; + } + } + + /// + /// Creates a new PathInfoV1 + /// + /// Information about path targets + /// Source Id, can be zero + public PathInfoV1(PathTargetInfoV1[] targetsInformation, uint sourceId = 0) + { + this = typeof(PathInfoV1).Instantiate(); + _TargetInfoCount = (uint) targetsInformation.Length; + _TargetsInfo = ValueTypeArray.FromArray(targetsInformation); + _SourceModeInfo = ValueTypeReference.Null; + _ReservedSourceId = sourceId; + } + + /// + /// Creates a new PathInfoV1 + /// + /// Source Id, can be zero + public PathInfoV1(uint sourceId) + { + this = typeof(PathInfoV1).Instantiate(); + _TargetInfoCount = 0; + _TargetsInfo = ValueTypeArray.Null; + _SourceModeInfo = ValueTypeReference.Null; + _ReservedSourceId = sourceId; + } + + /// + /// Creates a new PathInfoV1 + /// + /// Source mode information + /// Source Id, can be zero + public PathInfoV1(SourceModeInfo sourceModeInfo, uint sourceId) + { + this = typeof(PathInfoV1).Instantiate(); + _TargetInfoCount = 0; + _TargetsInfo = ValueTypeArray.Null; + _SourceModeInfo = ValueTypeReference.FromValueType(sourceModeInfo); + _ReservedSourceId = sourceId; + } + + /// + public void Dispose() + { + TargetsInfo.DisposeAll(); + _TargetsInfo.Dispose(); + _SourceModeInfo.Dispose(); + } + + void IAllocatable.Allocate() + { + if (_TargetInfoCount > 0 && _TargetsInfo.IsNull) + { + var targetInfo = typeof(PathTargetInfoV1).Instantiate(); + var targetInfoList = targetInfo.Repeat((int) _TargetInfoCount).AllocateAll(); + _TargetsInfo = ValueTypeArray.FromArray(targetInfoList.ToArray()); + } + + if (_SourceModeInfo.IsNull) + { + var sourceModeInfo = typeof(SourceModeInfo).Instantiate(); + _SourceModeInfo = ValueTypeReference.FromValueType(sourceModeInfo); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/PathInfoV2.cs b/NvAPIWrapper/Native/Display/Structures/PathInfoV2.cs new file mode 100644 index 0000000..ed721fe --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/PathInfoV2.cs @@ -0,0 +1,181 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Holds information about a path + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + // ReSharper disable once RedundantExtendsListEntry + public struct PathInfoV2 : IPathInfo, IInitializable, IAllocatable, IEquatable + { + internal StructureVersion _Version; + internal readonly uint _SourceId; + internal readonly uint _TargetInfoCount; + internal ValueTypeArray _TargetsInfo; + internal ValueTypeReference _SourceModeInfo; + internal readonly uint _RawReserved; + internal ValueTypeReference _OSAdapterLUID; + + /// + public uint SourceId + { + get => _SourceId; + } + + /// + public bool Equals(PathInfoV2 other) + { + return _TargetInfoCount == other._TargetInfoCount && + _TargetsInfo.Equals(other._TargetsInfo) && + _SourceModeInfo.Equals(other._SourceModeInfo) && + _RawReserved == other._RawReserved; + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is PathInfoV2 v2 && Equals(v2); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (int) _TargetInfoCount; + // ReSharper disable once NonReadonlyMemberInGetHashCode + hashCode = (hashCode * 397) ^ _TargetsInfo.GetHashCode(); + // ReSharper disable once NonReadonlyMemberInGetHashCode + hashCode = (hashCode * 397) ^ _SourceModeInfo.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) _RawReserved; + + return hashCode; + } + } + + /// + public IEnumerable TargetsInfo + { + get => _TargetsInfo.ToArray((int) _TargetInfoCount)?.Cast() ?? new IPathTargetInfo[0]; + } + + /// + public SourceModeInfo SourceModeInfo + { + get => _SourceModeInfo.ToValueType() ?? default(SourceModeInfo); + } + + /// + /// True for non-NVIDIA adapter. + /// + public bool IsNonNVIDIAAdapter + { + get => _RawReserved.GetBit(0); + } + + /// + /// Used by Non-NVIDIA adapter for OS Adapter of LUID + /// + public LUID? OSAdapterLUID + { + get => _OSAdapterLUID.ToValueType(); + } + + /// + /// Creates a new PathInfoV2 + /// + /// Information about path targets + /// Source mode information + /// Source Id, can be zero + public PathInfoV2(PathTargetInfoV2[] targetInformations, SourceModeInfo sourceModeInfo, uint sourceId = 0) + { + this = typeof(PathInfoV2).Instantiate(); + _TargetInfoCount = (uint) targetInformations.Length; + _TargetsInfo = ValueTypeArray.FromArray(targetInformations); + _SourceModeInfo = ValueTypeReference.FromValueType(sourceModeInfo); + _SourceId = sourceId; + } + + /// + /// Creates a new PathInfoV2 + /// + /// Information about path targets + /// Source Id, can be zero + public PathInfoV2(PathTargetInfoV2[] targetInformations, uint sourceId = 0) + { + this = typeof(PathInfoV2).Instantiate(); + _TargetInfoCount = (uint) targetInformations.Length; + _TargetsInfo = ValueTypeArray.FromArray(targetInformations); + _SourceModeInfo = ValueTypeReference.Null; + _SourceId = sourceId; + } + + + /// + /// Creates a new PathInfoV2 + /// + /// Source Id, can be zero + public PathInfoV2(uint sourceId) + { + this = typeof(PathInfoV2).Instantiate(); + _TargetInfoCount = 0; + _TargetsInfo = ValueTypeArray.Null; + _SourceModeInfo = ValueTypeReference.Null; + _SourceId = sourceId; + } + + /// + /// Creates a new PathInfoV2 + /// + /// Source mode information + /// Source Id, can be zero + public PathInfoV2(SourceModeInfo sourceModeInfo, uint sourceId) + { + this = typeof(PathInfoV2).Instantiate(); + _TargetInfoCount = 0; + _TargetsInfo = ValueTypeArray.Null; + _SourceModeInfo = ValueTypeReference.FromValueType(sourceModeInfo); + _SourceId = sourceId; + } + + /// + public void Dispose() + { + TargetsInfo.DisposeAll(); + _TargetsInfo.Dispose(); + _SourceModeInfo.Dispose(); + } + + void IAllocatable.Allocate() + { + if (_TargetInfoCount > 0 && _TargetsInfo.IsNull) + { + var targetInfo = typeof(PathTargetInfoV2).Instantiate(); + var targetInfoList = targetInfo.Repeat((int) _TargetInfoCount).AllocateAll(); + _TargetsInfo = ValueTypeArray.FromArray(targetInfoList.ToArray()); + } + + if (_SourceModeInfo.IsNull) + { + var sourceModeInfo = typeof(SourceModeInfo).Instantiate(); + _SourceModeInfo = ValueTypeReference.FromValueType(sourceModeInfo); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/PathTargetInfoV1.cs b/NvAPIWrapper/Native/Display/Structures/PathTargetInfoV1.cs new file mode 100644 index 0000000..4bdaddb --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/PathTargetInfoV1.cs @@ -0,0 +1,111 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.Display; + +// ReSharper disable RedundantExtendsListEntry + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Holds information about a path's target + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PathTargetInfoV1 : IPathTargetInfo, + IInitializable, + IDisposable, + IAllocatable, + IEquatable, + IEquatable + { + internal readonly uint _DisplayId; + internal ValueTypeReference _Details; + + /// + public override string ToString() + { + return $"PathTargetInfoV2: Display #{_DisplayId}"; + } + + /// + public uint DisplayId + { + get => _DisplayId; + } + + /// + public bool Equals(PathTargetInfoV1 other) + { + return _DisplayId == other._DisplayId && _Details.Equals(other._Details); + } + + /// + public bool Equals(PathTargetInfoV2 other) + { + return _DisplayId == other._DisplayId && _Details.Equals(other._Details); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is PathTargetInfoV1 && Equals((PathTargetInfoV1) obj); + } + + /// + public override int GetHashCode() + { + unchecked + { + // ReSharper disable once NonReadonlyMemberInGetHashCode + return ((int) _DisplayId * 397) ^ _Details.GetHashCode(); + } + } + + /// + public PathAdvancedTargetInfo? Details + { + get => _Details.ToValueType() ?? default(PathAdvancedTargetInfo); + } + + /// + /// Creates a new PathTargetInfoV1 + /// + /// Display Id + public PathTargetInfoV1(uint displayId) : this() + { + _DisplayId = displayId; + } + + /// + /// Creates a new PathTargetInfoV1 + /// + /// Display Id + /// Extra information + public PathTargetInfoV1(uint displayId, PathAdvancedTargetInfo details) : this(displayId) + { + _Details = ValueTypeReference.FromValueType(details); + } + + /// + public void Dispose() + { + _Details.Dispose(); + } + + void IAllocatable.Allocate() + { + if (_Details.IsNull) + { + var detail = typeof(PathAdvancedTargetInfo).Instantiate(); + _Details = ValueTypeReference.FromValueType(detail); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/PathTargetInfoV2.cs b/NvAPIWrapper/Native/Display/Structures/PathTargetInfoV2.cs new file mode 100644 index 0000000..00c21ac --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/PathTargetInfoV2.cs @@ -0,0 +1,147 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.Display; + +// ReSharper disable RedundantExtendsListEntry + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Holds information about a path's target + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PathTargetInfoV2 : IPathTargetInfo, + IInitializable, + IDisposable, + IAllocatable, + IEquatable, + IEquatable + { + internal readonly uint _DisplayId; + internal ValueTypeReference _Details; + internal readonly uint _WindowsCCDTargetId; + + /// + public uint DisplayId + { + get => _DisplayId; + } + + /// + public override string ToString() + { + return $"PathTargetInfoV2: Display #{_DisplayId}"; + } + + /// + public PathAdvancedTargetInfo? Details + { + get => _Details.ToValueType(); + } + + /// + /// Windows CCD target ID. Must be present only for non-NVIDIA adapter, for NVIDIA adapter this parameter is ignored. + /// + public uint WindowsCCDTargetId + { + get => _WindowsCCDTargetId; + } + + /// + /// Creates a new PathTargetInfoV1 + /// + /// Display Id + public PathTargetInfoV2(uint displayId) : this() + { + _DisplayId = displayId; + } + + /// + public bool Equals(PathTargetInfoV2 other) + { + return _DisplayId == other._DisplayId && _Details.Equals(other._Details); + } + + /// + public bool Equals(PathTargetInfoV1 other) + { + return _DisplayId == other._DisplayId && _Details.Equals(other._Details); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is PathTargetInfoV2 v2 && Equals(v2); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (int) _DisplayId; + // ReSharper disable once NonReadonlyMemberInGetHashCode + hashCode = (hashCode * 397) ^ _Details.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) _WindowsCCDTargetId; + + return hashCode; + } + } + + /// + /// Creates a new PathTargetInfoV1 + /// + /// Display Id + /// Windows CCD target Id + public PathTargetInfoV2(uint displayId, uint windowsCCDTargetId) : this(displayId) + { + _WindowsCCDTargetId = windowsCCDTargetId; + } + + /// + /// Creates a new PathTargetInfoV1 + /// + /// Display Id + /// Extra information + public PathTargetInfoV2(uint displayId, PathAdvancedTargetInfo details) : this(displayId) + { + _Details = ValueTypeReference.FromValueType(details); + } + + /// + /// Creates a new PathTargetInfoV1 + /// + /// Display Id + /// Windows CCD target Id + /// Extra information + public PathTargetInfoV2(uint displayId, uint windowsCCDTargetId, PathAdvancedTargetInfo details) + : this(displayId, windowsCCDTargetId) + { + _Details = ValueTypeReference.FromValueType(details); + } + + + /// + public void Dispose() + { + _Details.Dispose(); + } + + void IAllocatable.Allocate() + { + if (_Details.IsNull) + { + var detail = typeof(PathAdvancedTargetInfo).Instantiate(); + _Details = ValueTypeReference.FromValueType(detail); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/Position.cs b/NvAPIWrapper/Native/Display/Structures/Position.cs new file mode 100644 index 0000000..1d36732 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/Position.cs @@ -0,0 +1,96 @@ +using System; +using System.Runtime.InteropServices; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Holds a [X,Y] pair as a position on a 2D plane + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct Position : IEquatable + { + internal readonly int _X; + internal readonly int _Y; + + /// + public override string ToString() + { + return $"[{X}, {Y}]"; + } + + /// + public bool Equals(Position other) + { + return _X == other._X && _Y == other._Y; + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is Position position && Equals(position); + } + + /// + public override int GetHashCode() + { + unchecked + { + return (_X * 397) ^ _Y; + } + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(Position left, Position right) + { + return left.Equals(right); + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(Position left, Position right) + { + return !left.Equals(right); + } + + /// + /// Creates a new Position + /// + /// X value + /// Y value + public Position(int x, int y) + { + _X = x; + _Y = y; + } + + /// + /// X value + /// + public int X + { + get => _X; + } + + /// + /// Y value + /// + public int Y + { + get => _Y; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/PrivateDisplayDVCInfo.cs b/NvAPIWrapper/Native/Display/Structures/PrivateDisplayDVCInfo.cs new file mode 100644 index 0000000..69efc13 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/PrivateDisplayDVCInfo.cs @@ -0,0 +1,43 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivateDisplayDVCInfo : IInitializable, IDisplayDVCInfo + { + internal StructureVersion _Version; + internal int _CurrentLevel; + internal int _MinimumLevel; + internal int _MaximumLevel; + + /// + public int CurrentLevel + { + get => _CurrentLevel; + } + + /// + public int MinimumLevel + { + get => _MinimumLevel; + } + + /// + int IDisplayDVCInfo.DefaultLevel + { + get => 0; + } + + /// + public int MaximumLevel + { + get => _MaximumLevel; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/PrivateDisplayDVCInfoEx.cs b/NvAPIWrapper/Native/Display/Structures/PrivateDisplayDVCInfoEx.cs new file mode 100644 index 0000000..cb37c2e --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/PrivateDisplayDVCInfoEx.cs @@ -0,0 +1,51 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.Display; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivateDisplayDVCInfoEx : IInitializable, IDisplayDVCInfo + { + internal StructureVersion _Version; + internal int _CurrentLevel; + internal int _MinimumLevel; + internal int _MaximumLevel; + internal int _DefaultLevel; + + /// + public int CurrentLevel + { + get => _CurrentLevel; + } + + /// + public int MinimumLevel + { + get => _MinimumLevel; + } + + /// + public int MaximumLevel + { + get => _MaximumLevel; + } + + /// + public int DefaultLevel + { + get => _DefaultLevel; + } + + internal PrivateDisplayDVCInfoEx(int currentLevel) + { + this = typeof(PrivateDisplayDVCInfoEx).Instantiate(); + _CurrentLevel = currentLevel; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/PrivateDisplayHUEInfo.cs b/NvAPIWrapper/Native/Display/Structures/PrivateDisplayHUEInfo.cs new file mode 100644 index 0000000..38e2d10 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/PrivateDisplayHUEInfo.cs @@ -0,0 +1,35 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Holds the current and the default HUE information + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivateDisplayHUEInfo : IInitializable + { + internal StructureVersion _Version; + internal int _CurrentAngle; + internal int _DefaultAngle; + + /// + /// Gets or sets the current HUE offset angle [0-359] + /// + public int CurrentAngle + { + get => _CurrentAngle; + } + + /// + /// Gets or sets the default HUE offset angle [0-359] + /// + public int DefaultAngle + { + get => _DefaultAngle; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/Resolution.cs b/NvAPIWrapper/Native/Display/Structures/Resolution.cs new file mode 100644 index 0000000..ad34a57 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/Resolution.cs @@ -0,0 +1,111 @@ +using System; +using System.Runtime.InteropServices; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Holds a [Width, Height] pair as the resolution of a display device, as well as a color format + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct Resolution : IEquatable + { + internal readonly uint _Width; + internal readonly uint _Height; + internal readonly uint _ColorDepth; + + /// + /// Creates a new Resolution + /// + /// Display resolution width + /// Display resolution height + /// Display color depth + public Resolution(int width, int height, int colorDepth) + { + _Width = (uint) width; + _Height = (uint) height; + _ColorDepth = (uint) colorDepth; + } + + /// + public bool Equals(Resolution other) + { + return _Width == other._Width && _Height == other._Height && _ColorDepth == other._ColorDepth; + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is Resolution resolution && Equals(resolution); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (int) _Width; + hashCode = (hashCode * 397) ^ (int) _Height; + hashCode = (hashCode * 397) ^ (int) _ColorDepth; + + return hashCode; + } + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(Resolution left, Resolution right) + { + return left.Equals(right); + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(Resolution left, Resolution right) + { + return !left.Equals(right); + } + + /// + public override string ToString() + { + return $"({Width}, {Height}) @ {ColorDepth}bpp"; + } + + /// + /// Display resolution width + /// + public int Width + { + get => (int) _Width; + } + + /// + /// Display resolution height + /// + public int Height + { + get => (int) _Height; + } + + /// + /// Display color depth + /// + public int ColorDepth + { + get => (int) _ColorDepth; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/ScanOutInformationV1.cs b/NvAPIWrapper/Native/Display/Structures/ScanOutInformationV1.cs new file mode 100644 index 0000000..a4a6854 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/ScanOutInformationV1.cs @@ -0,0 +1,82 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Contains information regarding the scan-out configurations + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct ScanOutInformationV1 : IInitializable + { + internal StructureVersion _Version; + internal Rectangle _SourceDesktopRectangle; + internal Rectangle _SourceViewPortRectangle; + internal Rectangle _TargetViewPortRectangle; + internal uint _TargetDisplayWidth; + internal uint _TargetDisplayHeight; + internal uint _CloneImportance; + internal Rotate _SourceToTargetRotation; + + /// + /// Gets the operating system display device rectangle in desktop coordinates displayId is scanning out from. + /// + public Rectangle SourceDesktopRectangle + { + get => _SourceDesktopRectangle; + } + + /// + /// Gets the area inside the SourceDesktopRectangle which is scanned out to the display. + /// + public Rectangle SourceViewPortRectangle + { + get => _SourceViewPortRectangle; + } + + /// + /// Gets the area inside the rectangle described by targetDisplayWidth/Height SourceViewPortRectangle is scanned out + /// to. + /// + public Rectangle TargetViewPortRectangle + { + get => _TargetViewPortRectangle; + } + + /// + /// Gets the horizontal size of the active resolution scanned out to the display. + /// + public uint TargetDisplayWidth + { + get => _TargetDisplayWidth; + } + + /// + /// Gets the vertical size of the active resolution scanned out to the display. + /// + public uint TargetDisplayHeight + { + get => _TargetDisplayHeight; + } + + /// + /// Gets the clone importance assigned to the target if the target is a cloned view of the SourceDesktopRectangle + /// (0:primary,1 secondary,...). + /// + public uint CloneImportance + { + get => _CloneImportance; + } + + /// + /// Gets the rotation performed between the SourceViewPortRectangle and the TargetViewPortRectangle. + /// + public Rotate SourceToTargetRotation + { + get => _SourceToTargetRotation; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/ScanOutIntensityStateV1.cs b/NvAPIWrapper/Native/Display/Structures/ScanOutIntensityStateV1.cs new file mode 100644 index 0000000..bb5ef73 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/ScanOutIntensityStateV1.cs @@ -0,0 +1,26 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Contains information regarding the scan-out intensity state + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct ScanOutIntensityStateV1 : IInitializable + { + internal StructureVersion _Version; + internal uint _IsEnabled; + + /// + /// Gets a boolean value indicating if the scan out intensity is enabled or not + /// + public bool IsEnabled + { + get => _IsEnabled > 0; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/ScanOutIntensityV1.cs b/NvAPIWrapper/Native/Display/Structures/ScanOutIntensityV1.cs new file mode 100644 index 0000000..cba0093 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/ScanOutIntensityV1.cs @@ -0,0 +1,71 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct ScanOutIntensityV1 : IDisposable, IInitializable, IScanOutIntensity + { + internal StructureVersion _Version; + internal uint _Width; + internal uint _Height; + internal IntPtr _BlendingTexture; + + /// + /// Creates a new instance of . + /// + /// The width of the input texture. + /// The height of the input texture + /// The array of floating values building an intensity RGB texture. + public ScanOutIntensityV1(uint width, uint height, float[] blendingTexture) + { + if (blendingTexture?.Length != width * height * 3) + { + throw new ArgumentOutOfRangeException(nameof(blendingTexture)); + } + + this = typeof(ScanOutIntensityV1).Instantiate(); + _Width = width; + _Height = height; + _BlendingTexture = Marshal.AllocHGlobal((int) (width * height * 3 * sizeof(float))); + + Marshal.Copy(blendingTexture, 0, _BlendingTexture, blendingTexture.Length); + } + + /// + public uint Width + { + get => _Width; + } + + /// + public uint Height + { + get => _Height; + } + + /// + public float[] BlendingTexture + { + get + { + var floats = new float[_Width * _Height * 3]; + Marshal.Copy(_BlendingTexture, floats, 0, floats.Length); + + return floats; + } + } + + /// + public void Dispose() + { + Marshal.FreeHGlobal(_BlendingTexture); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/ScanOutIntensityV2.cs b/NvAPIWrapper/Native/Display/Structures/ScanOutIntensityV2.cs new file mode 100644 index 0000000..1bc8ffd --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/ScanOutIntensityV2.cs @@ -0,0 +1,112 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + public struct ScanOutIntensityV2 : IDisposable, IInitializable, IScanOutIntensity + { + internal StructureVersion _Version; + internal uint _Width; + internal uint _Height; + internal IntPtr _BlendingTexture; + internal IntPtr _OffsetTexture; + internal uint _OffsetTextureChannels; + + /// + /// Creates a new instance of . + /// + /// The width of the input texture. + /// The height of the input texture + /// The array of floating values building an intensity RGB texture + /// The number of channels per pixel in the offset texture + /// The array of floating values building an offset texture + // ReSharper disable once TooManyDependencies + public ScanOutIntensityV2( + uint width, + uint height, + float[] blendingTexture, + uint offsetTextureChannels, + float[] offsetTexture) + { + if (blendingTexture?.Length != width * height * 3) + { + throw new ArgumentOutOfRangeException(nameof(blendingTexture)); + } + + if (offsetTexture?.Length != width * height * offsetTextureChannels) + { + throw new ArgumentOutOfRangeException(nameof(offsetTexture)); + } + + this = typeof(ScanOutIntensityV2).Instantiate(); + _Width = width; + _Height = height; + _BlendingTexture = Marshal.AllocHGlobal((int) (width * height * 3 * sizeof(float))); + Marshal.Copy(blendingTexture, 0, _BlendingTexture, blendingTexture.Length); + + _OffsetTextureChannels = offsetTextureChannels; + _OffsetTexture = Marshal.AllocHGlobal((int) (width * height * offsetTextureChannels * sizeof(float))); + Marshal.Copy(offsetTexture, 0, _OffsetTexture, offsetTexture.Length); + } + + /// + public uint Width + { + get => _Width; + } + + /// + public uint Height + { + get => _Height; + } + + /// + /// Gets the number of channels per pixel in the offset texture + /// + public uint OffsetTextureChannels + { + get => _OffsetTextureChannels; + } + + /// + public float[] BlendingTexture + { + get + { + var floats = new float[_Width * _Height * 3]; + Marshal.Copy(_BlendingTexture, floats, 0, floats.Length); + + return floats; + } + } + + /// + /// Gets the array of floating values building an offset texture + /// + public float[] OffsetTexture + { + get + { + var floats = new float[_Width * _Height * _OffsetTextureChannels]; + Marshal.Copy(_OffsetTexture, floats, 0, floats.Length); + + return floats; + } + } + + /// + public void Dispose() + { + Marshal.FreeHGlobal(_BlendingTexture); + Marshal.FreeHGlobal(_OffsetTexture); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/ScanOutWarpingStateV1.cs b/NvAPIWrapper/Native/Display/Structures/ScanOutWarpingStateV1.cs new file mode 100644 index 0000000..a09fa23 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/ScanOutWarpingStateV1.cs @@ -0,0 +1,26 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Contains information regarding the scan-out warping state + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct ScanOutWarpingStateV1 : IInitializable + { + internal StructureVersion _Version; + internal uint _IsEnabled; + + /// + /// Gets a boolean value indicating if the scan out warping is enabled or not + /// + public bool IsEnabled + { + get => _IsEnabled > 0; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/ScanOutWarpingV1.cs b/NvAPIWrapper/Native/Display/Structures/ScanOutWarpingV1.cs new file mode 100644 index 0000000..66d0392 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/ScanOutWarpingV1.cs @@ -0,0 +1,83 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Contains information regarding the scan-out warping data + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct ScanOutWarpingV1 : IDisposable, IInitializable + { + internal StructureVersion _Version; + internal IntPtr _Vertices; + internal WarpingVerticeFormat _VertexFormat; + internal uint _NumberOfVertices; + internal IntPtr _TextureRectangle; + + /// + /// Creates a new instance of . + /// + /// The format of the input vertices. + /// The array of floating values containing the warping vertices. + /// The rectangle in desktop coordinates describing the source area for the warping. + public ScanOutWarpingV1(WarpingVerticeFormat vertexFormat, float[] vertices, Rectangle textureRectangle) + { + if (vertices.Length % 6 != 0) + { + throw new ArgumentOutOfRangeException(nameof(vertices)); + } + + this = typeof(ScanOutWarpingV1).Instantiate(); + _VertexFormat = vertexFormat; + _NumberOfVertices = (uint) (vertices.Length / 6); + _Vertices = Marshal.AllocHGlobal(vertices.Length * sizeof(float)); + Marshal.Copy(vertices, 0, _Vertices, vertices.Length); + + _TextureRectangle = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Rectangle))); + Marshal.StructureToPtr(textureRectangle, _TextureRectangle, true); + } + + /// + /// Gets the format of the input vertices + /// + public WarpingVerticeFormat VertexFormat + { + get => _VertexFormat; + } + + /// + /// Gets the rectangle in desktop coordinates describing the source area for the warping + /// + public Rectangle TextureRectangle + { + get => (Rectangle)Marshal.PtrToStructure(_TextureRectangle, typeof(Rectangle)); + } + + /// + /// Gets the array of floating values containing the warping vertices + /// + public float[] Vertices + { + get + { + var floats = new float[_NumberOfVertices * 6]; + Marshal.Copy(_Vertices, floats, 0, floats.Length); + + return floats; + } + } + + /// + public void Dispose() + { + Marshal.FreeHGlobal(_Vertices); + Marshal.FreeHGlobal(_TextureRectangle); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/SourceModeInfo.cs b/NvAPIWrapper/Native/Display/Structures/SourceModeInfo.cs new file mode 100644 index 0000000..132777b --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/SourceModeInfo.cs @@ -0,0 +1,138 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Holds information about a source mode + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct SourceModeInfo : IEquatable + { + internal readonly Resolution _Resolution; + internal readonly ColorFormat _ColorFormat; + internal readonly Position _Position; + internal readonly SpanningOrientation _SpanningOrientation; + internal uint _RawReserved; + + /// + /// Creates a new SourceModeInfo + /// + /// Source resolution + /// Must be Format.Unknown + /// Source position + /// Spanning orientation for XP + /// true if this source represents the GDI primary display, otherwise false + /// true if this source represents the SLI focus display, otherwise false + public SourceModeInfo( + Resolution resolution, + ColorFormat colorFormat, + Position position = default(Position), + SpanningOrientation spanningOrientation = SpanningOrientation.None, + bool isGDIPrimary = false, + bool isSLIFocus = false) : this() + { + _Resolution = resolution; + _ColorFormat = colorFormat; + _Position = position; + _SpanningOrientation = spanningOrientation; + IsGDIPrimary = isGDIPrimary; + IsSLIFocus = isSLIFocus; + } + + /// + public bool Equals(SourceModeInfo other) + { + return _Resolution.Equals(other._Resolution) && + _ColorFormat == other._ColorFormat && + _Position.Equals(other._Position) && + _SpanningOrientation == other._SpanningOrientation && + _RawReserved == other._RawReserved; + } + + /// + public override bool Equals(object obj) + { + if (obj == null) + { + return false; + } + + return obj is SourceModeInfo info && Equals(info); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = _Resolution.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) _ColorFormat; + hashCode = (hashCode * 397) ^ _Position.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) _SpanningOrientation; + // ReSharper disable once NonReadonlyMemberInGetHashCode + hashCode = (hashCode * 397) ^ (int) _RawReserved; + + return hashCode; + } + } + + /// + public override string ToString() + { + return $"{Resolution} @ {Position} - {ColorFormat}"; + } + + /// + /// Holds the source resolution + /// + public Resolution Resolution + { + get => _Resolution; + } + + /// + /// Ignored at present, must be Format.Unknown + /// + public ColorFormat ColorFormat + { + get => _ColorFormat; + } + + /// + /// Is all positions are 0 or invalid, displays will be automatically positioned from left to right with GDI Primary at + /// 0,0, and all other displays in the order of the path array. + /// + public Position Position + { + get => _Position; + } + + /// + /// Spanning is only supported on XP + /// + public SpanningOrientation SpanningOrientation + { + get => _SpanningOrientation; + } + + /// + /// Indicates if the path is for the primary GDI display + /// + public bool IsGDIPrimary + { + get => _RawReserved.GetBit(0); + private set => _RawReserved = _RawReserved.SetBit(0, value); + } + + /// + /// Indicates if the path is for the SLI focus display + /// + public bool IsSLIFocus + { + get => _RawReserved.GetBit(1); + private set => _RawReserved = _RawReserved.SetBit(1, value); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/Timing.cs b/NvAPIWrapper/Native/Display/Structures/Timing.cs new file mode 100644 index 0000000..e863f3d --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/Timing.cs @@ -0,0 +1,382 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Holds VESA scan out timing parameters + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct Timing : IEquatable + { + internal readonly ushort _HorizontalVisible; + internal readonly ushort _HorizontalBorder; + internal readonly ushort _HorizontalFrontPorch; + internal readonly ushort _HorizontalSyncWidth; + internal readonly ushort _HorizontalTotal; + internal readonly TimingHorizontalSyncPolarity _HorizontalSyncPolarity; + internal readonly ushort _VerticalVisible; + internal readonly ushort _VerticalBorder; + internal readonly ushort _VerticalFrontPorch; + internal readonly ushort _VerticalSyncWidth; + internal readonly ushort _VerticalTotal; + internal readonly TimingVerticalSyncPolarity _VerticalSyncPolarity; + internal readonly TimingScanMode _ScanMode; + internal readonly uint _PixelClockIn10KHertz; + internal readonly TimingExtra _Extra; + + /// + /// Creates an instance of structure. + /// + /// The horizontal visible pixels + /// The vertical visible pixels + /// The horizontal border pixels + /// The vertical border pixels + /// The horizontal front porch pixels + /// The vertical front porch pixels + /// The horizontal sync width pixels + /// The vertical sync width pixels + /// The horizontal total pixels + /// The vertical total pixels + /// The horizontal sync polarity + /// The vertical sync polarity + /// The scan mode + /// The extra timing information + public Timing( + ushort horizontalVisible, + ushort verticalVisible, + ushort horizontalBorder, + ushort verticalBorder, + ushort horizontalFrontPorch, + ushort verticalFrontPorch, + ushort horizontalSyncWidth, + ushort verticalSyncWidth, + ushort horizontalTotal, + ushort verticalTotal, + TimingHorizontalSyncPolarity horizontalPolarity, + TimingVerticalSyncPolarity verticalPolarity, + TimingScanMode scanMode, + TimingExtra extra + ) + { + this = typeof(Timing).Instantiate(); + + _HorizontalVisible = horizontalVisible; + _HorizontalBorder = horizontalBorder; + _HorizontalFrontPorch = horizontalFrontPorch; + _HorizontalSyncWidth = horizontalSyncWidth; + _HorizontalTotal = horizontalTotal; + _HorizontalSyncPolarity = horizontalPolarity; + + _VerticalVisible = verticalVisible; + _VerticalBorder = verticalBorder; + _VerticalFrontPorch = verticalFrontPorch; + _VerticalSyncWidth = verticalSyncWidth; + _VerticalTotal = verticalTotal; + _VerticalSyncPolarity = verticalPolarity; + + _ScanMode = scanMode; + _PixelClockIn10KHertz = + (uint) (horizontalTotal * verticalTotal * (extra.FrequencyInMillihertz / 1000d) / 10000); + + _Extra = extra; + } + + /// + /// Creates an instance of structure. + /// + /// The horizontal visible pixels + /// The vertical visible pixels + /// The horizontal border pixels + /// The vertical border pixels + /// The horizontal front porch pixels + /// The vertical front porch pixels + /// The horizontal sync width pixels + /// The vertical sync width pixels + /// The horizontal total pixels + /// The vertical total pixels + /// The horizontal sync polarity + /// The vertical sync polarity + /// The scan mode + /// The frequency in hertz + /// The number of identical horizontal pixels that are repeated; 1 = no repetition + public Timing( + ushort horizontalVisible, + ushort verticalVisible, + ushort horizontalBorder, + ushort verticalBorder, + ushort horizontalFrontPorch, + ushort verticalFrontPorch, + ushort horizontalSyncWidth, + ushort verticalSyncWidth, + ushort horizontalTotal, + ushort verticalTotal, + TimingHorizontalSyncPolarity horizontalPolarity, + TimingVerticalSyncPolarity verticalPolarity, + TimingScanMode scanMode, + double refreshRateFrequencyInHz, + ushort horizontalPixelRepetition = 1 + ) : this( + horizontalVisible, verticalVisible, horizontalBorder, + verticalBorder, horizontalFrontPorch, verticalFrontPorch, + horizontalSyncWidth, verticalSyncWidth, horizontalTotal, + verticalTotal, horizontalPolarity, verticalPolarity, scanMode, + new TimingExtra( + refreshRateFrequencyInHz, + $"CUST:{horizontalVisible}x{verticalVisible}x{refreshRateFrequencyInHz:F3}Hz", + 0, + 0, + horizontalPixelRepetition + ) + ) + { + } + + /// + public bool Equals(Timing other) + { + return _HorizontalVisible == other._HorizontalVisible && + _HorizontalBorder == other._HorizontalBorder && + _HorizontalFrontPorch == other._HorizontalFrontPorch && + _HorizontalSyncWidth == other._HorizontalSyncWidth && + _HorizontalTotal == other._HorizontalTotal && + _HorizontalSyncPolarity == other._HorizontalSyncPolarity && + _VerticalVisible == other._VerticalVisible && + _VerticalBorder == other._VerticalBorder && + _VerticalFrontPorch == other._VerticalFrontPorch && + _VerticalSyncWidth == other._VerticalSyncWidth && + _VerticalTotal == other._VerticalTotal && + _VerticalSyncPolarity == other._VerticalSyncPolarity && + _ScanMode == other._ScanMode && + _PixelClockIn10KHertz == other._PixelClockIn10KHertz && + _Extra.Equals(other._Extra); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is Timing timing && Equals(timing); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = _HorizontalVisible.GetHashCode(); + hashCode = (hashCode * 397) ^ _HorizontalBorder.GetHashCode(); + hashCode = (hashCode * 397) ^ _HorizontalFrontPorch.GetHashCode(); + hashCode = (hashCode * 397) ^ _HorizontalSyncWidth.GetHashCode(); + hashCode = (hashCode * 397) ^ _HorizontalTotal.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) _HorizontalSyncPolarity; + hashCode = (hashCode * 397) ^ _VerticalVisible.GetHashCode(); + hashCode = (hashCode * 397) ^ _VerticalBorder.GetHashCode(); + hashCode = (hashCode * 397) ^ _VerticalFrontPorch.GetHashCode(); + hashCode = (hashCode * 397) ^ _VerticalSyncWidth.GetHashCode(); + hashCode = (hashCode * 397) ^ _VerticalTotal.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) _VerticalSyncPolarity; + hashCode = (hashCode * 397) ^ (int) _ScanMode; + hashCode = (hashCode * 397) ^ (int) _PixelClockIn10KHertz; + hashCode = (hashCode * 397) ^ _Extra.GetHashCode(); + + return hashCode; + } + } + + /// + /// Checks two instance of for equality. + /// + /// The first instance. + /// The second instance. + /// Returns a boolean value indicating if the two instances are equal; otherwise false + public static bool operator ==(Timing left, Timing right) + { + return left.Equals(right); + } + + /// + /// Checks two instance of for in equality. + /// + /// The first instance. + /// The second instance. + /// Returns a boolean value indicating if the two instances are not equal; otherwise false + public static bool operator !=(Timing left, Timing right) + { + return !(left == right); + } + + /// + /// Get the horizontal visible pixels + /// + public int HorizontalVisible + { + get => _HorizontalVisible; + } + + /// + /// Get the horizontal border pixels + /// + public int HorizontalBorder + { + get => _HorizontalBorder; + } + + /// + /// Get the horizontal front porch pixels + /// + public int HorizontalFrontPorch + { + get => _HorizontalFrontPorch; + } + + /// + /// Get the horizontal sync width pixels + /// + public int HorizontalSyncWidth + { + get => _HorizontalSyncWidth; + } + + /// + /// Get the horizontal total pixels + /// + public int HorizontalTotal + { + get => _HorizontalTotal; + } + + /// + /// Get the horizontal sync polarity + /// + public TimingHorizontalSyncPolarity HorizontalSyncPolarity + { + get => _HorizontalSyncPolarity; + } + + /// + /// Get the vertical visible pixels + /// + public int VerticalVisible + { + get => _VerticalVisible; + } + + /// + /// Get the vertical border pixels + /// + public int VerticalBorder + { + get => _VerticalBorder; + } + + /// + /// Get the vertical front porch pixels + /// + public int VerticalFrontPorch + { + get => _VerticalFrontPorch; + } + + /// + /// Get the vertical sync width pixels + /// + public int VerticalSyncWidth + { + get => _VerticalSyncWidth; + } + + /// + /// Get the vertical total pixels + /// + public int VerticalTotal + { + get => _VerticalTotal; + } + + /// + /// Get the vertical sync polarity + /// + public TimingVerticalSyncPolarity VerticalSyncPolarity + { + get => _VerticalSyncPolarity; + } + + /// + /// Get the scan mode + /// + public TimingScanMode ScanMode + { + get => _ScanMode; + } + + /// + /// Get the pixel clock in 10 kHz + /// + public int PixelClockIn10KHertz + { + get => (int) _PixelClockIn10KHertz; + } + + /// + /// Get the other timing related extras + /// + public TimingExtra Extra + { + get => _Extra; + } + + /// + /// Gets the horizontal active pixels + /// + public int HorizontalActive + { + get => HorizontalVisible + HorizontalBorder; + } + + /// + /// Gets the vertical active pixels + /// + public int VerticalActive + { + get => VerticalVisible + VerticalBorder; + } + + /// + /// Gets the horizontal back porch pixels + /// + public int HorizontalBackPorch + { + get => HorizontalBlanking - (HorizontalFrontPorch + HorizontalSyncWidth); + } + + /// + /// Gets the horizontal blanking pixels + /// + public int HorizontalBlanking + { + get => HorizontalTotal - (HorizontalActive + HorizontalBorder); + } + + /// + /// Gets vertical back porch pixels + /// + public int VerticalBackPorch + { + get => VerticalBlanking - (VerticalFrontPorch + VerticalSyncWidth); + } + + /// + /// Gets the vertical blanking pixels + /// + public int VerticalBlanking + { + get => VerticalTotal - (VerticalActive + VerticalBorder); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/TimingExtra.cs b/NvAPIWrapper/Native/Display/Structures/TimingExtra.cs new file mode 100644 index 0000000..6c218b2 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/TimingExtra.cs @@ -0,0 +1,215 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Holds NVIDIA-specific timing extras + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct TimingExtra : IInitializable, IEquatable + { + internal readonly uint _HardwareFlags; + internal readonly ushort _RefreshRate; + internal readonly uint _FrequencyInMillihertz; + internal readonly ushort _VerticalAspect; + internal readonly ushort _HorizontalAspect; + internal readonly ushort _HorizontalPixelRepetition; + internal readonly uint _Standard; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)] + internal string _Name; + + /// + /// Creates a new instance of structure. + /// + /// The timing frequency in hertz + /// The timing source name + /// The display horizontal aspect + /// The display vertical aspect + /// The number of identical horizontal pixels that are repeated; 1 = no repetition + /// The NVIDIA hardware-based enhancement, such as double-scan. + public TimingExtra( + double frequencyInHertz, + string name, + ushort horizontalAspect = 0, + ushort verticalAspect = 0, + ushort horizontalPixelRepetition = 1, + uint hardwareFlags = 0 + ) : this( + (uint) (frequencyInHertz * 1000d), + (ushort) frequencyInHertz, + name, + horizontalAspect, + verticalAspect, + horizontalPixelRepetition, + hardwareFlags + ) + { + } + + /// + /// Creates a new instance of structure. + /// + /// The timing frequency in millihertz + /// The refresh rate + /// The timing source name + /// The display horizontal aspect + /// The display vertical aspect + /// The number of identical horizontal pixels that are repeated; 1 = no repetition + /// The NVIDIA hardware-based enhancement, such as double-scan. + public TimingExtra( + uint frequencyInMillihertz, + ushort refreshRate, + string name, + ushort horizontalAspect = 0, + ushort verticalAspect = 0, + ushort horizontalPixelRepetition = 1, + uint hardwareFlags = 0 + ) + { + this = typeof(TimingExtra).Instantiate(); + _FrequencyInMillihertz = frequencyInMillihertz; + _RefreshRate = refreshRate; + _HorizontalAspect = horizontalAspect; + _VerticalAspect = verticalAspect; + _HorizontalPixelRepetition = horizontalPixelRepetition; + _HardwareFlags = hardwareFlags; + _Name = name?.Length > 40 ? name.Substring(0, 40) : name ?? ""; + } + + /// + public bool Equals(TimingExtra other) + { + return _HardwareFlags == other._HardwareFlags && + _RefreshRate == other._RefreshRate && + _FrequencyInMillihertz == other._FrequencyInMillihertz && + _VerticalAspect == other._VerticalAspect && + _HorizontalAspect == other._HorizontalAspect && + _HorizontalPixelRepetition == other._HorizontalPixelRepetition && + _Standard == other._Standard; + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is TimingExtra extra && Equals(extra); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (int) _HardwareFlags; + hashCode = (hashCode * 397) ^ _RefreshRate.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) _FrequencyInMillihertz; + hashCode = (hashCode * 397) ^ _VerticalAspect.GetHashCode(); + hashCode = (hashCode * 397) ^ _HorizontalAspect.GetHashCode(); + hashCode = (hashCode * 397) ^ _HorizontalPixelRepetition.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) _Standard; + + return hashCode; + } + } + + /// + /// Gets the NVIDIA hardware-based enhancement, such as double-scan. + /// + public uint HardwareFlags + { + get => _HardwareFlags; + } + + /// + /// Gets the logical refresh rate to present + /// + public int RefreshRate + { + get => _RefreshRate; + } + + /// + /// Gets the physical vertical refresh rate in 0.001Hz + /// + public int FrequencyInMillihertz + { + get => (int) _FrequencyInMillihertz; + } + + /// + /// Gets the display vertical aspect + /// + public int VerticalAspect + { + get => _VerticalAspect; + } + + /// + /// Gets the display horizontal aspect + /// + public int HorizontalAspect + { + get => _HorizontalAspect; + } + + /// + /// Gets the bit-wise pixel repetition factor: 0x1:no pixel repetition; 0x2:each pixel repeats twice horizontally,.. + /// + public int PixelRepetition + { + get => _HorizontalPixelRepetition; + } + + /// + /// Gets the timing standard + /// + public uint Standard + { + get => _Standard; + } + + /// + /// Gets the timing name + /// + public string Name + { + get => _Name; + } + + /// + public override string ToString() + { + return Name; + } + + /// + /// Checks two instance of for equality. + /// + /// The first instance. + /// The second instance. + /// Returns a boolean value indicating if the two instances are equal; otherwise false + public static bool operator ==(TimingExtra left, TimingExtra right) + { + return left.Equals(right); + } + + /// + /// Checks two instance of for equality. + /// + /// The first instance. + /// The second instance. + /// Returns a boolean value indicating if the two instances are equal; otherwise false + public static bool operator !=(TimingExtra left, TimingExtra right) + { + return !(left == right); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/TimingInput.cs b/NvAPIWrapper/Native/Display/Structures/TimingInput.cs new file mode 100644 index 0000000..3303039 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/TimingInput.cs @@ -0,0 +1,253 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Contains the information required for calculating timing for a particular display + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct TimingInput : IInitializable + { + [StructLayout(LayoutKind.Explicit, Pack = 8, Size = 12)] + internal struct TimingFlag + { + [FieldOffset(0)] internal ushort _Flags; + [FieldOffset(4)] internal byte _TVFormatCEAIdPSFormatId; + [FieldOffset(8)] internal byte _Scaling; + + public bool IsInterlaced + { + get => _Flags.GetBit(0); + set => _Flags = _Flags.SetBit(0, value); + } + + public TVFormat TVFormat + { + get => (TVFormat) _TVFormatCEAIdPSFormatId; + set => _TVFormatCEAIdPSFormatId = (byte) value; + } + + public byte CEAId + { + get => _TVFormatCEAIdPSFormatId; + set => _TVFormatCEAIdPSFormatId = value; + } + + public byte PredefinedPSFormatId + { + get => _TVFormatCEAIdPSFormatId; + set => _TVFormatCEAIdPSFormatId = value; + } + + public byte Scaling + { + get => _Scaling; + set => _Scaling = value; + } + + public TimingFlag(bool isInterlaced, byte scaling) : this() + { + IsInterlaced = isInterlaced; + Scaling = scaling; + } + + public TimingFlag(bool isInterlaced, byte scaling, TVFormat tvFormat) : this(isInterlaced, scaling) + { + TVFormat = tvFormat; + } + + public TimingFlag(bool isInterlaced, byte scaling, byte ceaIdOrPredefinedPSFormatId) : this(isInterlaced, + scaling) + { + _TVFormatCEAIdPSFormatId = ceaIdOrPredefinedPSFormatId; + } + } + + internal StructureVersion _Version; + internal uint _Width; + internal uint _Height; + internal float _RefreshRate; + internal TimingFlag _Flags; + internal TimingOverride _TimingType; + + /// + /// Gets the visible horizontal size + /// + public uint Width + { + get => _Width; + } + + /// + /// Gets the visible vertical size + /// + public uint Height + { + get => _Height; + } + + /// + /// Gets the timing refresh rate + /// + public float RefreshRate + { + get => _RefreshRate; + } + + /// + /// Gets a boolean value indicating if the requested timing is an interlaced timing + /// + public bool IsInterlaced + { + get => _Flags.IsInterlaced; + } + + /// + /// Gets the preferred scaling + /// + public byte Scaling + { + get => _Flags.Scaling; + } + + /// + /// Gets timing type (formula) to use for calculating the timing + /// + public TimingOverride TimingType + { + get => _TimingType; + } + + /// + /// Creates an instance of the TimingInput + /// + /// The preferred visible horizontal size + /// The preferred visible vertical size + /// The preferred timing refresh rate + /// The preferred formula to be used for timing calculation + /// A boolean value indicating if the preferred timing is interlaced + /// The preferred scaling factor + public TimingInput( + uint width, + uint height, + float refreshRate, + TimingOverride timingType, + bool isInterlaced = false, + byte scaling = 0 + ) + { + this = typeof(TimingInput).Instantiate(); + _Width = width; + _Height = height; + _RefreshRate = refreshRate; + _TimingType = timingType; + _Flags = new TimingFlag(isInterlaced, scaling); + } + + /// + /// Creates an instance of the TimingInput + /// + /// The preferred analog TV format + /// A boolean value indicating if the preferred timing is interlaced + /// The preferred scaling factor + public TimingInput(TVFormat tvFormat, bool isInterlaced = false, byte scaling = 0) + : this(0, 0, 0, TimingOverride.AnalogTV, isInterlaced, scaling) + { + _Flags = new TimingFlag(isInterlaced, scaling, tvFormat); + } + + /// + /// Creates an instance of the TimingInput + /// + /// + /// The CEA id or the predefined PsF format id depending on the value of other + /// arguments + /// + /// + /// The preferred formula to be used for timing calculation, valid values for this overload are + /// and . + /// + /// A boolean value indicating if the preferred timing is interlaced + /// The preferred scaling factor + public TimingInput( + byte ceaIdOrPredefinedPSFormatId, + TimingOverride timingType, + bool isInterlaced = false, + byte scaling = 0 + ) + : this(0, 0, 0, timingType, isInterlaced, scaling) + { + if (timingType != TimingOverride.EIA861 && timingType != TimingOverride.Predefined) + { + throw new ArgumentException("Invalid timing type passed.", nameof(timingType)); + } + + _Flags = new TimingFlag(isInterlaced, scaling, ceaIdOrPredefinedPSFormatId); + } + + /// + /// Creates an instance of the TimingInput + /// + /// + /// The preferred formula to be used for timing calculation. + /// + public TimingInput(TimingOverride timingType) + : this(0, 0, 0, timingType) + { + } + + /// + /// Gets the analog TV actual HD/SDTV format + /// + public TVFormat? TVFormat + { + get + { + if (Width == 0 && Height == 0 && Math.Abs(RefreshRate) < 0.01 && TimingType == TimingOverride.AnalogTV) + { + return _Flags.TVFormat; + } + + return null; + } + } + + /// + /// Gets the EIA/CEA 861B/D predefined short timing descriptor id + /// + public byte? CEAId + { + get + { + if (Width == 0 && Height == 0 && Math.Abs(RefreshRate) < 0.01 && TimingType == TimingOverride.EIA861) + { + return _Flags.CEAId; + } + + return null; + } + } + + /// + /// Gets the Nvidia predefined PsF format id + /// + public byte? PredefinedPSFormatId + { + get + { + if (TimingType == TimingOverride.Predefined) + { + return _Flags.PredefinedPSFormatId; + } + + return null; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/UnAttachedDisplayHandle.cs b/NvAPIWrapper/Native/Display/Structures/UnAttachedDisplayHandle.cs new file mode 100644 index 0000000..528e706 --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/UnAttachedDisplayHandle.cs @@ -0,0 +1,78 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// UnAttachedDisplayHandle is a one-to-one map to the GDI handle of an unattached display. + /// + [StructLayout(LayoutKind.Sequential)] + public struct UnAttachedDisplayHandle : IHandle, IEquatable + { + internal readonly IntPtr _MemoryAddress; + + /// + public bool Equals(UnAttachedDisplayHandle other) + { + return _MemoryAddress.Equals(other._MemoryAddress); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is UnAttachedDisplayHandle && Equals((UnAttachedDisplayHandle) obj); + } + + /// + public override int GetHashCode() + { + return _MemoryAddress.GetHashCode(); + } + + /// + public override string ToString() + { + return $"UnAttachedDisplayHandle #{MemoryAddress.ToInt64()}"; + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(UnAttachedDisplayHandle left, UnAttachedDisplayHandle right) + { + return left.Equals(right); + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(UnAttachedDisplayHandle left, UnAttachedDisplayHandle right) + { + return !left.Equals(right); + } + + /// + public IntPtr MemoryAddress + { + get => _MemoryAddress; + } + + /// + public bool IsNull + { + get => _MemoryAddress == IntPtr.Zero; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/Structures/ViewPortF.cs b/NvAPIWrapper/Native/Display/Structures/ViewPortF.cs new file mode 100644 index 0000000..b01d18e --- /dev/null +++ b/NvAPIWrapper/Native/Display/Structures/ViewPortF.cs @@ -0,0 +1,87 @@ +using System.Drawing; +using System.Runtime.InteropServices; + +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Hold information about the screen view port rectangle + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct ViewPortF + { + internal float _X; + internal float _Y; + internal float _Width; + internal float _Height; + + /// + /// Gets the x-coordinate of the viewport top-left point + /// + public float X + { + get => _X; + } + + /// + /// Gets the y-coordinate of the viewport top-left point + /// + public float Y + { + get => _Y; + } + + /// + /// Gets the width of the viewport. + /// + public float Width + { + get => _Width; + } + + /// + /// Gets the height of the viewport. + /// + public float Height + { + get => _Height; + } + + /// + /// Creates an instance of ViewPortF + /// + /// The x-coordinate of the viewport top-left point + /// The y-coordinate of the viewport top-left point + /// The width of the viewport. + /// The height of the viewport. + public ViewPortF(float x, float y, float width, float height) + { + _X = x; + _Y = y; + _Width = width; + _Height = height; + } + + /// + /// Creates an instance of + /// + /// The rectangle to take view port information from. + public ViewPortF(RectangleF rect) : this(rect.X, rect.Y, rect.Width, rect.Height) + { + } + + /// + /// Return an instance of representing this view port. + /// + /// + public RectangleF ToRectangle() + { + return new RectangleF(X, Y, Width, Height); + } + + /// + public override string ToString() + { + return $"({Width:F1}, {Height:F1}) @ ({X:F1}, {Y:F1})"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/TVFormat.cs b/NvAPIWrapper/Native/Display/TVFormat.cs new file mode 100644 index 0000000..1571d41 --- /dev/null +++ b/NvAPIWrapper/Native/Display/TVFormat.cs @@ -0,0 +1,219 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Possible TV formats + /// + public enum TVFormat : uint + { + /// + /// Display is not a TV + /// + None = 0, + + /// + /// Standard definition NTSC M signal + /// + // ReSharper disable once InconsistentNaming + SD_NTSCM = 0x00000001, + + /// + /// Standard definition NTSC J signal + /// + // ReSharper disable once InconsistentNaming + SD_NTSCJ = 0x00000002, + + /// + /// Standard definition PAL M signal + /// + // ReSharper disable once InconsistentNaming + SD_PALM = 0x00000004, + + /// + /// Standard definition PAL DFGH signal + /// + // ReSharper disable once InconsistentNaming + SD_PALBDGH = 0x00000008, + + /// + /// Standard definition PAL N signal + /// + // ReSharper disable once InconsistentNaming + SD_PAL_N = 0x00000010, + + /// + /// Standard definition PAL NC signal + /// + // ReSharper disable once InconsistentNaming + SD_PAL_NC = 0x00000020, + + /// + /// Extended definition with height of 576 pixels interlaced + /// + // ReSharper disable once InconsistentNaming + SD576i = 0x00000100, + + /// + /// Extended definition with height of 480 pixels interlaced + /// + // ReSharper disable once InconsistentNaming + SD480i = 0x00000200, + + /// + /// Extended definition with height of 480 pixels progressive + /// + // ReSharper disable once InconsistentNaming + ED480p = 0x00000400, + + /// + /// Extended definition with height of 576 pixels progressive + /// + // ReSharper disable once InconsistentNaming + ED576p = 0x00000800, + + /// + /// High definition with height of 720 pixels progressive + /// + // ReSharper disable once InconsistentNaming + HD720p = 0x00001000, + + /// + /// High definition with height of 1080 pixels interlaced + /// + // ReSharper disable once InconsistentNaming + HD1080i = 0x00002000, + + /// + /// High definition with height of 1080 pixels progressive + /// + // ReSharper disable once InconsistentNaming + HD1080p = 0x00004000, + + /// + /// High definition 50 frames per second with height of 720 pixels progressive + /// + // ReSharper disable once InconsistentNaming + HD720p50 = 0x00008000, + + /// + /// High definition 24 frames per second with height of 1080 pixels progressive + /// + // ReSharper disable once InconsistentNaming + HD1080p24 = 0x00010000, + + /// + /// High definition 50 frames per second with height of 1080 pixels interlaced + /// + // ReSharper disable once InconsistentNaming + HD1080i50 = 0x00020000, + + /// + /// High definition 50 frames per second with height of 1080 pixels progressive + /// + // ReSharper disable once InconsistentNaming + HD1080p50 = 0x00040000, + + /// + /// Ultra high definition 30 frames per second + /// + // ReSharper disable once InconsistentNaming + UHD4Kp30 = 0x00080000, + + /// + /// Ultra high definition 30 frames per second with width of 3840 pixels + /// + // ReSharper disable once InconsistentNaming + UHD4Kp30_3840 = UHD4Kp30, + + /// + /// Ultra high definition 25 frames per second + /// + // ReSharper disable once InconsistentNaming + UHD4Kp25 = 0x00100000, + + /// + /// Ultra high definition 25 frames per second with width of 3840 pixels + /// + // ReSharper disable once InconsistentNaming + UHD4Kp25_3840 = UHD4Kp25, + + /// + /// Ultra high definition 24 frames per second + /// + // ReSharper disable once InconsistentNaming + UHD4Kp24 = 0x00200000, + + /// + /// Ultra high definition 24 frames per second with width of 3840 pixels + /// + // ReSharper disable once InconsistentNaming + UHD4Kp24_3840 = UHD4Kp24, + + /// + /// Ultra high definition 24 frames per second with SMPTE signal + /// + // ReSharper disable once InconsistentNaming + UHD4Kp24_SMPTE = 0x00400000, + + /// + /// Ultra high definition 50 frames per second with width of 3840 pixels + /// + // ReSharper disable once InconsistentNaming + UHD4Kp50_3840 = 0x00800000, + + /// + /// Ultra high definition 60 frames per second with width of 3840 pixels + /// + // ReSharper disable once InconsistentNaming + UHD4Kp60_3840 = 0x00900000, + + /// + /// Ultra high definition 30 frames per second with width of 4096 pixels + /// + // ReSharper disable once InconsistentNaming + UHD4Kp30_4096 = 0x00A00000, + + /// + /// Ultra high definition 25 frames per second with width of 4096 pixels + /// + // ReSharper disable once InconsistentNaming + UHD4Kp25_4096 = 0x00B00000, + + /// + /// Ultra high definition 24 frames per second with width of 4096 pixels + /// + // ReSharper disable once InconsistentNaming + UHD4Kp24_4096 = 0x00C00000, + + /// + /// Ultra high definition 50 frames per second with width of 4096 pixels + /// + // ReSharper disable once InconsistentNaming + UHD4Kp50_4096 = 0x00D00000, + + /// + /// Ultra high definition 60 frames per second with width of 4096 pixels + /// + // ReSharper disable once InconsistentNaming + UHD4Kp60_4096 = 0x00E00000, + + /// + /// Any other standard definition TV format + /// + SDOther = 0x01000000, + + /// + /// Any other extended definition TV format + /// + EDOther = 0x02000000, + + /// + /// Any other high definition TV format + /// + HDOther = 0x04000000, + + /// + /// Any other TV format + /// + Any = 0x80000000 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/TargetViewMode.cs b/NvAPIWrapper/Native/Display/TargetViewMode.cs new file mode 100644 index 0000000..39f24b1 --- /dev/null +++ b/NvAPIWrapper/Native/Display/TargetViewMode.cs @@ -0,0 +1,38 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Display view modes + /// + public enum TargetViewMode + { + /// + /// Standard view mode + /// + Standard = 0, + + /// + /// Cloned view mode + /// + Clone = 1, + + /// + /// Horizontal span view mode + /// + HorizontalSpan = 2, + + /// + /// Vertical span view mode + /// + VerticalSpan = 3, + + /// + /// Dual view mode + /// + DualView = 4, + + /// + /// Multi view mode + /// + MultiView = 5 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/TimingHorizontalSyncPolarity.cs b/NvAPIWrapper/Native/Display/TimingHorizontalSyncPolarity.cs new file mode 100644 index 0000000..90c541c --- /dev/null +++ b/NvAPIWrapper/Native/Display/TimingHorizontalSyncPolarity.cs @@ -0,0 +1,23 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Horizontal synchronized polarity modes + /// + public enum TimingHorizontalSyncPolarity : byte + { + /// + /// Positive horizontal synchronized polarity + /// + Positive = 0, + + /// + /// Negative horizontal synchronized polarity + /// + Negative = 1, + + /// + /// Default horizontal synchronized polarity + /// + Default = Negative + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/TimingOverride.cs b/NvAPIWrapper/Native/Display/TimingOverride.cs new file mode 100644 index 0000000..ead2b6d --- /dev/null +++ b/NvAPIWrapper/Native/Display/TimingOverride.cs @@ -0,0 +1,88 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Timing override modes + /// + public enum TimingOverride + { + /// + /// Current timing + /// + Current = 0, + + /// + /// Auto timing + /// + Auto, + + /// + /// EDID timing + /// + EDID, + + /// + /// VESA DMT timing + /// + DMT, + + /// + /// VESA DMT timing with reduced blanking + /// + DMTReducedBlanking, + + /// + /// VESA CVT timing + /// + CVT, + + /// + /// VESA CVT timing with reduced blanking + /// + CVTReducedBlanking, + + /// + /// VESA GTF + /// + GTF, + + /// + /// EIA 861x PreDefined timing + /// + EIA861, + + /// + /// AnalogTV PreDefined timing + /// + AnalogTV, + + /// + /// NVIDIA Custom timing + /// + Custom, + + /// + /// NVIDIA PreDefined timing + /// + Predefined, + + /// + /// NVIDIA PreDefined timing + /// + PSF = Predefined, + + /// + /// ASPR timing + /// + ASPR, + + /// + /// Override for SDI timing + /// + SDI, + + /// + /// Not used + /// + Max + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/TimingScanMode.cs b/NvAPIWrapper/Native/Display/TimingScanMode.cs new file mode 100644 index 0000000..a4d4271 --- /dev/null +++ b/NvAPIWrapper/Native/Display/TimingScanMode.cs @@ -0,0 +1,28 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Timing scan modes + /// + public enum TimingScanMode : ushort + { + /// + /// Progressive scan mode + /// + Progressive = 0, + + /// + /// Interlaced scan mode + /// + Interlaced = 1, + + /// + /// Interlaced scan mode with extra vertical blank + /// + InterlacedWithExtraVerticalBlank = 1, + + /// + /// Interlaced scan mode without extra vertical blank + /// + InterlacedWithNoExtraVerticalBlank = 2 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/TimingVerticalSyncPolarity.cs b/NvAPIWrapper/Native/Display/TimingVerticalSyncPolarity.cs new file mode 100644 index 0000000..3bf5292 --- /dev/null +++ b/NvAPIWrapper/Native/Display/TimingVerticalSyncPolarity.cs @@ -0,0 +1,23 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Vertical synchronized polarity modes + /// + public enum TimingVerticalSyncPolarity : byte + { + /// + /// Positive vertical synchronized polarity + /// + Positive = 0, + + /// + /// Negative vertical synchronized polarity + /// + Negative = 1, + + /// + /// Default vertical synchronized polarity + /// + Default = Positive + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Display/WarpingVerticeFormat.cs b/NvAPIWrapper/Native/Display/WarpingVerticeFormat.cs new file mode 100644 index 0000000..87dbc7d --- /dev/null +++ b/NvAPIWrapper/Native/Display/WarpingVerticeFormat.cs @@ -0,0 +1,18 @@ +namespace NvAPIWrapper.Native.Display +{ + /// + /// Holds a list of possible warping vertex formats + /// + public enum WarpingVerticeFormat : uint + { + /// + /// XYUVRQ Triangle Strip vertex format + /// + TriangleStripXYUVRQ = 0, + + /// + /// XYUVRQ Triangles format + /// + TrianglesXYUVRQ = 1 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/DisplayApi.cs b/NvAPIWrapper/Native/DisplayApi.cs new file mode 100644 index 0000000..18e359e --- /dev/null +++ b/NvAPIWrapper/Native/DisplayApi.cs @@ -0,0 +1,1674 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NvAPIWrapper.Native.Display; +using NvAPIWrapper.Native.Display.Structures; +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; +using NvAPIWrapper.Native.Interfaces.Display; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native +{ + /// + /// Contains display and display control static functions + /// + public static class DisplayApi + { + /// + /// This API controls the display color configurations. + /// + /// The targeted display id. + /// The structure to be filled with information requested or applied on the display. + public static void ColorControl(uint displayId, ref TColorData colorData) + where TColorData : struct, IColorData + { + var c = colorData as IColorData; + ColorControl(displayId, ref c); + colorData = (TColorData) c; + } + + /// + /// This API controls the display color configurations. + /// + /// The targeted display id. + /// The structure to be filled with information requested or applied on the display. + public static void ColorControl(uint displayId, ref IColorData colorData) + { + var colorControl = DelegateFactory.GetDelegate(); + var type = colorData.GetType(); + + if (!colorControl.Accepts().Contains(type)) + { + throw new ArgumentOutOfRangeException(nameof(type)); + } + + using (var colorDataReference = ValueTypeReference.FromValueType(colorData, type)) + { + var status = colorControl(displayId, colorDataReference); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + colorData = colorDataReference.ToValueType(type); + } + } + + /// + /// This API controls the display color configurations. + /// + /// The targeted display id. + /// The list of structures to be filled with information requested or applied on the display. + /// The structure that succeed in requesting information or used for applying configuration on the display. + // ReSharper disable once IdentifierTypo + public static IColorData ColorControl(uint displayId, IColorData[] colorDatas) + { + foreach (var colorData in colorDatas) + { + try + { + var c = colorData; + ColorControl(displayId, ref c); + + return c; + } + catch (NVIDIAApiException e) + { + if (e.Status == Status.IncompatibleStructureVersion) + { + continue; + } + + throw; + } + } + + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + /// + /// This function converts the unattached display handle to an active attached display handle. + /// At least one GPU must be present in the system and running an NVIDIA display driver. + /// + /// An unattached display handle to convert. + /// Display handle of newly created display. + /// Status.InvalidArgument: Invalid UnAttachedDisplayHandle handle. + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// A delegate callback throws an exception. + public static DisplayHandle CreateDisplayFromUnAttachedDisplay(UnAttachedDisplayHandle display) + { + var createDisplayFromUnAttachedDisplay = + DelegateFactory.GetDelegate(); + var status = createDisplayFromUnAttachedDisplay(display, out var newDisplay); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return newDisplay; + } + + /// + /// This function deletes the custom display configuration, specified from the registry for all the displays whose + /// display IDs are passed. + /// + /// Array of display IDs on which custom display configuration should be removed. + /// The custom display to remove. + public static void DeleteCustomDisplay(uint[] displayIds, CustomDisplay customDisplay) + { + if (displayIds.Length == 0) + { + return; + } + + using (var displayIdsReference = ValueTypeArray.FromArray(displayIds)) + { + using (var customDisplayReference = ValueTypeReference.FromValueType(customDisplay)) + { + var status = DelegateFactory.GetDelegate()( + displayIdsReference, + (uint) displayIds.Length, + customDisplayReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + } + + /// + /// This API enumerates the custom timing specified by the enum index. + /// + /// The display id of the display. + /// A list of + public static IEnumerable EnumCustomDisplays(uint displayId) + { + var instance = typeof(CustomDisplay).Instantiate(); + + using (var customDisplayReference = ValueTypeReference.FromValueType(instance)) + { + for (uint i = 0; i < uint.MaxValue; i++) + { + var status = DelegateFactory.GetDelegate()( + displayId, + i, + customDisplayReference + ); + + if (status == Status.EndEnumeration) + { + yield break; + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + yield return customDisplayReference.ToValueType().GetValueOrDefault(); + } + } + } + + /// + /// This function returns the handle of all NVIDIA displays + /// Note: Display handles can get invalidated on a mode-set, so the calling applications need to re-enum the handles + /// after every mode-set. + /// + /// Array of display handles. + /// Status.NvidiaDeviceNotFound: No NVIDIA device found in the system + /// A delegate callback throws an exception. + public static DisplayHandle[] EnumNvidiaDisplayHandle() + { + var enumNvidiaDisplayHandle = + DelegateFactory.GetDelegate(); + var results = new List(); + uint i = 0; + + while (true) + { + var status = enumNvidiaDisplayHandle(i, out var displayHandle); + + if (status == Status.EndEnumeration) + { + break; + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + results.Add(displayHandle); + i++; + } + + return results.ToArray(); + } + + /// + /// This function returns the handle of all unattached NVIDIA displays + /// Note: Display handles can get invalidated on a mode-set, so the calling applications need to re-enum the handles + /// after every mode-set. + /// + /// Array of unattached display handles. + /// Status.NvidiaDeviceNotFound: No NVIDIA device found in the system + /// A delegate callback throws an exception. + public static UnAttachedDisplayHandle[] EnumNvidiaUnAttachedDisplayHandle() + { + var enumNvidiaUnAttachedDisplayHandle = + DelegateFactory.GetDelegate(); + var results = new List(); + uint i = 0; + + while (true) + { + var status = enumNvidiaUnAttachedDisplayHandle(i, out var displayHandle); + + if (status == Status.EndEnumeration) + { + break; + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + results.Add(displayHandle); + i++; + } + + return results.ToArray(); + } + + /// + /// This function gets the active outputId associated with the display handle. + /// + /// + /// NVIDIA Display selection. It can be DisplayHandle.DefaultHandle or a handle enumerated from + /// DisplayApi.EnumNVidiaDisplayHandle(). + /// + /// + /// The active display output ID associated with the selected display handle hNvDisplay. The output id will have + /// only one bit set. In the case of Clone or Span mode, this will indicate the display outputId of the primary display + /// that the GPU is driving. + /// + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found. + /// Status.ExpectedDisplayHandle: display is not a valid display handle. + /// A delegate callback throws an exception. + public static OutputId GetAssociatedDisplayOutputId(DisplayHandle display) + { + var getAssociatedDisplayOutputId = + DelegateFactory.GetDelegate(); + var status = getAssociatedDisplayOutputId(display, out var outputId); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return outputId; + } + + /// + /// This function returns the handle of the NVIDIA display that is associated with the given display "name" (such as + /// "\\.\DISPLAY1"). + /// + /// Display name + /// Display handle of associated display + /// Status.InvalidArgument: Display name is null. + /// Status.NvidiaDeviceNotFound: No NVIDIA device maps to that display name. + /// A delegate callback throws an exception. + public static DisplayHandle GetAssociatedNvidiaDisplayHandle(string name) + { + var getAssociatedNvidiaDisplayHandle = + DelegateFactory.GetDelegate(); + var status = getAssociatedNvidiaDisplayHandle(name, out var display); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return display; + } + + /// + /// For a given NVIDIA display handle, this function returns a string (such as "\\.\DISPLAY1") to identify the display. + /// + /// Handle of the associated display + /// Name of the display + /// Status.InvalidArgument: Display handle is null. + /// Status.NvidiaDeviceNotFound: No NVIDIA device maps to that display name. + /// A delegate callback throws an exception. + public static string GetAssociatedNvidiaDisplayName(DisplayHandle display) + { + var getAssociatedNvidiaDisplayName = + DelegateFactory.GetDelegate(); + var status = getAssociatedNvidiaDisplayName(display, out var displayName); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return displayName.Value; + } + + /// + /// This function returns the handle of an unattached NVIDIA display that is associated with the given display "name" + /// (such as "\\DISPLAY1"). + /// + /// Display name + /// Display handle of associated unattached display + /// Status.InvalidArgument: Display name is null. + /// Status.NvidiaDeviceNotFound: No NVIDIA device maps to that display name. + /// A delegate callback throws an exception. + public static UnAttachedDisplayHandle GetAssociatedUnAttachedNvidiaDisplayHandle(string name) + { + var getAssociatedUnAttachedNvidiaDisplayHandle = + DelegateFactory.GetDelegate(); + var status = getAssociatedUnAttachedNvidiaDisplayHandle(name, out var display); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return display; + } + + /// + /// This API lets caller retrieve the current global display configuration. + /// Note: User should dispose all returned PathInfo objects + /// + /// Array of path information + /// This operation is not supported. + /// Status.InvalidArgument: Invalid input parameter. + /// Status.DeviceBusy: ModeSet has not yet completed. Please wait and call it again. + /// A delegate callback throws an exception. + public static IPathInfo[] GetDisplayConfig() + { + var getDisplayConfig = DelegateFactory.GetDelegate(); + uint allAvailable = 0; + var status = getDisplayConfig(ref allAvailable, ValueTypeArray.Null); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + if (allAvailable == 0) + { + return new IPathInfo[0]; + } + + foreach (var acceptType in getDisplayConfig.Accepts()) + { + var count = allAvailable; + var instances = acceptType.Instantiate().Repeat((int) allAvailable); + + using (var pathInfos = ValueTypeArray.FromArray(instances, acceptType)) + { + status = getDisplayConfig(ref count, pathInfos); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + instances = pathInfos.ToArray((int) count, acceptType); + } + + if (instances.Length <= 0) + { + return new IPathInfo[0]; + } + + // After allocation, we should make sure to dispose objects + // In this case however, the responsibility is on the user shoulders + instances = instances.AllocateAll().ToArray(); + + using (var pathInfos = ValueTypeArray.FromArray(instances, acceptType)) + { + status = getDisplayConfig(ref count, pathInfos); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return pathInfos.ToArray((int) count, acceptType); + } + } + + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + /// + /// Gets the build title of the Driver Settings Database for a display + /// + /// The display handle to get DRS build title. + /// The DRS build title. + public static string GetDisplayDriverBuildTitle(DisplayHandle displayHandle) + { + var status = + DelegateFactory.GetDelegate()(displayHandle, + out var name); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return name.Value; + } + + /// + /// This function retrieves the available driver memory footprint for the GPU associated with a display. + /// + /// Handle of the display for which the memory information of its GPU is to be extracted. + /// The memory footprint available in the driver. + /// This operation is not supported. + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found. + /// A delegate callback throws an exception. + public static IDisplayDriverMemoryInfo GetDisplayDriverMemoryInfo(DisplayHandle displayHandle) + { + var getMemoryInfo = DelegateFactory.GetDelegate(); + + foreach (var acceptType in getMemoryInfo.Accepts()) + { + var instance = acceptType.Instantiate(); + + using (var displayDriverMemoryInfo = ValueTypeReference.FromValueType(instance, acceptType)) + { + var status = getMemoryInfo(displayHandle, displayDriverMemoryInfo); + + if (status == Status.IncompatibleStructureVersion) + { + continue; + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return displayDriverMemoryInfo.ToValueType(acceptType); + } + } + + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + /// + /// This API retrieves the Display Id of a given display by display name. The display must be active to retrieve the + /// displayId. In the case of clone mode or Surround gaming, the primary or top-left display will be returned. + /// + /// Name of display (Eg: "\\DISPLAY1" to retrieve the displayId for. + /// Display ID of the requested display. + /// Status.InvalidArgument: One or more args passed in are invalid. + /// Status.ApiNotInitialized: The NvAPI API needs to be initialized first + /// Status.NoImplementation: This entry-point not available + /// Status.Error: Miscellaneous error occurred + /// A delegate callback throws an exception. + public static uint GetDisplayIdByDisplayName(string displayName) + { + var getDisplayIdByDisplayName = + DelegateFactory.GetDelegate(); + var status = getDisplayIdByDisplayName(displayName, out var display); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return display; + } + + /// [PRIVATE] + /// + /// This API returns the current saturation level from the Digital Vibrance Control + /// + /// + /// The targeted display's handle. + /// + /// An instance of the PrivateDisplayDVCInfo structure containing requested information. + public static PrivateDisplayDVCInfo GetDVCInfo(DisplayHandle display) + { + var instance = typeof(PrivateDisplayDVCInfo).Instantiate(); + + using (var displayDVCInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + display, + OutputId.Invalid, + displayDVCInfoReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return displayDVCInfoReference.ToValueType().GetValueOrDefault(); + } + } + + /// [PRIVATE] + /// + /// This API returns the current saturation level from the Digital Vibrance Control + /// + /// + /// The targeted display output id. + /// + /// An instance of the PrivateDisplayDVCInfo structure containing requested information. + public static PrivateDisplayDVCInfo GetDVCInfo(OutputId displayId) + { + var instance = typeof(PrivateDisplayDVCInfo).Instantiate(); + + using (var displayDVCInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + DisplayHandle.DefaultHandle, + displayId, + displayDVCInfoReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return displayDVCInfoReference.ToValueType().GetValueOrDefault(); + } + } + + /// [PRIVATE] + /// + /// This API returns the current and the default saturation level from the Digital Vibrance Control. + /// The difference between this API and the 'GetDVCInfo()' includes the possibility to get the default + /// saturation level as well as to query under saturated configurations. + /// + /// + /// The targeted display's handle. + /// + /// An instance of the PrivateDisplayDVCInfoEx structure containing requested information. + public static PrivateDisplayDVCInfoEx GetDVCInfoEx(DisplayHandle display) + { + var instance = typeof(PrivateDisplayDVCInfoEx).Instantiate(); + + using (var displayDVCInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + display, + OutputId.Invalid, + displayDVCInfoReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return displayDVCInfoReference.ToValueType().GetValueOrDefault(); + } + } + + /// [PRIVATE] + /// + /// This API returns the current and the default saturation level from the Digital Vibrance Control. + /// The difference between this API and the 'GetDVCInfo()' includes the possibility to get the default + /// saturation level as well as to query under saturated configurations. + /// + /// + /// The targeted display output id. + /// + /// An instance of the PrivateDisplayDVCInfoEx structure containing requested information. + public static PrivateDisplayDVCInfoEx GetDVCInfoEx(OutputId displayId) + { + var instance = typeof(PrivateDisplayDVCInfoEx).Instantiate(); + + using (var displayDVCInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + DisplayHandle.DefaultHandle, + displayId, + displayDVCInfoReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return displayDVCInfoReference.ToValueType().GetValueOrDefault(); + } + } + + /// + /// This API returns the current info-frame data on the specified device (monitor). + /// + /// The display handle of the device to retrieve HDMI support information for. + /// The target display's output id, or to determine automatically. + /// An instance of a type implementing the interface. + public static IHDMISupportInfo GetHDMISupportInfo(DisplayHandle displayHandle, OutputId outputId = OutputId.Invalid) + { + var getHDMISupportInfo = DelegateFactory.GetDelegate(); + + foreach (var acceptType in getHDMISupportInfo.Accepts()) + { + var instance = acceptType.Instantiate(); + + using (var supportInfoReference = ValueTypeReference.FromValueType(instance, acceptType)) + { + var status = getHDMISupportInfo(displayHandle, (uint)outputId, supportInfoReference); + + if (status == Status.IncompatibleStructureVersion) + { + continue; + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return supportInfoReference.ToValueType(acceptType); + } + } + + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + /// + /// This API returns the current info-frame data on the specified device (monitor). + /// + /// The display id of the device to retrieve HDMI support information for. + /// An instance of a type implementing the interface. + public static IHDMISupportInfo GetHDMISupportInfo(uint displayId) + { + var getHDMISupportInfo = DelegateFactory.GetDelegate(); + + foreach (var acceptType in getHDMISupportInfo.Accepts()) + { + var instance = acceptType.Instantiate(); + + using (var supportInfoReference = ValueTypeReference.FromValueType(instance, acceptType)) + { + var status = getHDMISupportInfo(DisplayHandle.DefaultHandle, displayId, supportInfoReference); + + if (status == Status.IncompatibleStructureVersion) + { + continue; + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return supportInfoReference.ToValueType(acceptType); + } + } + + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + /// [PRIVATE] + /// + /// This API returns the current default HUE angle + /// + /// + /// The targeted display's handle. + /// + /// An instance of the PrivateDisplayHUEInfo structure containing requested information. + public static PrivateDisplayHUEInfo GetHUEInfo(DisplayHandle display) + { + var instance = typeof(PrivateDisplayHUEInfo).Instantiate(); + + using (var displayDVCInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + display, + OutputId.Invalid, + displayDVCInfoReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return displayDVCInfoReference.ToValueType().GetValueOrDefault(); + } + } + + /// [PRIVATE] + /// + /// This API returns the current and default HUE angle + /// + /// + /// The targeted display output id. + /// + /// An instance of the PrivateDisplayHUEInfo structure containing requested information. + public static PrivateDisplayHUEInfo GetHUEInfo(OutputId displayId) + { + var instance = typeof(PrivateDisplayHUEInfo).Instantiate(); + + using (var displayDVCInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + DisplayHandle.DefaultHandle, + displayId, + displayDVCInfoReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return displayDVCInfoReference.ToValueType().GetValueOrDefault(); + } + } + + /// + /// This API returns all the monitor capabilities. + /// + /// The target display id. + /// The type of capabilities requested. + /// An instance of . + public static MonitorCapabilities? GetMonitorCapabilities( + uint displayId, + MonitorCapabilitiesType capabilitiesType) + { + var instance = new MonitorCapabilities(capabilitiesType); + + using (var monitorCapReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + displayId, + monitorCapReference + ); + + if (status == Status.Error) + { + return null; + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + + instance = monitorCapReference.ToValueType().GetValueOrDefault(); + + if (!instance.IsValid) + { + return null; + } + + return instance; + } + } + + /// + /// This API returns all the color formats and bit depth values supported by a given display port monitor. + /// + /// The target display id. + /// A list of instances. + public static MonitorColorData[] GetMonitorColorCapabilities(uint displayId) + { + var getMonitorColorCapabilities = + DelegateFactory.GetDelegate(); + var count = 0u; + + var status = getMonitorColorCapabilities(displayId, ValueTypeArray.Null, ref count); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + if (count == 0) + { + return new MonitorColorData[0]; + } + + var array = typeof(MonitorColorData).Instantiate().Repeat((int) count); + + using (var monitorCapsReference = ValueTypeArray.FromArray(array)) + { + status = getMonitorColorCapabilities(displayId, monitorCapsReference, ref count); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return monitorCapsReference.ToArray((int) count); + + } + } + + /// + /// This API returns the Display ID of the GDI Primary. + /// + /// Display ID of the GDI Primary. + /// Status.NvidiaDeviceNotFound: GDI Primary not on an NVIDIA GPU. + /// Status.ApiNotInitialized: The NvAPI API needs to be initialized first + /// Status.NoImplementation: This entry-point not available + /// Status.Error: Miscellaneous error occurred + /// A delegate callback throws an exception. + public static uint GetGDIPrimaryDisplayId() + { + var getGDIPrimaryDisplay = + DelegateFactory.GetDelegate(); + var status = getGDIPrimaryDisplay(out var displayId); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return displayId; + } + + /// + /// This API gets High Dynamic Range (HDR) capabilities of the display. + /// + /// The targeted display id. + /// + /// A boolean value indicating if the EDID HDR parameters should be expanded (true) or the actual current HDR + /// parameters should be reported (false). + /// + /// HDR capabilities of the display + public static HDRCapabilitiesV1 GetHDRCapabilities(uint displayId, bool driverExpandDefaultHDRParameters) + { + var hdrCapabilities = new HDRCapabilitiesV1(driverExpandDefaultHDRParameters); + + using (var hdrCapabilitiesReference = ValueTypeReference.FromValueType(hdrCapabilities)) + { + var status = DelegateFactory.GetDelegate()( + displayId, + hdrCapabilitiesReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return hdrCapabilitiesReference.ToValueType().GetValueOrDefault(); + } + } + + /// + /// This API queries current state of one of the various scan-out composition parameters on the specified display. + /// + /// Combined physical display and GPU identifier of the display to query the configuration. + /// Scan-out composition parameter to by queried. + /// Additional container containing the returning data associated with the specified parameter. + /// Scan-out composition parameter value. + public static ScanOutCompositionParameterValue GetScanOutCompositionParameter( + uint displayId, + ScanOutCompositionParameter parameter, + out float container) + { + var status = DelegateFactory.GetDelegate()( + displayId, + parameter, + out var parameterValue, + out container + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return parameterValue; + } + + /// + /// This API queries the desktop and scan-out portion of the specified display. + /// + /// Combined physical display and GPU identifier of the display to query the configuration. + /// Desktop area to displayId mapping information. + public static ScanOutInformationV1 GetScanOutConfiguration(uint displayId) + { + var instance = typeof(ScanOutInformationV1).Instantiate(); + + using (var scanOutInformationReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + displayId, + scanOutInformationReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return scanOutInformationReference.ToValueType().GetValueOrDefault(); + } + } + + /// + /// This API queries the desktop and scan-out portion of the specified display. + /// + /// Combined physical display and GPU identifier of the display to query the configuration. + /// Desktop area of the display in desktop coordinates. + /// Scan-out area of the display relative to desktopRect. + public static void GetScanOutConfiguration( + uint displayId, + out Rectangle desktopRectangle, + out Rectangle scanOutRectangle) + { + var instance1 = typeof(Rectangle).Instantiate(); + var instance2 = typeof(Rectangle).Instantiate(); + + using (var desktopRectangleReference = ValueTypeReference.FromValueType(instance1)) + { + using (var scanOutRectangleReference = ValueTypeReference.FromValueType(instance2)) + { + var status = DelegateFactory.GetDelegate()( + displayId, + desktopRectangleReference, + scanOutRectangleReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + desktopRectangle = desktopRectangleReference.ToValueType().GetValueOrDefault(); + scanOutRectangle = scanOutRectangleReference.ToValueType().GetValueOrDefault(); + } + } + } + + /// + /// This API queries current state of the intensity feature on the specified display. + /// + /// Combined physical display and GPU identifier of the display to query the configuration. + /// Intensity state data. + public static ScanOutIntensityStateV1 GetScanOutIntensityState(uint displayId) + { + var instance = typeof(ScanOutIntensityStateV1).Instantiate(); + + using (var scanOutIntensityReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + displayId, + scanOutIntensityReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return scanOutIntensityReference.ToValueType().GetValueOrDefault(); + } + } + + /// + /// This API queries current state of the warping feature on the specified display. + /// + /// Combined physical display and GPU identifier of the display to query the configuration. + /// The warping state data. + public static ScanOutWarpingStateV1 GetScanOutWarpingState(uint displayId) + { + var instance = typeof(ScanOutWarpingStateV1).Instantiate(); + + using (var scanOutWarpingReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + displayId, + scanOutWarpingReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return scanOutWarpingReference.ToValueType().GetValueOrDefault(); + } + } + + /// + /// This API lets caller enumerate all the supported NVIDIA display views - nView and DualView modes. + /// + /// + /// NVIDIA Display selection. It can be DisplayHandle.DefaultHandle or a handle enumerated from + /// DisplayApi.EnumNVidiaDisplayHandle(). + /// + /// Array of supported views. + /// This operation is not supported. + /// Status.Error: Miscellaneous error occurred + /// Status.InvalidArgument: Invalid input parameter. + /// A delegate callback throws an exception. + public static TargetViewMode[] GetSupportedViews(DisplayHandle display) + { + var getSupportedViews = DelegateFactory.GetDelegate(); + uint allAvailable = 0; + var status = getSupportedViews(display, ValueTypeArray.Null, ref allAvailable); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + if (allAvailable == 0) + { + return new TargetViewMode[0]; + } + + if (!getSupportedViews.Accepts().Contains(typeof(TargetViewMode))) + { + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + using ( + var viewModes = + ValueTypeArray.FromArray(TargetViewMode.Standard.Repeat((int) allAvailable).Cast(), + typeof(TargetViewMode).GetEnumUnderlyingType())) + { + status = getSupportedViews(display, viewModes, ref allAvailable); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return viewModes.ToArray((int) allAvailable, + typeof(TargetViewMode).GetEnumUnderlyingType()); + } + } + + /// + /// This function calculates the timing from the visible width/height/refresh-rate and timing type info. + /// + /// Display ID of the display. + /// Inputs used for calculating the timing. + /// An instance of the structure. + public static Timing GetTiming(uint displayId, TimingInput timingInput) + { + var instance = typeof(Timing).Instantiate(); + + using (var timingInputReference = ValueTypeReference.FromValueType(timingInput)) + { + using (var timingReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + displayId, + timingInputReference, + timingReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return timingReference.ToValueType().GetValueOrDefault(); + } + } + } + + /// + /// This function returns the display name given, for example, "\\DISPLAY1", using the unattached NVIDIA display handle + /// + /// Handle of the associated unattached display + /// Name of the display + /// Status.InvalidArgument: Display handle is null. + /// Status.NvidiaDeviceNotFound: No NVIDIA device maps to that display name. + /// A delegate callback throws an exception. + public static string GetUnAttachedAssociatedDisplayName(UnAttachedDisplayHandle display) + { + var getUnAttachedAssociatedDisplayName = + DelegateFactory.GetDelegate(); + var status = getUnAttachedAssociatedDisplayName(display, out var displayName); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return displayName.Value; + } + + /// + /// This API controls the InfoFrame values. + /// + /// The targeted display id. + /// The structure to be filled with information requested or applied on the display. + public static void InfoFrameControl(uint displayId, ref InfoFrameData infoFrameData) + { + var infoFrameControl = DelegateFactory.GetDelegate(); + + using (var infoFrameDataReference = ValueTypeReference.FromValueType(infoFrameData)) + { + var status = infoFrameControl(displayId, infoFrameDataReference); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + infoFrameData = infoFrameDataReference.ToValueType().GetValueOrDefault(); + } + } + + /// + /// This API is used to restore the display configuration, that was changed by calling . + /// This function must be called only after a custom display configuration is tested on the hardware, using + /// , otherwise no action is taken. + /// On Vista, should be called with an active display that was affected during + /// the call, per GPU. + /// + /// Array of display ids on which custom display configuration is to be reverted. + public static void RevertCustomDisplayTrial(uint[] displayIds) + { + if (displayIds.Length == 0) + { + return; + } + + using (var displayIdsReference = ValueTypeArray.FromArray(displayIds)) + { + var status = DelegateFactory.GetDelegate()( + displayIdsReference, + (uint) displayIds.Length + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// + /// This API configures High Dynamic Range (HDR) and Extended Dynamic Range (EDR) output. + /// + /// The targeted display id. + /// The structure to be filled with information requested or applied on the display. + public static void HDRColorControl(uint displayId, ref THDRColorData hdrColorData) + where THDRColorData : struct, IHDRColorData + { + var c = hdrColorData as IHDRColorData; + HDRColorControl(displayId, ref c); + hdrColorData = (THDRColorData)c; + } + + /// + /// This API configures High Dynamic Range (HDR) and Extended Dynamic Range (EDR) output. + /// + /// The targeted display id. + /// The structure to be filled with information requested or applied on the display. + public static void HDRColorControl(uint displayId, ref IHDRColorData hdrColorData) + { + var hdrColorControl = DelegateFactory.GetDelegate(); + var type = hdrColorData.GetType(); + + if (!hdrColorControl.Accepts().Contains(type)) + { + throw new ArgumentOutOfRangeException(nameof(type)); + } + + using (var hdrColorDataReference = ValueTypeReference.FromValueType(hdrColorData, type)) + { + var status = hdrColorControl(displayId, hdrColorDataReference); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + hdrColorData = hdrColorDataReference.ToValueType(type); + } + } + + /// + /// This function saves the current hardware display configuration on the specified Display IDs as a custom display + /// configuration. + /// This function should be called right after to save the custom display from the + /// current hardware context. + /// This function will not do anything if the custom display configuration is not tested on the hardware. + /// + /// Array of display ids on which custom display configuration is to be saved. + /// + /// If set, the saved custom display will only be applied on the monitor with the same + /// outputId. + /// + /// + /// If set, the saved custom display will only be applied on the monitor with the same EDID + /// ID or the same TV connector in case of analog TV. + /// + public static void SaveCustomDisplay(uint[] displayIds, bool isThisOutputIdOnly, bool isThisMonitorOnly) + { + if (displayIds.Length == 0) + { + return; + } + + using (var displayIdsReference = ValueTypeArray.FromArray(displayIds)) + { + var status = DelegateFactory.GetDelegate()( + displayIdsReference, + (uint) displayIds.Length, + isThisOutputIdOnly ? 1 : (uint) 0, + isThisMonitorOnly ? 1 : (uint) 0 + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// + /// This API configures High Dynamic Range (HDR) and Extended Dynamic Range (EDR) output. + /// + /// The targeted display id. + /// The list of structures to be filled with information requested or applied on the display. + /// The structure that succeed in requesting information or used for applying configuration on the display. + // ReSharper disable once IdentifierTypo + public static IHDRColorData HDRColorControl(uint displayId, IHDRColorData[] colorDatas) + { + foreach (var colorData in colorDatas) + { + try + { + var c = colorData; + HDRColorControl(displayId, ref c); + + return c; + } + catch (NVIDIAApiException e) + { + if (e.Status == Status.IncompatibleStructureVersion) + { + continue; + } + + throw; + } + } + + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + /// + /// This API lets caller apply a global display configuration across multiple GPUs. + /// If all sourceIds are zero, then NvAPI will pick up sourceId's based on the following criteria : + /// - If user provides SourceModeInfo then we are trying to assign 0th SourceId always to GDIPrimary. + /// This is needed since active windows always moves along with 0th sourceId. + /// - For rest of the paths, we are incrementally assigning the SourceId per adapter basis. + /// - If user doesn't provide SourceModeInfo then NVAPI just picks up some default SourceId's in incremental order. + /// Note : NVAPI will not intelligently choose the SourceIDs for any configs that does not need a mode-set. + /// + /// Array of path information + /// Flags for applying settings + /// This operation is not supported. + /// Status.ApiNotInitialized: NVAPI not initialized + /// Status.Error: Miscellaneous error occurred + /// Status.InvalidArgument: Invalid input parameter. + /// A delegate callback throws an exception. + public static void SetDisplayConfig(IPathInfo[] pathInfos, DisplayConfigFlags flags) + { + var setDisplayConfig = DelegateFactory.GetDelegate(); + + if (pathInfos.Length > 0 && !setDisplayConfig.Accepts().Contains(pathInfos[0].GetType())) + { + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + using (var arrayReference = ValueTypeArray.FromArray(pathInfos)) + { + var status = setDisplayConfig((uint) pathInfos.Length, arrayReference, flags); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// [PRIVATE] + /// + /// This API sets the current saturation level for the Digital Vibrance Control + /// + /// + /// The targeted display's handle. + /// + /// + /// The saturation level to be set. + /// + public static void SetDVCLevel(DisplayHandle display, int currentLevel) + { + var status = DelegateFactory.GetDelegate()( + display, + OutputId.Invalid, + currentLevel + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// [PRIVATE] + /// + /// This API sets the current saturation level for the Digital Vibrance Control + /// + /// + /// The targeted display output id. + /// + /// + /// The saturation level to be set. + /// + public static void SetDVCLevel(OutputId displayId, int currentLevel) + { + var status = DelegateFactory.GetDelegate()( + DisplayHandle.DefaultHandle, + displayId, + currentLevel + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// [PRIVATE] + /// + /// This API sets the current saturation level for the Digital Vibrance Control. + /// The difference between this API and the 'SetDVCLevel()' includes the possibility to set under saturated + /// levels. + /// + /// + /// The targeted display's handle. + /// + /// + /// The saturation level to be set. + /// + public static void SetDVCLevelEx(DisplayHandle display, int currentLevel) + { + var instance = new PrivateDisplayDVCInfoEx(currentLevel); + + using (var displayDVCInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + display, + OutputId.Invalid, + displayDVCInfoReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// [PRIVATE] + /// + /// This API sets the current saturation level for the Digital Vibrance Control. + /// The difference between this API and the 'SetDVCLevel()' includes the possibility to set under saturated + /// levels. + /// + /// + /// The targeted display output id. + /// + /// + /// The saturation level to be set. + /// + public static void SetDVCLevelEx(OutputId displayId, int currentLevel) + { + var instance = new PrivateDisplayDVCInfoEx(currentLevel); + + using (var displayDVCInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + DisplayHandle.DefaultHandle, + displayId, + displayDVCInfoReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// [PRIVATE] + /// + /// This API sets the current HUE angle + /// + /// + /// The targeted display's handle. + /// + /// + /// The HUE angle to be set. + /// + public static void SetHUEAngle(DisplayHandle display, int currentAngle) + { + var status = DelegateFactory.GetDelegate()( + display, + OutputId.Invalid, + currentAngle + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// [PRIVATE] + /// + /// This API sets the current HUE angle + /// + /// + /// The targeted display output id. + /// + /// + /// The HUE angle to be set. + /// + public static void SetHUEAngle(OutputId displayId, int currentAngle) + { + var status = DelegateFactory.GetDelegate()( + DisplayHandle.DefaultHandle, + displayId, + currentAngle + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// + /// This function overrides the refresh rate on the given display. + /// The new refresh rate can be applied right away in this API call or deferred to be applied with the next OS + /// mode-set. + /// The override is good for only one mode-set (regardless whether it's deferred or immediate). + /// + /// The display handle to override refresh rate of. + /// The override refresh rate. + /// + /// A boolean value indicating if the refresh rate override should be deferred to the next OS + /// mode-set. + /// + public static void SetRefreshRateOverride(DisplayHandle display, float refreshRate, bool isDeferred) + { + var status = DelegateFactory.GetDelegate()( + display, + OutputId.Invalid, + refreshRate, + isDeferred ? 1u : 0 + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// + /// This function overrides the refresh rate on the given output mask. + /// The new refresh rate can be applied right away in this API call or deferred to be applied with the next OS + /// mode-set. + /// The override is good for only one mode-set (regardless whether it's deferred or immediate). + /// + /// The output(s) to override refresh rate of. + /// The override refresh rate. + /// + /// A boolean value indicating if the refresh rate override should be deferred to the next OS + /// mode-set. + /// + public static void SetRefreshRateOverride(OutputId outputMask, float refreshRate, bool isDeferred) + { + var status = DelegateFactory.GetDelegate()( + DisplayHandle.DefaultHandle, + outputMask, + refreshRate, + isDeferred ? 1u : 0 + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// + /// This API sets various parameters that configure the scan-out composition feature on the specified display. + /// + /// Combined physical display and GPU identifier of the display to apply the intensity control. + /// The scan-out composition parameter to be set. + /// The value to be set for the specified parameter. + /// Additional container for data associated with the specified parameter. + // ReSharper disable once TooManyArguments + public static void SetScanOutCompositionParameter( + uint displayId, + ScanOutCompositionParameter parameter, + ScanOutCompositionParameterValue parameterValue, + ref float container) + { + var status = DelegateFactory.GetDelegate()( + displayId, + parameter, + parameterValue, + ref container + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// + /// This API enables and sets up per-pixel intensity feature on the specified display. + /// + /// Combined physical display and GPU identifier of the display to apply the intensity control. + /// The intensity texture info. + /// Indicates whether the settings will be kept over a reboot. + public static void SetScanOutIntensity(uint displayId, IScanOutIntensity scanOutIntensity, out bool isSticky) + { + Status status; + int isStickyInt; + + if (scanOutIntensity == null) + { + status = DelegateFactory.GetDelegate()( + displayId, + ValueTypeReference.Null, + out isStickyInt + ); + } + else + { + using (var scanOutWarpingReference = + ValueTypeReference.FromValueType(scanOutIntensity, scanOutIntensity.GetType())) + { + status = DelegateFactory.GetDelegate()( + displayId, + scanOutWarpingReference, + out isStickyInt + ); + } + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + isSticky = isStickyInt > 0; + } + + /// + /// This API enables and sets up the warping feature on the specified display. + /// + /// Combined physical display and GPU identifier of the display to apply the intensity control. + /// The warping data info. + /// The maximum number of vertices. + /// Indicates whether the settings will be kept over a reboot. + // ReSharper disable once TooManyArguments + public static void SetScanOutWarping( + uint displayId, + ScanOutWarpingV1? scanOutWarping, + ref int maximumNumberOfVertices, + out bool isSticky) + { + Status status; + int isStickyInt; + + if (scanOutWarping == null || maximumNumberOfVertices == 0) + { + maximumNumberOfVertices = 0; + status = DelegateFactory.GetDelegate()( + displayId, + ValueTypeReference.Null, + ref maximumNumberOfVertices, + out isStickyInt + ); + } + else + { + using (var scanOutWarpingReference = ValueTypeReference.FromValueType(scanOutWarping.Value)) + { + status = DelegateFactory.GetDelegate()( + displayId, + scanOutWarpingReference, + ref maximumNumberOfVertices, + out isStickyInt + ); + } + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + isSticky = isStickyInt > 0; + } + + /// + /// This API is used to set up a custom display without saving the configuration on multiple displays. + /// + /// A list of display ids with corresponding custom display instances. + public static void TryCustomDisplay(IDictionary displayIdCustomDisplayPairs) + { + if (displayIdCustomDisplayPairs.Count == 0) + { + return; + } + + using (var displayIdsReference = ValueTypeArray.FromArray(displayIdCustomDisplayPairs.Keys.ToArray())) + { + using (var customDisplaysReference = + ValueTypeArray.FromArray(displayIdCustomDisplayPairs.Values.ToArray())) + { + var status = DelegateFactory.GetDelegate()( + displayIdsReference, + (uint) displayIdCustomDisplayPairs.Count, + customDisplaysReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Exceptions/NVIDIAApiException.cs b/NvAPIWrapper/Native/Exceptions/NVIDIAApiException.cs new file mode 100644 index 0000000..a9a7a8d --- /dev/null +++ b/NvAPIWrapper/Native/Exceptions/NVIDIAApiException.cs @@ -0,0 +1,27 @@ +using System; +using NvAPIWrapper.Native.General; + +namespace NvAPIWrapper.Native.Exceptions +{ + /// + /// Represents errors that raised by NVIDIA Api + /// + public class NVIDIAApiException : Exception + { + internal NVIDIAApiException(Status status) + { + Status = status; + } + + /// + public override string Message + { + get => GeneralApi.GetErrorMessage(Status) ?? Status.ToString(); + } + + /// + /// Gets NVIDIA Api exception status code + /// + public Status Status { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Exceptions/NVIDIANotSupportedException.cs b/NvAPIWrapper/Native/Exceptions/NVIDIANotSupportedException.cs new file mode 100644 index 0000000..46bd62a --- /dev/null +++ b/NvAPIWrapper/Native/Exceptions/NVIDIANotSupportedException.cs @@ -0,0 +1,14 @@ +using System; + +namespace NvAPIWrapper.Native.Exceptions +{ + /// + /// Represents errors that raised by NvAPIWrapper + /// + public class NVIDIANotSupportedException : NotSupportedException + { + internal NVIDIANotSupportedException(string message) : base(message) + { + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/ClockLockMode.cs b/NvAPIWrapper/Native/GPU/ClockLockMode.cs new file mode 100644 index 0000000..fae99b5 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/ClockLockMode.cs @@ -0,0 +1,18 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Holds the possible clock lock modes + /// + public enum ClockLockMode : uint + { + /// + /// No clock lock + /// + None = 0, + + /// + /// Manual clock lock + /// + Manual = 3 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/ClockType.cs b/NvAPIWrapper/Native/GPU/ClockType.cs new file mode 100644 index 0000000..3bcee7e --- /dev/null +++ b/NvAPIWrapper/Native/GPU/ClockType.cs @@ -0,0 +1,23 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Clock types to request + /// + public enum ClockType : uint + { + /// + /// Current clock frequencies + /// + CurrentClock = 0, + + /// + /// Base clock frequencies + /// + BaseClock = 1, + + /// + /// Boost clock frequencies + /// + BoostClock = 2 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/ConnectedIdsFlag.cs b/NvAPIWrapper/Native/GPU/ConnectedIdsFlag.cs new file mode 100644 index 0000000..ae69370 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/ConnectedIdsFlag.cs @@ -0,0 +1,41 @@ +using System; + +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Flags used for retrieving a list of display identifications + /// + [Flags] + public enum ConnectedIdsFlag : uint + { + /// + /// No specific flag + /// + None = 0, + + /// + /// Get un-cached connected devices + /// + UnCached = 1, + + /// + /// Get devices such that those can be selected in an SLI configuration + /// + SLI = 2, + + /// + /// Get devices such that to reflect the Lid State + /// + LidState = 4, + + /// + /// Get devices that includes the fake connected monitors + /// + Fake = 8, + + /// + /// Excludes devices that are part of the multi stream topology + /// + ExcludeList = 16 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/ConnectorType.cs b/NvAPIWrapper/Native/GPU/ConnectorType.cs new file mode 100644 index 0000000..4e46a21 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/ConnectorType.cs @@ -0,0 +1,165 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Possible display connectors + /// + public enum ConnectorType : uint + { + /// + /// VGA 15 Pin connector + /// + VGA15Pin = 0x00000000, + + /// + /// TV Composite + /// + // ReSharper disable once InconsistentNaming + TV_Composite = 0x00000010, + + /// + /// TV SVideo + /// + // ReSharper disable once InconsistentNaming + TV_SVideo = 0x00000011, + + /// + /// TV HDTV Component + /// + // ReSharper disable once InconsistentNaming + TV_HDTVComponent = 0x00000013, + + /// + /// TV SCART + /// + // ReSharper disable once InconsistentNaming + TV_SCART = 0x00000014, + + /// + /// TV Composite through SCART on EIAJ4120 + /// + // ReSharper disable once InconsistentNaming + TV_CompositeSCARTOnEIAJ4120 = 0x00000016, + + /// + /// TV HDTV EIAJ4120 + /// + // ReSharper disable once InconsistentNaming + TV_HDTV_EIAJ4120 = 0x00000017, + + /// + /// HDTV YPbPr through VESA Plug On Display + /// + // ReSharper disable once InconsistentNaming + PC_POD_HDTV_YPbPr = 0x00000018, + + /// + /// SVideo through VESA Plug On Display + /// + // ReSharper disable once InconsistentNaming + PC_POD_SVideo = 0x00000019, + + /// + /// Composite through VESA Plug On Display + /// + // ReSharper disable once InconsistentNaming + PC_POD_Composite = 0x0000001A, + + /// + /// TV SVideo through DVI Integrated + /// + // ReSharper disable once InconsistentNaming + DVI_I_TV_SVideo = 0x00000020, + + /// + /// TV Composite through DVI Integrated + /// + // ReSharper disable once InconsistentNaming + DVI_I_TV_COMPOSITE = 0x00000021, + + /// + /// DVI Integrated + /// + // ReSharper disable once InconsistentNaming + DVI_I = 0x00000030, + + /// + /// DVI Digital + /// + // ReSharper disable once InconsistentNaming + DVI_D = 0x00000031, + + /// + /// Apple Display Connector + /// + ADC = 0x00000032, + + /// + /// DVI 1 through LFH + /// + // ReSharper disable once InconsistentNaming + LFH_DVI_I1 = 0x00000038, + + /// + /// DVI 2 through LFH + /// + // ReSharper disable once InconsistentNaming + LFH_DVI_I2 = 0x00000039, + + /// + /// SPWG pin-out connector + /// + SPWG = 0x00000040, + + /// + /// OEM connector + /// + OEM = 0x00000041, + + /// + /// External DisplayPort + /// + DisplayPortExternal = 0x00000046, + + /// + /// Internal DisplayPort + /// + DisplayPortInternal = 0x00000047, + + /// + /// External Mini DisplayPort + /// + DisplayPortMiniExternal = 0x00000048, + + /// + /// HDMI Analog + /// + // ReSharper disable once InconsistentNaming + HDMI_Analog = 0x00000061, + + /// + /// Mini HDMI + /// + // ReSharper disable once InconsistentNaming + HDMI_CMini = 0x00000063, + + /// + /// DisplayPort 1 through LFH + /// + LFHDisplayPort1 = 0x00000064, + + /// + /// DisplayPort 2 through LFH + /// + LFHDisplayPort2 = 0x00000065, + + /// + /// Virtual Wireless + /// + VirtualWFD = 0x00000070, + + /// + /// Unknown connector + /// + Unknown = 0xFFFFFFFF + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/CoolerControlMode.cs b/NvAPIWrapper/Native/GPU/CoolerControlMode.cs new file mode 100644 index 0000000..38c9425 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/CoolerControlMode.cs @@ -0,0 +1,23 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Holds possible cooler control modes + /// + public enum CoolerControlMode : uint + { + /// + /// No cooler control + /// + None = 0, + + /// + /// Toggle based cooler control mode + /// + Toggle, + + /// + /// Variable cooler control mode + /// + Variable + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/CoolerController.cs b/NvAPIWrapper/Native/GPU/CoolerController.cs new file mode 100644 index 0000000..9d625d9 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/CoolerController.cs @@ -0,0 +1,23 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Holds the list of possible cooler controllers + /// + public enum CoolerController : uint + { + /// + /// No cooler controller + /// + None = 0, + + /// + /// ADI cooler controller + /// + ADI, + + /// + /// Internal cooler controller + /// + Internal + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/CoolerPolicy.cs b/NvAPIWrapper/Native/GPU/CoolerPolicy.cs new file mode 100644 index 0000000..c7f6e76 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/CoolerPolicy.cs @@ -0,0 +1,41 @@ +using System; + +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Holds possible cooler policies + /// + [Flags] + public enum CoolerPolicy : uint + { + /// + /// No cooler policy + /// + None = 0, + + /// + /// Manual cooler control + /// + Manual = 0b1, + + /// + /// Performance optimized cooler policy + /// + Performance = 0b10, + + /// + /// Discrete temperature based cooler policy + /// + TemperatureDiscrete = 0b100, + + /// + /// Continues temperature based cooler policy + /// + TemperatureContinuous = 0b1000, + + /// + /// Silent cooler policy + /// + Silent = 0b10000 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/CoolerTarget.cs b/NvAPIWrapper/Native/GPU/CoolerTarget.cs new file mode 100644 index 0000000..f21cf1c --- /dev/null +++ b/NvAPIWrapper/Native/GPU/CoolerTarget.cs @@ -0,0 +1,36 @@ +using System; + +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Holds a list of possible cooler targets + /// + [Flags] + public enum CoolerTarget : uint + { + /// + /// No cooler target + /// + None = 0, + + /// + /// Cooler targets GPU + /// + GPU = 0b1, + + /// + /// Cooler targets memory + /// + Memory = 0b10, + + /// + /// Cooler targets power supply + /// + PowerSupply = 0b100, + + /// + /// Cooler targets GPU, memory and power supply + /// + All = GPU | Memory | PowerSupply + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/CoolerType.cs b/NvAPIWrapper/Native/GPU/CoolerType.cs new file mode 100644 index 0000000..edcd8fb --- /dev/null +++ b/NvAPIWrapper/Native/GPU/CoolerType.cs @@ -0,0 +1,28 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Holds a list of possible cooler types + /// + public enum CoolerType : uint + { + /// + /// No cooler type + /// + None, + + /// + /// Air cooling + /// + Fan, + + /// + /// Water cooling + /// + Water, + + /// + /// Liquid nitrogen cooling + /// + LiquidNitrogen + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/ECCConfiguration.cs b/NvAPIWrapper/Native/GPU/ECCConfiguration.cs new file mode 100644 index 0000000..5b7f02e --- /dev/null +++ b/NvAPIWrapper/Native/GPU/ECCConfiguration.cs @@ -0,0 +1,23 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Holds a list of possible ECC memory configurations + /// + public enum ECCConfiguration : uint + { + /// + /// ECC memory configurations are not supported + /// + NotSupported = 0, + + /// + /// Changes require a POST to take effect + /// + Deferred, + + /// + /// Changes can optionally be made to take effect immediately + /// + Immediate + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/FanCoolersControlMode.cs b/NvAPIWrapper/Native/GPU/FanCoolersControlMode.cs new file mode 100644 index 0000000..da4fcc3 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/FanCoolersControlMode.cs @@ -0,0 +1,21 @@ +using System; + +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Holds possible fan cooler control modes + /// + [Flags] + public enum FanCoolersControlMode : uint + { + /// + /// Automatic fan cooler control + /// + Auto = 0, + + /// + /// Manual fan cooler control + /// + Manual = 0b1, + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/GPUBusType.cs b/NvAPIWrapper/Native/GPU/GPUBusType.cs new file mode 100644 index 0000000..d33397e --- /dev/null +++ b/NvAPIWrapper/Native/GPU/GPUBusType.cs @@ -0,0 +1,38 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Associated GPU bus types + /// + public enum GPUBusType + { + /// + /// Bus type is undefined + /// + Undefined = 0, + + /// + /// PCI Bus + /// + PCI = 1, + + /// + /// AGP Bus + /// + AGP = 2, + + /// + /// PCIExpress Bus + /// + PCIExpress = 3, + + /// + /// FPCI Bus + /// + FPCI = 4, + + /// + /// AXI Bus + /// + AXI = 5 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/GPUFoundry.cs b/NvAPIWrapper/Native/GPU/GPUFoundry.cs new file mode 100644 index 0000000..26e1aaf --- /dev/null +++ b/NvAPIWrapper/Native/GPU/GPUFoundry.cs @@ -0,0 +1,46 @@ +using System.Diagnostics.CodeAnalysis; + +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Holds a list of known GPU foundries + /// + [SuppressMessage("ReSharper", "IdentifierTypo")] + public enum GPUFoundry : uint + { + /// + /// Unknown foundry + /// + Unknown, + + /// + /// Taiwan Semiconductor Manufacturing Company Limited + /// + TSMC, + + /// + /// United Microelectronics + /// + UMC, + + /// + /// International Business Machines Corporation + /// + IBM, + + /// + /// Semiconductor Manufacturing International Corporation + /// + SMIC, + + /// + /// Chartered Semiconductor Manufacturing + /// + CSM, + + /// + /// Toshiba Corporation + /// + Toshiba + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/GPUMemoryMaker.cs b/NvAPIWrapper/Native/GPU/GPUMemoryMaker.cs new file mode 100644 index 0000000..e938992 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/GPUMemoryMaker.cs @@ -0,0 +1,67 @@ +using System.Diagnostics.CodeAnalysis; + +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Holds a list of known memory makers + /// + [SuppressMessage("ReSharper", "IdentifierTypo")] + // ReSharper disable CommentTypo + public enum GPUMemoryMaker : uint + { + /// + /// Unknown memory maker + /// + Unknown = 0, + + /// + /// Samsung Group + /// + Samsung, + + /// + /// Qimonda AG + /// + Qimonda, + + /// + /// Elpida Memory, Inc. + /// + Elpida, + + /// + /// Etron Technology, Inc. + /// + Etron, + + /// + /// Nanya Technology Corporation + /// + Nanya, + + /// + /// SK Hynix + /// + Hynix, + + /// + /// Mosel Vitelic Corporation + /// + Mosel, + + /// + /// Winbond Electronics Corporation + /// + Winbond, + + /// + /// Elite Semiconductor Memory Technology Inc. + /// + Elite, + + /// + /// Micron Technology, Inc. + /// + Micron + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/GPUMemoryType.cs b/NvAPIWrapper/Native/GPU/GPUMemoryType.cs new file mode 100644 index 0000000..4d74f45 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/GPUMemoryType.cs @@ -0,0 +1,68 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Holds a list of known memory types + /// + public enum GPUMemoryType : uint + { + /// + /// Unknown memory type + /// + Unknown = 0, + + /// + /// Synchronous dynamic random-access memory + /// + SDRAM, + + /// + /// Double Data Rate Synchronous Dynamic Random-Access Memory + /// + DDR1, + + /// + /// Double Data Rate 2 Synchronous Dynamic Random-Access Memory + /// + DDR2, + + /// + /// Graphics Double Data Rate 2 Synchronous Dynamic Random-Access Memory + /// + GDDR2, + + /// + /// Graphics Double Data Rate 3 Synchronous Dynamic Random-Access Memory + /// + GDDR3, + + /// + /// Graphics Double Data Rate 4 Synchronous Dynamic Random-Access Memory + /// + GDDR4, + + /// + /// Double Data Rate 3 Synchronous Dynamic Random-Access Memory + /// + DDR3, + + /// + /// Graphics Double Data Rate 5 Synchronous Dynamic Random-Access Memory + /// + GDDR5, + + /// + /// Lowe Power Double Data Rate 2 Synchronous Dynamic Random-Access Memory + /// + LPDDR2, + + /// + /// Graphics Double Data Rate 5X Synchronous Dynamic Random-Access Memory + /// + GDDR5X, + LPDDR3, + LPDDR4, + LPDDR5, + GDDR6, + GDDR6X + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/GPUType.cs b/NvAPIWrapper/Native/GPU/GPUType.cs new file mode 100644 index 0000000..090f48d --- /dev/null +++ b/NvAPIWrapper/Native/GPU/GPUType.cs @@ -0,0 +1,23 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Possible GPU types + /// + public enum GPUType + { + /// + /// Unknown GPU type + /// + Unknown = 0, + + /// + /// Integrated GPU + /// + Integrated = 1, + + /// + /// Discrete GPU + /// + Discrete = 2 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/GetPerformanceStatesInfoFlags.cs b/NvAPIWrapper/Native/GPU/GetPerformanceStatesInfoFlags.cs new file mode 100644 index 0000000..94ecf9b --- /dev/null +++ b/NvAPIWrapper/Native/GPU/GetPerformanceStatesInfoFlags.cs @@ -0,0 +1,31 @@ +using System; + +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Contains the flags used by the GPUApi.GetPerformanceStatesInfo() function + /// + [Flags] + public enum GetPerformanceStatesInfoFlags + { + /// + /// Current performance states settings + /// + Current = 0, + + /// + /// Default performance states settings + /// + Default = 1, + + /// + /// Maximum range of performance states values + /// + Maximum = 2, + + /// + /// Minimum range of performance states values + /// + Minimum = 4 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/I2CSpeed.cs b/NvAPIWrapper/Native/GPU/I2CSpeed.cs new file mode 100644 index 0000000..0236941 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/I2CSpeed.cs @@ -0,0 +1,43 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Contains possible I2C bus speed values in kHz + /// + public enum I2CSpeed : uint + { + /// + /// Current / Default frequency setting + /// + Default, + + /// + /// 3kHz + /// + I2C3KHz, + + /// + /// 10kHz + /// + I2C10KHz, + + /// + /// 33kHz + /// + I2C33KHz, + + /// + /// 100kHz + /// + I2C100KHz, + + /// + /// 200kHz + /// + I2C200KHz, + + /// + /// 400kHz + /// + I2C400KHz + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/IlluminationAttribute.cs b/NvAPIWrapper/Native/GPU/IlluminationAttribute.cs new file mode 100644 index 0000000..d2e1e6c --- /dev/null +++ b/NvAPIWrapper/Native/GPU/IlluminationAttribute.cs @@ -0,0 +1,18 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Contains a list of valid illumination attributes + /// + public enum IlluminationAttribute : uint + { + /// + /// Logo brightness control + /// + LogoBrightness = 0, + + /// + /// SLI bridge brightness control + /// + SLIBrightness + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/IlluminationDeviceType.cs b/NvAPIWrapper/Native/GPU/IlluminationDeviceType.cs new file mode 100644 index 0000000..ec277ca --- /dev/null +++ b/NvAPIWrapper/Native/GPU/IlluminationDeviceType.cs @@ -0,0 +1,18 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Contains a list of valid illumination zone device types + /// + public enum IlluminationDeviceType : uint + { + /// + /// Invalid device type + /// + Invalid = 0, + + /// + /// MCUV10 device + /// + MCUV10 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/IlluminationPiecewiseLinearCycleType.cs b/NvAPIWrapper/Native/GPU/IlluminationPiecewiseLinearCycleType.cs new file mode 100644 index 0000000..79bbb58 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/IlluminationPiecewiseLinearCycleType.cs @@ -0,0 +1,28 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Contains a list of valid cycle types for the piecewise linear control mode + /// + public enum IlluminationPiecewiseLinearCycleType : uint + { + /// + /// Half half cycle mode + /// + HalfHalf = 0, + + /// + /// Full half cycle mode + /// + FullHalf, + + /// + /// Full repeat cycle mode + /// + FullRepeat, + + /// + /// Invalid cycle mode + /// + Invalid = 0xFF + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/IlluminationZoneControlMode.cs b/NvAPIWrapper/Native/GPU/IlluminationZoneControlMode.cs new file mode 100644 index 0000000..187f623 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/IlluminationZoneControlMode.cs @@ -0,0 +1,26 @@ +using System; + +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Contains a list of available illumination zone control modes + /// + [Flags] + public enum IlluminationZoneControlMode : uint + { + /// + /// manual RGB control + /// + ManualRGB = 0, + + /// + /// Piecewise linear RGB control + /// + PiecewiseLinearRGB, + + /// + /// Invalid control mode + /// + Invalid = 0xFF + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/IlluminationZoneControlValuesType.cs b/NvAPIWrapper/Native/GPU/IlluminationZoneControlValuesType.cs new file mode 100644 index 0000000..4bcf0c4 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/IlluminationZoneControlValuesType.cs @@ -0,0 +1,18 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Contains a list of valid zone control value types to set or to retrieve + /// + public enum IlluminationZoneControlValuesType + { + /// + /// Currently active values + /// + CurrentlyActive = 0, + + /// + /// Default values + /// + Default = 1 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/IlluminationZoneLocation.cs b/NvAPIWrapper/Native/GPU/IlluminationZoneLocation.cs new file mode 100644 index 0000000..c7f0cfd --- /dev/null +++ b/NvAPIWrapper/Native/GPU/IlluminationZoneLocation.cs @@ -0,0 +1,23 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Contains a list of possible illumination zone locations + /// + public enum IlluminationZoneLocation : uint + { + /// + /// Located on the top of GPU + /// + GPUTop = 0x00, + + /// + /// Located on the top of SLI bridge + /// + SLITop = 0x20, + + /// + /// Invalid zone location + /// + Invalid = 0xFFFFFFFF + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/IlluminationZoneType.cs b/NvAPIWrapper/Native/GPU/IlluminationZoneType.cs new file mode 100644 index 0000000..c524b1e --- /dev/null +++ b/NvAPIWrapper/Native/GPU/IlluminationZoneType.cs @@ -0,0 +1,23 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Contains a list of valid illumination zone types + /// + public enum IlluminationZoneType : uint + { + /// + /// Invalid zone type + /// + Invalid = 0, + + /// + /// RGB zone + /// + RGB, + + /// + /// Fixed color zone + /// + FixedColor + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/MonitorConnectionType.cs b/NvAPIWrapper/Native/GPU/MonitorConnectionType.cs new file mode 100644 index 0000000..567dfae --- /dev/null +++ b/NvAPIWrapper/Native/GPU/MonitorConnectionType.cs @@ -0,0 +1,58 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Monitor connection types. This is reserved for future use and clients should not rely on this information. + /// + public enum MonitorConnectionType + { + /// + /// Monitor not yet initialized + /// + Uninitialized = 0, + + /// + /// Connected through a VGA compatible connector + /// + VGA, + + /// + /// Connected through a Component compatible connector + /// + Component, + + /// + /// Connected through a SVideo compatible connector + /// + SVideo, + + /// + /// Connected through a HDMI compatible connector + /// + HDMI, + + /// + /// Connected through a LVDS compatible connector + /// + DVI, + + /// + /// Connected through a DisplayPort compatible connector + /// + LVDS, + + /// + /// Connected through a DisplayPort compatible connector + /// + DisplayPort, + + /// + /// Connected through a Composite compatible connector + /// + Composite, + + /// + /// Connection type unknown + /// + Unknown = -1 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/OutputId.cs b/NvAPIWrapper/Native/GPU/OutputId.cs new file mode 100644 index 0000000..32fdda1 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/OutputId.cs @@ -0,0 +1,179 @@ +using System; + +namespace NvAPIWrapper.Native.GPU +{ + /// + /// GPU output IDs are identifiers for the GPU outputs that drive display devices. The GPU output might or might not be + /// connected to a display, or be active. Each output is identified by a bit setting within a 32-bit unsigned integer. + /// A GPU output mask consists of a 32-bit integer with several bits set, identifying more than one output from the + /// same physical GPU. + /// + [Flags] + public enum OutputId : uint + { + /// + /// Invalid output if + /// + Invalid = 0, + + /// + /// Represents Output 1 + /// + Output1 = 1U, + + /// + /// Represents Output 2 + /// + Output2 = 1u << 1, + + /// + /// Represents Output 3 + /// + Output3 = 1u << 2, + + /// + /// Represents Output 4 + /// + Output4 = 1u << 3, + + /// + /// Represents Output 5 + /// + Output5 = 1u << 4, + + /// + /// Represents Output 6 + /// + Output6 = 1u << 5, + + /// + /// Represents Output 7 + /// + Output7 = 1u << 6, + + /// + /// Represents Output 8 + /// + Output8 = 1u << 7, + + /// + /// Represents Output 9 + /// + Output9 = 1u << 8, + + /// + /// Represents Output 10 + /// + Output10 = 1u << 9, + + /// + /// Represents Output 11 + /// + Output11 = 1u << 10, + + /// + /// Represents Output 12 + /// + Output12 = 1u << 11, + + /// + /// Represents Output 13 + /// + Output13 = 1u << 12, + + /// + /// Represents Output 14 + /// + Output14 = 1u << 13, + + /// + /// Represents Output 15 + /// + Output15 = 1u << 14, + + /// + /// Represents Output 16 + /// + Output16 = 1u << 15, + + /// + /// Represents Output 17 + /// + Output17 = 1u << 16, + + /// + /// Represents Output 18 + /// + Output18 = 1u << 17, + + /// + /// Represents Output 19 + /// + Output19 = 1u << 18, + + /// + /// Represents Output 20 + /// + Output20 = 1u << 19, + + /// + /// Represents Output 21 + /// + Output21 = 1u << 20, + + /// + /// Represents Output 22 + /// + Output22 = 1u << 21, + + /// + /// Represents Output 23 + /// + Output23 = 1u << 22, + + /// + /// Represents Output 24 + /// + Output24 = 1u << 23, + + /// + /// Represents Output 25 + /// + Output25 = 1u << 24, + + /// + /// Represents Output 26 + /// + Output26 = 1u << 25, + + /// + /// Represents Output 27 + /// + Output27 = 1u << 26, + + /// + /// Represents Output 28 + /// + Output28 = 1u << 27, + + /// + /// Represents Output 29 + /// + Output29 = 1u << 28, + + /// + /// Represents Output 30 + /// + Output30 = 1u << 29, + + /// + /// Represents Output 31 + /// + Output31 = 1u << 30, + + /// + /// Represents Output 32 + /// + Output32 = 1u << 31 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/OutputType.cs b/NvAPIWrapper/Native/GPU/OutputType.cs new file mode 100644 index 0000000..571ff3c --- /dev/null +++ b/NvAPIWrapper/Native/GPU/OutputType.cs @@ -0,0 +1,28 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Connected output device types + /// + public enum OutputType : uint + { + /// + /// Unknown display device + /// + Unknown = 0, + + /// + /// CRT display device + /// + CRT = 1, + + /// + /// Digital Flat Panel display device + /// + DFP = 2, + + /// + /// TV display device + /// + TV = 3 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/PCIeGeneration.cs b/NvAPIWrapper/Native/GPU/PCIeGeneration.cs new file mode 100644 index 0000000..e66cfe6 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/PCIeGeneration.cs @@ -0,0 +1,28 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Holds a list of known PCI-e generations and versions + /// + public enum PCIeGeneration : uint + { + /// + /// PCI-e 1.0 + /// + PCIe1 = 0, + + /// + /// PCI-e 1.1 + /// + PCIe1Minor1, + + /// + /// PCI-e 2.0 + /// + PCIe2, + + /// + /// PCI-e 3.0 + /// + PCIe3 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/PerformanceDecreaseReason.cs b/NvAPIWrapper/Native/GPU/PerformanceDecreaseReason.cs new file mode 100644 index 0000000..9b8f8fe --- /dev/null +++ b/NvAPIWrapper/Native/GPU/PerformanceDecreaseReason.cs @@ -0,0 +1,44 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Holds a list possible reasons for performance decrease + /// + public enum PerformanceDecreaseReason : uint + { + /// + /// No performance decrease + /// + None = 0, + + /// + /// Thermal protection performance decrease + /// + ThermalProtection = 0x00000001, + + /// + /// Power control performance decrease + /// + PowerControl = 0x00000002, + + /// + /// AC-BATT event performance decrease + /// + // ReSharper disable once InconsistentNaming + AC_BATT = 0x00000004, + + /// + /// API triggered performance decrease + /// + ApiTriggered = 0x00000008, + + /// + /// Insufficient performance decrease (Power Connector Missing) + /// + InsufficientPower = 0x00000010, + + /// + /// Unknown + /// + Unknown = 0x80000000 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/PerformanceLimit.cs b/NvAPIWrapper/Native/GPU/PerformanceLimit.cs new file mode 100644 index 0000000..3451267 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/PerformanceLimit.cs @@ -0,0 +1,41 @@ +using System; + +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Holds a list of known performance limitations + /// + [Flags] + public enum PerformanceLimit : uint + { + /// + /// No performance limitation + /// + None = 0, + + /// + /// Limited by power usage + /// + PowerLimit = 0b1, + + /// + /// Limited by temperature + /// + TemperatureLimit = 0b10, + + /// + /// Limited by voltage + /// + VoltageLimit = 0b100, + + /// + /// Unknown limitation + /// + Unknown8 = 0b1000, + + /// + /// Limited due to no load + /// + NoLoadLimit = 0b10000 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/PerformanceStateId.cs b/NvAPIWrapper/Native/GPU/PerformanceStateId.cs new file mode 100644 index 0000000..de13baa --- /dev/null +++ b/NvAPIWrapper/Native/GPU/PerformanceStateId.cs @@ -0,0 +1,105 @@ +using NvAPIWrapper.Native.GPU.Structures; + +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Contains the list of valid performance state identifications + /// + public enum PerformanceStateId : uint + { + /// + /// Performance state 0 (Maximum 3D Quality) + /// + P0_3DPerformance = 0, + + /// + /// Performance state 1 (Maximum 3D Quality) + /// + P1_3DPerformance, + + /// + /// Performance state 2 (Balanced Performance) + /// + // ReSharper disable once InconsistentNaming + P2_Balanced, + + /// + /// Performance state 3 (Balanced Performance) + /// + // ReSharper disable once InconsistentNaming + P3_Balanced, + + /// + /// Performance state 4 + /// + P4, + + /// + /// Performance state 5 + /// + P5, + + /// + /// Performance state 6 + /// + P6, + + /// + /// Performance state 7 + /// + P7, + + /// + /// Performance state 8 (HD Video Playback) + /// + // ReSharper disable once InconsistentNaming + P8_HDVideoPlayback, + + /// + /// Performance state 9 + /// + P9, + + /// + /// Performance state 10 (DVD Video Playback) + /// + // ReSharper disable once InconsistentNaming + P10_DVDPlayback, + + /// + /// Performance state 11 + /// + P11, + + /// + /// Performance state 12 (Idle - PowerSaving mode) + /// + // ReSharper disable once InconsistentNaming + P12_Idle, + + /// + /// Performance state 13 + /// + P13, + + /// + /// Performance state 14 + /// + P14, + + /// + /// Performance state 15 + /// + P15, + + /// + /// Undefined performance state + /// + Undefined = PerformanceStatesInfoV1.MaxPerformanceStates, + + /// + /// All performance states + /// + All + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/PerformanceStates20ClockType.cs b/NvAPIWrapper/Native/GPU/PerformanceStates20ClockType.cs new file mode 100644 index 0000000..7ea986a --- /dev/null +++ b/NvAPIWrapper/Native/GPU/PerformanceStates20ClockType.cs @@ -0,0 +1,18 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Contains valid clock frequency types + /// + public enum PerformanceStates20ClockType + { + /// + /// Single frequency clock + /// + Single = 0, + + /// + /// Variable frequency clock + /// + Range + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/PerformanceVoltageDomain.cs b/NvAPIWrapper/Native/GPU/PerformanceVoltageDomain.cs new file mode 100644 index 0000000..1a6673c --- /dev/null +++ b/NvAPIWrapper/Native/GPU/PerformanceVoltageDomain.cs @@ -0,0 +1,20 @@ +using NvAPIWrapper.Native.GPU.Structures; + +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Contains the list of possible voltage domains + /// + public enum PerformanceVoltageDomain : uint + { + /// + /// GPU Core + /// + Core = 0, + + /// + /// Undefined voltage domain + /// + Undefined = PerformanceStatesInfoV2.MaxPerformanceStateVoltages + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/PowerTopologyDomain.cs b/NvAPIWrapper/Native/GPU/PowerTopologyDomain.cs new file mode 100644 index 0000000..6e96a22 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/PowerTopologyDomain.cs @@ -0,0 +1,18 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Holds a list of known power topology domain + /// + public enum PowerTopologyDomain : uint + { + /// + /// The GPU + /// + GPU = 0, + + /// + /// The GPU board + /// + Board + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/PublicClockDomain.cs b/NvAPIWrapper/Native/GPU/PublicClockDomain.cs new file mode 100644 index 0000000..f97de00 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/PublicClockDomain.cs @@ -0,0 +1,35 @@ +using NvAPIWrapper.Native.GPU.Structures; + +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Contains the list of clocks available to public + /// + public enum PublicClockDomain + { + /// + /// Undefined + /// + Undefined = ClockFrequenciesV1.MaxClocksPerGPU, + + /// + /// 3D graphics clock + /// + Graphics = 0, + + /// + /// Memory clock + /// + Memory = 4, + + /// + /// Processor clock + /// + Processor = 7, + + /// + /// Video decoding clock + /// + Video = 8 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/BoardInfo.cs b/NvAPIWrapper/Native/GPU/Structures/BoardInfo.cs new file mode 100644 index 0000000..b30b2a2 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/BoardInfo.cs @@ -0,0 +1,82 @@ +using System; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds the board information (a unique GPU Board Serial Number) stored in the InfoROM + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct BoardInfo : IInitializable, IEquatable + { + internal StructureVersion _Version; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + internal byte[] _SerialNumber; + + /// + /// Board Serial Number + /// + public byte[] SerialNumber + { + get => _SerialNumber; + } + + /// + public bool Equals(BoardInfo other) + { + return _SerialNumber.SequenceEqual(other._SerialNumber); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is BoardInfo info && Equals(info); + } + + /// + public override int GetHashCode() + { + // ReSharper disable once NonReadonlyMemberInGetHashCode + return _SerialNumber?.GetHashCode() ?? 0; + } + + /// + public override string ToString() + { + return SerialNumber == null ? "Unknown" : "Serial " + BitConverter.ToString(SerialNumber); + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(BoardInfo left, BoardInfo right) + { + return left.Equals(right); + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(BoardInfo left, BoardInfo right) + { + return !left.Equals(right); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/ClockDomainInfo.cs b/NvAPIWrapper/Native/GPU/Structures/ClockDomainInfo.cs new file mode 100644 index 0000000..8a40d73 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/ClockDomainInfo.cs @@ -0,0 +1,37 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information about the clock frequency of an specific clock domain + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct ClockDomainInfo + { + internal readonly uint _IsPresent; + internal readonly uint _Frequency; + + /// + /// Gets a boolean value that indicates if this clock domain is present on this GPU and with the requested clock type. + /// + public bool IsPresent + { + get => _IsPresent.GetBit(0); + } + + /// + /// Gets the clock frequency in kHz + /// + public uint Frequency + { + get => _Frequency; + } + + /// + public override string ToString() + { + return IsPresent ? $"{_Frequency:N0} kHz" : "N/A"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/ClockFrequenciesV1.cs b/NvAPIWrapper/Native/GPU/Structures/ClockFrequenciesV1.cs new file mode 100644 index 0000000..c8abe0c --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/ClockFrequenciesV1.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds clock frequencies currently associated with a physical GPU + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct ClockFrequenciesV1 : IInitializable, IClockFrequencies + { + internal const int MaxClocksPerGPU = 32; + + internal StructureVersion _Version; + internal readonly uint _Reserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxClocksPerGPU)] + internal ClockDomainInfo[] _Clocks; + + /// + public IReadOnlyDictionary Clocks + { + get => _Clocks + .Select((value, index) => new {index, value}) + .Where(arg => Enum.IsDefined(typeof(PublicClockDomain), arg.index)) + .ToDictionary(arg => (PublicClockDomain) arg.index, arg => arg.value); + } + + /// + public ClockType ClockType + { + get => ClockType.CurrentClock; + } + + /// + public ClockDomainInfo GraphicsClock + { + get => _Clocks[(int) PublicClockDomain.Graphics]; + } + + /// + public ClockDomainInfo MemoryClock + { + get => _Clocks[(int) PublicClockDomain.Memory]; + } + + /// + public ClockDomainInfo VideoDecodingClock + { + get => _Clocks[(int) PublicClockDomain.Video]; + } + + /// + public ClockDomainInfo ProcessorClock + { + get => _Clocks[(int) PublicClockDomain.Processor]; + } + + /// + public override string ToString() + { + return + $"[{ClockType}] 3D Graphics = {GraphicsClock} - Memory = {MemoryClock} - Video Decoding = {VideoDecodingClock} - Processor = {ProcessorClock}"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/ClockFrequenciesV2.cs b/NvAPIWrapper/Native/GPU/Structures/ClockFrequenciesV2.cs new file mode 100644 index 0000000..f56c5f8 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/ClockFrequenciesV2.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds clock frequencies associated with a physical GPU and an specified clock type + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + public struct ClockFrequenciesV2 : IInitializable, IClockFrequencies + { + internal const int MaxClocksPerGpu = 32; + + internal StructureVersion _Version; + internal readonly uint _ClockTypeAndReserve; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxClocksPerGpu)] + internal ClockDomainInfo[] _Clocks; + + /// + /// Creates a new ClockFrequenciesV2 + /// + /// The type of the clock frequency being requested + public ClockFrequenciesV2(ClockType clockType = ClockType.CurrentClock) + { + this = typeof(ClockFrequenciesV2).Instantiate(); + _ClockTypeAndReserve = 0u.SetBits(0, 2, (uint) clockType); + } + + /// + public IReadOnlyDictionary Clocks + { + get => _Clocks + .Select((value, index) => new {index, value}) + .Where(arg => Enum.IsDefined(typeof(PublicClockDomain), arg.index)) + .ToDictionary(arg => (PublicClockDomain) arg.index, arg => arg.value); + } + + /// + public ClockType ClockType + { + get => (ClockType) _ClockTypeAndReserve.GetBits(0, 2); + } + + /// + public ClockDomainInfo GraphicsClock + { + get => _Clocks[(int) PublicClockDomain.Graphics]; + } + + /// + public ClockDomainInfo MemoryClock + { + get => _Clocks[(int) PublicClockDomain.Memory]; + } + + /// + public ClockDomainInfo VideoDecodingClock + { + get => _Clocks[(int) PublicClockDomain.Video]; + } + + /// + public ClockDomainInfo ProcessorClock + { + get => _Clocks[(int) PublicClockDomain.Processor]; + } + + /// + public override string ToString() + { + return + $"[{ClockType}] 3D Graphics = {GraphicsClock} - Memory = {MemoryClock} - Video Decoding = {VideoDecodingClock} - Processor = {ProcessorClock}"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/ClockFrequenciesV3.cs b/NvAPIWrapper/Native/GPU/Structures/ClockFrequenciesV3.cs new file mode 100644 index 0000000..2f7c638 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/ClockFrequenciesV3.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds clock frequencies associated with a physical GPU and an specified clock type + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(3)] + public struct ClockFrequenciesV3 : IInitializable, IClockFrequencies + { + internal const int MaxClocksPerGpu = 32; + + internal StructureVersion _Version; + internal readonly uint _ClockTypeAndReserve; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxClocksPerGpu)] + internal ClockDomainInfo[] _Clocks; + + /// + /// Creates a new ClockFrequenciesV3 + /// + /// The type of the clock frequency being requested + public ClockFrequenciesV3(ClockType clockType = ClockType.CurrentClock) + { + this = typeof(ClockFrequenciesV3).Instantiate(); + _ClockTypeAndReserve = 0u.SetBits(0, 2, (uint) clockType); + } + + /// + public IReadOnlyDictionary Clocks + { + get => _Clocks + .Select((value, index) => new {index, value}) + .Where(arg => Enum.IsDefined(typeof(PublicClockDomain), arg.index)) + .ToDictionary(arg => (PublicClockDomain) arg.index, arg => arg.value); + } + + /// + /// Gets the type of clock frequencies provided with this object + /// + public ClockType ClockType + { + get => (ClockType) _ClockTypeAndReserve.GetBits(0, 2); + } + + /// + public ClockDomainInfo GraphicsClock + { + get => _Clocks[(int) PublicClockDomain.Graphics]; + } + + /// + public ClockDomainInfo MemoryClock + { + get => _Clocks[(int) PublicClockDomain.Memory]; + } + + /// + public ClockDomainInfo VideoDecodingClock + { + get => _Clocks[(int) PublicClockDomain.Video]; + } + + /// + public ClockDomainInfo ProcessorClock + { + get => _Clocks[(int) PublicClockDomain.Processor]; + } + + /// + public override string ToString() + { + return + $"[{ClockType}] 3D Graphics = {GraphicsClock} - Memory = {MemoryClock} - Video Decoding = {VideoDecodingClock} - Processor = {ProcessorClock}"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/DisplayDriverMemoryInfoV1.cs b/NvAPIWrapper/Native/GPU/Structures/DisplayDriverMemoryInfoV1.cs new file mode 100644 index 0000000..8d1bc61 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/DisplayDriverMemoryInfoV1.cs @@ -0,0 +1,58 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information about the system's display driver memory. + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct DisplayDriverMemoryInfoV1 : IInitializable, IDisplayDriverMemoryInfo + { + internal StructureVersion _Version; + internal readonly uint _DedicatedVideoMemory; + internal readonly uint _AvailableDedicatedVideoMemory; + internal readonly uint _SystemVideoMemory; + internal readonly uint _SharedSystemMemory; + + /// + public uint DedicatedVideoMemoryInkB + { + get => _DedicatedVideoMemory; + } + + /// + public uint AvailableDedicatedVideoMemoryInkB + { + get => _AvailableDedicatedVideoMemory; + } + + /// + public uint SystemVideoMemoryInkB + { + get => _SystemVideoMemory; + } + + /// + public uint SharedSystemMemoryInkB + { + get => _SharedSystemMemory; + } + + /// + public uint CurrentAvailableDedicatedVideoMemoryInkB + { + get => _AvailableDedicatedVideoMemory; + } + + /// + public override string ToString() + { + return $"{AvailableDedicatedVideoMemoryInkB / 1024} MB / {DedicatedVideoMemoryInkB / 1024} MB"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/DisplayDriverMemoryInfoV2.cs b/NvAPIWrapper/Native/GPU/Structures/DisplayDriverMemoryInfoV2.cs new file mode 100644 index 0000000..c01cc58 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/DisplayDriverMemoryInfoV2.cs @@ -0,0 +1,60 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information about the system's display driver memory. + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + public struct DisplayDriverMemoryInfoV2 : IInitializable, IDisplayDriverMemoryInfo + { + internal StructureVersion _Version; + internal readonly uint _DedicatedVideoMemory; + internal readonly uint _AvailableDedicatedVideoMemory; + internal readonly uint _SystemVideoMemory; + internal readonly uint _SharedSystemMemory; + internal readonly uint _CurrentAvailableDedicatedVideoMemory; + + /// + public uint DedicatedVideoMemoryInkB + { + get => _DedicatedVideoMemory; + } + + /// + public uint AvailableDedicatedVideoMemoryInkB + { + get => _AvailableDedicatedVideoMemory; + } + + /// + public uint SystemVideoMemoryInkB + { + get => _SystemVideoMemory; + } + + /// + public uint SharedSystemMemoryInkB + { + get => _SharedSystemMemory; + } + + /// + public uint CurrentAvailableDedicatedVideoMemoryInkB + { + get => _CurrentAvailableDedicatedVideoMemory; + } + + /// + public override string ToString() + { + return + $"{AvailableDedicatedVideoMemoryInkB / 1024} MB ({CurrentAvailableDedicatedVideoMemoryInkB / 1024} MB) / {DedicatedVideoMemoryInkB / 1024} MB"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/DisplayDriverMemoryInfoV3.cs b/NvAPIWrapper/Native/GPU/Structures/DisplayDriverMemoryInfoV3.cs new file mode 100644 index 0000000..1d4f368 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/DisplayDriverMemoryInfoV3.cs @@ -0,0 +1,79 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information about the system's display driver memory. + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(3)] + public struct DisplayDriverMemoryInfoV3 : IInitializable, IDisplayDriverMemoryInfo + { + internal StructureVersion _Version; + internal readonly uint _DedicatedVideoMemory; + internal readonly uint _AvailableDedicatedVideoMemory; + internal readonly uint _SystemVideoMemory; + internal readonly uint _SharedSystemMemory; + internal readonly uint _CurrentAvailableDedicatedVideoMemory; + internal readonly uint _DedicatedVideoMemoryEvictionsSize; + internal readonly uint _DedicatedVideoMemoryEvictionCount; + + /// + public uint DedicatedVideoMemoryInkB + { + get => _DedicatedVideoMemory; + } + + /// + public uint AvailableDedicatedVideoMemoryInkB + { + get => _AvailableDedicatedVideoMemory; + } + + /// + public uint SystemVideoMemoryInkB + { + get => _SystemVideoMemory; + } + + /// + public uint SharedSystemMemoryInkB + { + get => _SharedSystemMemory; + } + + /// + public uint CurrentAvailableDedicatedVideoMemoryInkB + { + get => _CurrentAvailableDedicatedVideoMemory; + } + + /// + /// Size(in kb) of the total size of memory released as a result of the evictions. + /// + public uint DedicatedVideoMemoryEvictionsSize + { + get => _DedicatedVideoMemoryEvictionsSize; + } + + /// + /// Indicates the number of eviction events that caused an allocation to be removed from dedicated video memory to free + /// GPU video memory to make room for other allocations. + /// + public uint DedicatedVideoMemoryEvictionCount + { + get => _DedicatedVideoMemoryEvictionCount; + } + + /// + public override string ToString() + { + return + $"{AvailableDedicatedVideoMemoryInkB / 1024} MB ({CurrentAvailableDedicatedVideoMemoryInkB / 1024} MB) / {DedicatedVideoMemoryInkB / 1024} MB"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/DisplayIdsV2.cs b/NvAPIWrapper/Native/GPU/Structures/DisplayIdsV2.cs new file mode 100644 index 0000000..b1e5c00 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/DisplayIdsV2.cs @@ -0,0 +1,106 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Represents a display identification and its attributes + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(3)] + public struct DisplayIdsV2 : IInitializable, IDisplayIds, IEquatable + { + internal StructureVersion _Version; + internal readonly MonitorConnectionType _ConnectionType; + internal readonly uint _DisplayId; + internal readonly uint _RawReserved; + + /// + public uint DisplayId + { + get => _DisplayId; + } + + /// + public bool Equals(DisplayIdsV2 other) + { + return _DisplayId == other._DisplayId; + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is DisplayIdsV2 v2 && Equals(v2); + } + + /// + public override int GetHashCode() + { + return (int) _DisplayId; + } + + /// + public MonitorConnectionType ConnectionType + { + get => _ConnectionType; + } + + /// + public bool IsDynamic + { + get => _RawReserved.GetBit(0); + } + + /// + public bool IsMultiStreamRootNode + { + get => _RawReserved.GetBit(1); + } + + /// + public bool IsActive + { + get => _RawReserved.GetBit(2); + } + + /// + public bool IsCluster + { + get => _RawReserved.GetBit(3); + } + + /// + public bool IsOSVisible + { + get => _RawReserved.GetBit(4); + } + + /// + public bool IsWFD + { + get => _RawReserved.GetBit(5); + } + + /// + public bool IsConnected + { + get => _RawReserved.GetBit(6); + } + + /// + public bool IsPhysicallyConnected + { + get => _RawReserved.GetBit(17); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/DynamicPerformanceStatesInfoV1.cs b/NvAPIWrapper/Native/GPU/Structures/DynamicPerformanceStatesInfoV1.cs new file mode 100644 index 0000000..1c5fcd0 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/DynamicPerformanceStatesInfoV1.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information about the dynamic performance states (such as GPU utilization domain) + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct DynamicPerformanceStatesInfoV1 : IInitializable, IUtilizationStatus + { + internal const int MaxGpuUtilizations = 8; + + internal StructureVersion _Version; + internal readonly uint _Flags; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxGpuUtilizations)] + internal UtilizationDomainInfo[] _UtilizationDomain; + + /// + /// Gets a boolean value indicating if the dynamic performance state is enabled + /// + public bool IsDynamicPerformanceStatesEnabled + { + get => _Flags.GetBit(0); + } + + /// + public Dictionary Domains + { + get => _UtilizationDomain + .Select((value, index) => new {index, value}) + .Where(arg => Enum.IsDefined(typeof(UtilizationDomain), arg.index) && arg.value.IsPresent) + .ToDictionary(arg => (UtilizationDomain) arg.index, arg => arg.value as IUtilizationDomainInfo); + } + + /// + public IUtilizationDomainInfo GPU + { + get => _UtilizationDomain[(int) UtilizationDomain.GPU]; + } + + /// + public IUtilizationDomainInfo FrameBuffer + { + get => _UtilizationDomain[(int) UtilizationDomain.FrameBuffer]; + } + + /// + public IUtilizationDomainInfo VideoEngine + { + get => _UtilizationDomain[(int) UtilizationDomain.VideoEngine]; + } + + /// + public IUtilizationDomainInfo BusInterface + { + get => _UtilizationDomain[(int) UtilizationDomain.BusInterface]; + } + + /// + public override string ToString() + { + return $"GPU = {GPU} - " + + $"FrameBuffer = {FrameBuffer} - " + + $"VideoEngine = {VideoEngine} - " + + $"BusInterface = {BusInterface}"; + } + + /// + /// Holds information about a dynamic performance state utilization domain + /// + [StructLayout(LayoutKind.Sequential)] + public struct UtilizationDomainInfo : IUtilizationDomainInfo + { + internal readonly uint _IsPresent; + internal readonly uint _Percentage; + + /// + public bool IsPresent + { + get => _IsPresent.GetBit(0); + } + + /// + public uint Percentage + { + get => _Percentage; + } + + /// + public override string ToString() + { + return IsPresent ? $"{Percentage}%" : "N/A"; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/ECCConfigurationInfoV1.cs b/NvAPIWrapper/Native/GPU/Structures/ECCConfigurationInfoV1.cs new file mode 100644 index 0000000..b45142d --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/ECCConfigurationInfoV1.cs @@ -0,0 +1,35 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information about the ECC memory configurations + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct ECCConfigurationInfoV1 : IInitializable + { + internal StructureVersion _Version; + internal uint _Flags; + + /// + /// Gets a boolean value indicating if the ECC memory is enabled + /// + public bool IsEnabled + { + get => _Flags.GetBit(0); + } + + /// + /// Gets a boolean value indicating if the ECC memory is enabled by default + /// + public bool IsEnabledByDefault + { + get => _Flags.GetBit(1); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/ECCErrorInfoV1.cs b/NvAPIWrapper/Native/GPU/Structures/ECCErrorInfoV1.cs new file mode 100644 index 0000000..1f7980e --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/ECCErrorInfoV1.cs @@ -0,0 +1,61 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding the ECC Memory errors + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct ECCErrorInfoV1 : IInitializable + { + internal StructureVersion _Version; + internal ECCErrorInfo _CurrentErrors; + internal ECCErrorInfo _AggregatedErrors; + + /// + /// Gets the number of current errors + /// + public ECCErrorInfo CurrentErrors + { + get => _CurrentErrors; + } + + /// + /// Gets the number of aggregated errors + /// + public ECCErrorInfo AggregatedErrors + { + get => _AggregatedErrors; + } + + /// + /// Contains ECC memory error counters information + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct ECCErrorInfo + { + internal ulong _SingleBitErrors; + internal ulong _DoubleBitErrors; + + /// + /// Gets the number of single bit errors + /// + public ulong SingleBitErrors + { + get => _SingleBitErrors; + } + + /// + /// Gets the number of double bit errors + /// + public ulong DoubleBitErrors + { + get => _DoubleBitErrors; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/ECCStatusInfoV1.cs b/NvAPIWrapper/Native/GPU/Structures/ECCStatusInfoV1.cs new file mode 100644 index 0000000..c023fd9 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/ECCStatusInfoV1.cs @@ -0,0 +1,45 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding the ECC Memory status + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct ECCStatusInfoV1 : IInitializable + { + internal StructureVersion _Version; + internal uint _IsSupported; + internal ECCConfiguration _ConfigurationOptions; + internal uint _IsEnabled; + + /// + /// Gets a boolean value indicating if the ECC memory is available and supported + /// + public bool IsSupported + { + get => _IsSupported.GetBit(0); + } + + /// + /// Gets the ECC memory configurations + /// + public ECCConfiguration ConfigurationOptions + { + get => _ConfigurationOptions; + } + + /// + /// Gets boolean value indicating if the ECC memory is currently enabled + /// + public bool IsEnabled + { + get => _IsEnabled.GetBit(0); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/EDIDV1.cs b/NvAPIWrapper/Native/GPU/Structures/EDIDV1.cs new file mode 100644 index 0000000..4984e88 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/EDIDV1.cs @@ -0,0 +1,49 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds whole or a part of the EDID information + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct EDIDV1 : IEDID, IInitializable + { + /// + /// The maximum number of data bytes that this structure can hold + /// + public const int MaxDataSize = 256; + + internal StructureVersion _Version; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxDataSize)] + internal byte[] _Data; + + internal static EDIDV1 CreateWithData(byte[] data) + { + if (data.Length > MaxDataSize) + { + throw new ArgumentException("Data is too big.", nameof(data)); + } + + var edid = typeof(EDIDV1).Instantiate(); + Array.Copy(data, edid._Data, data.Length); + + return edid; + } + + /// + /// Gets whole or a part of the EDID data + /// + public byte[] Data + { + get => _Data; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/EDIDV2.cs b/NvAPIWrapper/Native/GPU/Structures/EDIDV2.cs new file mode 100644 index 0000000..28bf18a --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/EDIDV2.cs @@ -0,0 +1,61 @@ +using System; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds whole or a part of the EDID information + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + public struct EDIDV2 : IEDID, IInitializable + { + /// + /// The maximum number of data bytes that this structure can hold + /// + public const int MaxDataSize = EDIDV1.MaxDataSize; + + internal StructureVersion _Version; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxDataSize)] + internal byte[] _Data; + + internal uint _TotalSize; + + internal static EDIDV2 CreateWithData(byte[] data, int totalSize) + { + if (data.Length > MaxDataSize) + { + throw new ArgumentException("Data is too big.", nameof(data)); + } + + var edid = typeof(EDIDV2).Instantiate(); + edid._TotalSize = (uint) totalSize; + Array.Copy(data, 0, edid._Data, 0, totalSize); + + return edid; + } + + /// + /// Gets whole size of the EDID data + /// + public int TotalSize + { + get => (int) _TotalSize; + } + + /// + /// Gets whole or a part of the EDID data + /// + public byte[] Data + { + get => _Data.Take((int) Math.Min(_TotalSize, MaxDataSize)).ToArray(); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/EDIDV3.cs b/NvAPIWrapper/Native/GPU/Structures/EDIDV3.cs new file mode 100644 index 0000000..824eeeb --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/EDIDV3.cs @@ -0,0 +1,90 @@ +using System; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds whole or a part of the EDID information + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(3)] + public struct EDIDV3 : IEDID, IInitializable + { + /// + /// The maximum number of data bytes that this structure can hold + /// + public const int MaxDataSize = EDIDV1.MaxDataSize; + + internal StructureVersion _Version; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxDataSize)] + internal byte[] _Data; + + internal uint _TotalSize; + internal uint _Identification; + internal uint _DataOffset; + + internal static EDIDV3 CreateWithOffset(uint id, uint offset) + { + var edid = typeof(EDIDV3).Instantiate(); + edid._Identification = id; + edid._DataOffset = offset; + + return edid; + } + + internal static EDIDV3 CreateWithData(uint id, uint offset, byte[] data, int totalSize) + { + if (data.Length > MaxDataSize) + { + throw new ArgumentException("Data is too big.", nameof(data)); + } + + var edid = typeof(EDIDV3).Instantiate(); + edid._Identification = id; + edid._DataOffset = offset; + edid._TotalSize = (uint) totalSize; + Array.Copy(data, 0, edid._Data, offset, totalSize); + + return edid; + } + + /// + /// Identification which always returned in a monotonically increasing counter. Across a split-EDID read we need to + /// verify that all calls returned the same value. This counter is incremented if we get the updated EDID. + /// + public int Identification + { + get => (int) _DataOffset; + } + + /// + /// Gets data offset of this part of EDID data. Which 256-byte page of the EDID we want to read. Start at 0. If the + /// read succeeds with TotalSize > MaxDataSize, call back again with offset+256 until we have read the entire buffer + /// + public int DataOffset + { + get => (int) _DataOffset; + } + + /// + /// Gets whole size of the EDID data + /// + public int TotalSize + { + get => (int) _TotalSize; + } + + /// + public byte[] Data + { + get => _Data.Take((int) Math.Min(_TotalSize - DataOffset, MaxDataSize)).ToArray(); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/GetIlluminationParameterV1.cs b/NvAPIWrapper/Native/GPU/Structures/GetIlluminationParameterV1.cs new file mode 100644 index 0000000..af7a538 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/GetIlluminationParameterV1.cs @@ -0,0 +1,57 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds necessary information to get an illumination attribute value + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct GetIlluminationParameterV1 : IInitializable + { + internal StructureVersion _Version; + internal PhysicalGPUHandle _GPUHandle; + internal IlluminationAttribute _Attribute; + internal uint _ValueInPercentage; + + /// + /// Creates a new instance of . + /// + /// The physical gpu handle. + /// The attribute. + public GetIlluminationParameterV1(PhysicalGPUHandle gpuHandle, IlluminationAttribute attribute) + { + this = typeof(GetIlluminationParameterV1).Instantiate(); + _GPUHandle = gpuHandle; + _Attribute = attribute; + } + + /// + /// Gets the parameter physical gpu handle + /// + public PhysicalGPUHandle PhysicalGPUHandle + { + get => _GPUHandle; + } + + /// + /// Gets the parameter attribute + /// + public IlluminationAttribute Attribute + { + get => _Attribute; + } + + /// + /// Gets the parameter value in percentage + /// + public uint ValueInPercentage + { + get => _ValueInPercentage; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/I2CInfoV2.cs b/NvAPIWrapper/Native/GPU/Structures/I2CInfoV2.cs new file mode 100644 index 0000000..6c6602c --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/I2CInfoV2.cs @@ -0,0 +1,240 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + public struct I2CInfoV2 : IInitializable, IDisposable, II2CInfo + { + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly StructureVersion _Version; + private readonly OutputId _OutputMask; + private readonly byte _UseDDCPort; + private readonly byte _I2CDeviceAddress; + private ValueTypeArray _I2CRegisterAddress; + private readonly uint _I2CRegisterAddressLength; + private ValueTypeArray _Data; + private readonly uint _DataLength; + + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly uint _I2CSpeed; + private readonly I2CSpeed _I2CSpeedInKHz; + + /// + // ReSharper disable once ConvertToAutoProperty + public OutputId OutputMask + { + get => _OutputMask; + } + + /// + public bool UseDDCPort + { + get => _UseDDCPort > 0; + } + + + /// + // ReSharper disable once ConvertToAutoProperty + public I2CSpeed Speed + { + get => _I2CSpeedInKHz; + } + + /// + public bool IsReadOperation + { + get => (_I2CDeviceAddress & 1) == 1; + } + + /// + public byte DeviceAddress + { + get => (byte) (_I2CDeviceAddress >> 1); + } + + /// + public byte[] Data + { + get + { + if (_Data.IsNull || _DataLength == 0) + { + return new byte[0]; + } + + return _Data.ToArray((int) _DataLength); + } + } + + /// + public byte[] RegisterAddress + { + get + { + if (_I2CRegisterAddress.IsNull || _I2CRegisterAddressLength == 0) + { + return new byte[0]; + } + + return _I2CRegisterAddress.ToArray((int) _I2CRegisterAddressLength); + } + } + + /// + public byte? PortId + { + get => null; + } + + /// + /// Creates an instance of for write operations. + /// + /// The target display output mask + /// A boolean value indicating that the DDC port should be used instead of the communication port + /// The device I2C slave address + /// The target I2C register address + /// The payload data + /// The target speed of the transaction in kHz + public I2CInfoV2( + OutputId outputMask, + bool useDDCPort, + byte deviceAddress, + byte[] registerAddress, + byte[] data, + I2CSpeed speed = I2CSpeed.Default + ) : this(outputMask, useDDCPort, deviceAddress, false, registerAddress, data, speed) + { + } + + /// + /// Creates an instance of for read operations. + /// + /// The target display output mask + /// A boolean value indicating that the DDC port should be used instead of the communication port + /// The device I2C slave address + /// The target I2C register address + /// The length of the buffer to allocate for the read operation. + /// The target speed of the transaction in kHz + public I2CInfoV2( + OutputId outputMask, + bool useDDCPort, + byte deviceAddress, + byte[] registerAddress, + uint readDataLength, + I2CSpeed speed = I2CSpeed.Default + ) : this(outputMask, useDDCPort, deviceAddress, true, registerAddress, new byte[readDataLength], speed) + { + } + + private I2CInfoV2( + OutputId outputMask, + bool useDDCPort, + byte deviceAddress, + bool isRead, + byte[] registerAddress, + byte[] data, + I2CSpeed speed = I2CSpeed.Default + ) + { + this = typeof(I2CInfoV2).Instantiate(); + + _UseDDCPort = useDDCPort ? (byte) 1 : (byte) 0; + _OutputMask = outputMask; + _I2CDeviceAddress = (byte) (deviceAddress << 1); + _I2CSpeed = 0xFFFF; // Deprecated + _I2CSpeedInKHz = speed; + + if (isRead) + { + _I2CDeviceAddress |= 1; + } + + if (registerAddress?.Length > 0) + { + _I2CRegisterAddress = ValueTypeArray.FromArray(registerAddress); + _I2CRegisterAddressLength = (uint) registerAddress.Length; + } + else + { + _I2CRegisterAddress = ValueTypeArray.Null; + _I2CRegisterAddressLength = 0; + } + + if (data?.Length > 0) + { + _Data = ValueTypeArray.FromArray(data); + _DataLength = (uint) data.Length; + } + else + { + _Data = ValueTypeArray.Null; + _DataLength = 0; + } + } + + /// + /// Calculates and fills the last byte of data to the checksum value required by the DDCCI protocol + /// + /// The target device address. + /// The target register address. + /// The data to be sent and store the checksum. + public static void FillDDCCIChecksum(byte deviceAddress, byte[] registerAddress, byte[] data) + { + var checksum = deviceAddress; + + if (data == null) + { + throw new ArgumentNullException(nameof(data)); + } + + if (data.Length == 0) + { + throw new ArgumentException("Checksum needs at least one free byte.", nameof(data)); + } + + if (registerAddress == null) + { + throw new ArgumentNullException(nameof(registerAddress)); + } + + // ReSharper disable once ForCanBeConvertedToForeach + // ReSharper disable once LoopCanBeConvertedToQuery + for (var i = 0; i < registerAddress.Length; i++) + { + checksum ^= registerAddress[i]; + } + + // ReSharper disable once ForCanBeConvertedToForeach + // ReSharper disable once LoopCanBeConvertedToQuery + for (var i = 0; i < data.Length - 1; i++) + { + checksum ^= data[i]; + } + + data[data.Length - 1] = checksum; + } + + /// + public void Dispose() + { + if (!_I2CRegisterAddress.IsNull) + { + _I2CRegisterAddress.Dispose(); + } + + if (!_Data.IsNull) + { + _Data.Dispose(); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/I2CInfoV3.cs b/NvAPIWrapper/Native/GPU/Structures/I2CInfoV3.cs new file mode 100644 index 0000000..e62b677 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/I2CInfoV3.cs @@ -0,0 +1,233 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(3)] + public struct I2CInfoV3 : IInitializable, IDisposable, II2CInfo + { + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly StructureVersion _Version; + private readonly OutputId _OutputMask; + private readonly byte _UseDDCPort; + private readonly byte _I2CDeviceAddress; + private ValueTypeArray _I2CRegisterAddress; + private readonly uint _I2CRegisterAddressLength; + private ValueTypeArray _Data; + private readonly uint _DataLength; + + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly uint _I2CSpeed; + private readonly I2CSpeed _I2CSpeedInKHz; + private readonly byte _PortId; + private readonly uint _IsPortIdPresent; + + /// + // ReSharper disable once ConvertToAutoProperty + public OutputId OutputMask + { + get => _OutputMask; + } + + /// + public bool UseDDCPort + { + get => _UseDDCPort > 0; + } + + /// + // ReSharper disable once ConvertToAutoProperty + public I2CSpeed Speed + { + get => _I2CSpeedInKHz; + } + + /// + public bool IsReadOperation + { + get => (_I2CDeviceAddress & 1) == 1; + } + + /// + public byte DeviceAddress + { + get => (byte) (_I2CDeviceAddress >> 1); + } + + /// + public byte? PortId + { + get + { + if (_IsPortIdPresent > 0) + { + return _PortId; + } + + return null; + } + } + + /// + public byte[] Data + { + get + { + if (_Data.IsNull || _DataLength == 0) + { + return new byte[0]; + } + + return _Data.ToArray((int) _DataLength); + } + } + + /// + public byte[] RegisterAddress + { + get + { + if (_I2CRegisterAddress.IsNull || _I2CRegisterAddressLength == 0) + { + return new byte[0]; + } + + return _I2CRegisterAddress.ToArray((int) _I2CRegisterAddressLength); + } + } + + /// + /// Creates an instance of for write operations. + /// + /// The target display output mask + /// The port id on which device is connected + /// A boolean value indicating that the DDC port should be used instead of the communication port + /// The device I2C slave address + /// The target I2C register address + /// The payload data + /// The target speed of the transaction in kHz + public I2CInfoV3( + OutputId outputMask, + byte? portId, + bool useDDCPort, + byte deviceAddress, + byte[] registerAddress, + byte[] data, + I2CSpeed speed = I2CSpeed.Default + ) : this(outputMask, portId, useDDCPort, deviceAddress, false, registerAddress, data, speed) + { + } + + /// + /// Creates an instance of for read operations. + /// + /// The target display output mask + /// The port id on which device is connected + /// A boolean value indicating that the DDC port should be used instead of the communication port + /// The device I2C slave address + /// The target I2C register address + /// The length of the buffer to allocate for the read operation. + /// The target speed of the transaction in kHz + public I2CInfoV3( + OutputId outputMask, + byte? portId, + bool useDDCPort, + byte deviceAddress, + byte[] registerAddress, + uint readDataLength, + I2CSpeed speed = I2CSpeed.Default + ) : this(outputMask, portId, useDDCPort, deviceAddress, true, registerAddress, new byte[readDataLength], speed) + { + } + + private I2CInfoV3( + OutputId outputMask, + byte? portId, + bool useDDCPort, + byte deviceAddress, + bool isRead, + byte[] registerAddress, + byte[] data, + I2CSpeed speed = I2CSpeed.Default + ) + { + this = typeof(I2CInfoV3).Instantiate(); + + _UseDDCPort = useDDCPort ? (byte) 1 : (byte) 0; + _OutputMask = outputMask; + _I2CDeviceAddress = (byte) (deviceAddress << 1); + _I2CSpeed = 0xFFFF; // Deprecated + _I2CSpeedInKHz = speed; + + if (isRead) + { + _I2CDeviceAddress |= 1; + } + + if (portId != null) + { + _PortId = portId.Value; + _IsPortIdPresent = 1; + } + else + { + _IsPortIdPresent = 0; + } + + if (registerAddress?.Length > 0) + { + _I2CRegisterAddress = ValueTypeArray.FromArray(registerAddress); + _I2CRegisterAddressLength = (uint) registerAddress.Length; + } + else + { + _I2CRegisterAddress = ValueTypeArray.Null; + _I2CRegisterAddressLength = 0; + } + + if (data?.Length > 0) + { + _Data = ValueTypeArray.FromArray(data); + _DataLength = (uint) data.Length; + } + else + { + _Data = ValueTypeArray.Null; + _DataLength = 0; + } + } + + /// + /// Calculates and fills the last byte of data to the checksum value required by the DDCCI protocol + /// + /// The target device address. + /// The target register address. + /// The data to be sent and store the checksum. + public static void FillDDCCIChecksum(byte deviceAddress, byte[] registerAddress, byte[] data) + { + I2CInfoV2.FillDDCCIChecksum(deviceAddress, registerAddress, data); + } + + /// + public void Dispose() + { + if (!_I2CRegisterAddress.IsNull) + { + _I2CRegisterAddress.Dispose(); + } + + if (!_Data.IsNull) + { + _Data.Dispose(); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationDeviceControlParametersV1.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationDeviceControlParametersV1.cs new file mode 100644 index 0000000..cb22208 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationDeviceControlParametersV1.cs @@ -0,0 +1,53 @@ +using System; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding available devices illumination settings + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct IlluminationDeviceControlParametersV1 : IInitializable + { + private const int MaximumNumberOfReserved = 64; + private const int MaximumNumberOfDevices = 32; + internal StructureVersion _Version; + internal uint _NumberOfDevices; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfReserved)] + internal byte[] _Reserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfDevices)] + internal IlluminationDeviceControlV1[] _Devices; + + /// + /// Creates a new instance of . + /// + /// The list of illumination settings of devices. + public IlluminationDeviceControlParametersV1(IlluminationDeviceControlV1[] devices) + { + if (!(devices?.Length > 0) || devices.Length > MaximumNumberOfDevices) + { + throw new ArgumentOutOfRangeException(nameof(devices)); + } + + this = typeof(IlluminationDeviceControlParametersV1).Instantiate(); + _NumberOfDevices = (uint) devices.Length; + Array.Copy(devices, 0, _Devices, 0, devices.Length); + } + + /// + /// Gets a list of available illumination settings of devices. + /// + public IlluminationDeviceControlV1[] Devices + { + get => _Devices.Take((int) _NumberOfDevices).ToArray(); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationDeviceControlV1.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationDeviceControlV1.cs new file mode 100644 index 0000000..e4955f7 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationDeviceControlV1.cs @@ -0,0 +1,50 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding a device illumination settings + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct IlluminationDeviceControlV1 : IInitializable + { + private const int MaximumNumberOfReserved = 64; + internal IlluminationDeviceType _DeviceType; + internal IlluminationDeviceSyncV1 _SyncInformation; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfReserved)] + internal byte[] _Reserved; + + /// + /// Creates a new instance of . + /// + /// The device type. + /// The device sync information. + public IlluminationDeviceControlV1(IlluminationDeviceType deviceType, IlluminationDeviceSyncV1 syncInformation) + { + this = typeof(IlluminationDeviceControlV1).Instantiate(); + _DeviceType = deviceType; + _SyncInformation = syncInformation; + } + + /// + /// Gets the illumination device type + /// + public IlluminationDeviceType DeviceType + { + get => _DeviceType; + } + + /// + /// Gets the illumination synchronization information + /// + public IlluminationDeviceSyncV1 SyncInformation + { + get => _SyncInformation; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationDeviceInfoParametersV1.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationDeviceInfoParametersV1.cs new file mode 100644 index 0000000..728c373 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationDeviceInfoParametersV1.cs @@ -0,0 +1,35 @@ +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding available illumination devices + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct IlluminationDeviceInfoParametersV1 : IInitializable + { + private const int MaximumNumberOfReserved = 64; + private const int MaximumNumberOfDevices = 32; + internal StructureVersion _Version; + internal uint _NumberOfDevices; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfReserved)] + internal byte[] _Reserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfDevices)] + internal IlluminationDeviceInfoV1[] _Devices; + + /// + /// Gets an array containing all available illumination devices + /// + public IlluminationDeviceInfoV1[] Devices + { + get => _Devices.Take((int) _NumberOfDevices).ToArray(); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationDeviceInfoV1.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationDeviceInfoV1.cs new file mode 100644 index 0000000..222c58a --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationDeviceInfoV1.cs @@ -0,0 +1,57 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding a illumination device + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct IlluminationDeviceInfoV1 : IInitializable + { + private const int MaximumNumberOfReserved = 64; + private const int MaximumNumberOfDeviceData = 64; + internal IlluminationDeviceType _DeviceType; + internal IlluminationZoneControlMode _ControlModes; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfDeviceData)] + internal byte[] _DeviceData; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfReserved)] + internal byte[] _Reserved; + + /// + /// Gets the illumination device type + /// + public IlluminationDeviceType DeviceType + { + get => _DeviceType; + } + + /// + /// Gets the illumination device control mode + /// + public IlluminationZoneControlMode ControlMode + { + get => _ControlModes; + } + + /// + /// Gets the I2C index for a MCUV10 device + /// + /// Device type is not MCUV10. + public byte MCUV10DeviceI2CIndex + { + get + { + if (DeviceType != IlluminationDeviceType.MCUV10) + { + throw new InvalidOperationException("Device type is not MCUV10."); + } + + return _DeviceData[0]; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationDeviceSyncV1.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationDeviceSyncV1.cs new file mode 100644 index 0000000..69606bb --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationDeviceSyncV1.cs @@ -0,0 +1,48 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding the data necessary for synchronization. + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct IlluminationDeviceSyncV1 : IInitializable + { + private const int MaximumNumberOfReserved = 64; + internal byte _IsSync; + internal ulong _TimeStampInMS; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfReserved)] + internal byte[] _Reserved; + + /// + /// Creates a new instance of + /// + /// A boolean value indicating if synchronization is enabled. + /// The synchronization timestamp in ms + public IlluminationDeviceSyncV1(bool isSync, ulong timeStampInMS) + { + this = typeof(IlluminationDeviceSyncV1).Instantiate(); + _IsSync = isSync ? (byte) 1 : (byte) 0; + _TimeStampInMS = timeStampInMS; + } + + /// + /// Gets a boolean value indicating the need for synchronization. + /// + public bool IsSync + { + get => _IsSync > 0; + } + + /// + /// Gets the timestamp in milliseconds required for synchronization. + /// + public ulong TimeStampInMS + { + get => _TimeStampInMS; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataFixedColor.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataFixedColor.cs new file mode 100644 index 0000000..a35a461 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataFixedColor.cs @@ -0,0 +1,74 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding a fixed color control data + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct IlluminationZoneControlDataFixedColor : IInitializable + { + private const int MaximumNumberOfDataBytes = 64; + private const int MaximumNumberOfReservedBytes = 64; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfDataBytes)] + internal byte[] _Data; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfReservedBytes)] + internal byte[] _Reserved; + + /// + /// Creates a new instance of . + /// + /// The zone manual control data. + public IlluminationZoneControlDataFixedColor(IlluminationZoneControlDataManualFixedColor manualFixedColor) + : this(manualFixedColor.ToByteArray()) + { + } + + /// + /// Creates a new instance of . + /// + /// The zone piecewise linear control data. + public IlluminationZoneControlDataFixedColor( + IlluminationZoneControlDataPiecewiseLinearFixedColor piecewiseLinearFixedColor) + : this(piecewiseLinearFixedColor.ToByteArray()) + { + } + + private IlluminationZoneControlDataFixedColor(byte[] data) + { + if (!(data?.Length > 0) || data.Length > MaximumNumberOfDataBytes) + { + throw new ArgumentOutOfRangeException(nameof(data)); + } + + this = typeof(IlluminationZoneControlDataFixedColor).Instantiate(); + Array.Copy(data, 0, _Data, 0, data.Length); + } + + /// + /// Gets the control data as a manual control structure. + /// + /// An instance of containing manual settings. + public IlluminationZoneControlDataManualFixedColor AsManual() + { + return _Data.ToStructure(); + } + + /// + /// Gets the control data as a piecewise linear control structure. + /// + /// + /// An instance of containing piecewise + /// settings. + /// + public IlluminationZoneControlDataPiecewiseLinearFixedColor AsPiecewise() + { + return _Data.ToStructure(); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataFixedColorParameters.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataFixedColorParameters.cs new file mode 100644 index 0000000..efd45fb --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataFixedColorParameters.cs @@ -0,0 +1,30 @@ +using System.Runtime.InteropServices; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding a fixed color + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct IlluminationZoneControlDataFixedColorParameters + { + internal byte _BrightnessInPercentage; + + /// + /// Creates a new instance of . + /// + /// The brightness percentage value of the zone. + public IlluminationZoneControlDataFixedColorParameters(byte brightnessInPercentage) + { + _BrightnessInPercentage = brightnessInPercentage; + } + + /// + /// Gets the brightness percentage value of the zone. + /// + public byte BrightnessInPercentage + { + get => _BrightnessInPercentage; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataManualFixedColor.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataManualFixedColor.cs new file mode 100644 index 0000000..87fac35 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataManualFixedColor.cs @@ -0,0 +1,31 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding a manual fixed color control method + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct IlluminationZoneControlDataManualFixedColor : IInitializable + { + internal IlluminationZoneControlDataFixedColorParameters _Parameters; + + /// + /// Creates a new instance of . + /// + /// The fixed color parameters. + public IlluminationZoneControlDataManualFixedColor(IlluminationZoneControlDataFixedColorParameters parameters) + { + _Parameters = parameters; + } + + /// + /// Gets the fixed color parameters + /// + internal IlluminationZoneControlDataFixedColorParameters Parameters + { + get => _Parameters; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataManualRGB.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataManualRGB.cs new file mode 100644 index 0000000..26e582f --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataManualRGB.cs @@ -0,0 +1,31 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding a RGB control method + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct IlluminationZoneControlDataManualRGB : IInitializable + { + internal IlluminationZoneControlDataManualRGBParameters _Parameters; + + /// + /// Creates a new instance of . + /// + /// The RGB parameters. + public IlluminationZoneControlDataManualRGB(IlluminationZoneControlDataManualRGBParameters parameters) + { + _Parameters = parameters; + } + + /// + /// Gets the RGB parameters + /// + public IlluminationZoneControlDataManualRGBParameters Parameters + { + get => _Parameters; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataManualRGBParameters.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataManualRGBParameters.cs new file mode 100644 index 0000000..4a13623 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataManualRGBParameters.cs @@ -0,0 +1,68 @@ +using System.Runtime.InteropServices; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding a RGB color + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct IlluminationZoneControlDataManualRGBParameters + { + internal byte _Red; + internal byte _Green; + internal byte _Blue; + internal byte _BrightnessInPercentage; + + /// + /// Creates a new instance of . + /// + /// The red component of color applied to the zone. + /// The green component of color applied to the zone. + /// The blue component of color applied to the zone. + /// The brightness percentage value of the zone. + // ReSharper disable once TooManyDependencies + public IlluminationZoneControlDataManualRGBParameters( + byte red, + byte green, + byte blue, + byte brightnessInPercentage) + { + _Red = red; + _Green = green; + _Blue = blue; + _BrightnessInPercentage = brightnessInPercentage; + } + + /// + /// Gets the red component of color applied to the zone. + /// + public byte Red + { + get => _Red; + } + + /// + /// Gets the green component of color applied to the zone. + /// + public byte Green + { + get => _Green; + } + + /// + /// Gets the blue component of color applied to the zone. + /// + public byte Blue + { + get => _Blue; + } + + /// + /// Gets the brightness percentage value of the zone. + /// + public byte BrightnessInPercentage + { + get => _BrightnessInPercentage; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataPiecewiseLinear.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataPiecewiseLinear.cs new file mode 100644 index 0000000..16106ee --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataPiecewiseLinear.cs @@ -0,0 +1,119 @@ +using System.Runtime.InteropServices; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding a piecewise linear function settings + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct IlluminationZoneControlDataPiecewiseLinear + { + internal IlluminationPiecewiseLinearCycleType _CycleType; + internal byte _GroupPeriodRepeatCount; + internal ushort _RiseDurationInMS; + internal ushort _FallDurationInMS; + internal ushort _ADurationInMS; + internal ushort _BDurationInMS; + internal ushort _NextGroupIdleDurationInMS; + internal ushort _PhaseOffsetInMS; + + /// + /// Creates a new instance of . + /// + /// The type of cycle effect to apply. + /// The number of times to repeat function within group period. + /// The time in millisecond to transition from color A to color B. + /// The time in millisecond to transition from color B to color A. + /// The time in millisecond to remain at color A before color A to color B transition. + /// The time in millisecond to remain at color B before color B to color A transition. + /// + /// The time in millisecond to remain idle before next group of repeated function + /// cycles. + /// + /// The time in millisecond to offset the cycle relative to other zones. + // ReSharper disable once TooManyDependencies + public IlluminationZoneControlDataPiecewiseLinear( + IlluminationPiecewiseLinearCycleType cycleType, + byte groupPeriodRepeatCount, + ushort riseDurationInMS, + ushort fallDurationInMS, + ushort aDurationInMS, + ushort bDurationInMS, + ushort nextGroupIdleDurationInMS, + ushort phaseOffsetInMS) + { + _CycleType = cycleType; + _GroupPeriodRepeatCount = groupPeriodRepeatCount; + _RiseDurationInMS = riseDurationInMS; + _FallDurationInMS = fallDurationInMS; + _ADurationInMS = aDurationInMS; + _BDurationInMS = bDurationInMS; + _NextGroupIdleDurationInMS = nextGroupIdleDurationInMS; + _PhaseOffsetInMS = phaseOffsetInMS; + } + + /// + /// Gets the time in millisecond to offset the cycle relative to other zones. + /// + public ushort PhaseOffsetInMS + { + get => _PhaseOffsetInMS; + } + + /// + /// Gets the time in millisecond to remain idle before next group of repeated function cycles. + /// + public ushort NextGroupIdleDurationInMS + { + get => _NextGroupIdleDurationInMS; + } + + /// + /// Gets the time in millisecond to remain at color B before color B to color A transition. + /// + public ushort BDurationInMS + { + get => _BDurationInMS; + } + + /// + /// Gets the time in millisecond to remain at color A before color A to color B transition. + /// + public ushort ADurationInMS + { + get => _ADurationInMS; + } + + /// + /// Gets the time in millisecond to transition from color B to color A. + /// + public ushort FallDurationInMS + { + get => _FallDurationInMS; + } + + /// + /// Gets the time in millisecond to transition from color A to color B. + /// + public ushort RiseDurationInMS + { + get => _RiseDurationInMS; + } + + /// + /// Gets the number of times to repeat function within group period. + /// + public byte GroupPeriodRepeatCount + { + get => _GroupPeriodRepeatCount; + } + + /// + /// Gets the type of cycle effect to apply. + /// + public IlluminationPiecewiseLinearCycleType CycleType + { + get => _CycleType; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataPiecewiseLinearFixedColor.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataPiecewiseLinearFixedColor.cs new file mode 100644 index 0000000..6d6570b --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataPiecewiseLinearFixedColor.cs @@ -0,0 +1,57 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding a piecewise linear fixed color control method + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct IlluminationZoneControlDataPiecewiseLinearFixedColor : IInitializable + { + private const int NumberColorEndPoints = 2; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NumberColorEndPoints)] + internal IlluminationZoneControlDataFixedColorParameters[] _EndPoints; + + internal IlluminationZoneControlDataPiecewiseLinear _PiecewiseLinearData; + + /// + /// Creates a new instance of . + /// + /// The list of fixed color piecewise function endpoints. + /// The piecewise function settings. + public IlluminationZoneControlDataPiecewiseLinearFixedColor( + IlluminationZoneControlDataFixedColorParameters[] endPoints, + IlluminationZoneControlDataPiecewiseLinear piecewiseLinearData) + { + if (endPoints?.Length != NumberColorEndPoints) + { + throw new ArgumentOutOfRangeException(nameof(endPoints)); + } + + this = typeof(IlluminationZoneControlDataPiecewiseLinearFixedColor) + .Instantiate(); + _PiecewiseLinearData = piecewiseLinearData; + Array.Copy(endPoints, 0, _EndPoints, 0, endPoints.Length); + } + + /// + /// Gets the piecewise function settings + /// + public IlluminationZoneControlDataPiecewiseLinear PiecewiseLinearData + { + get => _PiecewiseLinearData; + } + + /// + /// Gets the list of fixed color piecewise function endpoints + /// + public IlluminationZoneControlDataFixedColorParameters[] EndPoints + { + get => _EndPoints; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataPiecewiseLinearRGB.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataPiecewiseLinearRGB.cs new file mode 100644 index 0000000..67f6b4b --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataPiecewiseLinearRGB.cs @@ -0,0 +1,57 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding a piecewise linear RGB control method + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct IlluminationZoneControlDataPiecewiseLinearRGB : IInitializable + { + private const int NumberColorEndPoints = 2; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NumberColorEndPoints)] + internal IlluminationZoneControlDataManualRGBParameters[] _EndPoints; + + internal IlluminationZoneControlDataPiecewiseLinear _PiecewiseLinearData; + + /// + /// Creates a new instance of . + /// + /// The list of RGB piecewise function endpoints. + /// The piecewise function settings. + public IlluminationZoneControlDataPiecewiseLinearRGB( + IlluminationZoneControlDataManualRGBParameters[] endPoints, + IlluminationZoneControlDataPiecewiseLinear piecewiseLinearData) + { + if (endPoints?.Length != NumberColorEndPoints) + { + throw new ArgumentOutOfRangeException(nameof(endPoints)); + } + + this = typeof(IlluminationZoneControlDataPiecewiseLinearRGB) + .Instantiate(); + _PiecewiseLinearData = piecewiseLinearData; + Array.Copy(endPoints, 0, _EndPoints, 0, endPoints.Length); + } + + /// + /// Gets the piecewise function settings + /// + public IlluminationZoneControlDataPiecewiseLinear PiecewiseLinearData + { + get => _PiecewiseLinearData; + } + + /// + /// Gets the list of RGB function endpoints + /// + public IlluminationZoneControlDataManualRGBParameters[] EndPoints + { + get => _EndPoints; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataRGB.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataRGB.cs new file mode 100644 index 0000000..033b373 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlDataRGB.cs @@ -0,0 +1,73 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding a RGB control data + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct IlluminationZoneControlDataRGB : IInitializable + { + private const int MaximumNumberOfDataBytes = 64; + private const int MaximumNumberOfReservedBytes = 64; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfDataBytes)] + internal byte[] _Data; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfReservedBytes)] + internal byte[] _Reserved; + + /// + /// Creates a new instance of . + /// + /// The zone manual control data. + public IlluminationZoneControlDataRGB(IlluminationZoneControlDataManualRGB manualRGB) + : this(manualRGB.ToByteArray()) + { + } + + /// + /// Creates a new instance of . + /// + /// The zone piecewise linear control data. + public IlluminationZoneControlDataRGB(IlluminationZoneControlDataPiecewiseLinearRGB piecewiseLinearRGB) + : this(piecewiseLinearRGB.ToByteArray()) + { + } + + private IlluminationZoneControlDataRGB(byte[] data) + { + if (!(data?.Length > 0) || data.Length > MaximumNumberOfDataBytes) + { + throw new ArgumentOutOfRangeException(nameof(data)); + } + + this = typeof(IlluminationZoneControlDataRGB).Instantiate(); + Array.Copy(data, 0, _Data, 0, data.Length); + } + + /// + /// Gets the control data as a manual control structure. + /// + /// An instance of containing manual settings. + public IlluminationZoneControlDataManualRGB AsManual() + { + return _Data.ToStructure(); + } + + /// + /// Gets the control data as a piecewise linear control structure. + /// + /// + /// An instance of containing piecewise linear + /// settings. + /// + public IlluminationZoneControlDataPiecewiseLinearRGB AsPiecewise() + { + return _Data.ToStructure(); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlParametersV1.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlParametersV1.cs new file mode 100644 index 0000000..193e8e2 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlParametersV1.cs @@ -0,0 +1,76 @@ +using System; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding available zone control settings + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct IlluminationZoneControlParametersV1 : IInitializable + { + private const int MaximumNumberOfZoneControls = 32; + private const int MaximumNumberOfReservedBytes = 64; + internal StructureVersion _Version; + internal uint _Flags; + internal uint _NumberOfZoneControls; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfReservedBytes)] + internal byte[] _Reserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfZoneControls)] + internal IlluminationZoneControlV1[] _ZoneControls; + + /// + /// Creates a new instance of . + /// + /// The type of settings to represents. + public IlluminationZoneControlParametersV1(IlluminationZoneControlValuesType valuesType) + { + this = typeof(IlluminationZoneControlParametersV1).Instantiate(); + _Flags.SetBit(0, valuesType == IlluminationZoneControlValuesType.Default); + } + + /// + /// Creates a new instance of . + /// + /// The type of settings to represents. + /// An array of zone control settings. + public IlluminationZoneControlParametersV1( + IlluminationZoneControlValuesType valuesType, + IlluminationZoneControlV1[] zoneControls) : this(valuesType) + { + if (!(zoneControls?.Length > 0) || zoneControls.Length > MaximumNumberOfZoneControls) + { + throw new ArgumentOutOfRangeException(nameof(valuesType)); + } + + _NumberOfZoneControls = (uint) zoneControls.Length; + Array.Copy(zoneControls, 0, _ZoneControls, 0, zoneControls.Length); + } + + /// + /// Gets the type of settings to represents. + /// + public IlluminationZoneControlValuesType ValuesType + { + get => _Flags.GetBit(0) + ? IlluminationZoneControlValuesType.Default + : IlluminationZoneControlValuesType.CurrentlyActive; + } + + /// + /// Gets an array of zone control settings + /// + public IlluminationZoneControlV1[] ZoneControls + { + get => _ZoneControls.Take((int) _NumberOfZoneControls).ToArray(); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlV1.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlV1.cs new file mode 100644 index 0000000..9509ff8 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneControlV1.cs @@ -0,0 +1,101 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding a zone control status + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct IlluminationZoneControlV1 : IInitializable + { + private const int MaximumNumberOfDataBytes = 128; + private const int MaximumNumberOfReservedBytes = 64; + + internal IlluminationZoneType _ZoneType; + + internal IlluminationZoneControlMode _ControlMode; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfDataBytes)] + internal byte[] _Data; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfReservedBytes)] + internal byte[] _Reserved; + + /// + /// Creates a new instance of . + /// + /// The zone control mode. + /// The zone control RGB data. + public IlluminationZoneControlV1( + IlluminationZoneControlMode controlMode, + IlluminationZoneControlDataRGB rgbData) + : this(controlMode, IlluminationZoneType.RGB, rgbData.ToByteArray()) + { + } + + /// + /// Creates a new instance of . + /// + /// The zone control mode. + /// The zone control fixed color data. + public IlluminationZoneControlV1( + IlluminationZoneControlMode controlMode, + IlluminationZoneControlDataFixedColor fixedColorData) + : this(controlMode, IlluminationZoneType.FixedColor, fixedColorData.ToByteArray()) + { + } + + private IlluminationZoneControlV1( + IlluminationZoneControlMode controlMode, + IlluminationZoneType zoneType, + byte[] data) + { + if (!(data?.Length > 0) || data.Length > MaximumNumberOfDataBytes) + { + throw new ArgumentOutOfRangeException(nameof(data)); + } + + this = typeof(IlluminationZoneControlV1).Instantiate(); + _ControlMode = controlMode; + _ZoneType = zoneType; + Array.Copy(data, 0, _Data, 0, data.Length); + } + + /// + /// Gets the type of zone and the type of data needed to control this zone + /// + internal IlluminationZoneType ZoneType + { + get => _ZoneType; + } + + /// + /// Gets the zone control mode + /// + internal IlluminationZoneControlMode ControlMode + { + get => _ControlMode; + } + + /// + /// Gets the control data as a RGB data structure. + /// + /// An instance of containing RGB settings. + public IlluminationZoneControlDataRGB AsRGBData() + { + return _Data.ToStructure(); + } + + /// + /// Gets the control data as a fixed color data structure. + /// + /// An instance of containing fixed color settings. + public IlluminationZoneControlDataFixedColor AsFixedColorData() + { + return _Data.ToStructure(); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneInfoParametersV1.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneInfoParametersV1.cs new file mode 100644 index 0000000..adb4b33 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneInfoParametersV1.cs @@ -0,0 +1,35 @@ +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding illumination zones + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct IlluminationZoneInfoParametersV1 : IInitializable + { + private const int MaximumNumberOfReserved = 64; + private const int MaximumNumberOfZones = 32; + internal StructureVersion _Version; + internal uint _NumberOfZones; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfReserved)] + internal byte[] _Reserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfZones)] + internal IlluminationZoneInfoV1[] _Zones; + + /// + /// Gets the list of illumination zones. + /// + public IlluminationZoneInfoV1[] Zones + { + get => _Zones.Take((int) _NumberOfZones).ToArray(); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneInfoV1.cs b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneInfoV1.cs new file mode 100644 index 0000000..d405d97 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/IlluminationZoneInfoV1.cs @@ -0,0 +1,58 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information regarding a illumination zone + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct IlluminationZoneInfoV1 : IInitializable + { + private const int MaximumNumberOfReserved = 64; + private const int MaximumNumberOfDataBytes = 64; + + internal IlluminationZoneType _ZoneType; + internal byte _DeviceIndex; + internal byte _ProviderIndex; + internal IlluminationZoneLocation _ZoneLocation; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfDataBytes)] + internal byte[] _Data; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaximumNumberOfReserved)] + internal byte[] _Reserved; + + /// + /// Gets the index of the illumination device that controls this zone. + /// + public int DeviceIndex + { + get => _DeviceIndex; + } + + /// + /// Gets the provider index used for representing logical to physical zone mapping. + /// + public int ProviderIndex + { + get => _ProviderIndex; + } + + /// + /// Gets the location of the zone on the board. + /// + public IlluminationZoneLocation ZoneLocation + { + get => _ZoneLocation; + } + + /// + /// Gets the zone type. + /// + internal IlluminationZoneType ZoneType + { + get => _ZoneType; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/LogicalGPUHandle.cs b/NvAPIWrapper/Native/GPU/Structures/LogicalGPUHandle.cs new file mode 100644 index 0000000..dd7a5c6 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/LogicalGPUHandle.cs @@ -0,0 +1,85 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// LogicalGPUHandle is a reference to one or more physical GPUs acting as a single logical device. A single GPU will + /// have a single logical GPU handle and a single physical GPU handle. Two GPUs acting in an SLI configuration will + /// have a single logical GPU handle and two physical GPU handles. + /// + [StructLayout(LayoutKind.Sequential)] + public struct LogicalGPUHandle : IHandle, IEquatable + { + /// + /// Maximum number of logical GPUs + /// + public const int MaxLogicalGPUs = 64; + + internal readonly IntPtr _MemoryAddress; + + /// + public bool Equals(LogicalGPUHandle other) + { + return _MemoryAddress.Equals(other._MemoryAddress); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is LogicalGPUHandle handle && Equals(handle); + } + + /// + public override int GetHashCode() + { + return _MemoryAddress.GetHashCode(); + } + + /// + public override string ToString() + { + return $"LogicalGPUHandle #{MemoryAddress.ToInt64()}"; + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(LogicalGPUHandle left, LogicalGPUHandle right) + { + return left.Equals(right); + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(LogicalGPUHandle left, LogicalGPUHandle right) + { + return !left.Equals(right); + } + + /// + public IntPtr MemoryAddress + { + get => _MemoryAddress; + } + + /// + public bool IsNull + { + get => _MemoryAddress == IntPtr.Zero; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20BaseVoltageEntryV1.cs b/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20BaseVoltageEntryV1.cs new file mode 100644 index 0000000..b84c213 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20BaseVoltageEntryV1.cs @@ -0,0 +1,69 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PerformanceStates20BaseVoltageEntryV1 : IPerformanceStates20VoltageEntry + { + internal PerformanceVoltageDomain _DomainId; + internal uint _Flags; + internal uint _Value; + internal PerformanceStates20ParameterDelta _ValueDelta; + + /// + /// Creates a new instance of . + /// + /// The voltage domain. + /// The value in micro volt. + /// The base value delta. + public PerformanceStates20BaseVoltageEntryV1( + PerformanceVoltageDomain domain, + uint value, + PerformanceStates20ParameterDelta valueDelta) : this() + { + _DomainId = domain; + _Value = value; + _ValueDelta = valueDelta; + } + + /// + /// Creates a new instance of . + /// + /// The voltage domain. + /// The base value delta. + public PerformanceStates20BaseVoltageEntryV1( + PerformanceVoltageDomain domain, + PerformanceStates20ParameterDelta valueDelta) : this() + { + _DomainId = domain; + _ValueDelta = valueDelta; + } + + /// + public PerformanceVoltageDomain DomainId + { + get => _DomainId; + } + + /// + public bool IsEditable + { + get => _Flags.GetBit(0); + } + + /// + public uint ValueInMicroVolt + { + get => _Value; + } + + /// + public PerformanceStates20ParameterDelta ValueDeltaInMicroVolt + { + get => _ValueDelta; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20ClockEntryV1.cs b/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20ClockEntryV1.cs new file mode 100644 index 0000000..8c99044 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20ClockEntryV1.cs @@ -0,0 +1,237 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PerformanceStates20ClockEntryV1 : IPerformanceStates20ClockEntry + { + internal PublicClockDomain _DomainId; + internal PerformanceStates20ClockType _ClockType; + internal uint _Flags; + internal PerformanceStates20ParameterDelta _FrequencyDeltaInkHz; + internal PerformanceStates20ClockDependentInfo _ClockDependentInfo; + + /// + /// Creates a new instance of + /// + /// The public clock domain. + /// The base value delta. + public PerformanceStates20ClockEntryV1( + PublicClockDomain domain, + PerformanceStates20ParameterDelta valueDelta) : this() + { + _DomainId = domain; + _FrequencyDeltaInkHz = valueDelta; + } + + /// + /// Creates a new instance of + /// + /// The public clock domain. + /// The type of the clock frequency. + /// The base value delta. + public PerformanceStates20ClockEntryV1( + PublicClockDomain domain, + PerformanceStates20ClockType clockType, + PerformanceStates20ParameterDelta valueDelta) : this(domain, valueDelta) + { + _ClockType = clockType; + } + + /// + /// Creates a new instance of + /// + /// The public clock domain. + /// The base value delta. + /// The clock frequency value. + // ReSharper disable once TooManyDependencies + public PerformanceStates20ClockEntryV1( + PublicClockDomain domain, + PerformanceStates20ParameterDelta valueDelta, + PerformanceStates20ClockDependentSingleFrequency singleFrequency) : + this(domain, PerformanceStates20ClockType.Single, valueDelta) + { + _ClockDependentInfo = new PerformanceStates20ClockDependentInfo(singleFrequency); + } + + /// + /// Creates a new instance of + /// + /// The public clock domain. + /// The base value delta. + /// The clock frequency range value. + // ReSharper disable once TooManyDependencies + public PerformanceStates20ClockEntryV1( + PublicClockDomain domain, + PerformanceStates20ParameterDelta valueDelta, + PerformanceStates20ClockDependentFrequencyRange frequencyRange) : + this(domain, PerformanceStates20ClockType.Range, valueDelta) + { + _ClockDependentInfo = new PerformanceStates20ClockDependentInfo(frequencyRange); + } + + /// + public PublicClockDomain DomainId + { + get => _DomainId; + } + + /// + public PerformanceStates20ClockType ClockType + { + get => _ClockType; + } + + /// + public bool IsEditable + { + get => _Flags.GetBit(0); + } + + /// + public PerformanceStates20ParameterDelta FrequencyDeltaInkHz + { + get => _FrequencyDeltaInkHz; + } + + /// + IPerformanceStates20ClockDependentSingleFrequency IPerformanceStates20ClockEntry.SingleFrequency + { + get => _ClockDependentInfo._Single; + } + + /// + IPerformanceStates20ClockDependentFrequencyRange IPerformanceStates20ClockEntry.FrequencyRange + { + get => _ClockDependentInfo._Range; + } + + /// + /// Gets the range of clock frequency and related voltage information if present + /// + public PerformanceStates20ClockDependentSingleFrequency SingleFrequency + { + get => _ClockDependentInfo._Single; + } + + /// + /// Gets the fixed frequency of the clock + /// + public PerformanceStates20ClockDependentFrequencyRange FrequencyRange + { + get => _ClockDependentInfo._Range; + } + + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PerformanceStates20ClockDependentSingleFrequency : + IPerformanceStates20ClockDependentSingleFrequency + { + internal uint _FrequencyInkHz; + + /// + public uint FrequencyInkHz + { + get => _FrequencyInkHz; + } + + /// + /// Creates a new instance of . + /// + /// The fixed frequency in kHz. + public PerformanceStates20ClockDependentSingleFrequency(uint frequencyInkHz) + { + _FrequencyInkHz = frequencyInkHz; + } + } + + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PerformanceStates20ClockDependentFrequencyRange : + IPerformanceStates20ClockDependentFrequencyRange + { + internal uint _MinimumFrequency; + internal uint _MaximumFrequency; + internal PerformanceVoltageDomain _VoltageDomainId; + internal uint _MinimumVoltage; + internal uint _MaximumVoltage; + + /// + /// Creates a new instance of . + /// + /// The minimum frequency in kHz. + /// The maximum frequency in kHz. + /// The corresponding voltage domain identification number. + /// The minimum voltage in uV. + /// The maximum voltage in uV. + // ReSharper disable once TooManyDependencies + public PerformanceStates20ClockDependentFrequencyRange( + uint minimumFrequency, + uint maximumFrequency, + PerformanceVoltageDomain voltageDomainId, + uint minimumVoltage, + uint maximumVoltage) : this() + { + _MinimumFrequency = minimumFrequency; + _MaximumFrequency = maximumFrequency; + _VoltageDomainId = voltageDomainId; + _MinimumVoltage = minimumVoltage; + _MaximumVoltage = maximumVoltage; + } + + /// + public uint MinimumFrequencyInkHz + { + get => _MinimumFrequency; + } + + /// + public uint MaximumFrequencyInkHz + { + get => _MaximumFrequency; + } + + /// + public PerformanceVoltageDomain VoltageDomainId + { + get => _VoltageDomainId; + } + + /// + public uint MinimumVoltageInMicroVolt + { + get => _MinimumVoltage; + } + + /// + public uint MaximumVoltageInMicroVolt + { + get => _MaximumVoltage; + } + } + + [StructLayout(LayoutKind.Explicit, Pack = 8)] + internal struct PerformanceStates20ClockDependentInfo + { + [FieldOffset(0)] internal PerformanceStates20ClockDependentSingleFrequency _Single; + [FieldOffset(0)] internal PerformanceStates20ClockDependentFrequencyRange _Range; + + public PerformanceStates20ClockDependentInfo( + PerformanceStates20ClockDependentSingleFrequency singleFrequency + ) : this() + { + _Single = singleFrequency; + } + + public PerformanceStates20ClockDependentInfo( + PerformanceStates20ClockDependentFrequencyRange frequencyRange + ) : this() + { + _Range = frequencyRange; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20InfoV1.cs b/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20InfoV1.cs new file mode 100644 index 0000000..dba636b --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20InfoV1.cs @@ -0,0 +1,213 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PerformanceStates20InfoV1 : IInitializable, IPerformanceStates20Info + { + internal const int MaxPerformanceStates = 16; + internal const int MaxPerformanceStatesClocks = 8; + internal const int MaxPerformanceStatesBaseVoltages = 4; + + internal StructureVersion _Version; + internal uint _Flags; + internal uint _NumberOfPerformanceStates; + internal uint _NumberOfClocks; + internal uint _NumberOfBaseVoltages; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxPerformanceStates)] + internal PerformanceState20[] _PerformanceStates; + + /// + /// Creates a new instance of + /// + /// The list of performance states and their settings. + /// Number of clock frequencies per each performance state. + /// Number of base voltage per each performance state. + public PerformanceStates20InfoV1( + PerformanceState20[] performanceStates, + uint clocksCount, + uint baseVoltagesCount) + { + if (performanceStates?.Length > MaxPerformanceStatesClocks) + { + throw new ArgumentException( + $"Maximum of {MaxPerformanceStates} performance states are configurable.", + nameof(performanceStates) + ); + } + + if (performanceStates == null) + { + throw new ArgumentNullException(nameof(performanceStates)); + } + + this = typeof(PerformanceStates20InfoV1).Instantiate(); + _NumberOfClocks = clocksCount; + _NumberOfBaseVoltages = baseVoltagesCount; + _NumberOfPerformanceStates = (uint) performanceStates.Length; + Array.Copy(performanceStates, 0, _PerformanceStates, 0, performanceStates.Length); + } + + /// + public IPerformanceStates20VoltageEntry[] GeneralVoltages + { + get => new IPerformanceStates20VoltageEntry[0]; + } + + /// + public bool IsEditable + { + get => _Flags.GetBit(0); + } + + /// + /// Gets an array of valid power states for the GPU + /// + public PerformanceState20[] PerformanceStates + { + get => _PerformanceStates.Take((int) _NumberOfPerformanceStates).ToArray(); + } + + /// + IPerformanceState20[] IPerformanceStates20Info.PerformanceStates + { + get => PerformanceStates.Cast().ToArray(); + } + + /// + /// Gets a dictionary for valid power states and their clock frequencies + /// + public IReadOnlyDictionary Clocks + { + get + { + var clocks = (int) _NumberOfClocks; + + return PerformanceStates.ToDictionary( + state20 => state20.StateId, + state20 => state20._Clocks.Take(clocks).ToArray() + ); + } + } + + /// + IReadOnlyDictionary IPerformanceStates20Info.Clocks + { + get + { + return Clocks.ToDictionary( + pair => pair.Key, + pair => pair.Value.Cast().ToArray() + ); + } + } + + /// + /// Gets a dictionary for valid power states and their voltage settings + /// + public IReadOnlyDictionary Voltages + { + get + { + var baseVoltages = (int) _NumberOfBaseVoltages; + + return PerformanceStates.ToDictionary( + state20 => state20.StateId, + state20 => state20._BaseVoltages.Take(baseVoltages).ToArray() + ); + } + } + + /// + IReadOnlyDictionary IPerformanceStates20Info.Voltages + { + get + { + return Voltages.ToDictionary( + pair => pair.Key, + pair => pair.Value.Cast().ToArray() + ); + } + } + + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PerformanceState20 : IInitializable, IPerformanceState20 + { + internal PerformanceStateId _Id; + internal uint _Flags; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxPerformanceStatesClocks)] + internal PerformanceStates20ClockEntryV1[] _Clocks; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxPerformanceStatesBaseVoltages)] + internal PerformanceStates20BaseVoltageEntryV1[] _BaseVoltages; + + /// + /// Creates a new instance of . + /// + /// The performance identification number. + /// The list of clock entries. + /// The list of base voltages. + public PerformanceState20( + PerformanceStateId stateId, + PerformanceStates20ClockEntryV1[] clocks, + PerformanceStates20BaseVoltageEntryV1[] baseVoltages) + { + if (clocks?.Length > MaxPerformanceStatesClocks) + { + throw new ArgumentException( + $"Maximum of {MaxPerformanceStatesClocks} clocks are configurable.", + nameof(clocks) + ); + } + + if (clocks == null) + { + throw new ArgumentNullException(nameof(clocks)); + } + + if (baseVoltages?.Length > MaxPerformanceStatesBaseVoltages) + { + throw new ArgumentException( + $"Maximum of {MaxPerformanceStatesBaseVoltages} base voltages are configurable.", + nameof(baseVoltages) + ); + } + + if (baseVoltages == null) + { + throw new ArgumentNullException(nameof(baseVoltages)); + } + + this = typeof(PerformanceState20).Instantiate(); + _Id = stateId; + Array.Copy(clocks, 0, _Clocks, 0, clocks.Length); + Array.Copy(baseVoltages, 0, _BaseVoltages, 0, baseVoltages.Length); + } + + /// + public PerformanceStateId StateId + { + get => _Id; + } + + /// + public bool IsEditable + { + get => _Flags.GetBit(0); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20InfoV2.cs b/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20InfoV2.cs new file mode 100644 index 0000000..085ecc9 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20InfoV2.cs @@ -0,0 +1,209 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + public struct PerformanceStates20InfoV2 : IInitializable, IPerformanceStates20Info + { + internal const int MaxPerformanceStates = PerformanceStates20InfoV1.MaxPerformanceStates; + + internal const int MaxPerformanceStatesBaseVoltages = + PerformanceStates20InfoV1.MaxPerformanceStatesBaseVoltages; + + internal StructureVersion _Version; + internal uint _Flags; + internal uint _NumberOfPerformanceStates; + internal uint _NumberOfClocks; + internal uint _NumberOfBaseVoltages; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxPerformanceStates)] + internal PerformanceStates20InfoV1.PerformanceState20[] _PerformanceStates; + + internal PerformanceStates20OverVoltingSetting _OverVoltingSettings; + + /// + /// Creates a new instance of + /// + /// The list of performance states and their settings. + /// Number of clock frequencies per each performance state. + /// Number of base voltage per each performance state. + public PerformanceStates20InfoV2( + PerformanceStates20InfoV1.PerformanceState20[] performanceStates, + uint clocksCount, + uint baseVoltagesCount) + { + if (performanceStates?.Length > PerformanceStates20InfoV1.MaxPerformanceStatesClocks) + { + throw new ArgumentException( + $"Maximum of {MaxPerformanceStates} performance states are configurable.", + nameof(performanceStates) + ); + } + + if (performanceStates == null) + { + throw new ArgumentNullException(nameof(performanceStates)); + } + + this = typeof(PerformanceStates20InfoV2).Instantiate(); + _NumberOfClocks = clocksCount; + _NumberOfBaseVoltages = baseVoltagesCount; + _NumberOfPerformanceStates = (uint) performanceStates.Length; + Array.Copy(performanceStates, 0, _PerformanceStates, 0, performanceStates.Length); + } + + /// + /// Creates a new instance of + /// + /// The list of performance states and their settings. + /// Number of clock frequencies per each performance state. + /// Number of base voltage per each performance state. + /// The list of general voltages and their settings. + // ReSharper disable once TooManyDependencies + public PerformanceStates20InfoV2( + PerformanceStates20InfoV1.PerformanceState20[] performanceStates, + uint clocksCount, + uint baseVoltagesCount, + PerformanceStates20BaseVoltageEntryV1[] generalVoltages) : + this(performanceStates, clocksCount, baseVoltagesCount) + { + _OverVoltingSettings = new PerformanceStates20OverVoltingSetting(generalVoltages); + } + + /// + /// Gets the list of general over-volting settings + /// + public PerformanceStates20BaseVoltageEntryV1[] GeneralVoltages + { + get => _OverVoltingSettings.Voltages.ToArray(); + } + + /// + IPerformanceStates20VoltageEntry[] IPerformanceStates20Info.GeneralVoltages + { + get => GeneralVoltages.Cast().ToArray(); + } + + /// + public bool IsEditable + { + get => _Flags.GetBit(0); + } + + /// + /// Gets an array of valid power states for the GPU + /// + public PerformanceStates20InfoV1.PerformanceState20[] PerformanceStates + { + get => _PerformanceStates.Take((int) _NumberOfPerformanceStates).ToArray(); + } + + /// + IPerformanceState20[] IPerformanceStates20Info.PerformanceStates + { + get => PerformanceStates.Cast().ToArray(); + } + + /// + /// Gets a dictionary for valid power states and their clock frequencies + /// + public IReadOnlyDictionary Clocks + { + get + { + var clocks = (int) _NumberOfClocks; + + return PerformanceStates.ToDictionary( + state20 => state20.StateId, + state20 => state20._Clocks.Take(clocks).ToArray() + ); + } + } + + /// + /// Gets a dictionary for valid power states and their voltage settings + /// + public IReadOnlyDictionary Voltages + { + get + { + var baseVoltages = (int) _NumberOfBaseVoltages; + + return PerformanceStates.ToDictionary( + state20 => state20.StateId, + state20 => state20._BaseVoltages.Take(baseVoltages) + .ToArray() + ); + } + } + + /// + IReadOnlyDictionary IPerformanceStates20Info.Clocks + { + get + { + return Clocks.ToDictionary( + pair => pair.Key, + pair => pair.Value.Cast().ToArray() + ); + } + } + + /// + IReadOnlyDictionary IPerformanceStates20Info.Voltages + { + get + { + return Voltages.ToDictionary( + pair => pair.Key, + pair => pair.Value.Cast().ToArray() + ); + } + } + + [StructLayout(LayoutKind.Sequential, Pack = 8)] + internal struct PerformanceStates20OverVoltingSetting : IInitializable + { + internal uint _NumberOfVoltages; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxPerformanceStatesBaseVoltages)] + internal PerformanceStates20BaseVoltageEntryV1[] _Voltages; + + public PerformanceStates20OverVoltingSetting(PerformanceStates20BaseVoltageEntryV1[] voltages) + { + if (voltages?.Length > PerformanceStates20InfoV1.MaxPerformanceStatesBaseVoltages) + { + throw new ArgumentException( + $"Maximum of {MaxPerformanceStatesBaseVoltages} voltages are configurable.", + nameof(voltages) + ); + } + + if (voltages == null) + { + throw new ArgumentNullException(nameof(voltages)); + } + + this = typeof(PerformanceStates20OverVoltingSetting) + .Instantiate(); + _NumberOfVoltages = (uint) voltages.Length; + Array.Copy(voltages, 0, _Voltages, 0, voltages.Length); + } + + public PerformanceStates20BaseVoltageEntryV1[] Voltages + { + get => _Voltages.Take((int) _NumberOfVoltages).ToArray(); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20InfoV3.cs b/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20InfoV3.cs new file mode 100644 index 0000000..adc1dc2 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20InfoV3.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(3)] + public struct PerformanceStates20InfoV3 : IInitializable, IPerformanceStates20Info + { + internal const int MaxPerformanceStates = PerformanceStates20InfoV2.MaxPerformanceStates; + + internal const int MaxPerformanceStates20BaseVoltages = + PerformanceStates20InfoV2.MaxPerformanceStatesBaseVoltages; + + internal StructureVersion _Version; + internal uint _Flags; + internal uint _NumberOfPerformanceStates; + internal uint _NumberOfClocks; + internal uint _NumberOfBaseVoltages; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxPerformanceStates)] + internal PerformanceStates20InfoV1.PerformanceState20[] _PerformanceStates; + + internal PerformanceStates20InfoV2.PerformanceStates20OverVoltingSetting _OverVoltingSettings; + + /// + /// Creates a new instance of + /// + /// The list of performance states and their settings. + /// Number of clock frequencies per each performance state. + /// Number of base voltage per each performance state. + public PerformanceStates20InfoV3( + PerformanceStates20InfoV1.PerformanceState20[] performanceStates, + uint clocksCount, + uint baseVoltagesCount) + { + if (performanceStates?.Length > PerformanceStates20InfoV1.MaxPerformanceStatesClocks) + { + throw new ArgumentException( + $"Maximum of {MaxPerformanceStates} performance states are configurable.", + nameof(performanceStates) + ); + } + + if (performanceStates == null) + { + throw new ArgumentNullException(nameof(performanceStates)); + } + + this = typeof(PerformanceStates20InfoV3).Instantiate(); + _NumberOfClocks = clocksCount; + _NumberOfBaseVoltages = baseVoltagesCount; + _NumberOfPerformanceStates = (uint) performanceStates.Length; + Array.Copy(performanceStates, 0, _PerformanceStates, 0, performanceStates.Length); + } + + /// + /// Creates a new instance of + /// + /// The list of performance states and their settings. + /// Number of clock frequencies per each performance state. + /// Number of base voltage per each performance state. + /// The list of general voltages and their settings. + // ReSharper disable once TooManyDependencies + public PerformanceStates20InfoV3( + PerformanceStates20InfoV1.PerformanceState20[] performanceStates, + uint clocksCount, + uint baseVoltagesCount, + PerformanceStates20BaseVoltageEntryV1[] generalVoltages) : + this(performanceStates, clocksCount, baseVoltagesCount) + { + _OverVoltingSettings = new PerformanceStates20InfoV2.PerformanceStates20OverVoltingSetting(generalVoltages); + } + + /// + /// Gets the list of general over-volting settings + /// + public PerformanceStates20BaseVoltageEntryV1[] GeneralVoltages + { + get => _OverVoltingSettings.Voltages.ToArray(); + } + + /// + IPerformanceStates20VoltageEntry[] IPerformanceStates20Info.GeneralVoltages + { + get => GeneralVoltages.Cast().ToArray(); + } + + /// + public bool IsEditable + { + get => _Flags.GetBit(0); + } + + /// + /// Gets an array of valid power states for the GPU + /// + public PerformanceStates20InfoV1.PerformanceState20[] PerformanceStates + { + get => _PerformanceStates.Take((int) _NumberOfPerformanceStates).ToArray(); + } + + /// + IPerformanceState20[] IPerformanceStates20Info.PerformanceStates + { + get => PerformanceStates.Cast().ToArray(); + } + + /// + /// Gets a dictionary for valid power states and their clock frequencies + /// + public IReadOnlyDictionary Clocks + { + get + { + var clocks = (int) _NumberOfClocks; + + return PerformanceStates.ToDictionary( + state20 => state20.StateId, + state20 => state20._Clocks.Take(clocks).ToArray() + ); + } + } + + /// + /// Gets a dictionary for valid power states and their voltage settings + /// + public IReadOnlyDictionary Voltages + { + get + { + var baseVoltages = (int) _NumberOfBaseVoltages; + + return PerformanceStates.ToDictionary( + state20 => state20.StateId, + state20 => state20._BaseVoltages.Take(baseVoltages) + .ToArray() + ); + } + } + + /// + IReadOnlyDictionary IPerformanceStates20Info.Clocks + { + get + { + return Clocks.ToDictionary( + pair => pair.Key, + pair => pair.Value.Cast().ToArray() + ); + } + } + + /// + IReadOnlyDictionary IPerformanceStates20Info.Voltages + { + get + { + return Voltages.ToDictionary( + pair => pair.Key, + pair => pair.Value.Cast().ToArray() + ); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20ParameterDelta.cs b/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20ParameterDelta.cs new file mode 100644 index 0000000..d4a5ccf --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PerformanceStates20ParameterDelta.cs @@ -0,0 +1,92 @@ +using System.Runtime.InteropServices; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Hold information regarding delta values and delta ranges for voltages or clock frequencies in their respective unit + /// (uV or kHz) + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PerformanceStates20ParameterDelta + { + internal int _DeltaValue; + internal PerformanceState20ParameterDeltaValueRange _DeltaRange; + + /// + /// Creates a new instance of + /// + /// The delta value. + /// The delta range minimum value. + /// The delta range maximum value. + public PerformanceStates20ParameterDelta(int deltaValue, int deltaMinimum, int deltaMaximum) + { + _DeltaValue = deltaValue; + _DeltaRange = new PerformanceState20ParameterDeltaValueRange(deltaMinimum, deltaMaximum); + } + + + /// + /// Creates a new instance of + /// + /// The delta value. + public PerformanceStates20ParameterDelta(int deltaValue) + { + _DeltaValue = deltaValue; + _DeltaRange = new PerformanceState20ParameterDeltaValueRange(); + } + + /// + /// Gets the delta value in the respective unit (uV or kHz) + /// + public int DeltaValue + { + get => _DeltaValue; + set => _DeltaValue = value; + } + + /// + /// Gets the range of the valid delta values in the respective unit (uV or kHz) + /// + public PerformanceState20ParameterDeltaValueRange DeltaRange + { + get => _DeltaRange; + } + + /// + /// Holds information regarding a range of values + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PerformanceState20ParameterDeltaValueRange + { + internal int _Minimum; + internal int _Maximum; + + /// + /// Creates a new instance of . + /// + /// The minimum value of delta range. + /// The maximum value of delta range. + public PerformanceState20ParameterDeltaValueRange(int minimum, int maximum) + { + _Minimum = minimum; + _Maximum = maximum; + } + + /// + /// Gets the minimum value + /// + public int Minimum + { + get => _Minimum; + } + + /// + /// Gets the maximum value + /// + public int Maximum + { + get => _Maximum; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PerformanceStatesInfoV1.cs b/NvAPIWrapper/Native/GPU/Structures/PerformanceStatesInfoV1.cs new file mode 100644 index 0000000..90966c7 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PerformanceStatesInfoV1.cs @@ -0,0 +1,156 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PerformanceStatesInfoV1 : IInitializable, IPerformanceStatesInfo + { + internal const int MaxPerformanceStates = 16; + internal const int MaxPerformanceStateClocks = 32; + + internal StructureVersion _Version; + internal uint _Flags; + internal uint _NumberOfPerformanceStates; + internal uint _NumberOfClocks; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxPerformanceStates)] + internal PerformanceState[] _PerformanceStates; + + /// + public bool IsPerformanceMonitorEnable + { + get => _Flags.GetBit(0); + } + + /// + public bool IsCapableOfDynamicPerformance + { + get => _Flags.GetBit(1); + } + + /// + public bool IsDynamicPerformanceEnable + { + get => _Flags.GetBit(2); + } + + /// + /// Gets an array of valid and available performance states information + /// + public PerformanceState[] PerformanceStates + { + get => _PerformanceStates.Take((int) _NumberOfPerformanceStates).ToArray(); + } + + /// + IPerformanceState[] IPerformanceStatesInfo.PerformanceStates + { + get => PerformanceStates.Cast().ToArray(); + } + + /// + public IReadOnlyDictionary PerformanceStatesVoltages + { + get => new ReadOnlyDictionary( + new Dictionary() + ); + } + + /// + /// Gets a dictionary of valid and available performance states and their clock information as an array + /// + public IReadOnlyDictionary + PerformanceStatesClocks + { + get + { + var clocks = (int) _NumberOfClocks; + + return PerformanceStates.ToDictionary( + state => state.StateId, + state => state._Clocks.Take(clocks).ToArray() + ); + } + } + + /// + IReadOnlyDictionary IPerformanceStatesInfo. + PerformanceStatesClocks + { + get + { + return PerformanceStatesClocks.ToDictionary( + pair => pair.Key, + pair => pair.Value.Cast().ToArray() + ); + } + } + + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PerformanceState : IInitializable, IPerformanceState + { + internal PerformanceStateId _Id; + internal uint _Flags; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxPerformanceStateClocks)] + internal PerformanceStatesClock[] _Clocks; + + /// + public PerformanceStateId StateId + { + get => _Id; + } + + /// + public bool IsPCIELimited + { + get => _Flags.GetBit(0); + } + + /// + public bool IsOverclocked + { + get => _Flags.GetBit(1); + } + + /// + public bool IsOverclockable + { + get => _Flags.GetBit(2); + } + + + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PerformanceStatesClock : IInitializable, IPerformanceStatesClock + { + internal PublicClockDomain _Id; + internal uint _Flags; + internal uint _Frequency; + + /// + public PublicClockDomain DomainId + { + get => _Id; + } + + /// + public uint Frequency + { + get => _Frequency; + } + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PerformanceStatesInfoV2.cs b/NvAPIWrapper/Native/GPU/Structures/PerformanceStatesInfoV2.cs new file mode 100644 index 0000000..6dfb3f6 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PerformanceStatesInfoV2.cs @@ -0,0 +1,210 @@ +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + public struct PerformanceStatesInfoV2 : IInitializable, IPerformanceStatesInfo + { + internal const int MaxPerformanceStates = PerformanceStatesInfoV1.MaxPerformanceStates; + internal const int MaxPerformanceStateClocks = PerformanceStatesInfoV1.MaxPerformanceStateClocks; + internal const int MaxPerformanceStateVoltages = 16; + + internal StructureVersion _Version; + internal uint _Flags; + internal uint _NumberOfPerformanceStates; + internal uint _NumberOfClocks; + internal uint _NumberOfVoltages; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxPerformanceStates)] + internal PerformanceState[] _PerformanceStates; + + /// + public bool IsPerformanceMonitorEnable + { + get => _Flags.GetBit(0); + } + + /// + public bool IsCapableOfDynamicPerformance + { + get => _Flags.GetBit(1); + } + + /// + public bool IsDynamicPerformanceEnable + { + get => _Flags.GetBit(2); + } + + /// + /// Gets an array of valid and available performance states information + /// + public PerformanceState[] PerformanceStates + { + get => _PerformanceStates.Take((int) _NumberOfPerformanceStates).ToArray(); + } + + /// + IPerformanceState[] IPerformanceStatesInfo.PerformanceStates + { + get => PerformanceStates.Cast().ToArray(); + } + + /// + /// Gets a dictionary of valid and available performance states and their voltage information as an array + /// + public IReadOnlyDictionary + PerformanceStatesVoltages + { + get + { + var voltages = (int) _NumberOfVoltages; + + return PerformanceStates.ToDictionary( + state => state.StateId, + state => state._Voltages.Take(voltages).ToArray() + ); + } + } + + /// + IReadOnlyDictionary IPerformanceStatesInfo. + PerformanceStatesVoltages + { + get + { + return PerformanceStatesVoltages.ToDictionary( + pair => pair.Key, + pair => pair.Value.Cast().ToArray() + ); + } + } + + /// + /// Gets a dictionary of valid and available performance states and their clock information as an array + /// + public IReadOnlyDictionary + PerformanceStatesClocks + { + get + { + var clocks = (int) _NumberOfClocks; + + return PerformanceStates.ToDictionary( + state => state.StateId, + state => state._Clocks.Take(clocks).ToArray() + ); + } + } + + /// + IReadOnlyDictionary IPerformanceStatesInfo. + PerformanceStatesClocks + { + get + { + return PerformanceStatesClocks.ToDictionary( + pair => pair.Key, + pair => pair.Value.Cast().ToArray() + ); + } + } + + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PerformanceState : IInitializable, IPerformanceState + { + internal PerformanceStateId _Id; + internal uint _Flags; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxPerformanceStateClocks)] + internal PerformanceStatesClock[] _Clocks; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxPerformanceStateVoltages)] + internal PerformanceStatesVoltage[] _Voltages; + + /// + public PerformanceStateId StateId + { + get => _Id; + } + + /// + public bool IsPCIELimited + { + get => _Flags.GetBit(0); + } + + /// + public bool IsOverclocked + { + get => _Flags.GetBit(1); + } + + /// + public bool IsOverclockable + { + get => _Flags.GetBit(2); + } + + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PerformanceStatesVoltage : IInitializable, IPerformanceStatesVoltage + { + internal PerformanceVoltageDomain _Id; + internal uint _Flags; + internal uint _Value; + + /// + public PerformanceVoltageDomain DomainId + { + get => _Id; + } + + /// + public uint Value + { + get => _Value; + } + } + + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PerformanceStatesClock : IInitializable, IPerformanceStatesClock + { + internal PublicClockDomain _Id; + internal uint _Flags; + internal uint _Frequency; + + /// + /// Gets a boolean value indicating if this clock domain is overclockable + /// + public bool IsOverclockable + { + get => _Flags.GetBit(0); + } + + /// + public PublicClockDomain DomainId + { + get => _Id; + } + + /// + public uint Frequency + { + get => _Frequency; + } + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PerformanceStatesInfoV3.cs b/NvAPIWrapper/Native/GPU/Structures/PerformanceStatesInfoV3.cs new file mode 100644 index 0000000..6c85388 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PerformanceStatesInfoV3.cs @@ -0,0 +1,124 @@ +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(3)] + public struct PerformanceStatesInfoV3 : IInitializable, IPerformanceStatesInfo + { + internal const int MaxPerformanceStates = PerformanceStatesInfoV2.MaxPerformanceStates; + internal const int MaxPerformanceStateClocks = PerformanceStatesInfoV2.MaxPerformanceStateClocks; + internal const int MaxPerformanceStateVoltages = PerformanceStatesInfoV2.MaxPerformanceStateVoltages; + + internal StructureVersion _Version; + internal uint _Flags; + internal uint _NumberOfPerformanceStates; + internal uint _NumberOfClocks; + internal uint _NumberOfVoltages; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxPerformanceStates)] + internal PerformanceStatesInfoV2.PerformanceState[] _PerformanceStates; + + /// + public bool IsPerformanceMonitorEnable + { + get => _Flags.GetBit(0); + } + + /// + public bool IsCapableOfDynamicPerformance + { + get => _Flags.GetBit(1); + } + + /// + public bool IsDynamicPerformanceEnable + { + get => _Flags.GetBit(2); + } + + /// + /// Gets an array of valid and available performance states information + /// + public PerformanceStatesInfoV2.PerformanceState[] PerformanceStates + { + get => _PerformanceStates.Take((int) _NumberOfPerformanceStates).ToArray(); + } + + /// + IPerformanceState[] IPerformanceStatesInfo.PerformanceStates + { + get => PerformanceStates.Cast().ToArray(); + } + + /// + /// Gets a dictionary of valid and available performance states and their voltage information as an array + /// + public IReadOnlyDictionary + PerformanceStatesVoltages + { + get + { + var voltages = (int) _NumberOfVoltages; + + return PerformanceStates.ToDictionary( + state => state.StateId, + state => state._Voltages.Take(voltages).ToArray() + ); + } + } + + /// + IReadOnlyDictionary IPerformanceStatesInfo. + PerformanceStatesVoltages + { + get + { + return PerformanceStatesVoltages.ToDictionary( + pair => pair.Key, + pair => pair.Value.Cast().ToArray() + ); + } + } + + /// + /// Gets a dictionary of valid and available performance states and their clock information as an array + /// + public IReadOnlyDictionary + PerformanceStatesClocks + { + get + { + var clocks = (int) _NumberOfClocks; + + return PerformanceStates.ToDictionary( + state => state.StateId, + state => state._Clocks.Take(clocks).ToArray() + ); + } + } + + /// + IReadOnlyDictionary IPerformanceStatesInfo. + PerformanceStatesClocks + { + get + { + return PerformanceStatesClocks.ToDictionary( + pair => pair.Key, + pair => pair.Value.Cast().ToArray() + ); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PhysicalGPUHandle.cs b/NvAPIWrapper/Native/GPU/Structures/PhysicalGPUHandle.cs new file mode 100644 index 0000000..6f06263 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PhysicalGPUHandle.cs @@ -0,0 +1,98 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// PhysicalGPUHandle is a reference to a physical GPU. Each GPU in a multi-GPU board will have its own handle. GPUs + /// are assigned a handle even if they are not in use by the OS. + /// + [StructLayout(LayoutKind.Sequential)] + public struct PhysicalGPUHandle : IHandle, IEquatable + { + /// + /// Queryable number of physical GPUs + /// + public const int PhysicalGPUs = 32; + + /// + /// Maximum number of physical GPUs + /// + public const int MaxPhysicalGPUs = 64; + + internal readonly IntPtr _MemoryAddress; + + /// + public bool Equals(PhysicalGPUHandle other) + { + return _MemoryAddress.Equals(other._MemoryAddress); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is PhysicalGPUHandle handle && Equals(handle); + } + + /// + public override int GetHashCode() + { + return _MemoryAddress.GetHashCode(); + } + + + /// + public override string ToString() + { + return $"PhysicalGPUHandle #{MemoryAddress.ToInt64()}"; + } + + /// + public IntPtr MemoryAddress + { + get => _MemoryAddress; + } + + /// + public bool IsNull + { + get => _MemoryAddress == IntPtr.Zero; + } + + /// + /// Checks for equality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are equal, otherwise false + public static bool operator ==(PhysicalGPUHandle left, PhysicalGPUHandle right) + { + return left.Equals(right); + } + + /// + /// Checks for inequality between two objects of same type + /// + /// The first object + /// The second object + /// true, if both objects are not equal, otherwise false + public static bool operator !=(PhysicalGPUHandle left, PhysicalGPUHandle right) + { + return !left.Equals(right); + } + + /// + /// Gets default PhysicalGPUHandle with a null pointer + /// + public static PhysicalGPUHandle DefaultHandle + { + get => default(PhysicalGPUHandle); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateActiveApplicationV2.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateActiveApplicationV2.cs new file mode 100644 index 0000000..3f758f0 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateActiveApplicationV2.cs @@ -0,0 +1,28 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + [StructureVersion(2)] + [StructLayout(LayoutKind.Sequential)] + public struct PrivateActiveApplicationV2 : IInitializable + { + internal const int MaximumNumberOfApplications = 128; + + internal StructureVersion _Version; + internal uint _ProcessId; + internal LongString _ProcessName; + + public int ProcessId + { + get => (int) _ProcessId; + } + + public string ProcessName + { + get => _ProcessName.Value; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateArchitectInfoV2.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateArchitectInfoV2.cs new file mode 100644 index 0000000..0cf5e70 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateArchitectInfoV2.cs @@ -0,0 +1,28 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding a GPU architecture + /// + [StructLayout(LayoutKind.Sequential)] + [StructureVersion(2)] + public struct PrivateArchitectInfoV2 : IInitializable + { + internal StructureVersion _Version; + internal uint _Unknown1; + internal uint _Unknown2; + internal uint _Revision; + + /// + /// Gets the GPU revision + /// + public uint Revision + { + get => _Revision; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateClockBoostLockV2.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateClockBoostLockV2.cs new file mode 100644 index 0000000..e990def --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateClockBoostLockV2.cs @@ -0,0 +1,108 @@ +using System; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding the GPU clock boost locks + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + public struct PrivateClockBoostLockV2 : IInitializable + { + internal const int MaxNumberOfClocksPerGPU = ClockFrequenciesV1.MaxClocksPerGPU; + + internal StructureVersion _Version; + internal uint _Unknown; + internal uint _ClockBoostLocksCount; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfClocksPerGPU)] + internal ClockBoostLock[] _ClockBoostLocks; + + /// + /// Gets the list of clock boost locks + /// + public ClockBoostLock[] ClockBoostLocks + { + get => _ClockBoostLocks.Take((int) _ClockBoostLocksCount).ToArray(); + } + + /// + /// Creates a new instance of + /// + /// The list of clock boost locks + public PrivateClockBoostLockV2(ClockBoostLock[] clockBoostLocks) + { + if (clockBoostLocks?.Length > MaxNumberOfClocksPerGPU) + { + throw new ArgumentException($"Maximum of {MaxNumberOfClocksPerGPU} clocks are configurable.", + nameof(clockBoostLocks)); + } + + if (clockBoostLocks == null || clockBoostLocks.Length == 0) + { + throw new ArgumentException("Array is null or empty.", nameof(clockBoostLocks)); + } + + this = typeof(PrivateClockBoostLockV2).Instantiate(); + _ClockBoostLocksCount = (uint) clockBoostLocks.Length; + Array.Copy(clockBoostLocks, 0, _ClockBoostLocks, 0, clockBoostLocks.Length); + } + + /// + /// Contains information regarding a clock boost lock + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct ClockBoostLock + { + internal PublicClockDomain _ClockDomain; + internal uint _Unknown1; + internal ClockLockMode _LockMode; + internal uint _Unknown2; + internal uint _VoltageInMicroV; + internal uint _Unknown3; + + /// + /// Gets the public clock domain + /// + public PublicClockDomain ClockDomain + { + get => _ClockDomain; + } + + /// + /// Gets the clock lock mode + /// + public ClockLockMode LockMode + { + get => _LockMode; + } + + /// + /// Gets the locked voltage in uV + /// + public uint VoltageInMicroV + { + get => _VoltageInMicroV; + } + + /// + /// Creates a new instance of . + /// + /// The public clock domain. + /// The clock lock mode. + /// The locked voltage in uV. + public ClockBoostLock(PublicClockDomain clockDomain, ClockLockMode lockMode, uint voltageInMicroV) : this() + { + _ClockDomain = clockDomain; + _LockMode = lockMode; + _VoltageInMicroV = voltageInMicroV; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateClockBoostMasksV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateClockBoostMasksV1.cs new file mode 100644 index 0000000..ba96b82 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateClockBoostMasksV1.cs @@ -0,0 +1,72 @@ +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; +using System.Runtime.InteropServices; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU clock boost masks + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivateClockBoostMasksV1 : IInitializable + { + internal const int MaxMasks = 4; + internal const int MaxUnknown1 = 8; + internal const int MaxClockBoostMasks = 103; + internal const int MaxUnknown2 = 916; + + internal StructureVersion _Version; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxMasks)] + public uint[] _Masks; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxUnknown1)] + public uint[] _Unknown1; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxClockBoostMasks)] + internal readonly ClockBoostMask[] _ClocksBoostMasks; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxUnknown2)] + internal readonly uint[] _Unknown2; + + /// + /// Gets a list of clock boost masks + /// + public ClockBoostMask[] ClockBoostMasks + { + get => _ClocksBoostMasks; + } + + /// + /// Contains information regarding a clock boost mask + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct ClockBoostMask + { + internal readonly uint _Unknown; + internal readonly uint _Unknown2; + internal readonly uint _Unknown3; + internal readonly uint _Unknown4; + internal readonly int _MemoryDelta; + internal readonly int _GPUDelta; + + /// + /// Memory clock frequency delta + /// + public int MemoryDelta + { + get => _MemoryDelta; + } + + /// + /// GPU clock frequency delta + /// + public int GPUDelta + { + get => _GPUDelta; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateClockBoostRangesV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateClockBoostRangesV1.cs new file mode 100644 index 0000000..465b519 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateClockBoostRangesV1.cs @@ -0,0 +1,94 @@ +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU clock boost ranges + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivateClockBoostRangesV1 : IInitializable + { + internal const int MaxNumberOfClocksPerGPU = ClockFrequenciesV1.MaxClocksPerGPU; + internal const int MaxNumberOfUnknown = 8; + + internal StructureVersion _Version; + internal uint _ClockBoostRangesCount; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfUnknown)] + internal uint[] _Unknown; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfClocksPerGPU)] + internal ClockBoostRange[] _ClockBoostRanges; + + /// + /// Gets a list of clock boost ranges + /// + public ClockBoostRange[] ClockBoostRanges + { + get => _ClockBoostRanges.Take((int) _ClockBoostRangesCount).ToArray(); + } + + /// + /// Contains information regarding a clock boost range + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct ClockBoostRange + { + internal uint _Unknown1; + internal ClockType _ClockType; + internal uint _Unknown2; + internal uint _Unknown3; + internal uint _Unknown4; + internal uint _Unknown5; + internal uint _Unknown6; + internal uint _Unknown7; + internal uint _Unknown8; + internal uint _Unknown9; + internal int _RangeMaximumInkHz; + internal int _RangeMinimumInkHz; + internal int _MaximumTemperature; + internal uint _Unknown10; + internal uint _Unknown11; + internal uint _Unknown12; + internal uint _Unknown13; + internal uint _Unknown14; + + /// + /// Gets the clock type + /// + public ClockType ClockType + { + get => _ClockType; + } + + /// + /// Gets the maximum boost frequency in kHz + /// + public int MaximumInkHz + { + get => _RangeMaximumInkHz; + } + + /// + /// Gets the minimum boost frequency in kHz + /// + public int MinimumInkHz + { + get => _RangeMinimumInkHz; + } + + /// + /// Gets the maximum boost temperature + /// + public int MaximumTemperature + { + get => _MaximumTemperature; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateClockBoostTableV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateClockBoostTableV1.cs new file mode 100644 index 0000000..c4c4177 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateClockBoostTableV1.cs @@ -0,0 +1,110 @@ +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using System; +using System.Runtime.InteropServices; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU clock boost table + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion()] + public struct PrivateClockBoostTableV1 : IInitializable + { + internal const int MaxNumberOfMasks = 4; + internal const int MaxNumberOfUnknown1 = 12; + internal const int MaxNumberOfGPUDeltas = 80; + internal const int MaxNumberOfMemoryFilled = 23; + internal const int MaxNumberOfMemoryDeltas = 23; + internal const int MaxNumberOfUnknown2 = 1529; + + internal StructureVersion _Version; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfMasks)] + internal uint[] _Masks; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfUnknown1)] + internal uint[] _Unknown1; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfGPUDeltas)] + internal GPUDelta[] _GPUDeltas; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfMemoryFilled)] + internal uint[] _MemoryFilled; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfMemoryDeltas)] + internal int[] _MemoryDeltas; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfUnknown2)] + internal uint[] _Unknown2; + + /// + /// Gets a list of clock delta entries + /// + public GPUDelta[] GPUDeltas + { + get => _GPUDeltas; + } + + /// + /// Creates a new instance of + /// + /// The list of GPU clock frequency delta entries. + // ReSharper disable once TooManyDependencies + public PrivateClockBoostTableV1(GPUDelta[] gpuDeltas) + { + if (gpuDeltas?.Length > MaxNumberOfGPUDeltas) + { + throw new ArgumentException($"Maximum of {MaxNumberOfGPUDeltas} GPU delta values are configurable.", + nameof(gpuDeltas)); + } + + if (gpuDeltas == null) + { + throw new ArgumentNullException(nameof(gpuDeltas)); + } + + this = typeof(PrivateClockBoostTableV1).Instantiate(); + + Array.Copy(gpuDeltas, 0, _GPUDeltas, 0, gpuDeltas.Length); + } + + + /// + /// Contains information regarding a GPU delta entry in the clock boost table + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct GPUDelta + { + internal uint _Unknown1; + internal uint _Unknown2; + internal uint _Unknown3; + internal uint _Unknown4; + internal uint _Unknown5; + internal int _FrequencyDeltaInkHz; + internal uint _Unknown7; + internal uint _Unknown8; + internal uint _Unknown9; + + /// + /// Gets the frequency delta in kHz + /// + public int FrequencyDeltaInkHz + { + get => _FrequencyDeltaInkHz; + } + + /// + /// Creates a new instance of GPUDelta. + /// + /// The clock frequency in kHz. + public GPUDelta(int frequencyDeltaInkHz) : this() + { + _FrequencyDeltaInkHz = frequencyDeltaInkHz; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateClockBoostTableV2.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateClockBoostTableV2.cs new file mode 100644 index 0000000..9baedf1 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateClockBoostTableV2.cs @@ -0,0 +1,93 @@ +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; +using System; +using System.Runtime.InteropServices; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU clock boost table + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + public struct PrivateClockBoostTableV2 : IInitializable + { + internal const int MaxNumberOfMasks = 4; + internal const int MaxNumberOfUnknown1 = 12; + internal const int MaxNumberOfClocks = 255; + + internal StructureVersion _Version; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfMasks)] + internal uint[] _Masks; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfUnknown1)] + internal uint[] _Unknown1; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfClocks)] + internal GPUDelta[] _GPUDeltas; + + /// + /// Gets a list of clock delta entries + /// + public GPUDelta[] GPUDeltas + { + get => _GPUDeltas; + } + + /// + /// Creates a new instance of + /// + /// The list of GPU clock frequency delta entries. + // ReSharper disable once TooManyDependencies + public PrivateClockBoostTableV2(GPUDelta[] gpuDeltas) + { + this = typeof(PrivateClockBoostTableV2).Instantiate(); + + Array.Copy(gpuDeltas, 0, _GPUDeltas, 0, gpuDeltas.Length); + } + + + /// + /// Contains information regarding a GPU delta entry in the clock boost table + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct GPUDelta + { + internal uint _ClockType; + internal uint _Unknown2; + internal uint _Unknown3; + internal uint _Unknown4; + internal uint _Unknown5; + internal int _FrequencyDeltaInkHz; + internal uint _Unknown7; + internal uint _Unknown8; + internal uint _Unknown9; + + /// + /// Gets the frequency delta in kHz + /// + public int FrequencyDeltaInkHz + { + get => _FrequencyDeltaInkHz; + set => _FrequencyDeltaInkHz = value; + } + + public uint ClockType + { + get => _ClockType; + } + + /// + /// Creates a new instance of GPUDelta. + /// + /// The clock frequency in kHz. + public GPUDelta(int frequencyDeltaInkHz) : this() + { + _FrequencyDeltaInkHz = frequencyDeltaInkHz; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateCoolerLevelsV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateCoolerLevelsV1.cs new file mode 100644 index 0000000..b5dc289 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateCoolerLevelsV1.cs @@ -0,0 +1,116 @@ +using System; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU cooler levels + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivateCoolerLevelsV1 : IInitializable + { + internal const int MaxNumberOfCoolersPerGPU = PrivateCoolerSettingsV1.MaxNumberOfCoolersPerGPU; + + internal StructureVersion _Version; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfCoolersPerGPU)] + internal CoolerLevel[] _CoolerLevels; + + /// + /// Gets the list of cooler levels. + /// + /// The number of cooler levels to return. + /// An array of instances. + public CoolerLevel[] GetCoolerLevels(int count) + { + return _CoolerLevels.Take(count).ToArray(); + } + + /// + /// Creates a new instance of . + /// + /// The list of cooler levels. + public PrivateCoolerLevelsV1(CoolerLevel[] levels) + { + if (levels?.Length > MaxNumberOfCoolersPerGPU) + { + throw new ArgumentException($"Maximum of {MaxNumberOfCoolersPerGPU} cooler levels are configurable.", + nameof(levels)); + } + + if (levels == null || levels.Length == 0) + { + throw new ArgumentException("Array is null or empty.", nameof(levels)); + } + + this = typeof(PrivateCoolerLevelsV1).Instantiate(); + Array.Copy(levels, 0, _CoolerLevels, 0, levels.Length); + } + + /// + /// Contains information regarding a cooler level + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct CoolerLevel + { + internal uint _CurrentLevel; + internal CoolerPolicy _CurrentPolicy; + + /// + /// Creates a new instance of + /// + /// The cooler policy. + /// The cooler level in percentage. + public CoolerLevel(CoolerPolicy coolerPolicy, uint level) + { + _CurrentPolicy = coolerPolicy; + _CurrentLevel = level; + } + + /// + /// Creates a new instance of + /// + /// The cooler policy. + public CoolerLevel(CoolerPolicy coolerPolicy) : this(coolerPolicy, 0) + { + if (coolerPolicy == CoolerPolicy.Manual) + { + throw new ArgumentException( + "Manual policy is not valid when no level value is provided.", + nameof(coolerPolicy) + ); + } + } + + /// + /// Creates a new instance of + /// + /// The cooler level in percentage. + public CoolerLevel(uint level) : this(CoolerPolicy.Manual, level) + { + } + + /// + /// Gets the cooler level in percentage. + /// + public uint CurrentLevel + { + get => _CurrentLevel; + } + + /// + /// Gets the cooler policy + /// + public CoolerPolicy CoolerPolicy + { + get => _CurrentPolicy; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateCoolerPolicyTableV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateCoolerPolicyTableV1.cs new file mode 100644 index 0000000..5468357 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateCoolerPolicyTableV1.cs @@ -0,0 +1,115 @@ +using System; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU cooler policy table + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivateCoolerPolicyTableV1 : IInitializable + { + internal const int MaxNumberOfPolicyLevels = 24; + + internal StructureVersion _Version; + internal CoolerPolicy _Policy; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfPolicyLevels)] + internal readonly CoolerPolicyTableEntry[] _TableEntries; + + /// + /// Gets an array of policy table entries + /// + /// The number of table entries. + /// An array of instances. + public CoolerPolicyTableEntry[] TableEntries(int count) + { + return _TableEntries.Take(count).ToArray(); + } + + /// + /// Gets the table cooler policy + /// + public CoolerPolicy Policy + { + get => _Policy; + } + + /// + /// Creates a new instance of + /// + /// The table cooler policy. + /// An array of table entries. + public PrivateCoolerPolicyTableV1(CoolerPolicy policy, CoolerPolicyTableEntry[] policyTableEntries) + { + if (policyTableEntries?.Length > MaxNumberOfPolicyLevels) + { + throw new ArgumentException($"Maximum of {MaxNumberOfPolicyLevels} policy levels are configurable.", + nameof(policyTableEntries)); + } + + if (policyTableEntries == null || policyTableEntries.Length == 0) + { + throw new ArgumentException("Array is null or empty.", nameof(policyTableEntries)); + } + + this = typeof(PrivateCoolerPolicyTableV1).Instantiate(); + _Policy = policy; + Array.Copy(policyTableEntries, 0, _TableEntries, 0, policyTableEntries.Length); + } + + /// + /// Contains information regarding a clock boost mask + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct CoolerPolicyTableEntry + { + internal uint _EntryId; + internal uint _CurrentLevel; + internal uint _DefaultLevel; + + /// + /// Gets the entry identification number + /// + public uint EntryId + { + get => _EntryId; + } + + /// + /// Gets the current level in percentage + /// + public uint CurrentLevel + { + get => _CurrentLevel; + } + + /// + /// Gets the default level in percentage + /// + public uint DefaultLevel + { + get => _DefaultLevel; + } + + /// + /// Creates a new instance of . + /// + /// The entry identification number. + /// The current level in percentage. + /// The default level in percentage. + public CoolerPolicyTableEntry(uint entryId, uint currentLevel, uint defaultLevel) + { + _EntryId = entryId; + _CurrentLevel = currentLevel; + _DefaultLevel = defaultLevel; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateCoolerSettingsV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateCoolerSettingsV1.cs new file mode 100644 index 0000000..703bef6 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateCoolerSettingsV1.cs @@ -0,0 +1,140 @@ +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU cooler settings + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivateCoolerSettingsV1 : IInitializable + { + internal const int MaxNumberOfCoolersPerGPU = 3; + + internal StructureVersion _Version; + internal readonly uint _CoolerSettingsCount; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfCoolersPerGPU)] + internal readonly CoolerSetting[] _CoolerSettings; + + /// + /// Gets the list of cooler settings + /// + public CoolerSetting[] CoolerSettings + { + get => _CoolerSettings.Take((int) _CoolerSettingsCount).ToArray(); + } + + /// + /// Contains information regarding a cooler settings + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct CoolerSetting + { + internal CoolerType _CoolerType; + internal CoolerController _CoolerController; + internal uint _DefaultMinimumLevel; + internal uint _DefaultMaximumLevel; + internal uint _CurrentMinimumLevel; + internal uint _CurrentMaximumLevel; + internal uint _CurrentLevel; + internal CoolerPolicy _DefaultPolicy; + internal CoolerPolicy _CurrentPolicy; + internal CoolerTarget _Target; + internal CoolerControlMode _ControlMode; + internal uint _IsActive; + + /// + /// Gets the current cooler level in percentage. + /// + public uint CurrentLevel + { + get => _CurrentLevel; + } + + /// + /// Gets the default minimum cooler level in percentage. + /// + public uint DefaultMinimumLevel + { + get => _DefaultMinimumLevel; + } + + /// + /// Gets the default maximum cooler level in percentage. + /// + public uint DefaultMaximumLevel + { + get => _DefaultMaximumLevel; + } + + /// + /// Gets the current minimum cooler level in percentage. + /// + public uint CurrentMinimumLevel + { + get => _CurrentMinimumLevel; + } + + /// + /// Gets the current maximum cooler level in percentage. + /// + public uint CurrentMaximumLevel + { + get => _CurrentMaximumLevel; + } + + /// + /// Gets the cooler type. + /// + public CoolerType CoolerType + { + get => _CoolerType; + } + + /// + /// Gets the cooler controller. + /// + public CoolerController CoolerController + { + get => _CoolerController; + } + + /// + /// Gets the cooler default policy. + /// + public CoolerPolicy DefaultPolicy + { + get => _DefaultPolicy; + } + + /// + /// Gets the cooler current policy. + /// + public CoolerPolicy CurrentPolicy + { + get => _CurrentPolicy; + } + + /// + /// Gets the cooler target. + /// + public CoolerTarget Target + { + get => _Target; + } + + /// + /// Gets the cooler control mode. + /// + public CoolerControlMode ControlMode + { + get => _ControlMode; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateFanCoolersControlV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateFanCoolersControlV1.cs new file mode 100644 index 0000000..f64f4fd --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateFanCoolersControlV1.cs @@ -0,0 +1,105 @@ +using System; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivateFanCoolersControlV1 : IInitializable + { + internal const int MaxNumberOfFanCoolerControlEntries = 32; + internal StructureVersion _Version; + internal readonly uint _UnknownUInt; + internal readonly uint _FanCoolersControlCount; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.U4)] + internal readonly uint[] _Reserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfFanCoolerControlEntries)] + internal readonly FanCoolersControlEntry[] _FanCoolersControlEntries; + + public FanCoolersControlEntry[] FanCoolersControlEntries + { + get => _FanCoolersControlEntries.Take((int) _FanCoolersControlCount).ToArray(); + } + + public uint UnknownUInt + { + get => _UnknownUInt; + } + + public PrivateFanCoolersControlV1(FanCoolersControlEntry[] entries, uint unknownUInt = 0) + { + if (entries?.Length > MaxNumberOfFanCoolerControlEntries) + { + throw new ArgumentException( + $"Maximum of {MaxNumberOfFanCoolerControlEntries} coolers are configurable.", + nameof(entries)); + } + + if (entries == null || entries.Length == 0) + { + throw new ArgumentException("Array is null or empty.", nameof(entries)); + } + + entries = entries.OrderBy(entry => entry.CoolerId).ToArray(); + + this = typeof(PrivateFanCoolersControlV1).Instantiate(); + _UnknownUInt = unknownUInt; + _FanCoolersControlCount = (uint) entries.Length; + Array.Copy(entries, 0, _FanCoolersControlEntries, 0, entries.Length); + } + + + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct FanCoolersControlEntry + { + internal readonly uint _CoolerId; + internal readonly uint _Level; + internal readonly FanCoolersControlMode _ControlMode; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.U4)] + internal readonly uint[] _Reserved; + + public FanCoolersControlEntry(uint coolerId, FanCoolersControlMode controlMode, uint level) + { + this = typeof(FanCoolersControlEntry).Instantiate(); + _CoolerId = coolerId; + _ControlMode = controlMode; + _Level = level; + } + + public FanCoolersControlEntry(uint coolerId, FanCoolersControlMode controlMode) : this(coolerId, + controlMode, 0) + { + if (controlMode == FanCoolersControlMode.Manual) + { + throw new ArgumentException( + "Manual control mode is not valid when no level value is provided.", + nameof(controlMode) + ); + } + } + + public uint CoolerId + { + get => _CoolerId; + } + + public uint Level + { + get => _Level; + } + + public FanCoolersControlMode ControlMode + { + get => _ControlMode; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateFanCoolersInfoV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateFanCoolersInfoV1.cs new file mode 100644 index 0000000..cc60cfd --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateFanCoolersInfoV1.cs @@ -0,0 +1,52 @@ +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivateFanCoolersInfoV1 : IInitializable + { + internal const int MaxNumberOfFanCoolerInfoEntries = 32; + + internal StructureVersion _Version; + internal readonly uint _UnknownUInt1; + internal readonly uint _FanCoolersInfoCount; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.U4)] + internal readonly uint[] _Reserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfFanCoolerInfoEntries)] + internal readonly FanCoolersInfoEntry[] _FanCoolersInfoEntries; + + public FanCoolersInfoEntry[] FanCoolersInfoEntries + { + get => _FanCoolersInfoEntries.Take((int) _FanCoolersInfoCount).ToArray(); + } + + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct FanCoolersInfoEntry + { + internal readonly uint _CoolerId; + internal readonly uint _UnknownUInt3; + internal readonly uint _UnknownUInt4; + internal readonly uint _MaximumRPM; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.U4)] + internal readonly uint[] _Reserved; + + public uint CoolerId + { + get => _CoolerId; + } + + public uint MaximumRPM + { + get => _MaximumRPM; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateFanCoolersStatusV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateFanCoolersStatusV1.cs new file mode 100644 index 0000000..a73ae99 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateFanCoolersStatusV1.cs @@ -0,0 +1,67 @@ +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivateFanCoolersStatusV1 : IInitializable + { + internal const int MaxNumberOfFanCoolerStatusEntries = 32; + + internal StructureVersion _Version; + internal readonly uint _FanCoolersStatusCount; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.U4)] + internal readonly uint[] _Reserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfFanCoolerStatusEntries)] + internal readonly FanCoolersStatusEntry[] _FanCoolersStatusEntries; + + public FanCoolersStatusEntry[] FanCoolersStatusEntries + { + get => _FanCoolersStatusEntries.Take((int) _FanCoolersStatusCount).ToArray(); + } + + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct FanCoolersStatusEntry + { + internal readonly uint _CoolerId; + internal readonly uint _CurrentRPM; + internal readonly uint _CurrentMinimumLevel; + internal readonly uint _CurrentMaximumLevel; + internal readonly uint _CurrentLevel; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.U4)] + internal readonly uint[] _Reserved; + + public uint CoolerId + { + get => _CoolerId; + } + + public uint CurrentRPM + { + get => _CurrentRPM; + } + + public uint CurrentMinimumLevel + { + get => _CurrentMinimumLevel; + } + + public uint CurrentMaximumLevel + { + get => _CurrentMaximumLevel; + } + + public uint CurrentLevel + { + get => _CurrentLevel; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivatePCIeInfoV2.cs b/NvAPIWrapper/Native/GPU/Structures/PrivatePCIeInfoV2.cs new file mode 100644 index 0000000..fc7c775 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivatePCIeInfoV2.cs @@ -0,0 +1,72 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU PCI-e connection configurations + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + public struct PrivatePCIeInfoV2 : IInitializable + { + internal StructureVersion _Version; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] + internal readonly PCIePerformanceStateInfo[] _PCIePerformanceStateInfos; + + /// + /// Gets the list of performance state PCI-e configurations information + /// + public PCIePerformanceStateInfo[] PCIePerformanceStateInfos + { + get => _PCIePerformanceStateInfos; + } + + /// + /// Contains information regarding a performance state PCI-e connection + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PCIePerformanceStateInfo + { + internal readonly uint _TransferRate; + internal readonly PCIeGeneration _Version; + internal readonly uint _LanesNumber; + internal readonly PCIeGeneration _Generation; + + /// + /// Gets the PCI-e transfer rate in Mega Transfers per Second + /// + public uint TransferRateInMTps + { + get => _TransferRate; + } + + /// + /// Gets the PCI-e generation + /// + public PCIeGeneration Generation + { + get => _Generation; + } + + /// + /// Gets the PCI-e down stream lanes + /// + public uint Lanes + { + get => _LanesNumber; + } + + /// + /// Gets the PCI-e version + /// + public PCIeGeneration Version + { + get => _Version; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivatePerformanceInfoV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivatePerformanceInfoV1.cs new file mode 100644 index 0000000..74f926a --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivatePerformanceInfoV1.cs @@ -0,0 +1,59 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU performance limitations + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivatePerformanceInfoV1 : IInitializable + { + internal const int MaxNumberOfUnknown2 = 16; + + internal StructureVersion _Version; + internal uint _Unknown1; + internal PerformanceLimit _SupportedLimits; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfUnknown2)] + internal uint[] _Unknown2; + + /// + /// Gets a boolean value indicating if performance limit by power usage is supported. + /// + public bool IsPowerLimitSupported + { + get => _SupportedLimits.HasFlag(PerformanceLimit.PowerLimit); + } + + + /// + /// Gets a boolean value indicating if performance limit by temperature is supported. + /// + public bool IsTemperatureLimitSupported + { + get => _SupportedLimits.HasFlag(PerformanceLimit.TemperatureLimit); + } + + + /// + /// Gets a boolean value indicating if performance limit by voltage usage is supported. + /// + public bool IsVoltageLimitSupported + { + get => _SupportedLimits.HasFlag(PerformanceLimit.VoltageLimit); + } + + + /// + /// Gets a boolean value indicating if performance limit by detecting no load is supported. + /// + public bool IsNoLoadLimitSupported + { + get => _SupportedLimits.HasFlag(PerformanceLimit.NoLoadLimit); + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivatePerformanceStatusV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivatePerformanceStatusV1.cs new file mode 100644 index 0000000..53672b8 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivatePerformanceStatusV1.cs @@ -0,0 +1,40 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU performance limitations status + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivatePerformanceStatusV1 : IInitializable + { + internal const int MaxNumberOfTimers = 3; + internal const int MaxNumberOfUnknown5 = 326; + + internal StructureVersion _Version; + internal uint _Unknown1; + internal ulong _TimerInNanoSecond; + internal PerformanceLimit _PerformanceLimit; + internal uint _Unknown2; + internal uint _Unknown3; + internal uint _Unknown4; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfTimers)] + internal ulong[] _TimersInNanoSecond; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfUnknown5)] + internal uint[] _Unknown5; + + /// + /// Gets the current effective performance limitation + /// + public PerformanceLimit PerformanceLimit + { + get => _PerformanceLimit; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivatePowerPoliciesInfoV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivatePowerPoliciesInfoV1.cs new file mode 100644 index 0000000..5e18331 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivatePowerPoliciesInfoV1.cs @@ -0,0 +1,84 @@ +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU power policies + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivatePowerPoliciesInfoV1 : IInitializable + { + internal const int MaxNumberOfPowerPolicyInfoEntries = 4; + + internal StructureVersion _Version; + internal readonly byte _Valid; + internal readonly byte _PowerPolicyEntriesCount; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfPowerPolicyInfoEntries)] + internal readonly PowerPolicyInfoEntry[] _PowerPolicyInfoEntries; + + /// + /// Gets a list of power policy entries + /// + public PowerPolicyInfoEntry[] PowerPolicyInfoEntries + { + get => _PowerPolicyInfoEntries.Take(_PowerPolicyEntriesCount).ToArray(); + } + + /// + /// Contains information regarding a GPU power policy entry + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PowerPolicyInfoEntry + { + internal PerformanceStateId _StateId; + internal uint _Unknown1; + internal uint _Unknown2; + internal uint _MinimumPower; + internal uint _Unknown3; + internal uint _Unknown4; + internal uint _DefaultPower; + internal uint _Unknown5; + internal uint _Unknown6; + internal uint _MaximumPower; + internal uint _Unknown7; + + /// + /// Gets the performance state identification number + /// + public PerformanceStateId PerformanceStateId + { + get => _StateId; + } + + /// + /// Gets the minimum power limit in per cent mille + /// + public uint MinimumPowerInPCM + { + get => _MinimumPower; + } + + /// + /// Gets the default power limit in per cent mille + /// + public uint DefaultPowerInPCM + { + get => _DefaultPower; + } + + /// + /// Gets the maximum power limit in per cent mille + /// + public uint MaximumPowerInPCM + { + get => _MaximumPower; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivatePowerPoliciesStatusV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivatePowerPoliciesStatusV1.cs new file mode 100644 index 0000000..c8438e3 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivatePowerPoliciesStatusV1.cs @@ -0,0 +1,102 @@ +using System; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU power policies status + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivatePowerPoliciesStatusV1 : IInitializable + { + internal const int MaxNumberOfPowerPoliciesStatusEntries = 4; + + internal StructureVersion _Version; + internal readonly uint _PowerPoliciesStatusEntriesCount; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfPowerPoliciesStatusEntries, + ArraySubType = UnmanagedType.Struct)] + internal readonly PowerPolicyStatusEntry[] _PowerPoliciesStatusEntries; + + /// + /// Gets a list of power policy status entries + /// + public PowerPolicyStatusEntry[] PowerPolicyStatusEntries + { + get => _PowerPoliciesStatusEntries.Take((int) _PowerPoliciesStatusEntriesCount).ToArray(); + } + + /// + /// Creates a new instance of + /// + /// The list of power policy status entries. + public PrivatePowerPoliciesStatusV1(PowerPolicyStatusEntry[] powerPoliciesStatusEntries) + { + if (powerPoliciesStatusEntries?.Length > MaxNumberOfPowerPoliciesStatusEntries) + { + throw new ArgumentException( + $"Maximum of {MaxNumberOfPowerPoliciesStatusEntries} power policies entries are configurable.", + nameof(powerPoliciesStatusEntries) + ); + } + + if (powerPoliciesStatusEntries == null || powerPoliciesStatusEntries.Length == 0) + { + throw new ArgumentException("Array is null or empty.", nameof(powerPoliciesStatusEntries)); + } + + this = typeof(PrivatePowerPoliciesStatusV1).Instantiate(); + _PowerPoliciesStatusEntriesCount = (uint) powerPoliciesStatusEntries.Length; + Array.Copy( + powerPoliciesStatusEntries, + 0, + _PowerPoliciesStatusEntries, + 0, + powerPoliciesStatusEntries.Length + ); + } + + /// + /// Contains information regarding a power policies status entry + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PowerPolicyStatusEntry + { + internal PerformanceStateId _PerformanceStateId; + internal uint _Unknown1; + internal uint _PowerTargetInPCM; + internal uint _Unknown2; + + /// + /// Gets the performance state identification number + /// + public PerformanceStateId PerformanceStateId + { + get => _PerformanceStateId; + } + + /// + /// Creates a new instance of PowerPolicyStatusEntry. + /// + /// The power limit target in per cent mille. + public PowerPolicyStatusEntry(uint powerTargetInPCM) : this() + { + _PowerTargetInPCM = powerTargetInPCM; + } + + /// + /// Gets the power limit target in per cent mille + /// + public uint PowerTargetInPCM + { + get => _PowerTargetInPCM; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivatePowerTopologiesStatusV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivatePowerTopologiesStatusV1.cs new file mode 100644 index 0000000..1f63a83 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivatePowerTopologiesStatusV1.cs @@ -0,0 +1,61 @@ +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU power topology status + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivatePowerTopologiesStatusV1 : IInitializable + { + internal const int MaxNumberOfPowerTopologiesStatusEntries = 4; + + internal StructureVersion _Version; + internal readonly uint _PowerTopologiesStatusEntriesCount; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfPowerTopologiesStatusEntries, + ArraySubType = UnmanagedType.Struct)] + internal readonly PowerTopologiesStatusEntry[] _PowerTopologiesStatusEntries; + + /// + /// Gets a list of power topology status entries + /// + public PowerTopologiesStatusEntry[] PowerPolicyStatusEntries + { + get => _PowerTopologiesStatusEntries.Take((int) _PowerTopologiesStatusEntriesCount).ToArray(); + } + + /// + /// Contains information regarding a power topology status entry + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct PowerTopologiesStatusEntry + { + internal PowerTopologyDomain _Domain; + internal uint _Unknown2; + internal uint _PowerUsageInPCM; + internal uint _Unknown3; + + /// + /// Gets the power topology domain + /// + public PowerTopologyDomain Domain + { + get => _Domain; + } + + /// + /// Gets the power usage in per cent mille + /// + public uint PowerUsageInPCM + { + get => _PowerUsageInPCM; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateThermalPoliciesInfoV2.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateThermalPoliciesInfoV2.cs new file mode 100644 index 0000000..0796f4a --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateThermalPoliciesInfoV2.cs @@ -0,0 +1,80 @@ +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU thermal policies + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + public struct PrivateThermalPoliciesInfoV2 : IInitializable + { + internal const int MaxNumberOfThermalPoliciesInfoEntries = 4; + + internal StructureVersion _Version; + internal readonly byte _ThermalPoliciesInfoCount; + internal readonly byte _Unknown; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfThermalPoliciesInfoEntries, + ArraySubType = UnmanagedType.Struct)] + internal readonly ThermalPoliciesInfoEntry[] _ThermalPoliciesInfoEntries; + + /// + /// Gets a list of thermal policy entries + /// + public ThermalPoliciesInfoEntry[] ThermalPoliciesInfoEntries + { + get => _ThermalPoliciesInfoEntries.Take(_ThermalPoliciesInfoCount).ToArray(); + } + + /// + /// Contains information regarding a thermal policies entry + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct ThermalPoliciesInfoEntry + { + internal ThermalController _Controller; + internal uint _Unknown1; + internal int _MinimumTemperature; + internal int _DefaultTemperature; + internal int _MaximumTemperature; + internal uint _Unknown2; + + /// + /// Gets the thermal controller + /// + public ThermalController Controller + { + get => _Controller; + } + + /// + /// Gets the minimum temperature limit target + /// + public int MinimumTemperature + { + get => _MinimumTemperature >> 8; + } + + /// + /// Gets the default temperature limit target + /// + public int DefaultTemperature + { + get => _DefaultTemperature >> 8; + } + + /// + /// Gets the maximum temperature limit target + /// + public int MaximumTemperature + { + get => _MaximumTemperature >> 8; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateThermalPoliciesStatusV2.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateThermalPoliciesStatusV2.cs new file mode 100644 index 0000000..37cb9a6 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateThermalPoliciesStatusV2.cs @@ -0,0 +1,124 @@ +using System; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU thermal policies status + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + public struct PrivateThermalPoliciesStatusV2 : IInitializable + { + internal const int MaxNumberOfThermalPoliciesStatusEntries = 4; + + internal StructureVersion _Version; + internal readonly uint _ThermalPoliciesStatusEntriesCount; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfThermalPoliciesStatusEntries)] + internal readonly ThermalPoliciesStatusEntry[] _ThermalPoliciesStatusEntries; + + /// + /// Gets a list of thermal policy status entries + /// + public ThermalPoliciesStatusEntry[] ThermalPoliciesStatusEntries + { + get => _ThermalPoliciesStatusEntries.Take((int) _ThermalPoliciesStatusEntriesCount).ToArray(); + } + + /// + /// Creates a new instance of + /// + /// The list of thermal policy status entries + public PrivateThermalPoliciesStatusV2(ThermalPoliciesStatusEntry[] policiesStatusEntries) + { + if (policiesStatusEntries?.Length > MaxNumberOfThermalPoliciesStatusEntries) + { + throw new ArgumentException( + $"Maximum of {MaxNumberOfThermalPoliciesStatusEntries} thermal policies entries are configurable.", + nameof(policiesStatusEntries) + ); + } + + if (policiesStatusEntries == null || policiesStatusEntries.Length == 0) + { + throw new ArgumentException("Array is null or empty.", nameof(policiesStatusEntries)); + } + + this = typeof(PrivateThermalPoliciesStatusV2).Instantiate(); + _ThermalPoliciesStatusEntriesCount = (uint) policiesStatusEntries.Length; + Array.Copy( + policiesStatusEntries, + 0, + _ThermalPoliciesStatusEntries, + 0, + policiesStatusEntries.Length + ); + } + + /// + /// Contains information regarding a thermal policies status entry + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct ThermalPoliciesStatusEntry + { + internal ThermalController _Controller; + internal int _TargetTemperature; + internal PerformanceStateId _PerformanceStateId; + + /// + /// Creates a new instance of + /// + /// The thermal controller + /// The target temperature. + public ThermalPoliciesStatusEntry(ThermalController controller, int targetTemperature) : this() + { + _Controller = controller; + _TargetTemperature = targetTemperature * 256; + } + + /// + /// Creates a new instance of + /// + /// The performance state identification number + /// The thermal controller + /// The target temperature. + public ThermalPoliciesStatusEntry( + PerformanceStateId performanceStateId, + ThermalController controller, + int targetTemperature) : this(controller, targetTemperature) + { + _PerformanceStateId = performanceStateId; + } + + /// + /// Gets the thermal controller + /// + public ThermalController Controller + { + get => _Controller; + } + + /// + /// Gets the performance state identification number + /// + public PerformanceStateId PerformanceStateId + { + get => _PerformanceStateId; + } + + /// + /// Gets the target temperature + /// + public int TargetTemperature + { + get => _TargetTemperature >> 8; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateThermalSensorsV2.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateThermalSensorsV2.cs new file mode 100644 index 0000000..bdbcbec --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateThermalSensorsV2.cs @@ -0,0 +1,47 @@ +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU thermal sensors status + /// + [StructLayout(LayoutKind.Sequential)] + [StructureVersion(2)] + public struct PrivateThermalSensorsV2 : IInitializable + { + internal StructureVersion _Version; + + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly uint _Mask; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable + private readonly int[] _Reserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + private readonly int[] _Temperatures; + + /// + /// Creates a new instance of + /// + /// A 32 bit unsigned integer flag containing sensors that are of interest + public PrivateThermalSensorsV2(uint mask) + { + this = typeof(PrivateThermalSensorsV2).Instantiate(); + _Mask = mask; + } + + public float[] Temperatures + { + get + { + return _Temperatures.Select((t) => t / 256.0f).ToArray(); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateUsagesInfoV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateUsagesInfoV1.cs new file mode 100644 index 0000000..517feec --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateUsagesInfoV1.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information about the GPU usage statistics + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivateUsagesInfoV1 : IInitializable, IUtilizationStatus + { + internal const int MaxNumberOfUsageEntries = DynamicPerformanceStatesInfoV1.MaxGpuUtilizations; + + internal StructureVersion _Version; + internal uint _Unknown; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfUsageEntries, ArraySubType = UnmanagedType.Struct)] + internal UsagesInfoEntry[] _UsagesInfoEntries; + + /// + public Dictionary Domains + { + get => _UsagesInfoEntries + .Select((value, index) => new {index, value}) + .Where(arg => Enum.IsDefined(typeof(UtilizationDomain), arg.index) && arg.value.IsPresent) + .ToDictionary(arg => (UtilizationDomain) arg.index, arg => arg.value as IUtilizationDomainInfo); + } + + /// + public IUtilizationDomainInfo GPU + { + get => _UsagesInfoEntries[(int) UtilizationDomain.GPU]; + } + + /// + public IUtilizationDomainInfo FrameBuffer + { + get => _UsagesInfoEntries[(int) UtilizationDomain.FrameBuffer]; + } + + /// + public IUtilizationDomainInfo VideoEngine + { + get => _UsagesInfoEntries[(int) UtilizationDomain.VideoEngine]; + } + + /// + public IUtilizationDomainInfo BusInterface + { + get => _UsagesInfoEntries[(int) UtilizationDomain.BusInterface]; + } + + /// + public override string ToString() + { + return $"GPU = {GPU} - " + + $"FrameBuffer = {FrameBuffer} - " + + $"VideoEngine = {VideoEngine} - " + + $"BusInterface = {BusInterface}"; + } + + /// + /// Holds information about the usage statistics for a domain + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct UsagesInfoEntry : IUtilizationDomainInfo + { + internal uint _IsPresent; + internal uint _Percentage; + internal uint _Unknown1; + internal uint _Unknown2; + + /// + public bool IsPresent + { + get => _IsPresent > 0; + } + + /// + public uint Percentage + { + get => _Percentage; + } + + /// + public override string ToString() + { + return IsPresent ? $"{Percentage}%" : "N/A"; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateVFPCurveV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateVFPCurveV1.cs new file mode 100644 index 0000000..1e29ec0 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateVFPCurveV1.cs @@ -0,0 +1,86 @@ +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; +using System.Runtime.InteropServices; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU boost frequency curve + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivateVFPCurveV1 : IInitializable + { + internal const int MaxNumberOfMasks = 4; + internal const int MaxNumberOfUnknown1 = 12; + internal const int MaxNumberOfGPUCurveEntries = 80; + internal const int MaxNumberOfMemoryCurveEntries = 23; + internal const int MaxNumberOfUnknown2 = 1064; + + internal StructureVersion _Version; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfMasks)] + public uint[] _Masks; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfUnknown1)] + internal readonly uint[] _Unknown1; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfGPUCurveEntries)] + internal readonly VFPCurveEntry[] _GPUCurveEntries; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfMemoryCurveEntries)] + internal readonly VFPCurveEntry[] _MemoryCurveEntries; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfUnknown2)] + internal readonly uint[] _Unknown2; + + + /// + /// Gets the list of GPU curve entries + /// + public VFPCurveEntry[] GPUCurveEntries + { + get => _GPUCurveEntries; + } + + /// + /// Gets the list of memory curve entries + /// + public VFPCurveEntry[] MemoryCurveEntries + { + get => _MemoryCurveEntries; + } + + /// + /// Contains information regarding a boost frequency curve entry + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct VFPCurveEntry + { + internal uint _Unknown1; + internal uint _FrequencyInkHz; + internal uint _VoltageInMicroV; + internal uint _Unknown2; + internal uint _Unknown3; + internal uint _Unknown4; + internal uint _Unknown5; + + /// + /// Gets the frequency in kHz + /// + public uint FrequencyInkHz + { + get => _FrequencyInkHz; + } + + /// + /// Gets the voltage in uV + /// + public uint VoltageInMicroV + { + get => _VoltageInMicroV; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateVFPCurveV3.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateVFPCurveV3.cs new file mode 100644 index 0000000..f525819 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateVFPCurveV3.cs @@ -0,0 +1,105 @@ +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; +using System.Runtime.InteropServices; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU boost frequency curve + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(3)] + public struct PrivateVFPCurveV3 : IInitializable + { + internal const int MaxNumberOfMasks = 4; + internal const int MaxNumberOfUnknown1 = 21; + internal const int MaxNumberOfGPUCurveEntries = 255; + + internal StructureVersion _Version; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfMasks)] + public uint[] _Masks; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfUnknown1)] + internal readonly uint[] _Unknown1; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfGPUCurveEntries)] + internal readonly VFPCurveEntry[] _GPUCurveEntries; + + /// + /// Gets the list of GPU curve entries + /// + public VFPCurveEntry[] GPUCurveEntries + { + get => _GPUCurveEntries; + } + + /// + /// Contains information regarding a boost frequency curve entry + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct VFPoint + { + internal uint _FrequencyInkHz; + internal uint _VoltageInUv; + } + + /// + /// Contains information regarding a boost frequency curve entry + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct VFPCurveEntry + { + internal const int MaxNumberOfUnknown1 = 8; + internal const int MaxNumberOfUnknown2 = 72; + + internal uint _ClockType; + internal VFPoint _Point; + internal VFPoint _PointDefault; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfUnknown1)] + internal readonly uint[] _Unknown1; + + internal VFPoint _PointOverclocked; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfUnknown2)] + internal readonly uint[] _Unknown2; + + /// + /// Gets the frequency in kHz + /// + public uint FrequencyInkHz + { + get => _Point._FrequencyInkHz; + } + + /// + /// Gets the voltage in uV + /// + public uint VoltageInMicroV + { + get => _Point._VoltageInUv; + } + + public uint DefaultFrequencyInkHz + { + get => _PointDefault._FrequencyInkHz; + } + + /// + /// Gets the voltage in uV + /// + public uint DefaultVoltageInMicroV + { + get => _PointDefault._VoltageInUv; + } + + public uint ClockType + { + get => _ClockType; + } + + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateVoltageBoostPercentV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateVoltageBoostPercentV1.cs new file mode 100644 index 0000000..13822ec --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateVoltageBoostPercentV1.cs @@ -0,0 +1,43 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU voltage boost percentage + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivateVoltageBoostPercentV1 : IInitializable + { + internal const int MaxNumberOfUnknown = 8; + + internal StructureVersion _Version; + + internal readonly uint _Percent; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfUnknown)] + internal readonly uint[] _Unknown; + + /// + /// Gets the voltage boost in percentage + /// + public uint Percent + { + get => _Percent; + } + + /// + /// Creates a new instance of + /// + /// The voltage boost in percentage + public PrivateVoltageBoostPercentV1(uint percent) + { + this = typeof(PrivateVoltageBoostPercentV1).Instantiate(); + _Percent = percent; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/PrivateVoltageStatusV1.cs b/NvAPIWrapper/Native/GPU/Structures/PrivateVoltageStatusV1.cs new file mode 100644 index 0000000..583985d --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/PrivateVoltageStatusV1.cs @@ -0,0 +1,38 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Contains information regarding GPU voltage boost status + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct PrivateVoltageStatusV1 : IInitializable + { + internal const int MaxNumberOfUnknown2 = 8; + internal const int MaxNumberOfUnknown3 = 8; + + internal StructureVersion _Version; + + internal readonly uint _Unknown1; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfUnknown2)] + internal readonly uint[] _Unknown2; + + internal readonly uint _ValueInuV; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxNumberOfUnknown3)] + internal readonly uint[] _Unknown3; + + /// + /// Gets the value in uV + /// + public uint ValueInMicroVolt + { + get => _ValueInuV; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/QueryIlluminationSupportParameterV1.cs b/NvAPIWrapper/Native/GPU/Structures/QueryIlluminationSupportParameterV1.cs new file mode 100644 index 0000000..49d733d --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/QueryIlluminationSupportParameterV1.cs @@ -0,0 +1,57 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds necessary information to get an illumination attribute support status + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct QueryIlluminationSupportParameterV1 : IInitializable + { + internal StructureVersion _Version; + internal PhysicalGPUHandle _GPUHandle; + internal IlluminationAttribute _Attribute; + internal uint _IsSupported; + + /// + /// Creates a new instance of . + /// + /// The physical gpu handle. + /// The attribute. + public QueryIlluminationSupportParameterV1(PhysicalGPUHandle gpuHandle, IlluminationAttribute attribute) + { + this = typeof(QueryIlluminationSupportParameterV1).Instantiate(); + _GPUHandle = gpuHandle; + _Attribute = attribute; + } + + /// + /// Gets the parameter physical gpu handle + /// + public PhysicalGPUHandle PhysicalGPUHandle + { + get => _GPUHandle; + } + + /// + /// Gets the parameter attribute + /// + public IlluminationAttribute Attribute + { + get => _Attribute; + } + + /// + /// Gets a boolean value indicating if this attribute is supported and controllable via this GPU + /// + public bool IsSupported + { + get => _IsSupported > 0; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/SetIlluminationParameterV1.cs b/NvAPIWrapper/Native/GPU/Structures/SetIlluminationParameterV1.cs new file mode 100644 index 0000000..041bbc8 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/SetIlluminationParameterV1.cs @@ -0,0 +1,62 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds necessary information to set an illumination attribute value + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct SetIlluminationParameterV1 : IInitializable + { + internal StructureVersion _Version; + internal PhysicalGPUHandle _GPUHandle; + internal IlluminationAttribute _Attribute; + internal uint _ValueInPercentage; + + /// + /// Creates a new instance of . + /// + /// The physical gpu handle. + /// The attribute. + /// The attribute value in percentage. + public SetIlluminationParameterV1( + PhysicalGPUHandle gpuHandle, + IlluminationAttribute attribute, + uint valueInPercentage) + { + this = typeof(SetIlluminationParameterV1).Instantiate(); + _GPUHandle = gpuHandle; + _Attribute = attribute; + _ValueInPercentage = valueInPercentage; + } + + /// + /// Gets the parameter physical gpu handle + /// + public PhysicalGPUHandle PhysicalGPUHandle + { + get => _GPUHandle; + } + + /// + /// Gets the parameter attribute + /// + public IlluminationAttribute Attribute + { + get => _Attribute; + } + + /// + /// Gets the parameter value in percentage + /// + public uint ValueInPercentage + { + get => _ValueInPercentage; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/ThermalSettingsV1.cs b/NvAPIWrapper/Native/GPU/Structures/ThermalSettingsV1.cs new file mode 100644 index 0000000..6364f46 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/ThermalSettingsV1.cs @@ -0,0 +1,82 @@ +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds a list of thermal sensor information settings (temperature values) + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct ThermalSettingsV1 : IInitializable, IThermalSettings + { + internal const int MaxThermalSensorsPerGPU = 3; + + internal StructureVersion _Version; + internal readonly uint _Count; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxThermalSensorsPerGPU)] + internal readonly ThermalSensor[] + _Sensors; + + /// + public IThermalSensor[] Sensors + { + get => _Sensors.Take((int) _Count).Cast().ToArray(); + } + + /// + /// Holds information about a single thermal sensor + /// + [StructLayout(LayoutKind.Sequential)] + public struct ThermalSensor : IThermalSensor + { + internal readonly ThermalController _Controller; + internal readonly uint _DefaultMinTemp; + internal readonly uint _DefaultMaxTemp; + internal readonly uint _CurrentTemp; + internal readonly ThermalSettingsTarget _Target; + + /// + public ThermalController Controller + { + get => _Controller; + } + + /// + public int DefaultMinimumTemperature + { + get => (int) _DefaultMinTemp; + } + + /// + public int DefaultMaximumTemperature + { + get => (int) _DefaultMaxTemp; + } + + /// + public int CurrentTemperature + { + get => (int) _CurrentTemp; + } + + /// + public ThermalSettingsTarget Target + { + get => _Target; + } + + /// + public override string ToString() + { + return + $"[{Target} @ {Controller}] Current: {CurrentTemperature}°C - Default Range: [({DefaultMinimumTemperature}°C) , ({DefaultMaximumTemperature}°C)]"; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/Structures/ThermalSettingsV2.cs b/NvAPIWrapper/Native/GPU/Structures/ThermalSettingsV2.cs new file mode 100644 index 0000000..73227dc --- /dev/null +++ b/NvAPIWrapper/Native/GPU/Structures/ThermalSettingsV2.cs @@ -0,0 +1,80 @@ +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds a list of thermal sensor information settings (temperature values) + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + public struct ThermalSettingsV2 : IInitializable, IThermalSettings + { + internal StructureVersion _Version; + internal readonly uint _Count; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = ThermalSettingsV1.MaxThermalSensorsPerGPU)] + internal readonly + ThermalSensor[] _Sensors; + + /// + public IThermalSensor[] Sensors + { + get => _Sensors.Take((int) _Count).Cast().ToArray(); + } + + /// + /// Holds information about a single thermal sensor + /// + [StructLayout(LayoutKind.Sequential)] + public struct ThermalSensor : IThermalSensor + { + internal readonly ThermalController _Controller; + internal readonly int _DefaultMinTemp; + internal readonly int _DefaultMaxTemp; + internal readonly int _CurrentTemp; + internal readonly ThermalSettingsTarget _Target; + + /// + public ThermalController Controller + { + get => _Controller; + } + + /// + public int DefaultMinimumTemperature + { + get => _DefaultMinTemp; + } + + /// + public int DefaultMaximumTemperature + { + get => _DefaultMaxTemp; + } + + /// + public int CurrentTemperature + { + get => _CurrentTemp; + } + + /// + public ThermalSettingsTarget Target + { + get => _Target; + } + + /// + public override string ToString() + { + return + $"[{Target} @ {Controller}] Current: {CurrentTemperature}°C - Default Range: [({DefaultMinimumTemperature}°C) , ({DefaultMaximumTemperature}°C)]"; + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/SystemType.cs b/NvAPIWrapper/Native/GPU/SystemType.cs new file mode 100644 index 0000000..935be41 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/SystemType.cs @@ -0,0 +1,23 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// GPU systems + /// + public enum SystemType + { + /// + /// Unknown type + /// + Unknown = 0, + + /// + /// Laptop GPU + /// + Laptop = 1, + + /// + /// Desktop GPU + /// + Desktop = 2 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/ThermalController.cs b/NvAPIWrapper/Native/GPU/ThermalController.cs new file mode 100644 index 0000000..e835ad9 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/ThermalController.cs @@ -0,0 +1,73 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// List of possible thermal sensor controllers + /// + public enum ThermalController + { + /// + /// No Thermal Controller + /// + None = 0, + + /// + /// GPU acting as thermal controller + /// + GPU, + + /// + /// ADM1032 Thermal Controller + /// + ADM1032, + + /// + /// MAX6649 Thermal Controller + /// + MAX6649, + + /// + /// MAX1617 Thermal Controller + /// + MAX1617, + + /// + /// LM99 Thermal Controller + /// + LM99, + + /// + /// LM89 Thermal Controller + /// + LM89, + + /// + /// LM64 Thermal Controller + /// + LM64, + + /// + /// ADT7473 Thermal Controller + /// + ADT7473, + + /// + /// SBMAX6649 Thermal Controller + /// + SBMAX6649, + + /// + /// VideoBios acting as thermal controller + /// + VideoBiosEvent, + + /// + /// Operating System acting as thermal controller + /// + OperatingSystem, + + /// + /// Unknown Thermal Controller + /// + Unknown = -1 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/ThermalSettingsTarget.cs b/NvAPIWrapper/Native/GPU/ThermalSettingsTarget.cs new file mode 100644 index 0000000..9f38417 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/ThermalSettingsTarget.cs @@ -0,0 +1,61 @@ +using System; + +namespace NvAPIWrapper.Native.GPU +{ + /// + /// List of possible thermal targets + /// + [Flags] + public enum ThermalSettingsTarget + { + /// + /// None + /// + None = 0, + + /// + /// GPU core temperature + /// + GPU = 1, + + /// + /// GPU memory temperature + /// + Memory = 2, + + /// + /// GPU power supply temperature + /// + PowerSupply = 4, + + /// + /// GPU board ambient temperature + /// + Board = 8, + + /// + /// Visual Computing Device Board temperature requires NvVisualComputingDeviceHandle + /// + VisualComputingBoard = 9, + + /// + /// Visual Computing Device Inlet temperature requires NvVisualComputingDeviceHandle + /// + VisualComputingInlet = 10, + + /// + /// Visual Computing Device Outlet temperature requires NvVisualComputingDeviceHandle + /// + VisualComputingOutlet = 11, + + /// + /// Used for retrieving all thermal settings + /// + All = 15, + + /// + /// Unknown thermal target + /// + Unknown = -1 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPU/UtilizationDomain.cs b/NvAPIWrapper/Native/GPU/UtilizationDomain.cs new file mode 100644 index 0000000..d8d4ff6 --- /dev/null +++ b/NvAPIWrapper/Native/GPU/UtilizationDomain.cs @@ -0,0 +1,28 @@ +namespace NvAPIWrapper.Native.GPU +{ + /// + /// Valid utilization domain + /// + public enum UtilizationDomain + { + /// + /// GPU utilization domain + /// + GPU, + + /// + /// Frame buffer utilization domain + /// + FrameBuffer, + + /// + /// Video engine utilization domain + /// + VideoEngine, + + /// + /// Bus interface utilization domain + /// + BusInterface + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPUApi.Display.cs b/NvAPIWrapper/Native/GPUApi.Display.cs new file mode 100644 index 0000000..0276e78 --- /dev/null +++ b/NvAPIWrapper/Native/GPUApi.Display.cs @@ -0,0 +1,505 @@ +using System; +using System.Linq; +using NvAPIWrapper.Native.Display.Structures; +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native +{ + public static partial class GPUApi + { + /// + /// This function is the same as GetAllOutputs() but returns only the set of GPU output identifiers that are actively + /// driving display devices. + /// + /// Physical GPU handle to get information about + /// Active output identifications as a flag + /// Status.InvalidArgument: display is not valid + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle. + public static OutputId GetActiveOutputs(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var outputMask); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return outputMask; + } + + /// + /// This API returns display IDs for all possible outputs on the GPU. + /// For DPMST connector, it will return display IDs for all the video sinks in the topology. + /// + /// Physical GPU handle to get information about + /// An array of display identifications and their attributes + /// This operation is not supported. + /// See NVIDIAApiException.Status for the reason of the exception. + /// A delegate callback throws an exception. + public static DisplayIdsV2[] GetAllDisplayIds(PhysicalGPUHandle gpuHandle) + { + var gpuGetConnectedDisplayIds = DelegateFactory.GetDelegate(); + + if (!gpuGetConnectedDisplayIds.Accepts().Contains(typeof(DisplayIdsV2))) + { + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + uint count = 0; + var status = gpuGetConnectedDisplayIds(gpuHandle, ValueTypeArray.Null, ref count); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + if (count == 0) + { + return new DisplayIdsV2[0]; + } + + using ( + var displayIds = + ValueTypeArray.FromArray(typeof(DisplayIdsV2).Instantiate().Repeat((int) count))) + { + status = gpuGetConnectedDisplayIds(gpuHandle, displayIds, ref count); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return displayIds.ToArray((int) count); + } + } + + /// + /// Due to space limitation GetConnectedOutputs() can return maximum 32 devices, but this is no longer true for DPMST. + /// GetConnectedDisplayIds() will return all the connected display devices in the form of displayIds for the associated + /// gpuHandle. + /// This function can accept set of flags to request cached, un-cached, sli and lid to get the connected devices. + /// Default value for flags will be cached. + /// + /// Physical GPU handle to get information about + /// ConnectedIdsFlag flags + /// An array of display identifications and their attributes + /// This operation is not supported. + /// Status.InvalidArgument: gpuHandle is invalid + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle + /// A delegate callback throws an exception. + public static DisplayIdsV2[] GetConnectedDisplayIds(PhysicalGPUHandle gpuHandle, ConnectedIdsFlag flags) + { + var gpuGetConnectedDisplayIds = + DelegateFactory.GetDelegate(); + + if (!gpuGetConnectedDisplayIds.Accepts().Contains(typeof(DisplayIdsV2))) + { + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + uint count = 0; + var status = gpuGetConnectedDisplayIds(gpuHandle, ValueTypeArray.Null, ref count, flags); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + if (count == 0) + { + return new DisplayIdsV2[0]; + } + + using ( + var displayIds = + ValueTypeArray.FromArray(typeof(DisplayIdsV2).Instantiate().Repeat((int) count))) + { + status = gpuGetConnectedDisplayIds(gpuHandle, displayIds, ref count, flags); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return displayIds.ToArray((int) count); + } + } + + /// + /// This API converts a Physical GPU handle and output ID to a display ID. + /// + /// Handle to the physical GPU + /// Connected display output identification on the target GPU - must only have one bit set + /// Display identification + /// Status.ApiNotInitialized: NVAPI not initialized + /// Status.Error: miscellaneous error occurred + /// Status.InvalidArgument: Invalid input parameter. + public static uint GetDisplayIdFromGPUAndOutputId(PhysicalGPUHandle gpuHandle, OutputId outputId) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + outputId, out var display); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return display; + } + + /// + /// This function returns the EDID data for the specified GPU handle and connection bit mask. + /// outputId should have exactly 1 bit set to indicate a single display. + /// + /// Physical GPU handle to check outputs + /// Output identification + /// EDID offset + /// EDID read identification for multi part read, or zero for first run + /// Whole or a part of the EDID data + /// This operation is not supported. + /// + /// Status.InvalidArgument: gpuHandle or edid is invalid, outputId has 0 or > 1 bits + /// set + /// + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found. + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle. + /// Status.DataNotFound: The requested display does not contain an EDID. + /// A delegate callback throws an exception. + // ReSharper disable once TooManyArguments + public static EDIDV3 GetEDID( + PhysicalGPUHandle gpuHandle, + OutputId outputId, + int offset, + int readIdentification = 0) + { + var gpuGetEDID = DelegateFactory.GetDelegate(); + + if (!gpuGetEDID.Accepts().Contains(typeof(EDIDV3))) + { + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + var instance = EDIDV3.CreateWithOffset((uint) readIdentification, (uint) offset); + + using (var edidReference = ValueTypeReference.FromValueType(instance)) + { + var status = gpuGetEDID(gpuHandle, outputId, edidReference); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return edidReference.ToValueType().GetValueOrDefault(); + } + } + + /// + /// This function returns the EDID data for the specified GPU handle and connection bit mask. + /// outputId should have exactly 1 bit set to indicate a single display. + /// + /// Physical GPU handle to check outputs + /// Output identification + /// Whole or a part of the EDID data + /// This operation is not supported. + /// + /// Status.InvalidArgument: gpuHandle or edid is invalid, outputId has 0 or > 1 bits + /// set + /// + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found. + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle. + /// Status.DataNotFound: The requested display does not contain an EDID. + /// A delegate callback throws an exception. + public static IEDID GetEDID(PhysicalGPUHandle gpuHandle, OutputId outputId) + { + var gpuGetEDID = DelegateFactory.GetDelegate(); + + foreach (var acceptType in gpuGetEDID.Accepts()) + { + using (var edidReference = ValueTypeReference.FromValueType(acceptType.Instantiate(), acceptType) + ) + { + var status = gpuGetEDID(gpuHandle, outputId, edidReference); + + if (status == Status.IncompatibleStructureVersion) + { + continue; + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return edidReference.ToValueType(acceptType); + } + } + + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + /// + /// This API converts a display ID to a Physical GPU handle and output ID. + /// + /// Display identification of display to retrieve GPU and outputId for + /// Handle to the physical GPU + /// Connected display output identification on the target GPU will only have one bit set. + /// Status.ApiNotInitialized: NVAPI not initialized + /// Status.Error: Miscellaneous error occurred + /// Status.InvalidArgument: Invalid input parameter + /// + /// Status.IdOutOfRange: The DisplayId corresponds to a display which is not within + /// the normal outputId range. + /// + public static OutputId GetGPUAndOutputIdFromDisplayId(uint displayId, out PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()( + displayId, + out gpuHandle, out var outputId); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return outputId; + } + + /// + /// This function returns the logical GPU handle associated with the specified display. + /// At least one GPU must be present in the system and running an NVIDIA display driver. + /// display can be DisplayHandle.DefaultHandle or a handle enumerated from EnumNVidiaDisplayHandle(). + /// + /// Display handle to get information about + /// Logical GPU handle associated with the specified display + /// Status.InvalidArgument: display is not valid + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + public static LogicalGPUHandle GetLogicalGPUFromDisplay(DisplayHandle display) + { + var status = + DelegateFactory.GetDelegate()(display, out var gpu); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return gpu; + } + + /// + /// This function returns the output type. User can either specify both 'physical GPU handle and outputId (exactly 1 + /// bit set)' or a valid displayId in the outputId parameter. + /// + /// GPU handle to get information about + /// Output identification of the output to get information about + /// Type of the output + /// Status.InvalidArgument: gpuHandle is NULL + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle + public static OutputType GetOutputType(PhysicalGPUHandle gpuHandle, OutputId outputId) + { + return GetOutputType(gpuHandle, (uint) outputId); + } + + /// + /// This function returns the output type. User can either specify both 'physical GPU handle and outputId (exactly 1 + /// bit set)' or a valid displayId in the outputId parameter. + /// + /// GPU handle to get information about + /// Display identification of the divide to get information about + /// Type of the output + /// Status.InvalidArgument: gpuHandle is NULL + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle + public static OutputType GetOutputType(PhysicalGPUHandle gpuHandle, uint displayId) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, displayId, + out var type); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return type; + } + + /// + /// This API retrieves the Physical GPU handle of the connected display + /// + /// Display identification of display to retrieve GPU handle + /// Handle to the physical GPU + /// Status.ApiNotInitialized: NVAPI not initialized + /// Status.Error: Miscellaneous error occurred + /// Status.InvalidArgument: Invalid input parameter + public static PhysicalGPUHandle GetPhysicalGPUFromDisplayId(uint displayId) + { + var status = + DelegateFactory.GetDelegate()(displayId, + out var gpu); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return gpu; + } + + /// + /// This function returns a physical GPU handle associated with the specified unattached display. + /// The source GPU is a physical render GPU which renders the frame buffer but may or may not drive the scan out. + /// At least one GPU must be present in the system and running an NVIDIA display driver. + /// + /// Display handle to get information about + /// Physical GPU handle associated with the specified unattached display. + /// Status.InvalidArgument: display is not valid + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + public static PhysicalGPUHandle GetPhysicalGPUFromUnAttachedDisplay(UnAttachedDisplayHandle display) + { + var status = + DelegateFactory.GetDelegate()(display, + out var gpu); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return gpu; + } + + /// + /// This function returns an array of physical GPU handles associated with the specified display. + /// At least one GPU must be present in the system and running an NVIDIA display driver. + /// If the display corresponds to more than one physical GPU, the first GPU returned is the one with the attached + /// active output. + /// + /// Display handle to get information about + /// An array of physical GPU handles + /// Status.InvalidArgument: display is not valid + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + public static PhysicalGPUHandle[] GetPhysicalGPUsFromDisplay(DisplayHandle display) + { + var gpuList = + typeof(PhysicalGPUHandle).Instantiate().Repeat(PhysicalGPUHandle.MaxPhysicalGPUs); + var status = DelegateFactory.GetDelegate()(display, gpuList, + out var count); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return gpuList.Take((int) count).ToArray(); + } + + /// + /// Thus function sets the EDID data for the specified GPU handle and connection bit mask. + /// User can either send (Gpu handle and output id) or only display Id in variable outputId parameter and gpuHandle + /// parameter can be default handle. + /// Note: The EDID will be cached across the boot session and will be enumerated to the OS in this call. To remove the + /// EDID set size of EDID to zero. OS and NVAPI connection status APIs will reflect the newly set or removed EDID + /// dynamically. + /// This feature will NOT be supported on the following boards: GeForce, Quadro VX, Tesla + /// + /// Physical GPU handle to check outputs + /// Output identification + /// EDID information + /// This operation is not supported. + /// + /// Status.InvalidArgument: gpuHandle or edid is invalid, outputId has 0 or > 1 bits + /// set + /// + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found. + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle. + /// Status.NotSupported: For the above mentioned GPUs + public static void SetEDID(PhysicalGPUHandle gpuHandle, OutputId outputId, IEDID edid) + { + SetEDID(gpuHandle, (uint) outputId, edid); + } + + /// + /// Thus function sets the EDID data for the specified GPU handle and connection bit mask. + /// User can either send (Gpu handle and output id) or only display Id in variable outputId parameter and gpuHandle + /// parameter can be default handle. + /// Note: The EDID will be cached across the boot session and will be enumerated to the OS in this call. To remove the + /// EDID set size of EDID to zero. OS and NVAPI connection status APIs will reflect the newly set or removed EDID + /// dynamically. + /// This feature will NOT be supported on the following boards: GeForce, Quadro VX, Tesla + /// + /// Physical GPU handle to check outputs + /// Output identification + /// EDID information + /// This operation is not supported. + /// + /// Status.InvalidArgument: gpuHandle or edid is invalid, outputId has 0 or > 1 bits + /// set + /// + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found. + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle. + /// Status.NotSupported: For the above mentioned GPUs + /// A delegate callback throws an exception. + public static void SetEDID(PhysicalGPUHandle gpuHandle, uint displayId, IEDID edid) + { + var gpuSetEDID = DelegateFactory.GetDelegate(); + + if (!gpuSetEDID.Accepts().Contains(edid.GetType())) + { + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + using (var edidReference = ValueTypeReference.FromValueType(edid, edid.GetType())) + { + var status = gpuSetEDID(gpuHandle, displayId, edidReference); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// + /// This function determines if a set of GPU outputs can be active simultaneously. While a GPU may have 'n' outputs, + /// typically they cannot all be active at the same time due to internal resource sharing. + /// Given a physical GPU handle and a mask of candidate outputs, this call will return true if all of the specified + /// outputs can be driven simultaneously. It will return false if they cannot. + /// + /// Physical GPU handle to check outputs + /// Output identification combination + /// true if all of the specified outputs can be driven simultaneously. It will return false if they cannot. + /// Status.InvalidArgument: display is not valid + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle. + public static bool ValidateOutputCombination(PhysicalGPUHandle gpuHandle, OutputId outputIds) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, outputIds); + + if (status == Status.InvalidCombination) + { + return false; + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return true; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPUApi.Illumination.cs b/NvAPIWrapper/Native/GPUApi.Illumination.cs new file mode 100644 index 0000000..46d3aeb --- /dev/null +++ b/NvAPIWrapper/Native/GPUApi.Illumination.cs @@ -0,0 +1,246 @@ +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; + +namespace NvAPIWrapper.Native +{ + public static partial class GPUApi + { + /// + /// Gets the control information about illumination devices on the given GPU. + /// + /// The physical GPU handle. + /// An instance of . + public static IlluminationDeviceControlParametersV1 ClientIlluminationDevicesGetControl( + PhysicalGPUHandle gpuHandle) + { + var instance = typeof(IlluminationDeviceControlParametersV1) + .Instantiate(); + + using (var deviceControlParametersReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + deviceControlParametersReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return deviceControlParametersReference.ToValueType() + .GetValueOrDefault(); + } + } + + /// + /// Returns static information about illumination devices on the given GPU. + /// + /// The physical GPU handle. + /// An instance of . + public static IlluminationDeviceInfoParametersV1 ClientIlluminationDevicesGetInfo(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(IlluminationDeviceInfoParametersV1).Instantiate(); + + using (var deviceInfoParametersReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + deviceInfoParametersReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return deviceInfoParametersReference.ToValueType() + .GetValueOrDefault(); + } + } + + /// + /// Sets the control information about illumination devices on the given GPU. + /// + /// The physical GPU handle. + /// The new control illumination devices control information. + public static void ClientIlluminationDevicesSetControl( + PhysicalGPUHandle gpuHandle, + IlluminationDeviceControlParametersV1 deviceControlParameters) + { + using (var deviceControlParametersReference = ValueTypeReference.FromValueType(deviceControlParameters)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + deviceControlParametersReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// + /// Gets the control information about illumination zones on the given GPU. + /// + /// The physical GPU handle. + /// The type of settings to retrieve. + /// An instance of . + public static IlluminationZoneControlParametersV1 ClientIlluminationZonesGetControl( + PhysicalGPUHandle gpuHandle, + IlluminationZoneControlValuesType valuesType) + { + var instance = new IlluminationZoneControlParametersV1(valuesType); + + using (var zoneControlParametersReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + zoneControlParametersReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return zoneControlParametersReference.ToValueType() + .GetValueOrDefault(); + } + } + + /// + /// Returns static information about illumination zones on the given GPU. + /// + /// The physical GPU handle. + /// An instance of . + public static IlluminationZoneInfoParametersV1 ClientIlluminationZonesGetInfo(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(IlluminationZoneInfoParametersV1).Instantiate(); + + using (var zoneInfoParametersReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + zoneInfoParametersReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return zoneInfoParametersReference.ToValueType().GetValueOrDefault(); + } + } + + /// + /// Sets the control information about illumination zones on the given GPU. + /// + /// The physical GPU handle. + /// The new control illumination zones control information. + public static void ClientIlluminationZonesSetControl( + PhysicalGPUHandle gpuHandle, + IlluminationZoneControlParametersV1 zoneControlParameters) + { + using (var zoneControlParametersReference = ValueTypeReference.FromValueType(zoneControlParameters)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + zoneControlParametersReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// + /// Reports value of the specified illumination attribute brightness. + /// + /// The physical GPU handle. + /// The attribute to get the value of. + /// Brightness value in percentage. + public static uint GetIllumination(PhysicalGPUHandle gpuHandle, IlluminationAttribute attribute) + { + var instance = new GetIlluminationParameterV1(gpuHandle, attribute); + + using (var getParameterReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + getParameterReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return getParameterReference.ToValueType() + .GetValueOrDefault() + .ValueInPercentage; + } + } + + /// + /// Queries a illumination attribute support status. + /// + /// The physical GPU handle. + /// The attribute to get the support status of. + /// true if the attribute is supported on this GPU; otherwise false. + public static bool QueryIlluminationSupport(PhysicalGPUHandle gpuHandle, IlluminationAttribute attribute) + { + var instance = new QueryIlluminationSupportParameterV1(gpuHandle, attribute); + + using (var querySupportParameterReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + querySupportParameterReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return querySupportParameterReference.ToValueType() + .GetValueOrDefault() + .IsSupported; + } + } + + /// + /// Sets the value of the specified illumination attribute brightness. + /// + /// The physical GPU handle. + /// The attribute to set the value of. + /// Brightness value in percentage. + public static void SetIllumination( + PhysicalGPUHandle gpuHandle, + IlluminationAttribute attribute, + uint valueInPercentage) + { + var instance = new SetIlluminationParameterV1(gpuHandle, attribute, valueInPercentage); + + using (var setParameterReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + setParameterReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPUApi.Performance.cs b/NvAPIWrapper/Native/GPUApi.Performance.cs new file mode 100644 index 0000000..81d4a38 --- /dev/null +++ b/NvAPIWrapper/Native/GPUApi.Performance.cs @@ -0,0 +1,607 @@ +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; +using NvAPIWrapper.Native.Interfaces.GPU; +using System; +using System.Diagnostics.CodeAnalysis; + +namespace NvAPIWrapper.Native +{ + public static partial class GPUApi + { + /// + /// [PRIVATE] + /// Enables the overclocked performance states + /// + /// The handle of the GPU to perform the operation on. + public static void EnableOverclockedPStates(PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// + /// This function retrieves the clock frequencies information from an specific physical GPU and fills the structure + /// + /// + /// Handle of the physical GPU for which the clock frequency information is to be + /// retrieved. + /// + /// + /// The structure that holds options for the operations and should be filled with the + /// results, use null to return current clock frequencies + /// + /// The device clock frequencies information. + /// This operation is not supported. + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found. + /// A delegate callback throws an exception. + public static IClockFrequencies GetAllClockFrequencies( + PhysicalGPUHandle physicalGPUHandle, + IClockFrequencies clockFrequencyOptions = null) + { + var getClocksInfo = DelegateFactory.GetDelegate(); + + if (clockFrequencyOptions == null) + { + foreach (var acceptType in getClocksInfo.Accepts()) + { + var instance = acceptType.Instantiate(); + + using (var clockFrequenciesInfo = ValueTypeReference.FromValueType(instance, acceptType)) + { + var status = getClocksInfo(physicalGPUHandle, clockFrequenciesInfo); + + if (status == Status.IncompatibleStructureVersion) + { + continue; + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return clockFrequenciesInfo.ToValueType(acceptType); + } + } + } + else + { + using (var clockFrequenciesInfo = + ValueTypeReference.FromValueType(clockFrequencyOptions, clockFrequencyOptions.GetType())) + { + var status = getClocksInfo(physicalGPUHandle, clockFrequenciesInfo); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return clockFrequenciesInfo.ToValueType(clockFrequencyOptions.GetType()); + } + } + + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + /// + /// [PRIVATE] - [Pascal Only] + /// Gets the clock boost lock for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The GPU clock boost lock. + public static PrivateClockBoostLockV2 GetClockBoostLock(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivateClockBoostLockV2).Instantiate(); + + using (var clockLockReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + clockLockReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return clockLockReference.ToValueType(typeof(PrivateClockBoostLockV2)); + } + } + + /// + /// [PRIVATE] - [Pascal Only] + /// Gets the clock boost mask for passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The GPI clock boost mask. + public static PrivateClockBoostMasksV1 GetClockBoostMask(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivateClockBoostMasksV1).Instantiate(); + instance._Masks = new[] { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; + + using (var clockBoostReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + clockBoostReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return clockBoostReference.ToValueType(typeof(PrivateClockBoostMasksV1)); + } + } + + /// + /// [PRIVATE] - [Pascal Only] + /// Gets the clock boost ranges for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The GPU clock boost ranges. + public static PrivateClockBoostRangesV1 GetClockBoostRanges(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivateClockBoostRangesV1).Instantiate(); + + using (var clockRangesReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + clockRangesReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return clockRangesReference.ToValueType(typeof(PrivateClockBoostRangesV1)); + } + } + + /// + /// [PRIVATE] - [Pascal Only] + /// Gets the clock boost table for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The GPU clock boost table. + public static PrivateClockBoostTableV1 GetClockBoostTable(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivateClockBoostTableV1).Instantiate(); + + using (var clockTableReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + clockTableReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return clockTableReference.ToValueType(typeof(PrivateClockBoostTableV1)); + } + } + + /// + /// [PRIVATE] - [Pascal Only] + /// Gets the clock boost table for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The GPU clock boost table. + public static PrivateClockBoostTableV2 GetClockBoostTableV2(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivateClockBoostTableV2).Instantiate(); + instance._Masks = new[] { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; + + using (var clockTableReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + clockTableReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return clockTableReference.ToValueType(typeof(PrivateClockBoostTableV2)); + } + } + + + /// + /// [PRIVATE] - [Pascal Only] + /// Gets the core voltage boost percentage for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The voltage boost percentage. + public static PrivateVoltageBoostPercentV1 GetCoreVoltageBoostPercent(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivateVoltageBoostPercentV1).Instantiate(); + + using (var voltageBoostReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + voltageBoostReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return voltageBoostReference.ToValueType( + typeof(PrivateVoltageBoostPercentV1)); + } + } + + /// + /// This function returns the current performance state (P-State). + /// + /// GPU handle to get information about + /// The current performance state. + /// Status.InvalidArgument: gpuHandle is NULL + public static PerformanceStateId GetCurrentPerformanceState(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, + out var performanceState); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return performanceState; + } + + /// + /// [PRIVATE] - [Pascal Only] + /// Gets the current voltage status for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The voltage status of the GPU. + public static PrivateVoltageStatusV1 GetCurrentVoltage(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivateVoltageStatusV1).Instantiate(); + + using (var voltageStatusReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + voltageStatusReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return voltageStatusReference.ToValueType(typeof(PrivateVoltageStatusV1)); + } + } + + /// + /// This function retrieves all available performance states (P-States) information. + /// P-States are GPU active/executing performance capability and power consumption states. + /// + /// GPU handle to get information about. + /// Flag to get specific information about a performance state. + /// Retrieved performance states information + /// Status.InvalidArgument: gpuHandle is NULL + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle + [SuppressMessage("ReSharper", "EventExceptionNotDocumented")] + public static IPerformanceStatesInfo GetPerformanceStates( + PhysicalGPUHandle physicalGPUHandle, + GetPerformanceStatesInfoFlags flags) + { + var getPerformanceStatesInfo = DelegateFactory.GetDelegate(); + + foreach (var acceptType in getPerformanceStatesInfo.Accepts()) + { + var instance = acceptType.Instantiate(); + + using (var performanceStateInfo = ValueTypeReference.FromValueType(instance, acceptType)) + { + var status = getPerformanceStatesInfo(physicalGPUHandle, performanceStateInfo, flags); + + if (status == Status.IncompatibleStructureVersion) + { + continue; + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return performanceStateInfo.ToValueType(acceptType); + } + } + + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + /// + /// This function retrieves all available performance states (P-States) 2.0 information. + /// P-States are GPU active/executing performance capability and power consumption states. + /// + /// GPU handle to get information about. + /// Retrieved performance states 2.0 information + /// Status.InvalidArgument: gpuHandle is NULL + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle + [SuppressMessage("ReSharper", "EventExceptionNotDocumented")] + public static IPerformanceStates20Info GetPerformanceStates20(PhysicalGPUHandle physicalGPUHandle) + { + var getPerformanceStates20 = DelegateFactory.GetDelegate(); + + foreach (var acceptType in getPerformanceStates20.Accepts()) + { + var instance = acceptType.Instantiate(); + + using (var performanceStateInfo = ValueTypeReference.FromValueType(instance, acceptType)) + { + var status = getPerformanceStates20(physicalGPUHandle, performanceStateInfo); + + if (status == Status.IncompatibleStructureVersion) + { + continue; + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return performanceStateInfo.ToValueType(acceptType); + } + } + + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + /// + /// [PRIVATE] - [Pascal Only] + /// Gets the GPU boost frequency curve controls for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The retrieved VFP curve. + public static PrivateVFPCurveV1 GetVFPCurve(PhysicalGPUHandle gpuHandle, uint[] masks) + { + var instance = typeof(PrivateVFPCurveV1).Instantiate(); + //instance._Masks = new[] { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; + instance._Masks = masks; + + using (var vfpCurveReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + vfpCurveReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return vfpCurveReference.ToValueType(typeof(PrivateVFPCurveV1)); + } + } + + /// + /// [PRIVATE] - [Pascal Only] + /// Gets the GPU boost frequency curve controls for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The retrieved VFP curve. + public static PrivateVFPCurveV3 GetVFPCurveV3(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivateVFPCurveV3).Instantiate(); + instance._Masks = new[] { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; + + using (var vfpCurveReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + vfpCurveReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return vfpCurveReference.ToValueType(typeof(PrivateVFPCurveV3)); + } + } + + /// + /// [PRIVATE] + /// Gets the performance policies current information for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The performance policies information. + public static PrivatePerformanceInfoV1 PerformancePoliciesGetInfo(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivatePerformanceInfoV1).Instantiate(); + + using (var performanceInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + performanceInfoReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return performanceInfoReference.ToValueType(typeof(PrivatePerformanceInfoV1)); + } + } + + /// + /// [PRIVATE] + /// Gets the performance policies status for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The performance policies status of the GPU. + public static PrivatePerformanceStatusV1 PerformancePoliciesGetStatus(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivatePerformanceStatusV1).Instantiate(); + + using (var performanceStatusReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + performanceStatusReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return performanceStatusReference.ToValueType( + typeof(PrivatePerformanceStatusV1)); + } + } + + /// + /// [PRIVATE] - [Pascal Only] + /// Sets the clock boost lock status for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The new clock boost lock status. + public static void SetClockBoostLock(PhysicalGPUHandle gpuHandle, PrivateClockBoostLockV2 clockBoostLock) + { + using (var clockLockReference = ValueTypeReference.FromValueType(clockBoostLock)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + clockLockReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// + /// [PRIVATE] - [Pascal Only] + /// Sets the clock boost table for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The new clock table. + public static void SetClockBoostTable(PhysicalGPUHandle gpuHandle, PrivateClockBoostTableV1 clockBoostTable) + { + using (var clockTableReference = ValueTypeReference.FromValueType(clockBoostTable)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + clockTableReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// + /// [PRIVATE] - [Pascal Only] + /// Sets the clock boost table for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The new clock table. + public static void SetClockBoostTableV2(PhysicalGPUHandle gpuHandle, PrivateClockBoostTableV2 clockBoostTable) + { + using (var clockTableReference = ValueTypeReference.FromValueType(clockBoostTable)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + clockTableReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// + /// [PRIVATE] - [Pascal Only] + /// Sets the core voltage boost percentage + /// + /// The handle of the GPU to perform the operation on. + /// The voltage boost percentages. + public static void SetCoreVoltageBoostPercent( + PhysicalGPUHandle gpuHandle, + PrivateVoltageBoostPercentV1 boostPercent) + { + using (var boostPercentReference = ValueTypeReference.FromValueType(boostPercent)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + boostPercentReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// + /// [PRIVATE] + /// This function sets the performance states (P-States) 2.0 information. + /// P-States are GPU active/executing performance capability and power consumption states. + /// + /// GPU handle to get information about. + /// Performance status 2.0 information to set + /// Status.InvalidArgument: gpuHandle is NULL + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle + public static void SetPerformanceStates20( + PhysicalGPUHandle physicalGPUHandle, + IPerformanceStates20Info performanceStates20Info) + { + using (var performanceStateInfo = + ValueTypeReference.FromValueType(performanceStates20Info, performanceStates20Info.GetType())) + { + var status = DelegateFactory.GetDelegate()( + physicalGPUHandle, + performanceStateInfo + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPUApi.PowerPolicies.cs b/NvAPIWrapper/Native/GPUApi.PowerPolicies.cs new file mode 100644 index 0000000..21322c3 --- /dev/null +++ b/NvAPIWrapper/Native/GPUApi.PowerPolicies.cs @@ -0,0 +1,115 @@ +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.GPU.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; + +namespace NvAPIWrapper.Native +{ + public static partial class GPUApi + { + /// + /// [PRIVATE] + /// Gets the current power policies information for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The current power policies information. + public static PrivatePowerPoliciesInfoV1 ClientPowerPoliciesGetInfo(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivatePowerPoliciesInfoV1).Instantiate(); + + using (var policiesInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, + policiesInfoReference); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return policiesInfoReference.ToValueType( + typeof(PrivatePowerPoliciesInfoV1)); + } + } + + /// + /// [PRIVATE] + /// Gets the power policies status for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The power policies status. + public static PrivatePowerPoliciesStatusV1 ClientPowerPoliciesGetStatus(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivatePowerPoliciesStatusV1).Instantiate(); + + using (var policiesStatusReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + policiesStatusReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return policiesStatusReference.ToValueType( + typeof(PrivatePowerPoliciesStatusV1)); + } + } + + /// + /// [PRIVATE] + /// Sets the power policies status for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The new power limiter policy. + public static void ClientPowerPoliciesSetStatus( + PhysicalGPUHandle gpuHandle, + PrivatePowerPoliciesStatusV1 policiesStatus) + { + using (var policiesStatusReference = ValueTypeReference.FromValueType(policiesStatus)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + policiesStatusReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// + /// [PRIVATE] + /// Gets the power topology status for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The power topology status. + public static PrivatePowerTopologiesStatusV1 ClientPowerTopologyGetStatus(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivatePowerTopologiesStatusV1).Instantiate(); + + using (var topologiesStatusReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + topologiesStatusReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return topologiesStatusReference.ToValueType( + typeof(PrivatePowerTopologiesStatusV1)); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPUApi.Thermal.cs b/NvAPIWrapper/Native/GPUApi.Thermal.cs new file mode 100644 index 0000000..f3e2966 --- /dev/null +++ b/NvAPIWrapper/Native/GPUApi.Thermal.cs @@ -0,0 +1,474 @@ +using System; +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native +{ + public static partial class GPUApi + { + /// + /// [PRIVATE] + /// Gets the cooler policy table for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The cooler policy to get the table for. + /// The cooler index. + /// Number of policy table entries retrieved. + /// The cooler policy table for the GPU. + // ReSharper disable once TooManyArguments + public static PrivateCoolerPolicyTableV1 GetCoolerPolicyTable( + PhysicalGPUHandle gpuHandle, + CoolerPolicy policy, + uint index, + out uint count) + { + var instance = typeof(PrivateCoolerPolicyTableV1).Instantiate(); + instance._Policy = policy; + + using (var policyTableReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + index, + policyTableReference, + out count + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return policyTableReference.ToValueType(typeof(PrivateCoolerPolicyTableV1)); + } + } + + /// + /// [PRIVATE] + /// Gets the cooler settings for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The cooler targets to get settings. + /// The cooler settings. + public static PrivateCoolerSettingsV1 GetCoolerSettings( + PhysicalGPUHandle gpuHandle, + CoolerTarget coolerTarget = CoolerTarget.All) + { + var instance = typeof(PrivateCoolerSettingsV1).Instantiate(); + + using (var coolerSettingsReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + coolerTarget, + coolerSettingsReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return coolerSettingsReference.ToValueType(typeof(PrivateCoolerSettingsV1)); + } + } + + /// + /// [PRIVATE] + /// Gets the current fan speed level for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The current fan speed level. + public static uint GetCurrentFanSpeedLevel(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory + .GetDelegate()(gpuHandle, out var count); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return count; + } + + /// + /// [PRIVATE] + /// Gets the current thermal level for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The current thermal level. + public static uint GetCurrentThermalLevel(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var count); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return count; + } + + /// + /// This function returns the fan speed tachometer reading for the specified physical GPU. + /// + /// Physical GPU handle to get tachometer reading from + /// The GPU fan speed in revolutions per minute. + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle. + public static uint GetTachReading(PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, out var value + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return value; + } + + /// + /// [PRIVATE] + /// Gets the current thermal policies information for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The current thermal policies information. + public static PrivateThermalPoliciesInfoV2 GetThermalPoliciesInfo(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivateThermalPoliciesInfoV2).Instantiate(); + + using (var policiesInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, + policiesInfoReference); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return policiesInfoReference.ToValueType( + typeof(PrivateThermalPoliciesInfoV2)); + } + } + + /// + /// [PRIVATE] + /// Gets the thermal policies status for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The thermal policies status. + public static PrivateThermalPoliciesStatusV2 GetThermalPoliciesStatus(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivateThermalPoliciesStatusV2).Instantiate(); + + using (var policiesStatusReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + policiesStatusReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return policiesStatusReference.ToValueType( + typeof(PrivateThermalPoliciesStatusV2)); + } + } + + /// + /// This function retrieves the thermal information of all thermal sensors or specific thermal sensor associated with + /// the selected GPU. To retrieve info for all sensors, set sensorTarget to ThermalSettingsTarget.All. + /// + /// Handle of the physical GPU for which the memory information is to be extracted. + /// Specifies the requested thermal sensor target. + /// The device thermal sensors information. + /// This operation is not supported. + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found. + /// A delegate callback throws an exception. + public static IThermalSettings GetThermalSettings( + PhysicalGPUHandle physicalGPUHandle, + ThermalSettingsTarget sensorTarget = ThermalSettingsTarget.All) + { + var getThermalSettings = DelegateFactory.GetDelegate(); + + foreach (var acceptType in getThermalSettings.Accepts()) + { + var instance = acceptType.Instantiate(); + + using (var gpuThermalSettings = ValueTypeReference.FromValueType(instance, acceptType)) + { + var status = getThermalSettings(physicalGPUHandle, sensorTarget, gpuThermalSettings); + + if (status == Status.IncompatibleStructureVersion) + { + continue; + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return gpuThermalSettings.ToValueType(acceptType); + } + } + + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + /// + /// [PRIVATE] + /// Restores the cooler policy table to default for the passed GPU handle and cooler index. + /// + /// The handle of the GPU to perform the operation on. + /// The cooler policy to restore to default. + /// The indexes of the coolers to restore their policy tables to default. + public static void RestoreCoolerPolicyTable( + PhysicalGPUHandle gpuHandle, + CoolerPolicy policy, + uint[] indexes = null) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + indexes, + (uint) (indexes?.Length ?? 0), + policy + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// + /// [PRIVATE] + /// Restores the cooler settings to default for the passed GPU handle and cooler index. + /// + /// The handle of the GPU to perform the operation on. + /// The indexes of the coolers to restore their settings to default. + public static void RestoreCoolerSettings( + PhysicalGPUHandle gpuHandle, + uint[] indexes = null) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + indexes, + (uint) (indexes?.Length ?? 0) + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// + /// [PRIVATE] + /// Sets the cooler levels for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The cooler index. + /// The cooler level information. + /// The number of entries in the cooler level information. + // ReSharper disable once TooManyArguments + public static void SetCoolerLevels( + PhysicalGPUHandle gpuHandle, + uint index, + PrivateCoolerLevelsV1 coolerLevels, + uint levelsCount + ) + { + using (var coolerLevelsReference = ValueTypeReference.FromValueType(coolerLevels)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + index, + coolerLevelsReference, + levelsCount + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// + /// [PRIVATE] + /// Sets the cooler policy table for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The cooler index. + /// The cooler policy table. + /// The number of entries in the cooler policy table. + // ReSharper disable once TooManyArguments + public static void SetCoolerPolicyTable( + PhysicalGPUHandle gpuHandle, + uint index, + PrivateCoolerPolicyTableV1 coolerPolicyTable, + uint policyLevelsCount + ) + { + var instance = typeof(PrivateCoolerPolicyTableV1).Instantiate(); + + using (var policyTableReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + index, + policyTableReference, + policyLevelsCount + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// + /// [PRIVATE] + /// Sets the thermal policies status for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The new thermal limiter policy to apply. + public static void SetThermalPoliciesStatus( + PhysicalGPUHandle gpuHandle, + PrivateThermalPoliciesStatusV2 thermalPoliciesStatus) + { + using (var policiesStatusReference = ValueTypeReference.FromValueType(thermalPoliciesStatus)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + policiesStatusReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + public static PrivateFanCoolersInfoV1 GetClientFanCoolersInfo(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivateFanCoolersInfoV1).Instantiate(); + + using (var policiesInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, + policiesInfoReference); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return policiesInfoReference.ToValueType( + typeof(PrivateFanCoolersInfoV1)); + } + } + + public static PrivateFanCoolersStatusV1 GetClientFanCoolersStatus(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivateFanCoolersStatusV1).Instantiate(); + + using (var policiesStatusReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + policiesStatusReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return policiesStatusReference.ToValueType( + typeof(PrivateFanCoolersStatusV1)); + } + } + + public static PrivateFanCoolersControlV1 GetClientFanCoolersControl(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivateFanCoolersControlV1).Instantiate(); + using (var policiesStatusReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + policiesStatusReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return policiesStatusReference.ToValueType( + typeof(PrivateFanCoolersControlV1)); + } + } + + public static void SetClientFanCoolersControl(PhysicalGPUHandle gpuHandle, PrivateFanCoolersControlV1 control) + { + using (var coolerLevelsReference = ValueTypeReference.FromValueType(control)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + coolerLevelsReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// + /// [PRIVATE] + /// Gets the current temperature reading of requested sensors. + /// + /// The handle of the GPU to perform the operation on. + /// A 32 bit unsigned integer flag containing sensors that are of interest + public static PrivateThermalSensorsV2 QueryThermalSensors(PhysicalGPUHandle gpuHandle, uint mask) + { + var instance = new PrivateThermalSensorsV2(mask); + using (var thermalReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + thermalReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return thermalReference.ToValueType(typeof(PrivateThermalSensorsV2)); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPUApi.Usage.cs b/NvAPIWrapper/Native/GPUApi.Usage.cs new file mode 100644 index 0000000..4fdcff1 --- /dev/null +++ b/NvAPIWrapper/Native/GPUApi.Usage.cs @@ -0,0 +1,149 @@ +using System; +using System.Linq; +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; + +namespace NvAPIWrapper.Native +{ + public static partial class GPUApi + { + /// + /// [PRIVATE] + /// Enables the dynamic performance states + /// + /// The handle of the GPU to perform the operation on. + public static void EnableDynamicPStates(PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// + /// This function retrieves the dynamic performance states information from specific GPU + /// + /// Handle of the physical GPU for which the memory information is to be extracted. + /// The device utilizations information array. + /// This operation is not supported. + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found. + /// A delegate callback throws an exception. + public static DynamicPerformanceStatesInfoV1 GetDynamicPerformanceStatesInfoEx( + PhysicalGPUHandle physicalGPUHandle) + { + var getDynamicPerformanceStatesInfoEx = + DelegateFactory.GetDelegate(); + + foreach (var acceptType in getDynamicPerformanceStatesInfoEx.Accepts()) + { + var instance = acceptType.Instantiate(); + + using (var gpuDynamicPStateInfo = ValueTypeReference.FromValueType(instance, acceptType)) + { + var status = getDynamicPerformanceStatesInfoEx(physicalGPUHandle, gpuDynamicPStateInfo); + + if (status == Status.IncompatibleStructureVersion) + { + continue; + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return gpuDynamicPStateInfo.ToValueType(acceptType); + } + } + + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + /// + /// Gets the reason behind the current decrease in performance. + /// + /// The handle of the GPU to perform the operation on. + /// A value indicating the reason of current performance decrease. + public static PerformanceDecreaseReason GetPerformanceDecreaseInfo(PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + out var decreaseReason + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return decreaseReason; + } + + /// + /// [PRIVATE] + /// Gets the GPU usage metrics for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The usage information for the selected GPU. + public static PrivateUsagesInfoV1 GetUsages(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivateUsagesInfoV1).Instantiate(); + + using (var usageInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + usageInfoReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return usageInfoReference.ToValueType(typeof(PrivateUsagesInfoV1)); + } + } + + /// + /// Queries active applications. + /// + /// The physical GPU handle. + /// The list of active applications. + public static PrivateActiveApplicationV2[] QueryActiveApps(PhysicalGPUHandle gpuHandle) + { + var queryActiveApps = DelegateFactory.GetDelegate(); + + // ReSharper disable once EventExceptionNotDocumented + if (!queryActiveApps.Accepts().Contains(typeof(PrivateActiveApplicationV2))) + { + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + uint count = PrivateActiveApplicationV2.MaximumNumberOfApplications; + var instances = typeof(PrivateActiveApplicationV2).Instantiate() + .Repeat((int) count); + + using (var applications = ValueTypeArray.FromArray(instances)) + { + // ReSharper disable once EventExceptionNotDocumented + var status = queryActiveApps(gpuHandle, applications, ref count); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return applications.ToArray((int) count); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GPUApi.cs b/NvAPIWrapper/Native/GPUApi.cs new file mode 100644 index 0000000..77e766e --- /dev/null +++ b/NvAPIWrapper/Native/GPUApi.cs @@ -0,0 +1,1197 @@ +using System; +using System.Linq; +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native +{ + /// + /// Contains GPU static functions + /// + // ReSharper disable once ClassTooBig + public static partial class GPUApi + { + /// + /// This function returns an array of logical GPU handles. + /// Each handle represents one or more GPUs acting in concert as a single graphics device. + /// At least one GPU must be present in the system and running an NVIDIA display driver. + /// All logical GPUs handles get invalidated on a GPU topology change, so the calling application is required to + /// re-enum + /// the logical GPU handles to get latest physical handle mapping after every GPU topology change activated by a call + /// to SetGpuTopologies(). + /// To detect if SLI rendering is enabled, use Direct3DApi.GetCurrentSLIState(). + /// + /// Array of logical GPU handles. + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + public static LogicalGPUHandle[] EnumLogicalGPUs() + { + var gpuList = + typeof(LogicalGPUHandle).Instantiate().Repeat(LogicalGPUHandle.MaxLogicalGPUs); + var status = DelegateFactory.GetDelegate()(gpuList, out var count); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return gpuList.Take((int) count).ToArray(); + } + + /// + /// This function returns an array of physical GPU handles. + /// Each handle represents a physical GPU present in the system. + /// That GPU may be part of an SLI configuration, or may not be visible to the OS directly. + /// At least one GPU must be present in the system and running an NVIDIA display driver. + /// Note: In drivers older than 105.00, all physical GPU handles get invalidated on a mode-set. So the calling + /// applications need to re-enum the handles after every mode-set. With drivers 105.00 and up, all physical GPU handles + /// are constant. Physical GPU handles are constant as long as the GPUs are not physically moved and the SBIOS VGA + /// order is unchanged. + /// For GPU handles in TCC MODE please use EnumTCCPhysicalGPUs() + /// + /// + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + public static PhysicalGPUHandle[] EnumPhysicalGPUs() + { + var gpuList = + typeof(PhysicalGPUHandle).Instantiate().Repeat(PhysicalGPUHandle.PhysicalGPUs); + var status = DelegateFactory.GetDelegate()(gpuList, out var count); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return gpuList.Take((int) count).ToArray(); + } + + /// + /// This function returns an array of physical GPU handles that are in TCC Mode. + /// Each handle represents a physical GPU present in the system in TCC Mode. + /// That GPU may not be visible to the OS directly. + /// NOTE: Handles enumerated by this API are only valid for NvAPIs that are tagged as TCC_SUPPORTED If handle is passed + /// to any other API, it will fail with Status.InvalidHandle + /// For WDDM GPU handles please use EnumPhysicalGPUs() + /// + /// An array of physical GPU handles that are in TCC Mode. + /// See NVIDIAApiException.Status for the reason of the exception. + public static PhysicalGPUHandle[] EnumTCCPhysicalGPUs() + { + var gpuList = + typeof(PhysicalGPUHandle).Instantiate().Repeat(PhysicalGPUHandle.PhysicalGPUs); + var status = DelegateFactory.GetDelegate()(gpuList, out var count); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return gpuList.Take((int) count).ToArray(); + } + + /// + /// This function returns the AGP aperture in megabytes. + /// + /// Physical GPU handle to get information about + /// AGP aperture in megabytes + /// Status.InvalidArgument: display is not valid + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle. + public static int GetAGPAperture(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var agpAperture); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return (int) agpAperture; + } + + /// + /// [PRIVATE] + /// Gets the architect information for the passed physical GPU handle. + /// + /// The GPU handle to retrieve information for. + /// The GPU architect information. + public static PrivateArchitectInfoV2 GetArchitectInfo(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivateArchitectInfoV2).Instantiate(); + + using (var architectInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + architectInfoReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return architectInfoReference.ToValueType( + typeof(PrivateArchitectInfoV2)); + } + } + + /// + /// This API Retrieves the Board information (a unique GPU Board Serial Number) stored in the InfoROM. + /// + /// Physical GPU Handle + /// Board Information + /// Status.Error: Miscellaneous error occurred + /// Status.ExpectedPhysicalGPUHandle: Handle passed is not a physical GPU handle + /// Status.ApiNotInitialized: NVAPI not initialized + public static BoardInfo GetBoardInfo(PhysicalGPUHandle gpuHandle) + { + var boardInfo = typeof(BoardInfo).Instantiate(); + var status = DelegateFactory.GetDelegate()(gpuHandle, ref boardInfo); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return boardInfo; + } + + /// + /// Returns the identification of the bus associated with this GPU. + /// + /// GPU handle to get information about + /// Id of the bus + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found. + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle. + public static int GetBusId(PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()(gpuHandle, out var busId); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return (int) busId; + } + + /// + /// Returns the identification of the bus slot associated with this GPU. + /// + /// GPU handle to get information about + /// Identification of the bus slot associated with this GPU + /// Status.InvalidArgument: gpuHandle is NULL + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle + public static int GetBusSlotId(PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()(gpuHandle, out var busId); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return (int) busId; + } + + /// + /// This function returns the type of bus associated with this GPU. + /// TCC_SUPPORTED + /// + /// GPU handle to get information about + /// Type of bus associated with this GPU + /// Status.InvalidArgument: gpuHandle is NULL + public static GPUBusType GetBusType(PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()(gpuHandle, out var busType); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return busType; + } + + /// + /// This function returns the current AGP Rate (0 = AGP not present, 1 = 1x, 2 = 2x, etc.). + /// + /// Physical GPU handle to get information about + /// Current AGP rate + /// Status.InvalidArgument: display is not valid + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle. + public static int GetCurrentAGPRate(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var agpRate); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return (int) agpRate; + } + + /// + /// This function returns the number of PCIE lanes being used for the PCIE interface downstream from the GPU. + /// + /// Physical GPU handle to get information about + /// PCIE lanes being used for the PCIE interface downstream + /// Status.InvalidArgument: display is not valid + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle. + public static int GetCurrentPCIEDownStreamWidth(PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()(gpuHandle, + out var width); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return (int) width; + } + + /// + /// [PRIVATE] + /// Gets the driver model for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The driver model of the GPU. + public static uint GetDriverModel(PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()(gpuHandle, out var count); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return count; + } + + /// + /// This function returns ECC memory configuration information. + /// + /// + /// handle identifying the physical GPU for which ECC configuration information is to be + /// retrieved. + /// + /// An instance of + public static ECCConfigurationInfoV1 GetECCConfigurationInfo(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(ECCConfigurationInfoV1).Instantiate(); + + using (var configurationInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + configurationInfoReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return configurationInfoReference.ToValueType(typeof(ECCConfigurationInfoV1)); + } + } + + /// + /// This function returns ECC memory error information. + /// + /// A handle identifying the physical GPU for which ECC error information is to be retrieved. + /// An instance of + public static ECCErrorInfoV1 GetECCErrorInfo(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(ECCErrorInfoV1).Instantiate(); + + using (var errorInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + errorInfoReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return errorInfoReference.ToValueType(typeof(ECCErrorInfoV1)); + } + } + + /// + /// This function returns ECC memory status information. + /// + /// A handle identifying the physical GPU for which ECC status information is to be retrieved. + /// An instance of + public static ECCStatusInfoV1 GetECCStatusInfo(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(ECCStatusInfoV1).Instantiate(); + + using (var statusInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + statusInfoReference + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return statusInfoReference.ToValueType(typeof(ECCStatusInfoV1)); + } + } + + /// + /// [PRIVATE] + /// Gets the GPU manufacturing foundry of the passed GPU handle. + /// + /// The handle of the GPU to retrieve this information from. + /// The GPU manufacturing foundry of the GPU. + public static GPUFoundry GetFoundry(PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()(gpuHandle, out var foundry); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return foundry; + } + + /// + /// [PRIVATE] + /// Gets the current frame buffer width and location for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The frame buffer width. + /// The frame buffer location. + public static void GetFrameBufferWidthAndLocation( + PhysicalGPUHandle gpuHandle, + out uint width, + out uint location) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out width, + out location); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// + /// This function retrieves the full GPU name as an ASCII string - for example, "Quadro FX 1400". + /// + /// Physical GPU handle to get information about + /// Full GPU name as an ASCII string + /// See NVIDIAApiException.Status for the reason of the exception. + public static string GetFullName(PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()(gpuHandle, out var name); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return name.Value; + } + + /// + /// Retrieves the total number of cores defined for a GPU. + /// Returns 0 on architectures that don't define GPU cores. + /// + /// Physical GPU handle to get information about + /// Total number of cores + /// Status.InvalidArgument: display is not valid + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle. + /// Status.NotSupported: API call is not supported on current architecture + public static uint GetGPUCoreCount(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var cores); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return cores; + } + + /// + /// [PRIVATE] + /// Gets the GPUID of the passed GPU handle. + /// + /// The GPU handle to get the GPUID for. + /// The GPU's GPUID. + public static uint GetGPUIDFromPhysicalGPU(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var gpuId); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return gpuId; + } + + /// + /// This function returns the GPU type (integrated or discrete). + /// TCC_SUPPORTED + /// + /// GPU handle to get information about + /// GPU type + /// Status.InvalidArgument: gpuHandle is NULL + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle + public static GPUType GetGPUType(PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()(gpuHandle, out var type); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return type; + } + + /// + /// This function returns the interrupt number associated with this GPU. + /// + /// GPU handle to get information about + /// Interrupt number associated with this GPU + /// Status.InvalidArgument: gpuHandle is NULL + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle + public static int GetIRQ(PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()(gpuHandle, out var irq); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return (int) irq; + } + + /// + /// [PRIVATE] + /// Gets the current frame buffer width and location for the passed logical GPU handle. + /// + /// The handle of the logical GPU to perform the operation on. + /// The frame buffer width. + /// The frame buffer location. + public static void GetLogicalFrameBufferWidthAndLocation( + LogicalGPUHandle gpuHandle, + out uint width, + out uint location) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, + out width, out location); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// + /// This function returns the logical GPU handle associated with specified physical GPU handle. + /// At least one GPU must be present in the system and running an NVIDIA display driver. + /// + /// GPU handle to get information about + /// Logical GPU handle associated with specified physical GPU handle + /// Status.InvalidArgument: gpuHandle is NULL + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + public static LogicalGPUHandle GetLogicalGPUFromPhysicalGPU(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var gpu); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return gpu; + } + + /// + /// This function retrieves the available driver memory footprint for the specified GPU. + /// If the GPU is in TCC Mode, only dedicatedVideoMemory will be returned. + /// + /// Handle of the physical GPU for which the memory information is to be extracted. + /// The memory footprint available in the driver. + /// This operation is not supported. + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found. + /// A delegate callback throws an exception. + public static IDisplayDriverMemoryInfo GetMemoryInfo(PhysicalGPUHandle physicalGPUHandle) + { + var getMemoryInfo = DelegateFactory.GetDelegate(); + + foreach (var acceptType in getMemoryInfo.Accepts()) + { + var instance = acceptType.Instantiate(); + + using (var displayDriverMemoryInfo = ValueTypeReference.FromValueType(instance, acceptType)) + { + var status = getMemoryInfo(physicalGPUHandle, displayDriverMemoryInfo); + + if (status == Status.IncompatibleStructureVersion) + { + continue; + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return displayDriverMemoryInfo.ToValueType(acceptType); + } + } + + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + /// + /// [PRIVATE] + /// Gets the number of GPC (Graphic Processing Clusters) of the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// The number of GPC units for the GPU. + public static uint GetPartitionCount(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var count); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return count; + } + + /// + /// [PRIVATE] + /// Gets additional information about the PCIe interface and configuration for the passed GPU handle. + /// + /// The handle of the GPU to perform the operation on. + /// PCIe information and configurations. + public static PrivatePCIeInfoV2 GetPCIEInfo(PhysicalGPUHandle gpuHandle) + { + var instance = typeof(PrivatePCIeInfoV2).Instantiate(); + + using (var pcieInfoReference = ValueTypeReference.FromValueType(instance)) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, pcieInfoReference); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return pcieInfoReference.ToValueType(typeof(PrivatePCIeInfoV2)); + } + } + + /// + /// This function returns the PCI identifiers associated with this GPU. + /// TCC_SUPPORTED + /// + /// GPU handle to get information about + /// The internal PCI device identifier for the GPU. + /// The internal PCI subsystem identifier for the GPU. + /// The internal PCI device-specific revision identifier for the GPU. + /// The external PCI device identifier for the GPU. + /// Status.InvalidArgument: gpuHandle or an argument is NULL + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle + // ReSharper disable once TooManyArguments + public static void GetPCIIdentifiers( + PhysicalGPUHandle gpuHandle, + out uint deviceId, + out uint subSystemId, + out uint revisionId, + out uint extDeviceId) + { + var status = DelegateFactory.GetDelegate()(gpuHandle, + out deviceId, + out subSystemId, out revisionId, out extDeviceId); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// + /// This function returns the physical size of frame buffer in KB. This does NOT include any system RAM that may be + /// dedicated for use by the GPU. + /// TCC_SUPPORTED + /// + /// GPU handle to get information about + /// Physical size of frame buffer in KB + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle + public static int GetPhysicalFrameBufferSize(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, + out var size); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return (int) size; + } + + /// + /// [PRIVATE] + /// Gets a physical GPU handle from the passed GPUID + /// + /// The GPUID to get the physical handle for. + /// The retrieved physical GPU handle. + public static PhysicalGPUHandle GetPhysicalGPUFromGPUID(uint gpuId) + { + var status = + DelegateFactory.GetDelegate()(gpuId, out var gpuHandle); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return gpuHandle; + } + + /// + /// This function returns the physical GPU handles associated with the specified logical GPU handle. + /// At least one GPU must be present in the system and running an NVIDIA display driver. + /// + /// Logical GPU handle to get information about + /// An array of physical GPU handles + /// Status.InvalidArgument: gpuHandle is not valid + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedLogicalGPUHandle: gpuHandle was not a logical GPU handle + public static PhysicalGPUHandle[] GetPhysicalGPUsFromLogicalGPU(LogicalGPUHandle gpuHandle) + { + var gpuList = + typeof(PhysicalGPUHandle).Instantiate().Repeat(PhysicalGPUHandle.MaxPhysicalGPUs); + var status = DelegateFactory.GetDelegate()(gpuHandle, + gpuList, + out var count); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return gpuList.Take((int) count).ToArray(); + } + + /// + /// This function retrieves the Quadro status for the GPU (true if Quadro, false if GeForce) + /// + /// GPU handle to get information about + /// true if Quadro, false if GeForce + /// Status.Error: Miscellaneous error occurred + public static bool GetQuadroStatus(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var isQuadro); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return isQuadro > 0; + } + + /// + /// [PRIVATE] + /// Gets the number of RAM banks for the passed GPU handle. + /// + /// The handle of the GPU to retrieve this information from. + /// The number of RAM memory banks. + public static uint GetRAMBankCount(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var bankCount); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return bankCount; + } + + /// + /// [PRIVATE] + /// Gets the RAM bus width for the passed GPU handle. + /// + /// The handle of the GPU to retrieve this information from. + /// The RAM memory bus width. + public static uint GetRAMBusWidth(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var busWidth); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return busWidth; + } + + /// + /// [PRIVATE] + /// Gets the RAM maker for the passed GPU handle. + /// + /// The handle of the GPU to retrieve this information from. + /// The RAM memory maker. + public static GPUMemoryMaker GetRAMMaker(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var ramMaker); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return ramMaker; + } + + /// + /// [PRIVATE] + /// Gets the RAM type for the passed GPU handle. + /// + /// The handle of the GPU to retrieve this information from. + /// The RAM memory type. + public static GPUMemoryType GetRAMType(PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()(gpuHandle, out var ramType); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return ramType; + } + + /// + /// [PRIVATE] + /// Gets the ROP count for the passed GPU handle. + /// + /// The handle of the GPU to retrieve this information from. + /// The number of ROP units. + public static uint GetROPCount(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var ropCount); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return ropCount; + } + + /// + /// [PRIVATE] + /// Gets the number of shader pipe lines for the passed GPU handle. + /// + /// The handle of the GPU to retrieve this information from. + /// The number of shader pipelines. + public static uint GetShaderPipeCount(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var spCount); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return spCount; + } + + /// + /// This function retrieves the number of Shader SubPipes on the GPU + /// On newer architectures, this corresponds to the number of SM units + /// + /// GPU handle to get information about + /// Number of Shader SubPipes on the GPU + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle + public static uint GetShaderSubPipeCount(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var count); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return count; + } + + /// + /// [PRIVATE] + /// Gets the GPU short name (code name) for the passed GPU handle. + /// + /// The handle of the GPU to retrieve this information from. + /// The GPU short name. + public static string GetShortName(PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()(gpuHandle, out var name); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return name.Value; + } + + /// + /// This function identifies whether the GPU is a notebook GPU or a desktop GPU. + /// + /// GPU handle to get information about + /// GPU system type + /// Status.InvalidArgument: gpuHandle is NULL + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle + public static SystemType GetSystemType(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var systemType); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return systemType; + } + + /// + /// [PRIVATE] + /// Gets the SM count for the passed GPU handle. + /// + /// The handle of the GPU to retrieve this information from. + /// The number of SM units. + public static uint GetTotalSMCount(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var smCount); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return smCount; + } + + /// + /// [PRIVATE] + /// Gets the SP count for the passed GPU handle. + /// + /// The handle of the GPU to retrieve this information from. + /// The number of SP units. + public static uint GetTotalSPCount(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var spCount); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return spCount; + } + + /// + /// [PRIVATE] + /// Gets the TPC count for the passed GPU handle. + /// + /// The handle of the GPU to retrieve this information from. + /// The number of TPC units. + public static uint GetTotalTPCCount(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var tpcCount); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return tpcCount; + } + + /// + /// This function returns the OEM revision of the video BIOS associated with this GPU. + /// + /// GPU handle to get information about + /// OEM revision of the video BIOS + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found. + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle. + public static uint GetVBIOSOEMRevision(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var revision); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return revision; + } + + /// + /// This function returns the revision of the video BIOS associated with this GPU. + /// TCC_SUPPORTED + /// + /// GPU handle to get information about + /// Revision of the video BIOS + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found. + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle. + public static uint GetVBIOSRevision(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var revision); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return revision; + } + + /// + /// This function returns the full video BIOS version string in the form of xx.xx.xx.xx.yy where xx numbers come from + /// GetVbiosRevision() and yy comes from GetVbiosOEMRevision(). + /// + /// Physical GPU handle to get information about + /// Full video BIOS version string + /// Status.InvalidArgument: display is not valid + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle. + public static string GetVBIOSVersionString(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, + out var version); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return version.Value; + } + + /// + /// This function returns the virtual size of frame buffer in KB. This includes the physical RAM plus any system RAM + /// that has been dedicated for use by the GPU. + /// + /// Physical GPU handle to get information about + /// Virtual size of frame buffer in KB + /// Status.InvalidArgument: display is not valid + /// Status.NvidiaDeviceNotFound: No NVIDIA GPU driving a display was found + /// Status.ExpectedPhysicalGPUHandle: gpuHandle was not a physical GPU handle. + public static int GetVirtualFrameBufferSize(PhysicalGPUHandle gpuHandle) + { + var status = DelegateFactory.GetDelegate()(gpuHandle, + out var bufferSize); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return (int) bufferSize; + } + + /// + /// [PRIVATE] + /// Gets the VPE count for the passed GPU handle. + /// + /// The handle of the GPU to retrieve this information from. + /// The number of VPE units. + public static uint GetVPECount(PhysicalGPUHandle gpuHandle) + { + var status = + DelegateFactory.GetDelegate()(gpuHandle, out var vpeCount); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return vpeCount; + } + + /// + /// Reads data from I2C bus + /// + /// The physical GPU to access I2C bus. + /// The information required for the operation. Will be filled with data after retrieval. + // ReSharper disable once InconsistentNaming + public static void I2CRead(PhysicalGPUHandle gpuHandle, ref TI2CInfo i2cInfo) + where TI2CInfo : struct, II2CInfo + { + var c = i2cInfo as II2CInfo; + I2CRead(gpuHandle, ref c); + i2cInfo = (TI2CInfo) c; + } + + /// + /// Reads data from I2C bus + /// + /// The physical GPU to access I2C bus. + /// The information required for the operation. Will be filled with data after retrieval. + // ReSharper disable once InconsistentNaming + public static void I2CRead(PhysicalGPUHandle gpuHandle, ref II2CInfo i2cInfo) + { + var type = i2cInfo.GetType(); + // ReSharper disable once InconsistentNaming + var i2cRead = DelegateFactory.GetDelegate(); + + if (!i2cRead.Accepts().Contains(type)) + { + throw new ArgumentOutOfRangeException(nameof(type)); + } + + // ReSharper disable once InconsistentNaming + using (var i2cInfoReference = ValueTypeReference.FromValueType(i2cInfo, type)) + { + var status = i2cRead(gpuHandle, i2cInfoReference); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + i2cInfo = i2cInfoReference.ToValueType(type); + } + } + + /// + /// Writes data to I2C bus + /// + /// The physical GPU to access I2C bus. + /// The information required for the operation. + // ReSharper disable once InconsistentNaming + public static void I2CWrite(PhysicalGPUHandle gpuHandle, II2CInfo i2cInfo) + { + var type = i2cInfo.GetType(); + // ReSharper disable once InconsistentNaming + var i2cWrite = DelegateFactory.GetDelegate(); + + if (!i2cWrite.Accepts().Contains(type)) + { + throw new ArgumentOutOfRangeException(nameof(type)); + } + + // ReSharper disable once InconsistentNaming + using (var i2cInfoReference = ValueTypeReference.FromValueType(i2cInfo, type)) + { + var status = i2cWrite(gpuHandle, i2cInfoReference); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } + + /// + /// This function resets ECC memory error counters. + /// + /// A handle identifying the physical GPU for which ECC error information is to be cleared. + /// Reset the current ECC error counters. + /// Reset the aggregate ECC error counters. + public static void ResetECCErrorInfo( + PhysicalGPUHandle gpuHandle, + bool resetCurrent, + bool resetAggregated) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + (byte) (resetCurrent ? 1 : 0), + (byte) (resetAggregated ? 1 : 0) + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// + /// This function updates the ECC memory configuration setting. + /// + /// A handle identifying the physical GPU for which to update the ECC configuration setting. + /// The new ECC configuration setting. + /// Request that the new setting take effect immediately. + public static void SetECCConfiguration( + PhysicalGPUHandle gpuHandle, + bool isEnable, + bool isEnableImmediately) + { + var status = DelegateFactory.GetDelegate()( + gpuHandle, + (byte) (isEnable ? 1 : 0), + (byte) (isEnableImmediately ? 1 : 0) + ); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/General/ChipsetInfoFlag.cs b/NvAPIWrapper/Native/General/ChipsetInfoFlag.cs new file mode 100644 index 0000000..a092177 --- /dev/null +++ b/NvAPIWrapper/Native/General/ChipsetInfoFlag.cs @@ -0,0 +1,21 @@ +using System; + +namespace NvAPIWrapper.Native.General +{ + /// + /// Chipset information flags - obsolete + /// + [Flags] + public enum ChipsetInfoFlag + { + /// + /// No flags + /// + None = 0, + + /// + /// Hybrid chipset configuration + /// + Hybrid = 1 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/General/Status.cs b/NvAPIWrapper/Native/General/Status.cs new file mode 100644 index 0000000..6a94e43 --- /dev/null +++ b/NvAPIWrapper/Native/General/Status.cs @@ -0,0 +1,642 @@ +namespace NvAPIWrapper.Native.General +{ + /// + /// NvAPI status codes + /// + public enum Status + { + /// + /// Success. Request is completed. + /// + Ok = 0, + + /// + /// Generic error + /// + Error = -1, + + /// + /// NVAPI support library cannot be loaded. + /// + LibraryNotFound = -2, + + /// + /// Not implemented in current driver installation + /// + NoImplementation = -3, + + /// + /// NvAPI_Initialize() has not been called (successfully) + /// + ApiNotInitialized = -4, + + /// + /// Invalid argument + /// + InvalidArgument = -5, + + /// + /// No NVIDIA display driver was found + /// + NvidiaDeviceNotFound = -6, + + /// + /// No more to enumerate + /// + EndEnumeration = -7, + + /// + /// Invalid handle + /// + InvalidHandle = -8, + + /// + /// An argument's structure version is not supported + /// + IncompatibleStructureVersion = -9, + + /// + /// Handle is no longer valid (likely due to GPU or display re-configuration) + /// + HandleInvalidated = -10, + + /// + /// No NVIDIA OpenGL context is current (but needs to be) + /// + OpenGLContextNotCurrent = -11, + + /// + /// An invalid pointer, usually NULL, was passed as a parameter + /// + InvalidPointer = -14, + + /// + /// OpenGL Expert is not supported by the current drivers + /// + NoGLExpert = -12, + + /// + /// OpenGL Expert is supported, but driver instrumentation is currently disabled + /// + InstrumentationDisabled = -13, + + /// + /// Expected a logical GPU handle for one or more parameters + /// + ExpectedLogicalGPUHandle = -100, + + /// + /// Expected a physical GPU handle for one or more parameters + /// + ExpectedPhysicalGPUHandle = -101, + + /// + /// Expected an NV display handle for one or more parameters + /// + ExpectedDisplayHandle = -102, + + /// + /// Used in some commands to indicate that the combination of parameters is not valid + /// + InvalidCombination = -103, + + /// + /// Requested feature not supported in the selected GPU + /// + NotSupported = -104, + + /// + /// NO port Id found for I2C transaction + /// + PortIdNotFound = -105, + + /// + /// Expected an unattached display handle as one of the input param + /// + ExpectedUnattachedDisplayHandle = -106, + + /// + /// Invalid performance level + /// + InvalidPerformanceLevel = -107, + + /// + /// Device is busy, request not fulfilled + /// + DeviceBusy = -108, + + /// + /// NVIDIA persist file is not found + /// + NvPersistFileNotFound = -109, + + /// + /// NVIDIA persist data is not found + /// + PersistDataNotFound = -110, + + /// + /// Expected TV output display + /// + ExpectedTVDisplay = -111, + + /// + /// Expected TV output on D Connector - HDTV_EIAJ4120. + /// + ExpectedTVDisplayOnDConnector = -112, + + /// + /// SLI is not active on this device + /// + NoActiveSLITopology = -113, + + /// + /// Setup of SLI rendering mode is not possible right now + /// + SLIRenderingModeNotAllowed = -114, + + /// + /// Expected digital flat panel + /// + ExpectedDigitalFlatPanel = -115, + + /// + /// Argument exceeds expected size + /// + ArgumentExceedMaxSize = -116, + + /// + /// Inhibit ON due to one of the flags in NV_GPU_DISPLAY_CHANGE_INHIBIT or SLI Active + /// + DeviceSwitchingNotAllowed = -117, + + /// + /// Testing clocks not supported + /// + TestingClocksNotSupported = -118, + + /// + /// The specified underscan config is from an unknown source (e.g. INF) + /// + UnknownUnderScanConfig = -119, + + /// + /// Timeout while reconfiguring GPUs + /// + TimeoutReConfiguringGPUTopology = -120, + + /// + /// Requested data was not found + /// + DataNotFound = -121, + + /// + /// Expected analog display + /// + ExpectedAnalogDisplay = -122, + + /// + /// No SLI video bridge present + /// + NoVideoLink = -123, + + /// + /// NvAPI requires reboot for its settings to take effect + /// + RequiresReboot = -124, + + /// + /// The function is not supported with the current hybrid mode. + /// + InvalidHybridMode = -125, + + /// + /// The target types are not all the same + /// + MixedTargetTypes = -126, + + /// + /// The function is not supported from 32-bit on a 64-bit system + /// + SYSWOW64NotSupported = -127, + + /// + /// There is any implicit GPU topology active. Use NVAPI_SetHybridMode to change topology. + /// + ImplicitSetGPUTopologyChangeNotAllowed = -128, + + + /// + /// Prompt the user to close all non-migratable applications. + /// + RequestUserToCloseNonMigratableApps = -129, + + /// + /// Could not allocate sufficient memory to complete the call + /// + OutOfMemory = -130, + + /// + /// The previous operation that is transferring information to or from this surface is incomplete + /// + WasStillDrawing = -131, + + /// + /// The file was not found + /// + FileNotFound = -132, + + /// + /// There are too many unique instances of a particular type of state object + /// + TooManyUniqueStateObjects = -133, + + + /// + /// The method call is invalid. For example, a method's parameter may not be a valid pointer + /// + InvalidCall = -134, + + /// + /// d3d10_1.dll can not be loaded + /// + D3D101LibraryNotFound = -135, + + /// + /// Couldn't find the function in loaded DLL library + /// + FunctionNotFound = -136, + + /// + /// Current User is not Administrator + /// + InvalidUserPrivilege = -137, + + /// + /// The handle corresponds to GDIPrimary + /// + ExpectedNonPrimaryDisplayHandle = -138, + + /// + /// Setting PhysX GPU requires that the GPU is compute capable + /// + ExpectedComputeGPUHandle = -139, + + /// + /// Stereo part of NvAPI failed to initialize completely. Check if stereo driver is installed. + /// + StereoNotInitialized = -140, + + /// + /// Access to stereo related registry keys or values failed. + /// + StereoRegistryAccessFailed = -141, + + /// + /// Given registry profile type is not supported. + /// + StereoRegistryProfileTypeNotSupported = -142, + + /// + /// Given registry value is not supported. + /// + StereoRegistryValueNotSupported = -143, + + /// + /// Stereo is not enabled and function needed it to execute completely. + /// + StereoNotEnabled = -144, + + /// + /// Stereo is not turned on and function needed it to execute completely. + /// + StereoNotTurnedOn = -145, + + /// + /// Invalid device interface. + /// + StereoInvalidDeviceInterface = -146, + + + /// + /// Separation percentage or JPEG image capture quality out of [0-100] range. + /// + StereoParameterOutOfRange = -147, + + /// + /// Given frustum adjust mode is not supported. + /// + StereoFrustumAdjustModeNotSupported = -148, + + /// + /// The mosaic topology is not possible given the current state of HW + /// + TopologyNotPossible = -149, + + /// + /// An attempt to do a display resolution mode change has failed + /// + ModeChangeFailed = -150, + + /// + /// d3d11.dll/d3d11_beta.dll cannot be loaded. + /// + D3D11LibraryNotFound = -151, + + /// + /// Address outside of valid range. + /// + InvalidAddress = -152, + + /// + /// The pre-allocated string is too small to hold the result. + /// + StringTooSmall = -153, + + /// + /// The input does not match any of the available devices. + /// + MatchingDeviceNotFound = -154, + + /// + /// Driver is running. + /// + DriverRunning = -155, + + /// + /// Driver is not running. + /// + DriverNotRunning = -156, + + /// + /// A driver reload is required to apply these settings. + /// + ErrorDriverReloadRequired = -157, + + /// + /// Intended setting is not allowed. + /// + SetNotAllowed = -158, + + /// + /// Information can't be returned due to "advanced display topology". + /// + AdvancedDisplayTopologyRequired = -159, + + /// + /// Setting is not found. + /// + SettingNotFound = -160, + + /// + /// Setting size is too large. + /// + SettingSizeTooLarge = -161, + + /// + /// There are too many settings for a profile. + /// + TooManySettingsInProfile = -162, + + /// + /// Profile is not found. + /// + ProfileNotFound = -163, + + /// + /// Profile name is duplicated. + /// + ProfileNameInUse = -164, + + /// + /// Profile name is empty. + /// + ProfileNameEmpty = -165, + + /// + /// Application not found in the Profile. + /// + ExecutableNotFound = -166, + + /// + /// Application already exists in the other profile. + /// + ExecutableAlreadyInUse = -167, + + /// + /// Data Type mismatch + /// + DataTypeMismatch = -168, + + /// + /// The profile passed as parameter has been removed and is no longer valid. + /// + ProfileRemoved = -169, + + /// + /// An unregistered resource was passed as a parameter. + /// + UnregisteredResource = -170, + + /// + /// The DisplayId corresponds to a display which is not within the normal outputId range. + /// + IdOutOfRange = -171, + + /// + /// Display topology is not valid so the driver cannot do a mode set on this configuration. + /// + DisplayConfigValidationFailed = -172, + + /// + /// Display Port Multi-Stream topology has been changed. + /// + DPMSTChanged = -173, + + /// + /// Input buffer is insufficient to hold the contents. + /// + InsufficientBuffer = -174, + + /// + /// No access to the caller. + /// + AccessDenied = -175, + + /// + /// The requested action cannot be performed without Mosaic being enabled. + /// + MosaicNotActive = -176, + + /// + /// The surface is relocated away from video memory. + /// + ShareResourceRelocated = -177, + + /// + /// The user should disable DWM before calling NvAPI. + /// + RequestUserToDisableDWM = -178, + + /// + /// D3D device status is "D3DERR_DEVICELOST" or "D3DERR_DEVICENOTRESET" - the user has to reset the device. + /// + D3DDeviceLost = -179, + + /// + /// The requested action cannot be performed in the current state. + /// + InvalidConfiguration = -180, + + /// + /// Call failed as stereo handshake not completed. + /// + StereoHandshakeNotDone = -181, + + /// + /// The path provided was too short to determine the correct NVDRS_APPLICATION + /// + ExecutablePathIsAmbiguous = -182, + + /// + /// Default stereo profile is not currently defined + /// + DefaultStereoProfileIsNotDefined = -183, + + /// + /// Default stereo profile does not exist + /// + DefaultStereoProfileDoesNotExist = -184, + + /// + /// A cluster is already defined with the given configuration. + /// + ClusterAlreadyExists = -185, + + /// + /// The input display id is not that of a multi stream enabled connector or a display device in a multi stream topology + /// + DPMSTDisplayIdExpected = -186, + + /// + /// The input display id is not valid or the monitor associated to it does not support the current operation + /// + InvalidDisplayId = -187, + + /// + /// While playing secure audio stream, stream goes out of sync + /// + StreamIsOutOfSync = -188, + + /// + /// Older audio driver version than required + /// + IncompatibleAudioDriver = -189, + + /// + /// Value already set, setting again not allowed. + /// + ValueAlreadySet = -190, + + /// + /// Requested operation timed out + /// + Timeout = -191, + + /// + /// The requested workstation feature set has incomplete driver internal allocation resources + /// + GPUWorkstationFeatureIncomplete = -192, + + /// + /// Call failed because InitActivation was not called. + /// + StereoInitActivationNotDone = -193, + + /// + /// The requested action cannot be performed without Sync being enabled. + /// + SyncNotActive = -194, + + /// + /// The requested action cannot be performed without Sync Master being enabled. + /// + SyncMasterNotFound = -195, + + /// + /// Invalid displays passed in the NV_GSYNC_DISPLAY pointer. + /// + InvalidSyncTopology = -196, + + /// + /// The specified signing algorithm is not supported. Either an incorrect value was entered or the current installed + /// driver/hardware does not support the input value. + /// + ECIDSignAlgoUnsupported = -197, + + /// + /// The encrypted public key verification has failed. + /// + ECIDKeyVerificationFailed = -198, + + /// + /// The device's firmware is out of date. + /// + FirmwareOutOfDate = -199, + + /// + /// The device's firmware is not supported. + /// + FirmwareRevisionNotSupported = -200, + + /// + /// The caller is not authorized to modify the License. + /// + LicenseCallerAuthenticationFailed = -201, + + /// + /// The user tried to use a deferred context without registering the device first + /// + D3DDeviceNotRegistered = -202, + + /// + /// Head or SourceId was not reserved for the VR Display before doing the Mode-Set. + /// + ResourceNotAcquired = -203, + + /// + /// Provided timing is not supported. + /// + TimingNotSupported = -204, + + /// + /// HDCP Encryption Failed for the device. Would be applicable when the device is HDCP Capable. + /// + HDCPEncryptionFailed = -205, + + /// + /// Provided mode is over sink device pclk limitation. + /// + PCLKLimitationFailed = -206, + + /// + /// No connector on GPU found. + /// + NoConnectorFound = -207, + + /// + /// When a non-HDCP capable HMD is connected, we would inform user by this code. + /// + HDCPDisabled = -208, + + /// + /// At least an API is still being called + /// + ApiInUse = -209, + + /// + /// No display found on Nvidia GPU(s). + /// + NVIDIADisplayNotFound = -210 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/General/Structures/ChipsetInfoV1.cs b/NvAPIWrapper/Native/General/Structures/ChipsetInfoV1.cs new file mode 100644 index 0000000..3420a59 --- /dev/null +++ b/NvAPIWrapper/Native/General/Structures/ChipsetInfoV1.cs @@ -0,0 +1,92 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.General; + +namespace NvAPIWrapper.Native.General.Structures +{ + /// + /// Holds information about the system's chipset. + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct ChipsetInfoV1 : IInitializable, IChipsetInfo, IEquatable + { + internal StructureVersion _Version; + internal readonly uint _VendorId; + internal readonly uint _DeviceId; + internal readonly ShortString _VendorName; + internal readonly ShortString _ChipsetName; + + /// + public bool Equals(ChipsetInfoV1 other) + { + return _VendorId == other._VendorId && + _DeviceId == other._DeviceId && + _VendorName.Equals(other._VendorName) && + _ChipsetName.Equals(other._ChipsetName); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is ChipsetInfoV1 v1 && Equals(v1); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (int) _VendorId; + hashCode = (hashCode * 397) ^ (int) _DeviceId; + hashCode = (hashCode * 397) ^ _VendorName.GetHashCode(); + hashCode = (hashCode * 397) ^ _ChipsetName.GetHashCode(); + + return hashCode; + } + } + + /// + public override string ToString() + { + return $"{VendorName} {ChipsetName}"; + } + + /// + public int VendorId + { + get => (int) _VendorId; + } + + /// + public int DeviceId + { + get => (int) _DeviceId; + } + + /// + public string VendorName + { + get => _VendorName.Value; + } + + /// + public string ChipsetName + { + get => _ChipsetName.Value; + } + + /// + public ChipsetInfoFlag Flags + { + get => ChipsetInfoFlag.None; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/General/Structures/ChipsetInfoV2.cs b/NvAPIWrapper/Native/General/Structures/ChipsetInfoV2.cs new file mode 100644 index 0000000..3abb1e0 --- /dev/null +++ b/NvAPIWrapper/Native/General/Structures/ChipsetInfoV2.cs @@ -0,0 +1,95 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.General; + +namespace NvAPIWrapper.Native.General.Structures +{ + /// + /// Holds information about the system's chipset. + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(2)] + public struct ChipsetInfoV2 : IInitializable, IChipsetInfo, IEquatable + { + internal StructureVersion _Version; + internal readonly uint _VendorId; + internal readonly uint _DeviceId; + internal readonly ShortString _VendorName; + internal readonly ShortString _ChipsetName; + internal readonly ChipsetInfoFlag _Flags; + + /// + public bool Equals(ChipsetInfoV2 other) + { + return _VendorId == other._VendorId && + _DeviceId == other._DeviceId && + _VendorName.Equals(other._VendorName) && + _ChipsetName.Equals(other._ChipsetName) && + _Flags == other._Flags; + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is ChipsetInfoV2 v2 && Equals(v2); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (int) _VendorId; + hashCode = (hashCode * 397) ^ (int) _DeviceId; + hashCode = (hashCode * 397) ^ _VendorName.GetHashCode(); + hashCode = (hashCode * 397) ^ _ChipsetName.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) _Flags; + + return hashCode; + } + } + + /// + public override string ToString() + { + return $"{VendorName} {ChipsetName}"; + } + + /// + public int VendorId + { + get => (int) _VendorId; + } + + /// + public int DeviceId + { + get => (int) _DeviceId; + } + + /// + public string VendorName + { + get => _VendorName.Value; + } + + /// + public string ChipsetName + { + get => _ChipsetName.Value; + } + + /// + public ChipsetInfoFlag Flags + { + get => _Flags; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/General/Structures/ChipsetInfoV3.cs b/NvAPIWrapper/Native/General/Structures/ChipsetInfoV3.cs new file mode 100644 index 0000000..e05f386 --- /dev/null +++ b/NvAPIWrapper/Native/General/Structures/ChipsetInfoV3.cs @@ -0,0 +1,128 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.General; + +namespace NvAPIWrapper.Native.General.Structures +{ + /// + /// Holds information about the system's chipset. + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(3)] + public struct ChipsetInfoV3 : IInitializable, IChipsetInfo, IEquatable + { + internal StructureVersion _Version; + internal readonly uint _VendorId; + internal readonly uint _DeviceId; + internal readonly ShortString _VendorName; + internal readonly ShortString _ChipsetName; + internal readonly ChipsetInfoFlag _Flags; + internal readonly uint _SubSystemVendorId; + internal readonly uint _SubSystemDeviceId; + internal readonly ShortString _SubSystemVendorName; + + /// + public bool Equals(ChipsetInfoV3 other) + { + return _VendorId == other._VendorId && + _DeviceId == other._DeviceId && + _VendorName.Equals(other._VendorName) && + _ChipsetName.Equals(other._ChipsetName) && + _Flags == other._Flags && + _SubSystemVendorId == other._SubSystemVendorId && + _SubSystemDeviceId == other._SubSystemDeviceId && + _SubSystemVendorName.Equals(other._SubSystemVendorName); + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is ChipsetInfoV3 v3 && Equals(v3); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (int) _VendorId; + hashCode = (hashCode * 397) ^ (int) _DeviceId; + hashCode = (hashCode * 397) ^ _VendorName.GetHashCode(); + hashCode = (hashCode * 397) ^ _ChipsetName.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) _Flags; + hashCode = (hashCode * 397) ^ (int) _SubSystemVendorId; + hashCode = (hashCode * 397) ^ (int) _SubSystemDeviceId; + hashCode = (hashCode * 397) ^ _SubSystemVendorName.GetHashCode(); + + return hashCode; + } + } + + /// + public override string ToString() + { + return $"{SubSystemVendorName} {VendorName} {ChipsetName}"; + } + + /// + public int VendorId + { + get => (int) _VendorId; + } + + /// + public int DeviceId + { + get => (int) _DeviceId; + } + + /// + public string VendorName + { + get => _VendorName.Value; + } + + /// + public string ChipsetName + { + get => _ChipsetName.Value; + } + + /// + public ChipsetInfoFlag Flags + { + get => _Flags; + } + + /// + /// Chipset subsystem vendor identification + /// + public int SubSystemVendorId + { + get => (int) _SubSystemVendorId; + } + + /// + /// Chipset subsystem device identification + /// + public int SubSystemDeviceId + { + get => (int) _SubSystemDeviceId; + } + + /// + /// Chipset subsystem vendor name + /// + public string SubSystemVendorName + { + get => _SubSystemVendorName.Value; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/General/Structures/ChipsetInfoV4.cs b/NvAPIWrapper/Native/General/Structures/ChipsetInfoV4.cs new file mode 100644 index 0000000..00bdf30 --- /dev/null +++ b/NvAPIWrapper/Native/General/Structures/ChipsetInfoV4.cs @@ -0,0 +1,172 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.Interfaces; +using NvAPIWrapper.Native.Interfaces.General; + +namespace NvAPIWrapper.Native.General.Structures +{ + /// + /// Holds information about the system's chipset. + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(4)] + public struct ChipsetInfoV4 : IInitializable, IChipsetInfo, IEquatable + { + internal StructureVersion _Version; + internal readonly uint _VendorId; + internal readonly uint _DeviceId; + internal readonly ShortString _VendorName; + internal readonly ShortString _ChipsetName; + internal readonly ChipsetInfoFlag _Flags; + internal readonly uint _SubSystemVendorId; + internal readonly uint _SubSystemDeviceId; + internal readonly ShortString _SubSystemVendorName; + internal readonly uint _HostBridgeVendorId; + internal readonly uint _HostBridgeDeviceId; + internal readonly uint _HostBridgeSubSystemVendorId; + internal readonly uint _HostBridgeSubSystemDeviceId; + + /// + public bool Equals(ChipsetInfoV4 other) + { + return _VendorId == other._VendorId && + _DeviceId == other._DeviceId && + _VendorName.Equals(other._VendorName) && + _ChipsetName.Equals(other._ChipsetName) && + _Flags == other._Flags && + _SubSystemVendorId == other._SubSystemVendorId && + _SubSystemDeviceId == other._SubSystemDeviceId && + _SubSystemVendorName.Equals(other._SubSystemVendorName) && + _HostBridgeVendorId == other._HostBridgeVendorId && + _HostBridgeDeviceId == other._HostBridgeDeviceId && + _HostBridgeSubSystemVendorId == other._HostBridgeSubSystemVendorId && + _HostBridgeSubSystemDeviceId == other._HostBridgeSubSystemDeviceId; + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is ChipsetInfoV4 v4 && Equals(v4); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (int) _VendorId; + hashCode = (hashCode * 397) ^ (int) _DeviceId; + hashCode = (hashCode * 397) ^ _VendorName.GetHashCode(); + hashCode = (hashCode * 397) ^ _ChipsetName.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) _Flags; + hashCode = (hashCode * 397) ^ (int) _SubSystemVendorId; + hashCode = (hashCode * 397) ^ (int) _SubSystemDeviceId; + hashCode = (hashCode * 397) ^ _SubSystemVendorName.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) _HostBridgeVendorId; + hashCode = (hashCode * 397) ^ (int) _HostBridgeDeviceId; + hashCode = (hashCode * 397) ^ (int) _HostBridgeSubSystemVendorId; + hashCode = (hashCode * 397) ^ (int) _HostBridgeSubSystemDeviceId; + + return hashCode; + } + } + + /// + public override string ToString() + { + return $"{SubSystemVendorName} {VendorName} {ChipsetName}"; + } + + /// + public int VendorId + { + get => (int) _VendorId; + } + + /// + public int DeviceId + { + get => (int) _DeviceId; + } + + /// + public string VendorName + { + get => _VendorName.Value; + } + + /// + public string ChipsetName + { + get => _ChipsetName.Value; + } + + /// + public ChipsetInfoFlag Flags + { + get => _Flags; + } + + /// + /// Chipset subsystem vendor identification + /// + public int SubSystemVendorId + { + get => (int) _SubSystemVendorId; + } + + /// + /// Chipset subsystem device identification + /// + public int SubSystemDeviceId + { + get => (int) _SubSystemDeviceId; + } + + /// + /// Chipset subsystem vendor name + /// + public string SubSystemVendorName + { + get => _SubSystemVendorName.Value; + } + + /// + /// Host bridge vendor identification + /// + public int HostBridgeVendorId + { + get => (int) _HostBridgeVendorId; + } + + /// + /// Host bridge device identification + /// + public int HostBridgeDeviceId + { + get => (int) _HostBridgeDeviceId; + } + + /// + /// Host bridge subsystem vendor identification + /// + public int HostBridgeSubSystemVendorId + { + get => (int) _HostBridgeSubSystemVendorId; + } + + /// + /// Host bridge subsystem device identification + /// + public int HostBridgeSubSystemDeviceId + { + get => (int) _HostBridgeSubSystemDeviceId; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/General/Structures/GenericString.cs b/NvAPIWrapper/Native/General/Structures/GenericString.cs new file mode 100644 index 0000000..ad6dfe0 --- /dev/null +++ b/NvAPIWrapper/Native/General/Structures/GenericString.cs @@ -0,0 +1,29 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.General.Structures +{ + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + internal struct GenericString : IInitializable + { + public const int GenericStringLength = 4096; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = GenericStringLength)] + private readonly string _Value; + + public string Value + { + get => _Value; + } + + public GenericString(string value) + { + _Value = value ?? string.Empty; + } + + public override string ToString() + { + return Value; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/General/Structures/LIDDockParameters.cs b/NvAPIWrapper/Native/General/Structures/LIDDockParameters.cs new file mode 100644 index 0000000..02b5ae5 --- /dev/null +++ b/NvAPIWrapper/Native/General/Structures/LIDDockParameters.cs @@ -0,0 +1,109 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.General.Structures +{ + /// + /// Holds information about the lid and dock + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [StructureVersion(1)] + public struct LidDockParameters : IInitializable, IEquatable + { + internal StructureVersion _Version; + internal readonly uint _CurrentLIDState; + internal readonly uint _CurrentDockState; + internal readonly uint _CurrentLIDPolicy; + internal readonly uint _CurrentDockPolicy; + internal readonly uint _ForcedLIDMechanismPresent; + internal readonly uint _ForcedDockMechanismPresent; + + /// + public bool Equals(LidDockParameters other) + { + return _CurrentLIDState == other._CurrentLIDState && + _CurrentDockState == other._CurrentDockState && + _CurrentLIDPolicy == other._CurrentLIDPolicy && + _CurrentDockPolicy == other._CurrentDockPolicy && + _ForcedLIDMechanismPresent == other._ForcedLIDMechanismPresent && + _ForcedDockMechanismPresent == other._ForcedDockMechanismPresent; + } + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is LidDockParameters parameters && Equals(parameters); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (int) _CurrentLIDState; + hashCode = (hashCode * 397) ^ (int) _CurrentDockState; + hashCode = (hashCode * 397) ^ (int) _CurrentLIDPolicy; + hashCode = (hashCode * 397) ^ (int) _CurrentDockPolicy; + hashCode = (hashCode * 397) ^ (int) _ForcedLIDMechanismPresent; + hashCode = (hashCode * 397) ^ (int) _ForcedDockMechanismPresent; + + return hashCode; + } + } + + /// + /// Gets current lid state + /// + public uint CurrentLidState + { + get => _CurrentLIDState; + } + + /// + /// Gets current dock state + /// + public uint CurrentDockState + { + get => _CurrentDockState; + } + + /// + /// Gets current lid policy + /// + public uint CurrentLidPolicy + { + get => _CurrentLIDPolicy; + } + + /// + /// Gets current dock policy + /// + public uint CurrentDockPolicy + { + get => _CurrentDockPolicy; + } + + /// + /// Gets forced lid mechanism present + /// + public uint ForcedLidMechanismPresent + { + get => _ForcedLIDMechanismPresent; + } + + /// + /// Gets forced dock mechanism present + /// + public uint ForcedDockMechanismPresent + { + get => _ForcedDockMechanismPresent; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/General/Structures/LongString.cs b/NvAPIWrapper/Native/General/Structures/LongString.cs new file mode 100644 index 0000000..9717020 --- /dev/null +++ b/NvAPIWrapper/Native/General/Structures/LongString.cs @@ -0,0 +1,29 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.General.Structures +{ + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + internal struct LongString : IInitializable + { + public const int LongStringLength = 256; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = LongStringLength)] + private readonly string _Value; + + public string Value + { + get => _Value; + } + + public LongString(string value) + { + _Value = value ?? string.Empty; + } + + public override string ToString() + { + return Value; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/General/Structures/Rectangle.cs b/NvAPIWrapper/Native/General/Structures/Rectangle.cs new file mode 100644 index 0000000..1a0c7a8 --- /dev/null +++ b/NvAPIWrapper/Native/General/Structures/Rectangle.cs @@ -0,0 +1,80 @@ +using System.Runtime.InteropServices; + +namespace NvAPIWrapper.Native.General.Structures +{ + /// + /// Represents a rectangle coordinates + /// + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct Rectangle + { + internal int _X; + internal int _Y; + internal int _Width; + internal int _Height; + + /// + /// Creates a new instance of + /// + /// The horizontal location value. + /// The vertical location value. + /// The width of the rectangle. + /// The height of the rectangle. + // ReSharper disable once TooManyDependencies + public Rectangle(int x, int y, int width, int height) + { + _X = x; + _Y = y; + _Width = width; + _Height = height; + } + + /// + /// Gets the horizontal location value + /// + public int X + { + get => _X; + } + + /// + /// Gets the vertical location value + /// + public int Y + { + get => _Y; + } + + /// + /// Gets the rectangle width value + /// + public int Width + { + get => _Width; + } + + /// + /// Gets the rectangle height value + /// + public int Height + { + get => _Height; + } + + /// + /// Gets the horizontal left edge value + /// + public int X2 + { + get => X + Width; + } + + /// + /// Gets the vertical bottom edge value + /// + public int Y2 + { + get => Y + Height; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/General/Structures/ShortString.cs b/NvAPIWrapper/Native/General/Structures/ShortString.cs new file mode 100644 index 0000000..3385b33 --- /dev/null +++ b/NvAPIWrapper/Native/General/Structures/ShortString.cs @@ -0,0 +1,29 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.General.Structures +{ + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + internal struct ShortString : IInitializable + { + public const int ShortStringLength = 64; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ShortStringLength)] + private readonly string _Value; + + public string Value + { + get => _Value; + } + + public ShortString(string value) + { + _Value = value ?? string.Empty; + } + + public override string ToString() + { + return Value; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/General/Structures/StructureVersion.cs b/NvAPIWrapper/Native/General/Structures/StructureVersion.cs new file mode 100644 index 0000000..e18f8f7 --- /dev/null +++ b/NvAPIWrapper/Native/General/Structures/StructureVersion.cs @@ -0,0 +1,31 @@ +using System; +using System.Runtime.InteropServices; + +namespace NvAPIWrapper.Native.General.Structures +{ + [StructLayout(LayoutKind.Sequential)] + internal struct StructureVersion + { + private readonly uint _version; + + public int VersionNumber + { + get => (int) (_version >> 16); + } + + public int StructureSize + { + get => (int) (_version & ~(0xFFFF << 16)); + } + + public StructureVersion(int version, Type structureType) + { + _version = (uint) (Marshal.SizeOf(structureType) | (version << 16)); + } + + public override string ToString() + { + return $"Structure Size: {StructureSize} Bytes, Version: {VersionNumber}"; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/General/Structures/UnicodeString.cs b/NvAPIWrapper/Native/General/Structures/UnicodeString.cs new file mode 100644 index 0000000..5ba67b1 --- /dev/null +++ b/NvAPIWrapper/Native/General/Structures/UnicodeString.cs @@ -0,0 +1,29 @@ +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.General.Structures +{ + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct UnicodeString : IInitializable + { + public const int UnicodeStringLength = 2048; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = UnicodeStringLength)] + private readonly string _Value; + + public string Value + { + get => _Value; + } + + public UnicodeString(string value) + { + _Value = value ?? string.Empty; + } + + public override string ToString() + { + return Value; + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/GeneralApi.cs b/NvAPIWrapper/Native/GeneralApi.cs new file mode 100644 index 0000000..4d31533 --- /dev/null +++ b/NvAPIWrapper/Native/GeneralApi.cs @@ -0,0 +1,195 @@ +using System; +using NvAPIWrapper.Native.Exceptions; +using NvAPIWrapper.Native.General; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Helpers; +using NvAPIWrapper.Native.Helpers.Structures; +using NvAPIWrapper.Native.Interfaces.General; + +namespace NvAPIWrapper.Native +{ + /// + /// Contains system and general static functions + /// + public static class GeneralApi + { + /// + /// This function returns information about the system's chipset. + /// + /// Information about the system's chipset + /// This operation is not supported. + /// Status.InvalidArgument: Invalid argument + /// A delegate callback throws an exception. + public static IChipsetInfo GetChipsetInfo() + { + var getChipSetInfo = DelegateFactory.GetDelegate(); + + foreach (var acceptType in getChipSetInfo.Accepts()) + { + var instance = acceptType.Instantiate(); + + using (var chipsetInfoReference = ValueTypeReference.FromValueType(instance, acceptType)) + { + var status = getChipSetInfo(chipsetInfoReference); + + if (status == Status.IncompatibleStructureVersion) + { + continue; + } + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return chipsetInfoReference.ToValueType(acceptType); + } + } + + throw new NVIDIANotSupportedException("This operation is not supported."); + } + + + /// + /// This API returns display driver version and driver-branch string. + /// + /// Contains the driver-branch string after successful return. + /// Returns driver version + /// Status.ApiNotInitialized: NVAPI not initialized + /// Status.Error: Miscellaneous error occurred + public static uint GetDriverAndBranchVersion(out string branchVersion) + { + var status = DelegateFactory.GetDelegate()( + out var driverVersion, out var branchVersionShortString); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + branchVersion = branchVersionShortString.Value; + + return driverVersion; + } + + /// + /// This function converts an NvAPI error code into a null terminated string. + /// + /// The error code to convert + /// The string corresponding to the error code + // ReSharper disable once FlagArgument + public static string GetErrorMessage(Status statusCode) + { + statusCode = + DelegateFactory.GetDelegate()(statusCode, out var message); + + if (statusCode != Status.Ok) + { + return null; + } + + return message.Value; + } + + /// + /// This function returns a string describing the version of the NvAPI library. The contents of the string are human + /// readable. Do not assume a fixed format. + /// + /// User readable string giving NvAPI version information + /// See NVIDIAApiException.Status for the reason of the exception. + public static string GetInterfaceVersionString() + { + var status = + DelegateFactory.GetDelegate()(out var version); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return version.Value; + } + + /// + /// This function returns the current lid and dock information. + /// + /// Current lid and dock information + /// Status.Error: Generic error + /// Status.NotSupported: Requested feature not supported + /// Status.HandleInvalidated: Handle is no longer valid + /// Status.ApiNotInitialized: NvAPI_Initialize() has not been called + public static LidDockParameters GetLidAndDockInfo() + { + var dockInfo = typeof(LidDockParameters).Instantiate(); + var status = DelegateFactory.GetDelegate()(ref dockInfo); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + + return dockInfo; + } + + /// + /// This function initializes the NvAPI library (if not already initialized) but always increments the ref-counter. + /// This must be called before calling other NvAPI_ functions. + /// + /// Status.Error: Generic error + /// Status.LibraryNotFound: nvapi.dll can not be loaded + public static void Initialize() + { + var status = DelegateFactory.GetDelegate()(); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// + /// PRIVATE - Requests to restart the display driver + /// + public static void RestartDisplayDriver() + { + var status = DelegateFactory.GetDelegate()(); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + + /// + /// Decrements the ref-counter and when it reaches ZERO, unloads NVAPI library. + /// This must be called in pairs with NvAPI_Initialize. + /// Note: By design, it is not mandatory to call NvAPI_Initialize before calling any NvAPI. + /// When any NvAPI is called without first calling NvAPI_Initialize, the internal ref-counter will be implicitly + /// incremented. In such cases, calling NvAPI_Initialize from a different thread will result in incrementing the + /// ref-count again and the user has to call NvAPI_Unload twice to unload the library. However, note that the implicit + /// increment of the ref-counter happens only once. + /// If the client wants unload functionality, it is recommended to always call NvAPI_Initialize and NvAPI_Unload in + /// pairs. + /// Unloading NvAPI library is not supported when the library is in a resource locked state. + /// Some functions in the NvAPI library initiates an operation or allocates certain resources and there are + /// corresponding functions available, to complete the operation or free the allocated resources. All such function + /// pairs are designed to prevent unloading NvAPI library. + /// For example, if NvAPI_Unload is called after NvAPI_XXX which locks a resource, it fails with NVAPI_ERROR. + /// Developers need to call the corresponding NvAPI_YYY to unlock the resources, before calling NvAPI_Unload again. + /// + /// Status.Error: Generic error + /// + /// Status.ApiInUse: At least an API is still being called hence cannot unload NVAPI + /// library from process + /// + public static void Unload() + { + var status = DelegateFactory.GetDelegate()(); + + if (status != Status.Ok) + { + throw new NVIDIAApiException(status); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Helpers/DelegateFactory.cs b/NvAPIWrapper/Native/Helpers/DelegateFactory.cs new file mode 100644 index 0000000..662692e --- /dev/null +++ b/NvAPIWrapper/Native/Helpers/DelegateFactory.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.Exceptions; + +namespace NvAPIWrapper.Native.Helpers +{ + internal static class DelegateFactory + { + private static readonly Dictionary, object> Delegates = + new Dictionary, object>(); + + public static T GetDelegate() where T : class + { + if (!typeof(T).IsSubclassOf(typeof(Delegate))) + { + throw new InvalidOperationException($"{typeof(T).Name} is not a delegate type"); + } + + var functionId = typeof(T).GetCustomAttributes(typeof(FunctionIdAttribute), true) + .Cast() + .FirstOrDefault(); + + if (functionId == null) + { + throw new InvalidOperationException($"{typeof(T).Name}'s address is unknown."); + } + + var delegateKey = new KeyValuePair(functionId.FunctionId, typeof(T)); + + lock (Delegates) + { + if (Delegates.ContainsKey(delegateKey)) + { + return Delegates[delegateKey] as T; + } + + var ptr = NvAPI_QueryInterface((uint) functionId.FunctionId); + + if (ptr != IntPtr.Zero) + { + var delegateValue = Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T; + Delegates.Add(delegateKey, delegateValue); + + return delegateValue; + } + } + + throw new NVIDIANotSupportedException(@"Function identification number is invalid or not supported."); + } + + private static IntPtr NvAPI_QueryInterface(uint interfaceId) + { + if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess) + { + throw new NVIDIANotSupportedException( + "32bit process running in a 64bit environment can't access NVIDIA API."); + } + + return Environment.Is64BitProcess + ? NvAPI64_QueryInterface(interfaceId) + : NvAPI32_QueryInterface(interfaceId); + } + + [DllImport(@"nvapi", EntryPoint = @"nvapi_QueryInterface", CallingConvention = CallingConvention.Cdecl, + PreserveSig = true)] + private static extern IntPtr NvAPI32_QueryInterface(uint interfaceId); + + [DllImport(@"nvapi64", EntryPoint = @"nvapi_QueryInterface", CallingConvention = CallingConvention.Cdecl, + PreserveSig = true)] + private static extern IntPtr NvAPI64_QueryInterface(uint interfaceId); + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Helpers/ExtensionMethods.cs b/NvAPIWrapper/Native/Helpers/ExtensionMethods.cs new file mode 100644 index 0000000..f9727d8 --- /dev/null +++ b/NvAPIWrapper/Native/Helpers/ExtensionMethods.cs @@ -0,0 +1,291 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Attributes; +using NvAPIWrapper.Native.General.Structures; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Helpers +{ + internal static class ExtensionMethods + { + /// A delegate callback throws an exception. + public static Type[] Accepts(this Delegate @delegate, int parameterIndex = 0) + { + Type[] types = null; + var parameters = @delegate.GetType().GetMethod("Invoke")?.GetParameters(); + + if (parameterIndex > 0) + { + if (parameters?.Length >= parameterIndex) + { + types = parameters[parameterIndex - 1].GetCustomAttributes(typeof(AcceptsAttribute), true) + .Cast() + .FirstOrDefault()? + .Types; + } + } + + if (types == null) + { + if (parameters != null) + { + types = parameters.SelectMany(param => param.GetCustomAttributes(typeof(AcceptsAttribute), true)) + .Cast() + .FirstOrDefault()? + .Types; + } + else + { + types = @delegate.GetType().GetCustomAttributes(typeof(AcceptsAttribute), false) + .Cast() + .FirstOrDefault()? + .Types; + } + } + + return types ?? new Type[0]; + } + + public static IEnumerable AllocateAll(this IEnumerable allocatableArray) + { + foreach ( + var allocatable in + allocatableArray.Where(item => item.GetType().GetInterfaces().Contains(typeof(IAllocatable)))) + { + var boxedCopy = (IAllocatable) allocatable; + boxedCopy.Allocate(); + + yield return (T) boxedCopy; + } + } + + public static TResult BitWiseConvert(T source) + where TResult : struct, IConvertible + where T : struct, IConvertible + { + if (typeof(T) == typeof(TResult)) + { + return (TResult) (object) source; + } + + var sourceSize = Marshal.SizeOf(typeof(T)); + var destinationSize = Marshal.SizeOf(typeof(TResult)); + var minSize = Math.Min(sourceSize, destinationSize); + var sourcePointer = Marshal.AllocHGlobal(sourceSize); + Marshal.StructureToPtr(source, sourcePointer, false); + var bytes = new byte[destinationSize]; + + if (BitConverter.IsLittleEndian) + { + Marshal.Copy(sourcePointer, bytes, 0, minSize); + } + else + { + Marshal.Copy(sourcePointer + (sourceSize - minSize), bytes, destinationSize - minSize, minSize); + } + + Marshal.FreeHGlobal(sourcePointer); + var destinationPointer = Marshal.AllocHGlobal(destinationSize); + Marshal.Copy(bytes, 0, destinationPointer, destinationSize); + var destination = (TResult) Marshal.PtrToStructure(destinationPointer, typeof(TResult)); + Marshal.FreeHGlobal(destinationPointer); + + return destination; + } + + public static void DisposeAll(this IEnumerable disposableArray) + { + foreach ( + var disposable in + disposableArray.Where( + item => + item.GetType() + .GetInterfaces() + .Any(i => i == typeof(IDisposable) || i == typeof(IAllocatable)))) + { + ((IDisposable) disposable).Dispose(); + } + } + + public static bool GetBit(this T integer, int index) where T : struct, IConvertible + { + var bigInteger = BitWiseConvert(integer); + var mask = 1ul << index; + + return (bigInteger & mask) > 0; + } + + public static ulong GetBits(this T integer, int index, int count) where T : struct, IConvertible + { + var bigInteger = BitWiseConvert(integer); + + if (index > 0) + { + bigInteger >>= index; + } + + count = 64 - count; + bigInteger <<= count; + bigInteger >>= count; + + return bigInteger; + } + + + // ReSharper disable once FunctionComplexityOverflow + // ReSharper disable once ExcessiveIndentation + public static T Instantiate(this Type type) + { + object instance = default(T); + + try + { + if (type.IsValueType) + { + instance = (T) Activator.CreateInstance(type); + } + + if (type.GetInterfaces().Any(i => i == typeof(IInitializable) || i == typeof(IAllocatable))) + { + foreach (var field in type.GetRuntimeFields()) + { + if (field.IsStatic || field.IsLiteral) + { + continue; + } + + if (field.FieldType == typeof(StructureVersion)) + { + var version = + type.GetCustomAttributes(typeof(StructureVersionAttribute), true) + .Cast() + .FirstOrDefault()? + .VersionNumber; + field.SetValue(instance, + version.HasValue ? new StructureVersion(version.Value, type) : new StructureVersion()); + } + else if (field.FieldType.IsArray) + { + var size = + field.GetCustomAttributes(typeof(MarshalAsAttribute), false) + .Cast() + .FirstOrDefault(attribute => attribute.Value != UnmanagedType.LPArray)? + .SizeConst; + var arrayType = field.FieldType.GetElementType(); + var array = Array.CreateInstance( + arrayType ?? throw new InvalidOperationException("Field type is null."), size ?? 0); + + if (arrayType.IsValueType) + { + for (var i = 0; i < array.Length; i++) + { + var obj = arrayType.Instantiate(); + array.SetValue(obj, i); + } + } + + field.SetValue(instance, array); + } + else if (field.FieldType == typeof(string)) + { + var isByVal = field.GetCustomAttributes(typeof(MarshalAsAttribute), false) + .Cast() + .Any(attribute => attribute.Value == UnmanagedType.ByValTStr); + + if (isByVal) + { + field.SetValue(instance, string.Empty); + } + } + else if (field.FieldType.IsValueType) + { + var isByRef = field.GetCustomAttributes(typeof(MarshalAsAttribute), false) + .Cast() + .Any(attribute => attribute.Value == UnmanagedType.LPStruct); + + if (!isByRef) + { + var value = field.FieldType.Instantiate(); + field.SetValue(instance, value); + } + } + } + } + } + catch + { + // ignored + } + + return (T) instance; + } + + public static T[] Repeat(this T structure, int count) + { + return Enumerable.Range(0, count).Select(i => structure).ToArray(); + } + + public static T SetBit(this T integer, int index, bool value) where T : struct, IConvertible + { + var bigInteger = BitWiseConvert(integer); + + var mask = 1ul << index; + var newInteger = value ? bigInteger | mask : bigInteger & ~mask; + + return BitWiseConvert(newInteger); + } + + // ReSharper disable once TooManyArguments + public static T SetBits(this T integer, int index, int count, ulong value) where T : struct, IConvertible + { + var bigInteger = BitWiseConvert(integer); + + count = 64 - count; + value <<= count; + value >>= count - index; + + bigInteger |= value; + + return BitWiseConvert(bigInteger); + } + + public static byte[] ToByteArray(this T structure) where T : struct + { + var size = Marshal.SizeOf(typeof(T)); + var array = new byte[size]; + var pointer = Marshal.AllocHGlobal(size); + + try + { + Marshal.StructureToPtr(structure, pointer, true); + Marshal.Copy(pointer, array, 0, size); + + return array; + } + finally + { + Marshal.FreeHGlobal(pointer); + } + } + + public static T ToStructure(this byte[] byteArray) where T : struct + { + var size = Marshal.SizeOf(typeof(T)); + var pointer = Marshal.AllocHGlobal(size); + + try + { + Marshal.Copy(byteArray, 0, pointer, Math.Min(byteArray.Length, size)); + + return (T) Marshal.PtrToStructure(pointer, typeof(T)); + } + finally + { + Marshal.FreeHGlobal(pointer); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Helpers/FunctionId.cs b/NvAPIWrapper/Native/Helpers/FunctionId.cs new file mode 100644 index 0000000..8dc6885 --- /dev/null +++ b/NvAPIWrapper/Native/Helpers/FunctionId.cs @@ -0,0 +1,710 @@ +using System.Diagnostics.CodeAnalysis; + +namespace NvAPIWrapper.Native.Helpers +{ + [SuppressMessage("ReSharper", "InconsistentNaming")] + internal enum FunctionId : uint + { + // ------------------------------------------------- + // Public NvAPI Functions + // ------------------------------------------------- + + #region Public NvAPI Functions + + NvAPI_CreateDisplayFromUnAttachedDisplay = 0x63F9799E, + NvAPI_D3D_BeginResourceRendering = 0x91123D6A, + NvAPI_D3D_ConfigureAnsel = 0x341C6C7F, + NvAPI_D3D_CreateLateLatchObject = 0x2DB27D09, + NvAPI_D3D_EndResourceRendering = 0x37E7191C, + NvAPI_D3D_GetCurrentSLIState = 0x4B708B54, + NvAPI_D3D_GetObjectHandleForResource = 0xFCEAC864, + NvAPI_D3D_ImplicitSLIControl = 0x2AEDE111, + NvAPI_D3D_InitializeSMPAssist = 0x42763D0C, + NvAPI_D3D_IsGSyncActive = 0xE942B0FF, + NvAPI_D3D_IsGSyncCapable = 0x9C1EED78, + NvAPI_D3D_QueryLateLatchSupport = 0x8CECA0EC, + NvAPI_D3D_QueryModifiedWSupport = 0xCBF9F4F5, + NvAPI_D3D_QueryMultiViewSupport = 0xB6E0A41C, + NvAPI_D3D_QuerySinglePassStereoSupport = 0x6F5F0A6D, + NvAPI_D3D_QuerySMPAssistSupport = 0xC57921DE, + NvAPI_D3D_RegisterDevice = 0x8C02C4D0, + NvAPI_D3D_SetFPSIndicatorState = 0xA776E8DB, + NvAPI_D3D_SetModifiedWMode = 0x6EA4BF4, + NvAPI_D3D_SetMultiViewMode = 0x8285C8DA, + NvAPI_D3D_SetResourceHint = 0x6C0ED98C, + NvAPI_D3D_SetSinglePassStereoMode = 0xA39E6E6E, + NvAPI_D3D10_SetDepthBoundsTest = 0x4EADF5D2, + NvAPI_D3D11_AliasMSAATexture2DAsNonMSAA = 0xF1C54FC9, + NvAPI_D3D11_BeginUAVOverlap = 0x65B93CA8, + NvAPI_D3D11_BeginUAVOverlapEx = 0xBA08208A, + NvAPI_D3D11_CopyTileMappings = 0xC09EE6BC, + NvAPI_D3D11_CreateDevice = 0x6A16D3A0, + NvAPI_D3D11_CreateDeviceAndSwapChain = 0xBB939EE5, + NvAPI_D3D11_CreateDomainShaderEx = 0xA0D7180D, + NvAPI_D3D11_CreateFastGeometryShader = 0x525D43BE, + NvAPI_D3D11_CreateFastGeometryShaderExplicit = 0x71AB7C9C, + NvAPI_D3D11_CreateGeometryShaderEx_2 = 0x99ED5C1C, + NvAPI_D3D11_CreateHullShaderEx = 0xB53CAB00, + NvAPI_D3D11_CreateMultiGPUDevice = 0xBDB20007, + NvAPI_D3D11_CreatePixelShaderEx_2 = 0x4162822B, + NvAPI_D3D11_CreateRasterizerState = 0xDB8D28AF, + NvAPI_D3D11_CreateShadingRateResourceView = 0x99CA2DFF, + NvAPI_D3D11_CreateTiledTexture2DArray = 0x7886981A, + NvAPI_D3D11_CreateVertexShaderEx = 0xBEAA0B2, + NvAPI_D3D11_EndUAVOverlap = 0x2216A357, + NvAPI_D3D11_IsNvShaderExtnOpCodeSupported = 0x5F68DA40, + NvAPI_D3D11_MultiDrawIndexedInstancedIndirect = 0x59E890F9, + NvAPI_D3D11_MultiDrawInstancedIndirect = 0xD4E26BBF, + NvAPI_D3D11_MultiGPU_GetCaps = 0xD2D25687, + NvAPI_D3D11_MultiGPU_Init = 0x17BE49E, + NvAPI_D3D11_RSGetPixelShadingRateSampleOrder = 0x92442A1, + NvAPI_D3D11_RSSetExclusiveScissorRects = 0xAE4D73EF, + NvAPI_D3D11_RSSetPixelShadingRateSampleOrder = 0xA942373A, + NvAPI_D3D11_RSSetShadingRateResourceView = 0x1B0C2F83, + NvAPI_D3D11_RSSetViewportsPixelShadingRates = 0x34F7938F, + NvAPI_D3D11_SetDepthBoundsTest = 0x7AAF7A04, + NvAPI_D3D11_SetNvShaderExtnSlot = 0x8E90BB9F, + NvAPI_D3D11_SetNvShaderExtnSlotLocalThread = 0xE6482A0, + NvAPI_D3D11_TiledResourceBarrier = 0xD6839099, + NvAPI_D3D11_TiledTexture2DArrayGetDesc = 0xF1A2B9D5, + NvAPI_D3D11_UpdateTileMappings = 0x9A06EA07, + NvAPI_D3D12_CopyTileMappings = 0x47F78194, + NvAPI_D3D12_CreateComputePipelineState = 0x2762DEAC, + NvAPI_D3D12_CreateGraphicsPipelineState = 0x2FC28856, + NvAPI_D3D12_CreateHeap = 0x5CB397CF, + NvAPI_D3D12_CreateReservedResource = 0x2C85F101, + NvAPI_D3D12_IsNvShaderExtnOpCodeSupported = 0x3DFACEC8, + NvAPI_D3D12_Mosaic_GetCompanionAllocations = 0xA46022C7, + NvAPI_D3D12_Mosaic_GetViewportAndGpuPartitions = 0xB092B818, + NvAPI_D3D12_QueryModifiedWSupport = 0x51235248, + NvAPI_D3D12_QuerySinglePassStereoSupport = 0x3B03791B, + NvAPI_D3D12_ReservedResourceGetDesc = 0x9AA2AABB, + NvAPI_D3D12_ResourceAliasingBarrier = 0xB942BAB7, + NvAPI_D3D12_SetDepthBoundsTestValues = 0xB9333FE9, + NvAPI_D3D12_SetModifiedWMode = 0xE1FDABA7, + NvAPI_D3D12_SetSinglePassStereoMode = 0x83556D87, + NvAPI_D3D12_UpdateTileMappings = 0xC6017A7D, + NvAPI_D3D12_UseDriverHeapPriorities = 0xF0D978A8, + NvAPI_D3D1x_CreateSwapChain = 0x1BC21B66, + NvAPI_D3D1x_DisableShaderDiskCache = 0xD0CBCA7D, + NvAPI_D3D1x_GetGraphicsCapabilities = 0x52B1499A, + NvAPI_D3D9_AliasSurfaceAsTexture = 0xE5CEAE41, + NvAPI_D3D9_ClearRT = 0x332D3942, + NvAPI_D3D9_CreateSwapChain = 0x1A131E09, + NvAPI_D3D9_GetSurfaceHandle = 0xF2DD3F2, + NvAPI_D3D9_RegisterResource = 0xA064BDFC, + NvAPI_D3D9_StretchRectEx = 0x22DE03AA, + NvAPI_D3D9_UnregisterResource = 0xBB2B17AA, + NvAPI_D3D9_VideoSetStereoInfo = 0xB852F4DB, + NvAPI_DisableHWCursor = 0xAB163097, + NvAPI_Disp_ColorControl = 0x92F9D80D, + NvAPI_DISP_DeleteCustomDisplay = 0x552E5B9B, + NvAPI_DISP_EnumCustomDisplay = 0xA2072D59, + NvAPI_DISP_GetAssociatedUnAttachedNvidiaDisplayHandle = 0xA70503B2, + NvAPI_DISP_GetDisplayConfig = 0x11ABCCF8, + NvAPI_DISP_GetDisplayIdByDisplayName = 0xAE457190, + NvAPI_DISP_GetGDIPrimaryDisplayId = 0x1E9D8A31, + NvAPI_Disp_GetHdrCapabilities = 0x84F2A8DF, + NvAPI_DISP_GetMonitorCapabilities = 0x3B05C7E1, + NvAPI_DISP_GetMonitorColorCapabilities = 0x6AE4CFB5, + NvAPI_DISP_GetTiming = 0x175167E9, + NvAPI_Disp_HdrColorControl = 0x351DA224, + NvAPI_Disp_InfoFrameControl = 0x6067AF3F, + NvAPI_DISP_RevertCustomDisplayTrial = 0xCBBD40F0, + NvAPI_DISP_SaveCustomDisplay = 0x49882876, + NvAPI_DISP_SetDisplayConfig = 0x5D8CF8DE, + NvAPI_DISP_TryCustomDisplay = 0x1F7DB630, + NvAPI_DRS_CreateApplication = 0x4347A9DE, + NvAPI_DRS_CreateProfile = 0xCC176068, + NvAPI_DRS_CreateSession = 0x694D52E, + NvAPI_DRS_DeleteApplication = 0x2C694BC6, + NvAPI_DRS_DeleteApplicationEx = 0xC5EA85A1, + NvAPI_DRS_DeleteProfile = 0x17093206, + NvAPI_DRS_DeleteProfileSetting = 0xE4A26362, + NvAPI_DRS_DestroySession = 0xDAD9CFF8, + NvAPI_DRS_EnumApplications = 0x7FA2173A, + NvAPI_DRS_EnumAvailableSettingIds = 0xF020614A, + NvAPI_DRS_EnumAvailableSettingValues = 0x2EC39F90, + NvAPI_DRS_EnumProfiles = 0xBC371EE0, + NvAPI_DRS_EnumSettings = 0xAE3039DA, + NvAPI_DRS_FindApplicationByName = 0xEEE566B2, + NvAPI_DRS_FindProfileByName = 0x7E4A9A0B, + NvAPI_DRS_GetApplicationInfo = 0xED1F8C69, + NvAPI_DRS_GetBaseProfile = 0xDA8466A0, + NvAPI_DRS_GetCurrentGlobalProfile = 0x617BFF9F, + NvAPI_DRS_GetNumProfiles = 0x1DAE4FBC, + NvAPI_DRS_GetProfileInfo = 0x61CD6FD6, + NvAPI_DRS_GetSetting = 0x73BF8338, + NvAPI_DRS_GetSettingIdFromName = 0xCB7309CD, + NvAPI_DRS_GetSettingNameFromId = 0xD61CBE6E, + NvAPI_DRS_LoadSettings = 0x375DBD6B, + NvAPI_DRS_LoadSettingsFromFile = 0xD3EDE889, + NvAPI_DRS_RestoreAllDefaults = 0x5927B094, + NvAPI_DRS_RestoreProfileDefault = 0xFA5F6134, + NvAPI_DRS_RestoreProfileDefaultSetting = 0x53F0381E, + NvAPI_DRS_SaveSettings = 0xFCBC7E14, + NvAPI_DRS_SaveSettingsToFile = 0x2BE25DF8, + NvAPI_DRS_SetCurrentGlobalProfile = 0x1C89C5DF, + NvAPI_DRS_SetProfileInfo = 0x16ABD3A9, + NvAPI_DRS_SetSetting = 0x577DD202, + NvAPI_EnableCurrentMosaicTopology = 0x74073CC9, + NvAPI_EnableHWCursor = 0x2863148D, + NvAPI_EnumLogicalGPUs = 0x48B3EA59, + NvAPI_EnumNvidiaDisplayHandle = 0x9ABDD40D, + NvAPI_EnumNvidiaUnAttachedDisplayHandle = 0x20DE9260, + NvAPI_EnumPhysicalGPUs = 0xE5AC921F, + NvAPI_EnumTCCPhysicalGPUs = 0xD9930B07, + NvAPI_GetAssociatedDisplayOutputId = 0xD995937E, + NvAPI_GetAssociatedNvidiaDisplayHandle = 0x35C29134, + NvAPI_GetAssociatedNvidiaDisplayName = 0x22A78B05, + NvAPI_GetCurrentMosaicTopology = 0xF60852BD, + NvAPI_GetDisplayDriverVersion = 0xF951A4D1, + NvAPI_GetDisplayPortInfo = 0xC64FF367, + NvAPI_GetErrorMessage = 0x6C2D048C, + NvAPI_GetHDMISupportInfo = 0x6AE16EC3, + NvAPI_GetInterfaceVersionString = 0x1053FA5, + NvAPI_GetLogicalGPUFromDisplay = 0xEE1370CF, + NvAPI_GetLogicalGPUFromPhysicalGPU = 0xADD604D1, + NvAPI_GetPhysicalGPUFromUnAttachedDisplay = 0x5018ED61, + NvAPI_GetPhysicalGPUsFromDisplay = 0x34EF9506, + NvAPI_GetPhysicalGPUsFromLogicalGPU = 0xAEA3FA32, + NvAPI_GetSupportedMosaicTopologies = 0x410B5C25, + NvAPI_GetSupportedViews = 0x66FB7FC0, + NvAPI_GetUnAttachedAssociatedDisplayName = 0x4888D790, + NvAPI_GetVBlankCounter = 0x67B5DB55, + NvAPI_GetView = 0xD6B99D89, + NvAPI_GetViewEx = 0xDBBC0AF4, + NvAPI_GPU_ClientIllumDevicesGetControl = 0x73C01D58, + NvAPI_GPU_ClientIllumDevicesGetInfo = 0xD4100E58, + NvAPI_GPU_ClientIllumDevicesSetControl = 0x57024C62, + NvAPI_GPU_ClientIllumZonesGetControl = 0x3DBF5764, + NvAPI_GPU_ClientIllumZonesGetInfo = 0x4B81241B, + NvAPI_GPU_ClientIllumZonesSetControl = 0x197D065E, + NvAPI_GPU_GetActiveOutputs = 0xE3E89B6F, + NvAPI_GPU_GetAGPAperture = 0x6E042794, + NvAPI_GPU_GetAllClockFrequencies = 0xDCB616C3, + NvAPI_GPU_GetAllDisplayIds = 0x785210A2, + NvAPI_GPU_GetAllOutputs = 0x7D554F8E, + NvAPI_GPU_GetBoardInfo = 0x22D54523, + NvAPI_GPU_GetBusId = 0x1BE0B8E5, + NvAPI_GPU_GetBusSlotId = 0x2A0A350F, + NvAPI_GPU_GetBusType = 0x1BB18724, + NvAPI_GPU_GetConnectedDisplayIds = 0x78DBA2, + NvAPI_GPU_GetConnectedOutputs = 0x1730BFC9, + NvAPI_GPU_GetConnectedOutputsWithLidState = 0xCF8CAF39, + NvAPI_GPU_GetConnectedSLIOutputs = 0x680DE09, + NvAPI_GPU_GetConnectedSLIOutputsWithLidState = 0x96043CC7, + NvAPI_GPU_GetCurrentAGPRate = 0xC74925A0, + NvAPI_GPU_GetCurrentPCIEDownstreamWidth = 0xD048C3B1, + NvAPI_GPU_GetCurrentPstate = 0x927DA4F6, + NvAPI_GPU_GetDynamicPstatesInfoEx = 0x60DED2ED, + NvAPI_GPU_GetECCConfigurationInfo = 0x77A796F3, + NvAPI_GPU_GetECCErrorInfo = 0xC71F85A6, + NvAPI_GPU_GetECCStatusInfo = 0xCA1DDAF3, + NvAPI_GPU_GetEDID = 0x37D32E69, + NvAPI_GPU_GetFullName = 0xCEEE8E9F, + NvAPI_GPU_GetGpuCoreCount = 0xC7026A87, + NvAPI_GPU_GetGPUType = 0xC33BAEB1, + NvAPI_GPU_GetHDCPSupportStatus = 0xF089EEF5, + NvAPI_GPU_GetIllumination = 0x9A1B9365, + NvAPI_GPU_GetIRQ = 0xE4715417, + NvAPI_GPU_GetMemoryInfo = 0x7F9B368, + NvAPI_GPU_GetOutputType = 0x40A505E4, + NvAPI_GPU_GetPCIIdentifiers = 0x2DDFB66E, + NvAPI_GPU_GetPerfDecreaseInfo = 0x7F7F4600, + NvAPI_GPU_GetPhysicalFrameBufferSize = 0x46FBEB03, + NvAPI_GPU_GetPstates20 = 0x6FF81213, + NvAPI_GPU_GetPstatesInfoEx = 0x843C0256, + NvAPI_GPU_GetQuadroStatus = 0xE332FA47, + NvAPI_GPU_GetScanoutCompositionParameter = 0x58FE51E6, + NvAPI_GPU_GetScanoutConfiguration = 0x6A9F5B63, + NvAPI_GPU_GetScanoutConfigurationEx = 0xE2E1E6F0, + NvAPI_GPU_GetScanoutIntensityState = 0xE81CE836, + NvAPI_GPU_GetScanoutWarpingState = 0x6F5435AF, + NvAPI_GPU_GetShaderSubPipeCount = 0xBE17923, + NvAPI_GPU_GetSystemType = 0xBAAABFCC, + NvAPI_GPU_GetTachReading = 0x5F608315, + NvAPI_GPU_GetThermalSettings = 0xE3640A56, + NvAPI_GPU_GetVbiosOEMRevision = 0x2D43FB31, + NvAPI_GPU_GetVbiosRevision = 0xACC3DA0A, + NvAPI_GPU_GetVbiosVersionString = 0xA561FD7D, + NvAPI_GPU_GetVirtualFrameBufferSize = 0x5A04B644, + NvAPI_GPU_QueryIlluminationSupport = 0xA629DA31, + NvAPI_GPU_ResetECCErrorInfo = 0xC02EEC20, + NvAPI_GPU_SetECCConfiguration = 0x1CF639D9, + NvAPI_GPU_SetEDID = 0xE83D6456, + NvAPI_GPU_SetIllumination = 0x254A187, + NvAPI_GPU_SetScanoutCompositionParameter = 0xF898247D, + NvAPI_GPU_SetScanoutIntensity = 0xA57457A4, + NvAPI_GPU_SetScanoutWarping = 0xB34BAB4F, + NvAPI_GPU_ValidateOutputCombination = 0x34C9C2D4, + NvAPI_GPU_WorkstationFeatureQuery = 0x4537DF, + NvAPI_GPU_WorkstationFeatureSetup = 0x6C1F3FE4, + NvAPI_GSync_AdjustSyncDelay = 0x2D11FF51, + NvAPI_GSync_EnumSyncDevices = 0xD9639601, + NvAPI_GSync_GetControlParameters = 0x16DE1C6A, + NvAPI_GSync_GetStatusParameters = 0x70D404EC, + NvAPI_GSync_GetSyncStatus = 0xF1F5B434, + NvAPI_GSync_GetTopology = 0x4562BC38, + NvAPI_GSync_QueryCapabilities = 0x44A3F1D1, + NvAPI_GSync_SetControlParameters = 0x8BBFF88B, + NvAPI_GSync_SetSyncStateSettings = 0x60ACDFDD, + NvAPI_I2CRead = 0x2FDE12C5, + NvAPI_I2CWrite = 0xE812EB07, + NvAPI_Mosaic_EnableCurrentTopo = 0x5F1AA66C, + NvAPI_Mosaic_EnumDisplayGrids = 0xDF2887AF, + NvAPI_Mosaic_EnumDisplayModes = 0x78DB97D7, + NvAPI_Mosaic_GetCurrentTopo = 0xEC32944E, + NvAPI_Mosaic_GetDisplayViewportsByResolution = 0xDC6DC8D3, + NvAPI_Mosaic_GetOverlapLimits = 0x989685F0, + NvAPI_Mosaic_GetSupportedTopoInfo = 0xFDB63C81, + NvAPI_Mosaic_GetTopoGroup = 0xCB89381D, + NvAPI_Mosaic_SetCurrentTopo = 0x9B542831, + NvAPI_Mosaic_SetDisplayGrids = 0x4D959A89, + NvAPI_Mosaic_ValidateDisplayGrids = 0xCF43903D, + NvAPI_OGL_ExpertModeDefaultsGet = 0xAE921F12, + NvAPI_OGL_ExpertModeDefaultsSet = 0xB47A657E, + NvAPI_OGL_ExpertModeGet = 0x22ED9516, + NvAPI_OGL_ExpertModeSet = 0x3805EF7A, + NvAPI_SetCurrentMosaicTopology = 0xD54B8989, + NvAPI_SetDisplayPort = 0xFA13E65A, + NvAPI_SetRefreshRateOverride = 0x3092AC32, + NvAPI_SetView = 0x957D7B6, + NvAPI_SetViewEx = 0x6B89E68, + NvAPI_Stereo_Activate = 0xF6A1AD68, + NvAPI_Stereo_CaptureJpegImage = 0x932CB140, + NvAPI_Stereo_CapturePngImage = 0x8B7E99B5, + NvAPI_Stereo_CreateConfigurationProfileRegistryKey = 0xBE7692EC, + NvAPI_Stereo_CreateHandleFromIUnknown = 0xAC7E37F4, + NvAPI_Stereo_Deactivate = 0x2D68DE96, + NvAPI_Stereo_Debug_WasLastDrawStereoized = 0xED4416C5, + NvAPI_Stereo_DecreaseConvergence = 0x4C87E317, + NvAPI_Stereo_DecreaseSeparation = 0xDA044458, + NvAPI_Stereo_DeleteConfigurationProfileRegistryKey = 0xF117B834, + NvAPI_Stereo_DeleteConfigurationProfileValue = 0x49BCEECF, + NvAPI_Stereo_DestroyHandle = 0x3A153134, + NvAPI_Stereo_Disable = 0x2EC50C2B, + NvAPI_Stereo_Enable = 0x239C4545, + NvAPI_Stereo_GetConvergence = 0x4AB00934, + NvAPI_Stereo_GetDefaultProfile = 0x624E21C2, + NvAPI_Stereo_GetEyeSeparation = 0xCE653127, + NvAPI_Stereo_GetFrustumAdjustMode = 0xE6839B43, + NvAPI_Stereo_GetSeparation = 0x451F2134, + NvAPI_Stereo_GetStereoSupport = 0x296C434D, + NvAPI_Stereo_GetSurfaceCreationMode = 0x36F1C736, + NvAPI_Stereo_IncreaseConvergence = 0xA17DAABE, + NvAPI_Stereo_IncreaseSeparation = 0xC9A8ECEC, + NvAPI_Stereo_InitActivation = 0xC7177702, + NvAPI_Stereo_IsActivated = 0x1FB0BC30, + NvAPI_Stereo_IsEnabled = 0x348FF8E1, + NvAPI_Stereo_IsWindowedModeSupported = 0x40C8ED5E, + NvAPI_Stereo_ReverseStereoBlitControl = 0x3CD58F89, + NvAPI_Stereo_SetActiveEye = 0x96EEA9F8, + NvAPI_Stereo_SetConfigurationProfileValue = 0x24409F48, + NvAPI_Stereo_SetConvergence = 0x3DD6B54B, + NvAPI_Stereo_SetDefaultProfile = 0x44F0ECD1, + NvAPI_Stereo_SetDriverMode = 0x5E8F0BEC, + NvAPI_Stereo_SetFrustumAdjustMode = 0x7BE27FA2, + NvAPI_Stereo_SetNotificationMessage = 0x6B9B409E, + NvAPI_Stereo_SetSeparation = 0x5C069FA3, + NvAPI_Stereo_SetSurfaceCreationMode = 0xF5DCFCBA, + NvAPI_Stereo_Trigger_Activation = 0xD6C6CD2, + NvAPI_SYS_GetChipSetInfo = 0x53DABBCA, + NvAPI_SYS_GetDisplayIdFromGpuAndOutputId = 0x8F2BAB4, + NvAPI_SYS_GetDriverAndBranchVersion = 0x2926AAAD, + NvAPI_SYS_GetGpuAndOutputIdFromDisplayId = 0x112BA1A5, + NvAPI_SYS_GetLidAndDockInfo = 0xCDA14D8A, + NvAPI_SYS_GetPhysicalGpuFromDisplayId = 0x9EA74659, + NvAPI_VIO_Close = 0xD01BD237, + NvAPI_VIO_EnumDataFormats = 0x221FA8E8, + NvAPI_VIO_EnumDevices = 0xFD7C5557, + NvAPI_VIO_EnumSignalFormats = 0xEAD72FE4, + NvAPI_VIO_GetCapabilities = 0x1DC91303, + NvAPI_VIO_GetConfig = 0xD34A789B, + NvAPI_VIO_GetCSC = 0x7B0D72A3, + NvAPI_VIO_GetGamma = 0x51D53D06, + NvAPI_VIO_GetPCIInfo = 0xB981D935, + NvAPI_VIO_GetSyncDelay = 0x462214A9, + NvAPI_VIO_IsFrameLockModeCompatible = 0x7BF0A94D, + NvAPI_VIO_IsRunning = 0x96BD040E, + NvAPI_VIO_Open = 0x44EE4841, + NvAPI_VIO_QueryTopology = 0x869534E2, + NvAPI_VIO_SetConfig = 0xE4EEC07, + NvAPI_VIO_SetCSC = 0xA1EC8D74, + NvAPI_VIO_SetGamma = 0x964BF452, + NvAPI_VIO_SetSyncDelay = 0x2697A8D1, + NvAPI_VIO_Start = 0xCDE8E1A3, + NvAPI_VIO_Status = 0xE6CE4F1, + NvAPI_VIO_Stop = 0x6BA2A5D6, + NvAPI_VIO_SyncFormatDetect = 0x118D48A3, + + #endregion + + // ------------------------------------------------- + // Private Internal NvAPI Functions + // ------------------------------------------------- + + #region Private Internal NvAPI Functions + + NvAPI_3D_GetProperty = 0x8061A4B1, + NvAPI_3D_GetPropertyRange = 0x0B85DE27C, + NvAPI_3D_SetProperty = 0x0C9175E8D, + NvAPI_AccessDisplayDriverRegistry = 0xF5579360, + NvAPI_Coproc_GetApplicationCoprocInfo = 0x79232685, + NvAPI_Coproc_GetCoprocInfoFlagsEx = 0x69A9874D, + NvAPI_Coproc_GetCoprocStatus = 0x1EFC3957, + NvAPI_Coproc_NotifyCoprocPowerState = 0x0CADCB956, + NvAPI_Coproc_SetCoprocInfoFlagsEx = 0x0F4C863AC, + NvAPI_CreateUnAttachedDisplayFromDisplay = 0xA0C72EE4, + NvAPI_D3D_CreateQuery = 0x5D19BCA4, + NvAPI_D3D_DestroyQuery = 0x0C8FF7258, + NvAPI_D3D_Query_Begin = 0x0E5A9AAE0, + NvAPI_D3D_Query_End = 0x2AC084FA, + NvAPI_D3D_Query_GetData = 0x0F8B53C69, + NvAPI_D3D_Query_GetDataSize = 0x0F2A54796, + NvAPI_D3D_Query_GetType = 0x4ACEEAF7, + NvAPI_D3D_RegisterApp = 0x0D44D3C4E, + NvAPI_D3D10_AliasPrimaryAsTexture = 0x8AAC133D, + NvAPI_D3D10_BeginShareResource = 0x35233210, + NvAPI_D3D10_BeginShareResourceEx = 0x0EF303A9D, + NvAPI_D3D10_CreateDevice = 0x2DE11D61, + NvAPI_D3D10_CreateDeviceAndSwapChain = 0x5B803DAF, + NvAPI_D3D10_EndShareResource = 0x0E9C5853, + NvAPI_D3D10_GetRenderedCursorAsBitmap = 0x0CAC3CE5D, + NvAPI_D3D10_ProcessCallbacks = 0x0AE9C2019, + NvAPI_D3D10_SetPrimaryFlipChainCallbacks = 0x73EB9329, + NvAPI_D3D11_BeginShareResource = 0x121BDC6, + NvAPI_D3D11_EndShareResource = 0x8FFB8E26, + NvAPI_D3D1x_BindSwapBarrier = 0x9DE8C729, + NvAPI_D3D1x_IFR_SetUpTargetBufferToSys = 0x473F7828, + NvAPI_D3D1x_IFR_TransferRenderTarget = 0x9FBAE4EB, + NvAPI_D3D1x_JoinSwapGroup = 0x14610CD7, + NvAPI_D3D1x_Present = 0x3B845A1, + NvAPI_D3D1x_QueryFrameCount = 0x9152E055, + NvAPI_D3D1x_QueryMaxSwapGroup = 0x9BB9D68F, + NvAPI_D3D1x_QuerySwapGroup = 0x407F67AA, + NvAPI_D3D1x_ResetFrameCount = 0x0FBBB031A, + NvAPI_D3D9_AliasPrimaryAsTexture = 0x13C7112E, + NvAPI_D3D9_AliasPrimaryFromDevice = 0x7C20C5BE, + NvAPI_D3D9_BindSwapBarrier = 0x9C39C246, + NvAPI_D3D9_CreatePathContextNV = 0x0A342F682, + NvAPI_D3D9_CreatePathNV = 0x71329DF3, + NvAPI_D3D9_CreateRenderTarget = 0x0B3827C8, + NvAPI_D3D9_CreateTexture = 0x0D5E13573, + NvAPI_D3D9_CreateVideo = 0x89FFD9A3, + NvAPI_D3D9_CreateVideoBegin = 0x84C9D553, + NvAPI_D3D9_CreateVideoEnd = 0x0B476BF61, + NvAPI_D3D9_DeletePathNV = 0x73E0019A, + NvAPI_D3D9_DestroyPathContextNV = 0x667C2929, + NvAPI_D3D9_DMA = 0x962B8AF6, + NvAPI_D3D9_DrawPathNV = 0x13199B3D, + NvAPI_D3D9_EnableStereo = 0x492A6954, + NvAPI_D3D9_EnumVideoFeatures = 0x1DB7C52C, + NvAPI_D3D9_FreeVideo = 0x3111BED1, + NvAPI_D3D9_GetCurrentRenderTargetHandle = 0x22CAD61, + NvAPI_D3D9_GetCurrentZBufferHandle = 0x0B380F218, + NvAPI_D3D9_GetIndexBufferHandle = 0x0FC5A155B, + NvAPI_D3D9_GetOverlaySurfaceHandles = 0x6800F5FC, + NvAPI_D3D9_GetSLIInfo = 0x694BFF4D, + NvAPI_D3D9_GetTextureHandle = 0x0C7985ED5, + NvAPI_D3D9_GetVertexBufferHandle = 0x72B19155, + NvAPI_D3D9_GetVideoCapabilities = 0x3D596B93, + NvAPI_D3D9_GetVideoState = 0x0A4527BF8, + NvAPI_D3D9_GPUBasedCPUSleep = 0x0D504DDA7, + NvAPI_D3D9_GpuSyncAcquire = 0x0D00B8317, + NvAPI_D3D9_GpuSyncEnd = 0x754033F0, + NvAPI_D3D9_GpuSyncGetHandleSize = 0x80C9FD3B, + NvAPI_D3D9_GpuSyncInit = 0x6D6FDAD4, + NvAPI_D3D9_GpuSyncMapIndexBuffer = 0x12EE68F2, + NvAPI_D3D9_GpuSyncMapSurfaceBuffer = 0x2AB714AB, + NvAPI_D3D9_GpuSyncMapTexBuffer = 0x0CDE4A28A, + NvAPI_D3D9_GpuSyncMapVertexBuffer = 0x0DBC803EC, + NvAPI_D3D9_GpuSyncRelease = 0x3D7A86BB, + NvAPI_D3D9_IFR_SetUpTargetBufferToNV12BLVideoSurface = 0x0CFC92C15, + NvAPI_D3D9_IFR_SetUpTargetBufferToSys = 0x55255D05, + NvAPI_D3D9_IFR_TransferRenderTarget = 0x0AB7C2DC, + NvAPI_D3D9_IFR_TransferRenderTargetToNV12BLVideoSurface = 0x5FE72F64, + NvAPI_D3D9_JoinSwapGroup = 0x7D44BB54, + NvAPI_D3D9_Lock = 0x6317345C, + NvAPI_D3D9_NVFBC_GetStatus = 0x0bd3eb475, + NvAPI_D3D9_PathClearDepthNV = 0x157E45C4, + NvAPI_D3D9_PathDepthNV = 0x0FCB16330, + NvAPI_D3D9_PathEnableColorWriteNV = 0x3E2804A2, + NvAPI_D3D9_PathEnableDepthTestNV = 0x0E99BA7F3, + NvAPI_D3D9_PathMatrixNV = 0x0D2F6C499, + NvAPI_D3D9_PathParameterfNV = 0x0F7FF00C1, + NvAPI_D3D9_PathParameteriNV = 0x0FC31236C, + NvAPI_D3D9_PathVerticesNV = 0x0C23DF926, + NvAPI_D3D9_Present = 0x5650BEB, + NvAPI_D3D9_PresentSurfaceToDesktop = 0x0F7029C5, + NvAPI_D3D9_PresentVideo = 0x5CF7F862, + NvAPI_D3D9_QueryAAOverrideMode = 0x0DDF5643C, + NvAPI_D3D9_QueryFrameCount = 0x9083E53A, + NvAPI_D3D9_QueryMaxSwapGroup = 0x5995410D, + NvAPI_D3D9_QuerySwapGroup = 0x0EBA4D232, + NvAPI_D3D9_QueryVideoInfo = 0x1E6634B3, + NvAPI_D3D9_ResetFrameCount = 0x0FA6A0675, + NvAPI_D3D9_SetGamutData = 0x2BBDA32E, + NvAPI_D3D9_SetPitchSurfaceCreation = 0x18CDF365, + NvAPI_D3D9_SetResourceHint = 0x905F5C27, + NvAPI_D3D9_SetSLIMode = 0x0BFDC062C, + NvAPI_D3D9_SetSurfaceCreationLayout = 0x5609B86A, + NvAPI_D3D9_SetVideoState = 0x0BD4BC56F, + NvAPI_D3D9_StretchRect = 0x0AEAECD41, + NvAPI_D3D9_Unlock = 0x0C182027E, + NvAPI_D3D9_VideoSurfaceEncryptionControl = 0x9D2509EF, + NvAPI_DeleteCustomDisplay = 0x0E7CB998D, + NvAPI_DeleteUnderscanConfig = 0x0F98854C8, + NvAPI_Disp_DpAuxChannelControl = 0x8EB56969, + NvAPI_DISP_EnumHDMIStereoModes = 0x0D2CCF5D6, + NvAPI_DISP_GetDisplayBlankingState = 0x63E5D8DB, + NvAPI_DISP_GetHCloneTopology = 0x47BAD137, + NvAPI_DISP_GetVirtualModeData = 0x3230D69A, + NvAPI_DISP_OverrideDisplayModeList = 0x291BFF2, + NvAPI_DISP_SetDisplayBlankingState = 0x1E17E29B, + NvAPI_DISP_SetHCloneTopology = 0x61041C24, + NvAPI_DISP_ValidateHCloneTopology = 0x5F4C2664, + NvAPI_EnumCustomDisplay = 0x42892957, + NvAPI_EnumUnderscanConfig = 0x4144111A, + NvAPI_Event_RegisterCallback = 0x0E6DBEA69, + NvAPI_Event_UnregisterCallback = 0x0DE1F9B45, + NvAPI_GetDisplayDriverBuildTitle = 0x7562E947, + NvAPI_GetDisplayDriverCompileType = 0x988AEA78, + NvAPI_GetDisplayDriverMemoryInfo = 0x774AA982, + NvAPI_GetDisplayDriverRegistryPath = 0x0E24CEEE, + NvAPI_GetDisplayDriverSecurityLevel = 0x9D772BBA, + NvAPI_GetDisplayFeatureConfig = 0x8E985CCD, + NvAPI_GetDisplayFeatureConfigDefaults = 0x0F5F4D01, + NvAPI_GetDisplayPosition = 0x6BB1EE5D, + NvAPI_GetDisplaySettings = 0x0DC27D5D4, + NvAPI_GetDriverMemoryInfo = 0x2DC95125, + NvAPI_GetDriverModel = 0x25EEB2C4, + NvAPI_GetDVCInfo = 0x4085DE45, + NvAPI_GetDVCInfoEx = 0x0E45002D, + NvAPI_GetGPUIDfromPhysicalGPU = 0x6533EA3E, + NvAPI_GetHDCPLinkParameters = 0x0B3BB0772, + NvAPI_GetHUEInfo = 0x95B64341, + NvAPI_GetHybridMode = 0x0E23B68C1, + NvAPI_GetImageSharpeningInfo = 0x9FB063DF, + NvAPI_GetInfoFrame = 0x9734F1D, + NvAPI_GetInfoFrameState = 0x41511594, + NvAPI_GetInfoFrameStatePvt = 0x7FC17574, + NvAPI_GetInvalidGpuTopologies = 0x15658BE6, + NvAPI_GetLoadedMicrocodePrograms = 0x919B3136, + NvAPI_GetPhysicalGPUFromDisplay = 0x1890E8DA, + NvAPI_GetPhysicalGPUFromGPUID = 0x5380AD1A, + NvAPI_GetPVExtName = 0x2F5B08E0, + NvAPI_GetPVExtProfile = 0x1B1B9A16, + NvAPI_GetScalingCaps = 0x8E875CF9, + NvAPI_GetTiming = 0x0AFC4833E, + NvAPI_GetTopologyDisplayGPU = 0x813D89A8, + NvAPI_GetTVEncoderControls = 0x5757474A, + NvAPI_GetTVOutputBorderColor = 0x6DFD1C8C, + NvAPI_GetTVOutputInfo = 0x30C805D5, + NvAPI_GetUnAttachedDisplayDriverRegistryPath = 0x633252D8, + NvAPI_GetValidGpuTopologies = 0x5DFAB48A, + NvAPI_GetVideoState = 0x1C5659CD, + NvAPI_GPS_GetPerfSensors = 0x271C1109, + NvAPI_GPS_GetPowerSteeringStatus = 0x540EE82E, + NvAPI_GPS_GetThermalLimit = 0x583113ED, + NvAPI_GPS_GetVPStateCap = 0x71913023, + NvAPI_GPS_SetPowerSteeringStatus = 0x9723D3A2, + NvAPI_GPS_SetThermalLimit = 0x0C07E210F, + NvAPI_GPS_SetVPStateCap = 0x68888EB4, + NvAPI_GPU_ClearPCIELinkAERInfo = 0x521566BB, + NvAPI_GPU_ClearPCIELinkErrorInfo = 0x8456FF3D, + NvAPI_GPU_ClientPowerPoliciesGetInfo = 0x34206D86, + NvAPI_GPU_ClientPowerPoliciesGetStatus = 0x70916171, + NvAPI_GPU_ClientPowerPoliciesSetStatus = 0x0AD95F5ED, + NvAPI_GPU_ClientPowerTopologyGetInfo = 0x0A4DFD3F2, + NvAPI_GPU_ClientPowerTopologyGetStatus = 0x0EDCF624E, + NvAPI_GPU_CudaEnumComputeCapableGpus = 0x5786CC6E, + NvAPI_GPU_EnableDynamicPstates = 0x0FA579A0F, + NvAPI_GPU_EnableOverclockedPstates = 0x0B23B70EE, + NvAPI_GPU_Get_DisplayPort_DongleInfo = 0x76A70E8D, + NvAPI_GPU_GetAllClocks = 0x1BD69F49, + NvAPI_GPU_GetAllGpusOnSameBoard = 0x4DB019E6, + NvAPI_GPU_GetArchInfo = 0xD8265D24, + NvAPI_GPU_GetBarInfo = 0xE4B701E3, + NvAPI_GPU_GetClockBoostLock = 0xe440b867, // unknown name, NVAPI_ID_CURVE_GET + NvAPI_GPU_GetClockBoostMask = 0x507b4b59, + NvAPI_GPU_GetClockBoostRanges = 0x64b43a6a, + NvAPI_GPU_GetClockBoostTable = 0x23f1b133, + NvAPI_GPU_GetColorSpaceConversion = 0x8159E87A, + NvAPI_GPU_GetConnectorInfo = 0x4ECA2C10, + NvAPI_GPU_GetCoolerPolicyTable = 0x518A32C, + NvAPI_GPU_GetCoolerSettings = 0x0DA141340, + NvAPI_GPU_GetCoreVoltageBoostPercent = 0x9df23ca1, + NvAPI_GPU_GetCurrentFanSpeedLevel = 0x0BD71F0C9, + NvAPI_GPU_GetCurrentThermalLevel = 0x0D2488B79, + NvAPI_GPU_GetCurrentVoltage = 0x465f9bcf, + NvAPI_GPU_GetDeepIdleState = 0x1AAD16B4, + NvAPI_GPU_GetDeviceDisplayMode = 0x0D2277E3A, + NvAPI_GPU_GetDisplayUnderflowStatus = 0xED9E8057, + NvAPI_GPU_GetDitherControl = 0x932AC8FB, + NvAPI_GPU_GetExtendedMinorRevision = 0x25F17421, + NvAPI_GPU_GetFBWidthAndLocation = 0x11104158, + NvAPI_GPU_GetFlatPanelInfo = 0x36CFF969, + NvAPI_GPU_GetFoundry = 0x5D857A00, + NvAPI_GPU_GetFrameBufferCalibrationLockFailures = 0x524B9773, + NvAPI_GPU_GetHardwareQualType = 0xF91E777B, + NvAPI_GPU_GetHybridControllerInfo = 0xD26B8A58, + NvAPI_GPU_GetLogicalFBWidthAndLocation = 0x8efc0978, + NvAPI_GPU_GetManufacturingInfo = 0xA4218928, + NvAPI_GPU_GetMemPartitionMask = 0x329D77CD, + NvAPI_GPU_GetMXMBlock = 0xB7AB19B9, + NvAPI_GPU_GetPartitionCount = 0x86F05D7A, + NvAPI_GPU_GetPCIEInfo = 0xE3795199, + NvAPI_GPU_GetPerfClocks = 0x1EA54A3B, + NvAPI_GPU_GetPerfHybridMode = 0x5D7CCAEB, + NvAPI_GPU_GetPerGpuTopologyStatus = 0x0A81F8992, + NvAPI_GPU_GetPixelClockRange = 0x66AF10B7, + NvAPI_GPU_GetPowerMizerInfo = 0x76BFA16B, + NvAPI_GPU_GetPSFloorSweepStatus = 0xDEE047AB, + NvAPI_GPU_GetPstateClientLimits = 0x88C82104, + NvAPI_GPU_GetPstatesInfo = 0x0BA94C56E, + NvAPI_GPU_GetRamBankCount = 0x17073A3C, + NvAPI_GPU_GetRamBusWidth = 0x7975C581, + NvAPI_GPU_GetRamConfigStrap = 0x51CCDB2A, + NvAPI_GPU_GetRamMaker = 0x42aea16a, + NvAPI_GPU_GetRamType = 0x57F7CAAC, + NvAPI_GPU_GetRawFuseData = 0xE0B1DCE9, + NvAPI_GPU_GetROPCount = 0xfdc129fa, + NvAPI_GPU_GetSampleType = 0x32E1D697, + NvAPI_GPU_GetSerialNumber = 0x14B83A5F, + NvAPI_GPU_GetShaderPipeCount = 0x63E2F56F, + NvAPI_GPU_GetShortName = 0xD988F0F3, + NvAPI_GPU_GetSMMask = 0x0EB7AF173, + NvAPI_GPU_GetTargetID = 0x35B5FD2F, + NvAPI_GPU_GetThermalPoliciesInfo = 0x00D258BB5, // NvAPI_GPU_ClientThermalPoliciesGetInfo + NvAPI_GPU_GetThermalPoliciesStatus = 0x0E9C425A1, + NvAPI_GPU_GetThermalTable = 0xC729203C, + NvAPI_GPU_GetTotalSMCount = 0x0AE5FBCFE, + NvAPI_GPU_GetTotalSPCount = 0x0B6D62591, + NvAPI_GPU_GetTotalTPCCount = 0x4E2F76A8, + NvAPI_GPU_GetTPCMask = 0x4A35DF54, + NvAPI_GPU_GetUsages = 0x189a1fdf, + NvAPI_GPU_GetVbiosImage = 0xFC13EE11, + NvAPI_GPU_GetVbiosMxmVersion = 0xE1D5DABA, + NvAPI_GPU_GetVFPCurve = 0x21537ad4, + NvAPI_GPU_GetVoltageDomainsStatus = 0x0C16C7E2C, + NvAPI_GPU_GetVoltages = 0x7D656244, + NvAPI_GPU_GetVoltageStep = 0x28766157, // unsure of the name + NvAPI_GPU_GetVPECount = 0xD8CBF37B, + NvAPI_GPU_GetVSFloorSweepStatus = 0xD4F3944C, + NvAPI_GPU_GPIOQueryLegalPins = 0x0FAB69565, + NvAPI_GPU_GPIOReadFromPin = 0x0F5E10439, + NvAPI_GPU_GPIOWriteToPin = 0x0F3B11E68, + NvAPI_GPU_PerfPoliciesGetInfo = 0x409d9841, + NvAPI_GPU_PerfPoliciesGetStatus = 0x3d358a0c, + NvAPI_GPU_PhysxQueryRecommendedState = 0x7A4174F4, + NvAPI_GPU_PhysxSetState = 0x4071B85E, + NvAPI_GPU_QueryActiveApps = 0x65B1C5F5, + NvAPI_GPU_RestoreCoolerPolicyTable = 0x0D8C4FE63, + NvAPI_GPU_RestoreCoolerSettings = 0x8F6ED0FB, + NvAPI_GPU_SetClockBoostLock = 0x39442cfb, // unknown name, NVAPI_ID_CURVE_SET + NvAPI_GPU_SetClockBoostTable = 0x0733e009, + NvAPI_GPU_SetClocks = 0x6F151055, + NvAPI_GPU_SetColorSpaceConversion = 0x0FCABD23A, + NvAPI_GPU_SetCoolerLevels = 0x891FA0AE, + NvAPI_GPU_SetCoolerPolicyTable = 0x987947CD, + NvAPI_GPU_SetCoreVoltageBoostPercent = 0xb9306d9b, + NvAPI_GPU_SetCurrentPCIESpeed = 0x3BD32008, + NvAPI_GPU_SetCurrentPCIEWidth = 0x3F28E1B9, + NvAPI_GPU_SetDeepIdleState = 0x568A2292, + NvAPI_GPU_SetDisplayUnderflowMode = 0x387B2E41, + NvAPI_GPU_SetDitherControl = 0x0DF0DFCDD, + NvAPI_GPU_SetPerfClocks = 0x7BCF4AC, + NvAPI_GPU_SetPerfHybridMode = 0x7BC207F8, + NvAPI_GPU_SetPixelClockRange = 0x5AC7F8E5, + NvAPI_GPU_SetPowerMizerInfo = 0x50016C78, + NvAPI_GPU_SetPstateClientLimits = 0x0FDFC7D49, + NvAPI_GPU_SetPstates20 = 0x0F4DAE6B, + NvAPI_GPU_SetPstatesInfo = 0x0CDF27911, + NvAPI_GPU_SetThermalPoliciesStatus = 0x034C0B13D, + NvAPI_Hybrid_IsAppMigrationStateChangeable = 0x584CB0B6, + NvAPI_Hybrid_QueryBlockedMigratableApps = 0x0F4C2F8CC, + NvAPI_Hybrid_QueryUnblockedNonMigratableApps = 0x5F35BCB5, + NvAPI_Hybrid_SetAppMigrationState = 0x0FA0B9A59, + NvAPI_I2CReadEx = 0x4D7B0709, + NvAPI_I2CWriteEx = 0x283AC65A, + NvAPI_LoadMicrocode = 0x3119F36E, + NvAPI_Mosaic_ChooseGpuTopologies = 0x0B033B140, + NvAPI_Mosaic_EnumGridTopologies = 0x0A3C55220, + NvAPI_Mosaic_GetDisplayCapabilities = 0x0D58026B9, + NvAPI_Mosaic_GetMosaicCapabilities = 0x0DA97071E, + NvAPI_Mosaic_GetMosaicViewports = 0x7EBA036, + NvAPI_Mosaic_SetGridTopology = 0x3F113C77, + NvAPI_Mosaic_ValidateDisplayGridsWithSLI = 0x1ECFD263, + NvAPI_QueryNonMigratableApps = 0x0BB9EF1C3, + NvAPI_QueryUnderscanCap = 0x61D7B624, + NvAPI_RestartDisplayDriver = 0xB4B26B65, + NvAPI_RevertCustomDisplayTrial = 0x854BA405, + NvAPI_SaveCustomDisplay = 0x0A9062C78, + NvAPI_SetDisplayFeatureConfig = 0x0F36A668D, + NvAPI_SetDisplayPosition = 0x57D9060F, + NvAPI_SetDisplaySettings = 0x0E04F3D86, + NvAPI_SetDVCLevel = 0x172409B4, + NvAPI_SetDVCLevelEx = 0x4A82C2B1, + NvAPI_SetFrameRateNotify = 0x18919887, + NvAPI_SetGpuTopologies = 0x25201F3D, + NvAPI_SetHUEAngle = 0x0F5A0F22C, + NvAPI_SetHybridMode = 0x0FB22D656, + NvAPI_SetImageSharpeningLevel = 0x3FC9A59C, + NvAPI_SetInfoFrame = 0x69C6F365, + NvAPI_SetInfoFrameState = 0x67EFD887, + NvAPI_SetPVExtName = 0x4FEEB498, + NvAPI_SetPVExtProfile = 0x8354A8F4, + NvAPI_SetTopologyDisplayGPU = 0xF409D5E5, + NvAPI_SetTopologyFocusDisplayAndView = 0x0A8064F9, + NvAPI_SetTVEncoderControls = 0x0CA36A3AB, + NvAPI_SetTVOutputBorderColor = 0x0AED02700, + NvAPI_SetUnderscanConfig = 0x3EFADA1D, + NvAPI_SetVideoState = 0x54FE75A, + NvAPI_Stereo_AppHandShake = 0x8C610BDA, + NvAPI_Stereo_ForceToScreenDepth = 0x2D495758, + NvAPI_Stereo_GetCursorSeparation = 0x72162B35, + NvAPI_Stereo_GetPixelShaderConstantB = 0x0C79333AE, + NvAPI_Stereo_GetPixelShaderConstantF = 0x0D4974572, + NvAPI_Stereo_GetPixelShaderConstantI = 0x0ECD8F8CF, + NvAPI_Stereo_GetStereoCaps = 0x0DFC063B7, + NvAPI_Stereo_GetVertexShaderConstantB = 0x712BAA5B, + NvAPI_Stereo_GetVertexShaderConstantF = 0x622FDC87, + NvAPI_Stereo_GetVertexShaderConstantI = 0x5A60613A, + NvAPI_Stereo_HandShake_Message_Control = 0x315E0EF0, + NvAPI_Stereo_HandShake_Trigger_Activation = 0x0B30CD1A7, + NvAPI_Stereo_Is3DCursorSupported = 0x0D7C9EC09, + NvAPI_Stereo_SetCursorSeparation = 0x0FBC08FC1, + NvAPI_Stereo_SetPixelShaderConstantB = 0x0BA6109EE, + NvAPI_Stereo_SetPixelShaderConstantF = 0x0A9657F32, + NvAPI_Stereo_SetPixelShaderConstantI = 0x912AC28F, + NvAPI_Stereo_SetVertexShaderConstantB = 0x5268716F, + NvAPI_Stereo_SetVertexShaderConstantF = 0x416C07B3, + NvAPI_Stereo_SetVertexShaderConstantI = 0x7923BA0E, + NvAPI_SYS_GetChipSetTopologyStatus = 0x8A50F126, + NvAPI_SYS_GetSliApprovalCookie = 0xB539A26E, + NvAPI_SYS_SetPostOutput = 0xD3A092B1, + NvAPI_SYS_VenturaGetCoolingBudget = 0x0C9D86E33, + NvAPI_SYS_VenturaGetPowerReading = 0x63685979, + NvAPI_SYS_VenturaGetState = 0x0CB7C208D, + NvAPI_SYS_VenturaSetCoolingBudget = 0x85FF5A15, + NvAPI_SYS_VenturaSetState = 0x0CE2E9D9, + NvAPI_TryCustomDisplay = 0x0BF6C1762, + NvAPI_VideoGetStereoInfo = 0x8E1F8CFE, + NvAPI_VideoSetStereoInfo = 0x97063269, + NvAPI_GPU_ClientFanCoolersGetInfo = 0xfb85b01e, + NvAPI_GPU_ClientFanCoolersGetStatus = 0x35aed5e8, + NvAPI_GPU_ClientFanCoolersGetControl = 0x814b209f, + NvAPI_GPU_ClientFanCoolersSetControl = 0xa58971a5, + Unknown_1629A173 = 0x1629a173, // `Unknown(*mut { version = 0x00030038, count, .. })` + Unknown_36E39E6B = 0x36e39e6b, // `Unknown(*mut { version = 0x0002000c, count, ... })` might be handles? + Unknown_B7BCF50D = 0xb7bcf50d, // `Unknown(hGpu, *mut { version = 0x00010008, value })` seen `value = 0x703` + Unknown_F1D2777B = 0xf1d2777b, // `Unknown(hDisplayHandle, *mut hGpu)` maybe? + NvAPI_GPU_QueryThermalSensors = 0x65FE3AAD, + + #endregion + + NvAPI_Unload = 0xD22BDD7E, + NvAPI_Initialize = 0x150E828 + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Helpers/Structures/ValueTypeArray.cs b/NvAPIWrapper/Native/Helpers/Structures/ValueTypeArray.cs new file mode 100644 index 0000000..68db675 --- /dev/null +++ b/NvAPIWrapper/Native/Helpers/Structures/ValueTypeArray.cs @@ -0,0 +1,262 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Helpers.Structures +{ + [StructLayout(LayoutKind.Sequential)] + internal struct ValueTypeArray : IDisposable, IHandle, IEquatable + { + // ReSharper disable once ConvertToAutoProperty + public IntPtr MemoryAddress { get; } + + public static ValueTypeArray Null + { + get => new ValueTypeArray(); + } + + public bool IsNull + { + get => MemoryAddress == IntPtr.Zero; + } + + public ValueTypeArray(IntPtr memoryAddress) + { + MemoryAddress = memoryAddress; + } + + public static ValueTypeArray FromArray(IEnumerable list) + { + var array = list.ToArray(); + + if (array.Length > 0) + { + if (array[0] == null || !array[0].GetType().IsValueType) + { + throw new ArgumentException("Only Value Types are acceptable.", nameof(list)); + } + + var type = array[0].GetType(); + + if (array.Any(item => item.GetType() != type)) + { + throw new ArgumentException("Array should not hold objects of multiple types.", nameof(list)); + } + + return FromArray(array, type); + } + + return Null; + } + + + // ReSharper disable once ExcessiveIndentation + // ReSharper disable once MethodTooLong + public static ValueTypeArray FromArray(IEnumerable list, Type type) + { + var array = list.ToArray(); + + if (array.Length > 0) + { + var typeSize = Marshal.SizeOf(type); + var memoryAddress = Marshal.AllocHGlobal(array.Length * typeSize); + + if (memoryAddress != IntPtr.Zero) + { + var result = new ValueTypeArray(memoryAddress); + + foreach (var item in array) + { + if (type == typeof(int)) + { + Marshal.WriteInt32(memoryAddress, (int) item); + } + else if (type == typeof(uint)) + { + Marshal.WriteInt32(memoryAddress, (int) (uint) item); + } + else if (type == typeof(short)) + { + Marshal.WriteInt16(memoryAddress, (short) item); + } + else if (type == typeof(ushort)) + { + Marshal.WriteInt16(memoryAddress, (short) (ushort) item); + } + else if (type == typeof(long)) + { + Marshal.WriteInt64(memoryAddress, (long) item); + } + else if (type == typeof(ulong)) + { + Marshal.WriteInt64(memoryAddress, (long) (ulong) item); + } + else if (type == typeof(byte)) + { + Marshal.WriteByte(memoryAddress, (byte) item); + } + else if (type == typeof(IntPtr)) + { + Marshal.WriteIntPtr(memoryAddress, (IntPtr) item); + } + else + { + Marshal.StructureToPtr(item, memoryAddress, false); + } + + memoryAddress += typeSize; + } + + return result; + } + } + + return Null; + } + + public bool Equals(ValueTypeArray other) + { + return MemoryAddress.Equals(other.MemoryAddress); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is ValueTypeArray array && Equals(array); + } + + public override int GetHashCode() + { + return MemoryAddress.GetHashCode(); + } + + public static bool operator ==(ValueTypeArray left, ValueTypeArray right) + { + return left.Equals(right); + } + + public static bool operator !=(ValueTypeArray left, ValueTypeArray right) + { + return !left.Equals(right); + } + + public static ValueTypeArray FromArray(T[] array) where T : struct + { + return FromArray(array.Cast()); + } + + public T[] ToArray(int count) where T : struct + { + return ToArray(count, typeof(T)); + } + + public T[] ToArray(int count, Type type) + { + return ToArray(0, count, type); + } + + public T[] ToArray(int start, int count) where T : struct + { + return ToArray(start, count, typeof(T)).ToArray(); + } + + public T[] ToArray(int start, int count, Type type) + { + if (IsNull) + { + return null; + } + + return AsEnumerable(start, count, type).ToArray(); + } + + public IEnumerable AsEnumerable(int count) where T : struct + { + return AsEnumerable(count, typeof(T)); + } + + + public IEnumerable AsEnumerable(int count, Type type) + { + return AsEnumerable(0, count, type); + } + + public IEnumerable AsEnumerable(int start, int count) where T : struct + { + return AsEnumerable(start, count, typeof(T)); + } + + // ReSharper disable once ExcessiveIndentation + // ReSharper disable once MethodTooLong + public IEnumerable AsEnumerable(int start, int count, Type type) + { + if (!IsNull) + { + if (!type.IsValueType) + { + throw new ArgumentException("Only Value Types are acceptable.", nameof(type)); + } + + var typeSize = Marshal.SizeOf(type); + var address = MemoryAddress + start * typeSize; + + for (var i = 0; i < count; i++) + { + if (type == typeof(int)) + { + yield return (T) (object) Marshal.ReadInt32(address); + } + else if (type == typeof(uint)) + { + yield return (T) (object) (uint) Marshal.ReadInt32(address); + } + else if (type == typeof(short)) + { + yield return (T) (object) Marshal.ReadInt16(address); + } + else if (type == typeof(ushort)) + { + yield return (T) (object) (ushort) Marshal.ReadInt16(address); + } + else if (type == typeof(long)) + { + yield return (T) (object) Marshal.ReadInt64(address); + } + else if (type == typeof(ulong)) + { + yield return (T) (object) (ulong) Marshal.ReadInt64(address); + } + else if (type == typeof(byte)) + { + yield return (T) (object) Marshal.ReadByte(address); + } + else if (type == typeof(IntPtr)) + { + yield return (T) (object) Marshal.ReadIntPtr(address); + } + else + { + yield return (T) Marshal.PtrToStructure(address, type); + } + + address += typeSize; + } + } + } + + + public void Dispose() + { + if (!IsNull) + { + Marshal.FreeHGlobal(MemoryAddress); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Helpers/Structures/ValueTypeArray`1.cs b/NvAPIWrapper/Native/Helpers/Structures/ValueTypeArray`1.cs new file mode 100644 index 0000000..4556812 --- /dev/null +++ b/NvAPIWrapper/Native/Helpers/Structures/ValueTypeArray`1.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Helpers.Structures +{ + [StructLayout(LayoutKind.Sequential)] + internal struct ValueTypeArray : IDisposable, IHandle, IEquatable> where T : struct + { + private ValueTypeArray underlyingArray; + + public IntPtr MemoryAddress + { + get => underlyingArray.MemoryAddress; + } + + public static ValueTypeArray Null + { + get => new ValueTypeArray(); + } + + public bool IsNull + { + get => underlyingArray.IsNull; + } + + public ValueTypeArray(IntPtr memoryAddress) + { + underlyingArray = new ValueTypeArray(memoryAddress); + } + + private ValueTypeArray(ValueTypeArray underlyingArray) + { + this.underlyingArray = underlyingArray; + } + + public static ValueTypeArray FromArray(T[] array) + { + return new ValueTypeArray(ValueTypeArray.FromArray(array)); + } + + public static ValueTypeArray FromArray(IEnumerable list, Type type) + { + return new ValueTypeArray(ValueTypeArray.FromArray(list.Cast(), type)); + } + + public bool Equals(ValueTypeArray other) + { + return underlyingArray.Equals(other.underlyingArray); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is ValueTypeArray array && Equals(array); + } + + public override int GetHashCode() + { + // ReSharper disable once NonReadonlyMemberInGetHashCode + return underlyingArray.GetHashCode(); + } + + public static bool operator ==(ValueTypeArray left, ValueTypeArray right) + { + return left.Equals(right); + } + + public static bool operator !=(ValueTypeArray left, ValueTypeArray right) + { + return !left.Equals(right); + } + + public T[] ToArray(int count) + { + return underlyingArray.ToArray(count, typeof(T)); + } + + public T[] ToArray(int count, Type type) + { + return underlyingArray.ToArray(0, count, type); + } + + public T[] ToArray(int start, int count) + { + return underlyingArray.ToArray(start, count, typeof(T)).ToArray(); + } + + public T[] ToArray(int start, int count, Type type) + { + return underlyingArray.ToArray(start, count, type); + } + + public IEnumerable AsEnumerable(int count) + { + return underlyingArray.AsEnumerable(count, typeof(T)); + } + + public IEnumerable AsEnumerable(int count, Type type) + { + return underlyingArray.AsEnumerable(0, count, type); + } + + public IEnumerable AsEnumerable(int start, int count) + { + return underlyingArray.AsEnumerable(start, count, typeof(T)); + } + + public IEnumerable AsEnumerable(int start, int count, Type type) + { + return underlyingArray.AsEnumerable(start, count, type); + } + + public void Dispose() + { + if (!IsNull) + { + underlyingArray.Dispose(); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Helpers/Structures/ValueTypeReference.cs b/NvAPIWrapper/Native/Helpers/Structures/ValueTypeReference.cs new file mode 100644 index 0000000..7d983b5 --- /dev/null +++ b/NvAPIWrapper/Native/Helpers/Structures/ValueTypeReference.cs @@ -0,0 +1,116 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Helpers.Structures +{ + [StructLayout(LayoutKind.Sequential)] + internal struct ValueTypeReference : IDisposable, IHandle, IEquatable + { + // ReSharper disable once ConvertToAutoProperty + public IntPtr MemoryAddress { get; } + + public static ValueTypeReference Null + { + get => new ValueTypeReference(); + } + + public bool IsNull + { + get => MemoryAddress == IntPtr.Zero; + } + + public ValueTypeReference(IntPtr memoryAddress) + { + MemoryAddress = memoryAddress; + } + + public static ValueTypeReference FromValueType(T valueType) where T : struct + { + return FromValueType(valueType, typeof(T)); + } + + public static ValueTypeReference FromValueType(object valueType, Type type) + { + if (!type.IsValueType) + { + throw new ArgumentException("Only Value Types are acceptable.", nameof(type)); + } + + var memoryAddress = Marshal.AllocHGlobal(Marshal.SizeOf(type)); + + if (memoryAddress != IntPtr.Zero) + { + var result = new ValueTypeReference(memoryAddress); + Marshal.StructureToPtr(valueType, memoryAddress, false); + + return result; + } + + return Null; + } + + public bool Equals(ValueTypeReference other) + { + return MemoryAddress.Equals(other.MemoryAddress); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is ValueTypeReference reference && Equals(reference); + } + + public override int GetHashCode() + { + return MemoryAddress.GetHashCode(); + } + + public static bool operator ==(ValueTypeReference left, ValueTypeReference right) + { + return left.Equals(right); + } + + public static bool operator !=(ValueTypeReference left, ValueTypeReference right) + { + return !left.Equals(right); + } + + public T ToValueType(Type type) + { + if (MemoryAddress == IntPtr.Zero) + { + return default(T); + } + + if (!type.IsValueType) + { + throw new ArgumentException("Only Value Types are acceptable.", nameof(type)); + } + + return (T) Marshal.PtrToStructure(MemoryAddress, type); + } + + public T? ToValueType() where T : struct + { + if (IsNull) + { + return null; + } + + return ToValueType(typeof(T)); + } + + public void Dispose() + { + if (!IsNull) + { + Marshal.FreeHGlobal(MemoryAddress); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Helpers/Structures/ValueTypeReference`1.cs b/NvAPIWrapper/Native/Helpers/Structures/ValueTypeReference`1.cs new file mode 100644 index 0000000..3fd8e66 --- /dev/null +++ b/NvAPIWrapper/Native/Helpers/Structures/ValueTypeReference`1.cs @@ -0,0 +1,96 @@ +using System; +using System.Runtime.InteropServices; +using NvAPIWrapper.Native.Interfaces; + +namespace NvAPIWrapper.Native.Helpers.Structures +{ + [StructLayout(LayoutKind.Sequential)] + internal struct ValueTypeReference : IDisposable, IHandle, IEquatable> where T : struct + { + private ValueTypeReference underlyingReference; + + public IntPtr MemoryAddress + { + get => underlyingReference.MemoryAddress; + } + + public static ValueTypeReference Null + { + get => new ValueTypeReference(); + } + + public bool IsNull + { + get => underlyingReference.IsNull; + } + + public ValueTypeReference(IntPtr memoryAddress) + { + underlyingReference = new ValueTypeReference(memoryAddress); + } + + private ValueTypeReference(ValueTypeReference underlyingReference) + { + this.underlyingReference = underlyingReference; + } + + public static ValueTypeReference FromValueType(T valueType) + { + return new ValueTypeReference(ValueTypeReference.FromValueType(valueType)); + } + + public static ValueTypeReference FromValueType(object valueType, Type type) + { + return new ValueTypeReference(ValueTypeReference.FromValueType(valueType, type)); + } + + public bool Equals(ValueTypeReference other) + { + return underlyingReference.Equals(other.underlyingReference); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is ValueTypeReference reference && Equals(reference); + } + + public override int GetHashCode() + { + // ReSharper disable once NonReadonlyMemberInGetHashCode + return underlyingReference.GetHashCode(); + } + + public static bool operator ==(ValueTypeReference left, ValueTypeReference right) + { + return left.Equals(right); + } + + public static bool operator !=(ValueTypeReference left, ValueTypeReference right) + { + return !left.Equals(right); + } + + public T ToValueType(Type type) + { + return underlyingReference.ToValueType(type); + } + + public T? ToValueType() + { + return underlyingReference.ToValueType(); + } + + public void Dispose() + { + if (!IsNull) + { + underlyingReference.Dispose(); + } + } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/Display/IColorData.cs b/NvAPIWrapper/Native/Interfaces/Display/IColorData.cs new file mode 100644 index 0000000..4f2821d --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/Display/IColorData.cs @@ -0,0 +1,40 @@ +using NvAPIWrapper.Native.Display; + +namespace NvAPIWrapper.Native.Interfaces.Display +{ + /// + /// Contains data corresponding to color information + /// + public interface IColorData + { + /// + /// Gets the color data color depth + /// + ColorDataDepth? ColorDepth { get; } + + /// + /// Gets the color data dynamic range + /// + ColorDataDynamicRange? DynamicRange { get; } + + /// + /// Gets the color data color format + /// + ColorDataFormat ColorFormat { get; } + + /// + /// Gets the color data color space + /// + ColorDataColorimetry Colorimetry { get; } + + /// + /// Gets the color data selection policy + /// + ColorDataSelectionPolicy? SelectionPolicy { get; } + + /// + /// Gets the color data desktop color depth + /// + ColorDataDesktopDepth? DesktopColorDepth { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/Display/IDisplayColorData.cs b/NvAPIWrapper/Native/Interfaces/Display/IDisplayColorData.cs new file mode 100644 index 0000000..9ff47b2 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/Display/IDisplayColorData.cs @@ -0,0 +1,30 @@ +using NvAPIWrapper.Native.Display.Structures; + +namespace NvAPIWrapper.Native.Interfaces.Display +{ + /// + /// Holds information regarding a display color space configurations + /// + public interface IDisplayColorData + { + /// + /// Gets the first primary color space coordinate (e.g. Red for RGB) [(0.0, 0.0)-(1.0, 1.0)] + /// + ColorDataColorCoordinate FirstColorCoordinate { get; } + + /// + /// Gets the second primary color space coordinate (e.g. Green for RGB) [(0.0, 0.0)-(1.0, 1.0)] + /// + ColorDataColorCoordinate SecondColorCoordinate { get; } + + /// + /// Gets the third primary color space coordinate (e.g. Blue for RGB) [(0.0, 0.0)-(1.0, 1.0)] + /// + ColorDataColorCoordinate ThirdColorCoordinate { get; } + + /// + /// Gets the white color space coordinate [(0.0, 0.0)-(1.0, 1.0)] + /// + ColorDataColorCoordinate WhiteColorCoordinate { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/Display/IDisplayDVCInfo.cs b/NvAPIWrapper/Native/Interfaces/Display/IDisplayDVCInfo.cs new file mode 100644 index 0000000..39a08b1 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/Display/IDisplayDVCInfo.cs @@ -0,0 +1,28 @@ +namespace NvAPIWrapper.Native.Interfaces.Display +{ + /// + /// Holds the Digital Vibrance Control information regarding the saturation level. + /// + public interface IDisplayDVCInfo + { + /// + /// Gets the current saturation level + /// + int CurrentLevel { get; } + + /// + /// Gets the default saturation level + /// + int DefaultLevel { get; } + + /// + /// Gets the maximum valid saturation level + /// + int MaximumLevel { get; } + + /// + /// Gets the minimum valid saturation level + /// + int MinimumLevel { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/Display/IHDMISupportInfo.cs b/NvAPIWrapper/Native/Interfaces/Display/IHDMISupportInfo.cs new file mode 100644 index 0000000..aa97a85 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/Display/IHDMISupportInfo.cs @@ -0,0 +1,74 @@ +namespace NvAPIWrapper.Native.Interfaces.Display +{ + /// + /// Contains information about the HDMI capabilities of the GPU, output and the display device attached + /// + public interface IHDMISupportInfo + { + /// + /// Gets the display's EDID 861 Extension Revision + /// + uint EDID861ExtensionRevision { get; } + + /// + /// Gets a boolean value indicating that the GPU is capable of HDMI output + /// + bool IsGPUCapableOfHDMIOutput { get; } + + /// + /// Gets a boolean value indicating that the display is connected via HDMI + /// + bool IsHDMIMonitor { get; } + + /// + /// Gets a boolean value indicating that the connected display is capable of Adobe RGB if such data is available; + /// otherwise null + /// + bool? IsMonitorCapableOfAdobeRGB { get; } + + /// + /// Gets a boolean value indicating that the connected display is capable of Adobe YCC601 if such data is available; + /// otherwise null + /// + bool? IsMonitorCapableOfAdobeYCC601 { get; } + + /// + /// Gets a boolean value indicating that the connected display is capable of basic audio + /// + bool IsMonitorCapableOfBasicAudio { get; } + + /// + /// Gets a boolean value indicating that the connected display is capable of sYCC601 if such data is available; + /// otherwise null + /// + bool? IsMonitorCapableOfsYCC601 { get; } + + + /// + /// Gets a boolean value indicating that the connected display is capable of underscan + /// + bool IsMonitorCapableOfUnderscan { get; } + + /// + /// Gets a boolean value indicating that the connected display is capable of xvYCC601 + /// + // ReSharper disable once IdentifierTypo + bool IsMonitorCapableOfxvYCC601 { get; } + + /// + /// Gets a boolean value indicating that the connected display is capable of xvYCC709 + /// + // ReSharper disable once IdentifierTypo + bool IsMonitorCapableOfxvYCC709 { get; } + + /// + /// Gets a boolean value indicating that the connected display is capable of YCbCr422 + /// + bool IsMonitorCapableOfYCbCr422 { get; } + + /// + /// Gets a boolean value indicating that the connected display is capable of YCbCr444 + /// + bool IsMonitorCapableOfYCbCr444 { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/Display/IHDRColorData.cs b/NvAPIWrapper/Native/Interfaces/Display/IHDRColorData.cs new file mode 100644 index 0000000..5ce244f --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/Display/IHDRColorData.cs @@ -0,0 +1,37 @@ +using NvAPIWrapper.Native.Display; +using NvAPIWrapper.Native.Display.Structures; + +namespace NvAPIWrapper.Native.Interfaces.Display +{ + /// + /// Contains information regarding HDR color data + /// + public interface IHDRColorData + { + /// + /// Gets the HDR color depth if available; otherwise null + /// For Dolby Vision only, should and will be ignored if HDR is on + /// + ColorDataDepth? ColorDepth { get; } + + /// + /// Gets the HDR color format if available; otherwise null + /// + ColorDataFormat? ColorFormat { get; } + + /// + /// Gets the HDR dynamic range if available; otherwise null + /// + ColorDataDynamicRange? DynamicRange { get; } + + /// + /// Gets the HDR mode + /// + ColorDataHDRMode HDRMode { get; } + + /// + /// Gets the color space coordinates + /// + MasteringDisplayColorData MasteringDisplayData { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/Display/IPathInfo.cs b/NvAPIWrapper/Native/Interfaces/Display/IPathInfo.cs new file mode 100644 index 0000000..13fa7f9 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/Display/IPathInfo.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using NvAPIWrapper.Native.Display.Structures; + +namespace NvAPIWrapper.Native.Interfaces.Display +{ + /// + /// Interface for all PathInfo structures + /// + public interface IPathInfo : IDisposable + { + /// + /// Identifies sourceId used by Windows CCD. This can be optionally set. + /// + uint SourceId { get; } + + /// + /// Contains information about the source mode + /// + SourceModeInfo SourceModeInfo { get; } + + /// + /// Contains information about path targets + /// + IEnumerable TargetsInfo { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/Display/IPathTargetInfo.cs b/NvAPIWrapper/Native/Interfaces/Display/IPathTargetInfo.cs new file mode 100644 index 0000000..0278842 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/Display/IPathTargetInfo.cs @@ -0,0 +1,20 @@ +using NvAPIWrapper.Native.Display.Structures; + +namespace NvAPIWrapper.Native.Interfaces.Display +{ + /// + /// Interface for all PathTargetInfo structures + /// + public interface IPathTargetInfo + { + /// + /// Contains extra information. NULL for Non-NVIDIA Display. + /// + PathAdvancedTargetInfo? Details { get; } + + /// + /// Display identification + /// + uint DisplayId { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/Display/IScanOutIntensityData.cs b/NvAPIWrapper/Native/Interfaces/Display/IScanOutIntensityData.cs new file mode 100644 index 0000000..3aae9c2 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/Display/IScanOutIntensityData.cs @@ -0,0 +1,24 @@ +namespace NvAPIWrapper.Native.Display.Structures +{ + /// + /// Contains information regarding the scan-out intensity data + /// + public interface IScanOutIntensity { + + /// + /// Gets the array of floating values building an intensity RGB texture + /// + float[] BlendingTexture { get; } + + /// + /// Gets the height of the input texture + /// + uint Height { get; } + + + /// + /// Gets the width of the input texture + /// + uint Width { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IClockFrequencies.cs b/NvAPIWrapper/Native/Interfaces/GPU/IClockFrequencies.cs new file mode 100644 index 0000000..fe4d43d --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IClockFrequencies.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; + +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Interface for all ClockFrequencies structures + /// + public interface IClockFrequencies + { + /// + /// Gets all valid clocks + /// + IReadOnlyDictionary Clocks { get; } + + /// + /// Gets the type of clock frequencies provided with this object + /// + ClockType ClockType { get; } + + /// + /// Gets graphics engine clock + /// + ClockDomainInfo GraphicsClock { get; } + + /// + /// Gets memory decoding clock + /// + ClockDomainInfo MemoryClock { get; } + + /// + /// Gets processor clock + /// + ClockDomainInfo ProcessorClock { get; } + + /// + /// Gets video decoding clock + /// + ClockDomainInfo VideoDecodingClock { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IDisplayDriverMemoryInfo.cs b/NvAPIWrapper/Native/Interfaces/GPU/IDisplayDriverMemoryInfo.cs new file mode 100644 index 0000000..f4dbea2 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IDisplayDriverMemoryInfo.cs @@ -0,0 +1,33 @@ +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Interface for all DisplayDriverMemoryInfo structures + /// + public interface IDisplayDriverMemoryInfo + { + /// + /// Size(in kb) of the available physical frame buffer for allocating video memory surfaces. + /// + uint AvailableDedicatedVideoMemoryInkB { get; } + + /// + /// Size(in kb) of the current available physical frame buffer for allocating video memory surfaces. + /// + uint CurrentAvailableDedicatedVideoMemoryInkB { get; } + + /// + /// Size(in kb) of the physical frame buffer. + /// + uint DedicatedVideoMemoryInkB { get; } + + /// + /// Size(in kb) of shared system memory that driver is allowed to commit for surfaces across all allocations. + /// + uint SharedSystemMemoryInkB { get; } + + /// + /// Size(in kb) of system memory the driver allocates at load time. + /// + uint SystemVideoMemoryInkB { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IDisplayIds.cs b/NvAPIWrapper/Native/Interfaces/GPU/IDisplayIds.cs new file mode 100644 index 0000000..4e0c2e4 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IDisplayIds.cs @@ -0,0 +1,65 @@ +using NvAPIWrapper.Native.GPU; + +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Interface for all DisplayIds structures + /// + public interface IDisplayIds + { + /// + /// Gets connection type. This is reserved for future use and clients should not rely on this information. Instead get + /// the GPU connector type from NvAPI_GPU_GetConnectorInfo/NvAPI_GPU_GetConnectorInfoEx + /// + MonitorConnectionType ConnectionType { get; } + + /// + /// Gets a unique identifier for each device + /// + uint DisplayId { get; } + + /// + /// Indicates if the display is being actively driven + /// + bool IsActive { get; } + + /// + /// Indicates if the display is the representative display + /// + bool IsCluster { get; } + + /// + /// Indicates if the display is connected + /// + bool IsConnected { get; } + + /// + /// Indicates if the display is part of MST topology and it's a dynamic + /// + bool IsDynamic { get; } + + /// + /// Indicates if the display identification belongs to a multi stream enabled connector (root node). Note that when + /// multi stream is enabled and a single multi stream capable monitor is connected to it, the monitor will share the + /// display id with the RootNode. + /// When there is more than one monitor connected in a multi stream topology, then the root node will have a separate + /// displayId. + /// + bool IsMultiStreamRootNode { get; } + + /// + /// Indicates if the display is reported to the OS + /// + bool IsOSVisible { get; } + + /// + /// Indicates if the display is a physically connected display; Valid only when IsConnected is true + /// + bool IsPhysicallyConnected { get; } + + /// + /// Indicates if the display is wireless + /// + bool IsWFD { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IEDID.cs b/NvAPIWrapper/Native/Interfaces/GPU/IEDID.cs new file mode 100644 index 0000000..3dfac15 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IEDID.cs @@ -0,0 +1,13 @@ +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Interface for all EDID structures + /// + public interface IEDID + { + /// + /// Gets whole or a part of the EDID data + /// + byte[] Data { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/II2CInfo.cs b/NvAPIWrapper/Native/Interfaces/GPU/II2CInfo.cs new file mode 100644 index 0000000..aaf7a09 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/II2CInfo.cs @@ -0,0 +1,50 @@ +using NvAPIWrapper.Native.GPU; + +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Contains an I2C packet transmitted or to be transmitted + /// + public interface II2CInfo + { + /// + /// Gets the payload data + /// + byte[] Data { get; } + + /// + /// Gets the device I2C slave address + /// + byte DeviceAddress { get; } + + /// + /// Gets a boolean value indicating that this instance contents information about a read operation + /// + bool IsReadOperation { get; } + + /// + /// Gets the target display output mask + /// + OutputId OutputMask { get; } + + /// + /// Gets the port id on which device is connected + /// + byte? PortId { get; } + + /// + /// Gets the target I2C register address + /// + byte[] RegisterAddress { get; } + + /// + /// Gets the target speed of the transaction in kHz + /// + I2CSpeed Speed { get; } + + /// + /// Gets a boolean value indicating that the DDC port should be used instead of the communication port + /// + bool UseDDCPort { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceState.cs b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceState.cs new file mode 100644 index 0000000..233bb9c --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceState.cs @@ -0,0 +1,30 @@ +using NvAPIWrapper.Native.GPU; + +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Holds information regarding a performance state + /// + public interface IPerformanceState + { + /// + /// Gets a boolean value indicating if this performance state is overclockable + /// + bool IsOverclockable { get; } + + /// + /// Gets a boolean value indicating if this performance state is currently overclocked + /// + bool IsOverclocked { get; } + + /// + /// Gets a boolean value indicating if this performance state is limited to use PCIE generation 1 or PCIE generation 2 + /// + bool IsPCIELimited { get; } + + /// + /// Gets the performance state identification + /// + PerformanceStateId StateId { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceState20.cs b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceState20.cs new file mode 100644 index 0000000..f98549e --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceState20.cs @@ -0,0 +1,20 @@ +using NvAPIWrapper.Native.GPU; + +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Holds information regarding a performance state v2 + /// + public interface IPerformanceState20 + { + /// + /// Gets a boolean value indicating if this performance state is editable + /// + bool IsEditable { get; } + + /// + /// Gets the performance state identification + /// + PerformanceStateId StateId { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStates20ClockDependentFrequencyRange.cs b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStates20ClockDependentFrequencyRange.cs new file mode 100644 index 0000000..464d55d --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStates20ClockDependentFrequencyRange.cs @@ -0,0 +1,36 @@ +using NvAPIWrapper.Native.GPU; + +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Holds information regarding the frequency range of a clock domain as well as the dependent voltage domain and the + /// range of the voltage + /// + public interface IPerformanceStates20ClockDependentFrequencyRange + { + /// + /// Gets the maximum clock frequency in kHz + /// + uint MaximumFrequencyInkHz { get; } + + /// + /// Gets the dependent voltage domain's maximum voltage in uV + /// + uint MaximumVoltageInMicroVolt { get; } + + /// + /// Gets the minimum clock frequency in kHz + /// + uint MinimumFrequencyInkHz { get; } + + /// + /// Gets the dependent voltage domain's minimum voltage in uV + /// + uint MinimumVoltageInMicroVolt { get; } + + /// + /// Gets the dependent voltage domain identification + /// + PerformanceVoltageDomain VoltageDomainId { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStates20ClockDependentSingleFrequency.cs b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStates20ClockDependentSingleFrequency.cs new file mode 100644 index 0000000..7db0792 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStates20ClockDependentSingleFrequency.cs @@ -0,0 +1,13 @@ +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Holds information regarding the clock frequency of a fixed frequency clock domain + /// + public interface IPerformanceStates20ClockDependentSingleFrequency + { + /// + /// Gets the clock frequency of a clock domain in kHz + /// + uint FrequencyInkHz { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStates20ClockEntry.cs b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStates20ClockEntry.cs new file mode 100644 index 0000000..a6119aa --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStates20ClockEntry.cs @@ -0,0 +1,42 @@ +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; + +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Holds information regarding a clock domain of a performance states + /// + public interface IPerformanceStates20ClockEntry + { + /// + /// Gets the type of clock frequency + /// + PerformanceStates20ClockType ClockType { get; } + + /// + /// Gets the domain identification + /// + PublicClockDomain DomainId { get; } + + /// + /// Gets the current base frequency delta value and the range for a valid delta value + /// + PerformanceStates20ParameterDelta FrequencyDeltaInkHz { get; } + + /// + /// Gets the fixed frequency of the clock + /// + IPerformanceStates20ClockDependentFrequencyRange FrequencyRange { get; } + + + /// + /// Gets a boolean value indicating if this clock is editable + /// + bool IsEditable { get; } + + /// + /// Gets the range of clock frequency and related voltage information if present + /// + IPerformanceStates20ClockDependentSingleFrequency SingleFrequency { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStates20Info.cs b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStates20Info.cs new file mode 100644 index 0000000..4515dc8 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStates20Info.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using NvAPIWrapper.Native.GPU; + +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Holds information regarding the valid power states and their clock and voltage settings as well as general + /// over-volting settings + /// + public interface IPerformanceStates20Info + { + /// + /// Gets a dictionary for valid power states and their clock frequencies + /// + IReadOnlyDictionary Clocks { get; } + + /// + /// Gets the list of general over-volting settings + /// + IPerformanceStates20VoltageEntry[] GeneralVoltages { get; } + + /// + /// Gets a boolean value indicating if performance states are editable + /// + bool IsEditable { get; } + + /// + /// Gets an array of valid power states for the GPU + /// + IPerformanceState20[] PerformanceStates { get; } + + /// + /// Gets a dictionary for valid power states and their voltage settings + /// + IReadOnlyDictionary Voltages { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStates20VoltageEntry.cs b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStates20VoltageEntry.cs new file mode 100644 index 0000000..b4912e3 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStates20VoltageEntry.cs @@ -0,0 +1,31 @@ +using NvAPIWrapper.Native.GPU; +using NvAPIWrapper.Native.GPU.Structures; + +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Holds information regarding the voltage of a voltage domain + /// + public interface IPerformanceStates20VoltageEntry + { + /// + /// Gets the voltage domain identification + /// + PerformanceVoltageDomain DomainId { get; } + + /// + /// Gets a boolean value indicating this voltage domain is editable + /// + bool IsEditable { get; } + + /// + /// Gets the base voltage delta and the range of valid values for the delta value + /// + PerformanceStates20ParameterDelta ValueDeltaInMicroVolt { get; } + + /// + /// Gets the current value of this voltage domain in uV + /// + uint ValueInMicroVolt { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStatesClock.cs b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStatesClock.cs new file mode 100644 index 0000000..1d41828 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStatesClock.cs @@ -0,0 +1,20 @@ +using NvAPIWrapper.Native.GPU; + +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Holds information regarding a clock domain of a performance state + /// + public interface IPerformanceStatesClock + { + /// + /// Gets the clock domain identification + /// + PublicClockDomain DomainId { get; } + + /// + /// Gets the clock frequency in kHz + /// + uint Frequency { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStatesInfo.cs b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStatesInfo.cs new file mode 100644 index 0000000..4fd6e8d --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStatesInfo.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using NvAPIWrapper.Native.GPU; + +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Holds information regarding performance states status of a GPU + /// + public interface IPerformanceStatesInfo + { + /// + /// Gets a boolean value indicating if the device is capable of dynamic performance state switching + /// + bool IsCapableOfDynamicPerformance { get; } + + /// + /// Gets a boolean value indicating if the dynamic performance state switching is enable + /// + bool IsDynamicPerformanceEnable { get; } + + /// + /// Gets a boolean value indicating if the performance monitoring is enable + /// + bool IsPerformanceMonitorEnable { get; } + + /// + /// Gets an array of valid and available performance states information + /// + IPerformanceState[] PerformanceStates { get; } + + /// + /// Gets a dictionary of valid and available performance states and their clock information as an array + /// + IReadOnlyDictionary PerformanceStatesClocks { get; } + + /// + /// Gets a dictionary of valid and available performance states and their voltage information as an array + /// + IReadOnlyDictionary PerformanceStatesVoltages { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStatesVoltage.cs b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStatesVoltage.cs new file mode 100644 index 0000000..28bff24 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IPerformanceStatesVoltage.cs @@ -0,0 +1,20 @@ +using NvAPIWrapper.Native.GPU; + +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Holds information regarding a voltage domain of a performance state + /// + public interface IPerformanceStatesVoltage + { + /// + /// Gets the voltage domain identification + /// + PerformanceVoltageDomain DomainId { get; } + + /// + /// Gets the voltage in mV + /// + uint Value { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IThermalSensor.cs b/NvAPIWrapper/Native/Interfaces/GPU/IThermalSensor.cs new file mode 100644 index 0000000..8279633 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IThermalSensor.cs @@ -0,0 +1,35 @@ +using NvAPIWrapper.Native.GPU; + +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Provides information about a single thermal sensor + /// + public interface IThermalSensor + { + /// + /// Internal, ADM1032, MAX6649... + /// + ThermalController Controller { get; } + + /// + /// Current temperature value of the thermal sensor in degree Celsius + /// + int CurrentTemperature { get; } + + /// + /// Maximum default temperature value of the thermal sensor in degree Celsius + /// + int DefaultMaximumTemperature { get; } + + /// + /// Minimum default temperature value of the thermal sensor in degree Celsius + /// + int DefaultMinimumTemperature { get; } + + /// + /// Thermal sensor targeted - GPU, memory, chipset, power supply, Visual Computing Device, etc + /// + ThermalSettingsTarget Target { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IThermalSettings.cs b/NvAPIWrapper/Native/Interfaces/GPU/IThermalSettings.cs new file mode 100644 index 0000000..0fa64f9 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IThermalSettings.cs @@ -0,0 +1,13 @@ +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + /// + /// Holds a list of thermal sensors + /// + public interface IThermalSettings + { + /// + /// Gets a list of requested thermal sensor information + /// + IThermalSensor[] Sensors { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IUtilizationDomainInfo.cs b/NvAPIWrapper/Native/Interfaces/GPU/IUtilizationDomainInfo.cs new file mode 100644 index 0000000..e3e161c --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IUtilizationDomainInfo.cs @@ -0,0 +1,19 @@ +namespace NvAPIWrapper.Native.Interfaces.GPU +{ + + /// + /// Holds information about a utilization domain + /// + public interface IUtilizationDomainInfo + { + /// + /// Gets a boolean value that indicates if this utilization domain is present on this GPU. + /// + bool IsPresent { get; } + + /// + /// Gets the percentage of time where the domain is considered busy in the last 1 second interval. + /// + uint Percentage { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/GPU/IUtilizationStatus.cs b/NvAPIWrapper/Native/Interfaces/GPU/IUtilizationStatus.cs new file mode 100644 index 0000000..a5cc333 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/GPU/IUtilizationStatus.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using NvAPIWrapper.Native.Interfaces.GPU; + +namespace NvAPIWrapper.Native.GPU.Structures +{ + /// + /// Holds information about the GPU utilization domains + /// + public interface IUtilizationStatus + { + + /// + /// Gets the Bus interface (BUS) utilization + /// + IUtilizationDomainInfo BusInterface { get; } + /// + /// Gets all valid utilization domains and information + /// + Dictionary Domains { get; } + + /// + /// Gets the frame buffer (FB) utilization + /// + IUtilizationDomainInfo FrameBuffer { get; } + + /// + /// Gets the graphic engine (GPU) utilization + /// + IUtilizationDomainInfo GPU { get; } + + + /// + /// Gets the Video engine (VID) utilization + /// + IUtilizationDomainInfo VideoEngine { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/General/IChipsetInfo.cs b/NvAPIWrapper/Native/Interfaces/General/IChipsetInfo.cs new file mode 100644 index 0000000..cb17efa --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/General/IChipsetInfo.cs @@ -0,0 +1,35 @@ +using NvAPIWrapper.Native.General; + +namespace NvAPIWrapper.Native.Interfaces.General +{ + /// + /// Interface for all ChipsetInfo structures + /// + public interface IChipsetInfo + { + /// + /// Chipset device name + /// + string ChipsetName { get; } + + /// + /// Chipset device identification + /// + int DeviceId { get; } + + /// + /// Chipset information flags - obsolete + /// + ChipsetInfoFlag Flags { get; } + + /// + /// Chipset vendor identification + /// + int VendorId { get; } + + /// + /// Chipset vendor name + /// + string VendorName { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/IAllocatable.cs b/NvAPIWrapper/Native/Interfaces/IAllocatable.cs new file mode 100644 index 0000000..7655d40 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/IAllocatable.cs @@ -0,0 +1,12 @@ +using System; + +namespace NvAPIWrapper.Native.Interfaces +{ + /// + /// Marker interface for all types that should be allocated before passing to the managed code + /// + internal interface IAllocatable : IInitializable, IDisposable + { + void Allocate(); + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/IHandle.cs b/NvAPIWrapper/Native/Interfaces/IHandle.cs new file mode 100644 index 0000000..655a3a9 --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/IHandle.cs @@ -0,0 +1,20 @@ +using System; + +namespace NvAPIWrapper.Native.Interfaces +{ + /// + /// Interface for all pointer based handles + /// + public interface IHandle + { + /// + /// Returns true if the handle is null and not pointing to a valid location in the memory + /// + bool IsNull { get; } + + /// + /// Gets the address of the handle in the memory + /// + IntPtr MemoryAddress { get; } + } +} \ No newline at end of file diff --git a/NvAPIWrapper/Native/Interfaces/IInitializable.cs b/NvAPIWrapper/Native/Interfaces/IInitializable.cs new file mode 100644 index 0000000..d526aba --- /dev/null +++ b/NvAPIWrapper/Native/Interfaces/IInitializable.cs @@ -0,0 +1,9 @@ +namespace NvAPIWrapper.Native.Interfaces +{ + /// + /// Marker interface for all types that should be filled with information before passing to un-managed code + /// + internal interface IInitializable + { + } +} \ No newline at end of file diff --git a/NvAPIWrapper/NvAPIWrapper.csproj b/NvAPIWrapper/NvAPIWrapper.csproj new file mode 100644 index 0000000..06c7f50 --- /dev/null +++ b/NvAPIWrapper/NvAPIWrapper.csproj @@ -0,0 +1,51 @@ + + + + net6.0-windows10.0.20348.0 + 0.8.1.101 + falahati.net + NvAPIWrapper is a .Net wrapper for NVIDIA public API + Soroush Falahati + Copyright © Soroush Falahati 2018 (falahati.net) + AnyCPU + NvAPIWrapper.Net + https://github.com/falahati/NvAPIWrapper + https://github.com/falahati/NvAPIWrapper/blob/master/LICENSE + https://github.com/falahati/NvAPIWrapper/blob/master/NvAPIWrapper/Icon.png?raw=true + true + true + AnyCPU + NvAPIWrapper (for NVAPI 410) + NvAPIWrapper.Net + OpenSourceStrongNameSignKey.pfx + + + ..\Debug + + + True + true + ..\Release + ..\Release\NvAPIWrapper.xml + true + + + + all + runtime; build; native; contentfiles; analyzers + + + + + true + \ + + + true + \ + + + + + + \ No newline at end of file diff --git a/NvAPIWrapper/readme.txt b/NvAPIWrapper/readme.txt new file mode 100644 index 0000000..211a58c --- /dev/null +++ b/NvAPIWrapper/readme.txt @@ -0,0 +1,12 @@ + NvAPIWrapper Library +------------------------------------------------------------ +NvAPIWrapper is a library released under the LGPLv3 license, +allowing all .Net developers to access and use the NVAPI +functionalities. + +For more information about this library, please check out +our GitHub page: +https://github.com/falahati/NvAPIWrapper + + +2017 Soroush Falahati (https://falahati.net) \ No newline at end of file