mirror of
https://github.com/jkocon/g-helper.git
synced 2026-02-23 13:00:52 +01:00
Experimental GPU overclock
This commit is contained in:
373
app/NvAPIWrapper/Mosaic/GridTopology.cs
Normal file
373
app/NvAPIWrapper/Mosaic/GridTopology.cs
Normal file
@@ -0,0 +1,373 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.Exceptions;
|
||||
using NvAPIWrapper.Native.General;
|
||||
using NvAPIWrapper.Native.Interfaces.Mosaic;
|
||||
using NvAPIWrapper.Native.Mosaic;
|
||||
using NvAPIWrapper.Native.Mosaic.Structures;
|
||||
|
||||
namespace NvAPIWrapper.Mosaic
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a mosaic grid topology
|
||||
/// </summary>
|
||||
public class GridTopology : IEquatable<GridTopology>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new GridTopology
|
||||
/// </summary>
|
||||
/// <param name="rows">Mosaic rows</param>
|
||||
/// <param name="columns">Mosaic columns</param>
|
||||
/// <param name="displays">Topology displays</param>
|
||||
public GridTopology(int rows, int columns, GridTopologyDisplay[] displays)
|
||||
{
|
||||
SetDisplays(rows, columns, displays);
|
||||
var possibleDisplaySettings = GetPossibleDisplaySettings();
|
||||
|
||||
if (possibleDisplaySettings.Any())
|
||||
{
|
||||
SetDisplaySettings(
|
||||
possibleDisplaySettings.OrderByDescending(
|
||||
settings => (long) settings.Width *
|
||||
settings.Height *
|
||||
settings.BitsPerPixel *
|
||||
settings.Frequency)
|
||||
.First());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new GridTopology
|
||||
/// </summary>
|
||||
/// <param name="gridTopology">A IGridTopology implamented object</param>
|
||||
public GridTopology(IGridTopology gridTopology)
|
||||
{
|
||||
Rows = gridTopology.Rows;
|
||||
Columns = gridTopology.Columns;
|
||||
Displays = gridTopology.Displays.Select(display => new GridTopologyDisplay(display)).ToArray();
|
||||
SetDisplaySettings(gridTopology.DisplaySettings);
|
||||
ApplyWithBezelCorrectedResolution = gridTopology.ApplyWithBezelCorrectedResolution;
|
||||
ImmersiveGaming = gridTopology.ImmersiveGaming;
|
||||
BaseMosaicPanoramic = gridTopology.BaseMosaicPanoramic;
|
||||
DriverReloadAllowed = gridTopology.DriverReloadAllowed;
|
||||
AcceleratePrimaryDisplay = gridTopology.AcceleratePrimaryDisplay;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean value enabling SLI acceleration on the primary display while in single-wide mode (For
|
||||
/// Immersive Gaming only).
|
||||
/// </summary>
|
||||
public bool AcceleratePrimaryDisplay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean value forcing to the bezel-corrected resolution when enabling and doing the modeset
|
||||
/// </summary>
|
||||
public bool ApplyWithBezelCorrectedResolution { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean value enabling the Base Mosaic (Panoramic) instead of Mosaic SLI (for NVS and Quadro-boards
|
||||
/// only)
|
||||
/// </summary>
|
||||
public bool BaseMosaicPanoramic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mosaic columns
|
||||
/// </summary>
|
||||
public int Columns { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets topology displays
|
||||
/// </summary>
|
||||
public GridTopologyDisplay[] Displays { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean value allowing the API to, if necessary, realod the driver (for Vista and above only). Will
|
||||
/// not be persisted. Value undefined on get.
|
||||
/// </summary>
|
||||
public bool DriverReloadAllowed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the topology Frequency
|
||||
/// </summary>
|
||||
public int Frequency { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean value enabling as immersive gaming instead of Mosaic SLI (for Quadro-boards only)
|
||||
/// </summary>
|
||||
public bool ImmersiveGaming { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the topology resolution
|
||||
/// </summary>
|
||||
public Resolution Resolution { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mosaic rows
|
||||
/// </summary>
|
||||
public int Rows { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(GridTopology other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Resolution.Equals(other.Resolution) &&
|
||||
Frequency == other.Frequency &&
|
||||
Rows == other.Rows &&
|
||||
Columns == other.Columns &&
|
||||
Displays.SequenceEqual(other.Displays) &&
|
||||
ApplyWithBezelCorrectedResolution == other.ApplyWithBezelCorrectedResolution &&
|
||||
ImmersiveGaming == other.ImmersiveGaming &&
|
||||
BaseMosaicPanoramic == other.BaseMosaicPanoramic &&
|
||||
AcceleratePrimaryDisplay == other.AcceleratePrimaryDisplay;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a list of currently active mosaic grid topologies
|
||||
/// </summary>
|
||||
/// <returns>An array of GridTopology objects</returns>
|
||||
public static GridTopology[] GetGridTopologies()
|
||||
{
|
||||
return MosaicApi.EnumDisplayGrids().Select(topology => new GridTopology(topology)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(GridTopology left, GridTopology right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(GridTopology left, GridTopology right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the requested grid topologies
|
||||
/// </summary>
|
||||
/// <param name="grids">An array of grid topologies to apply</param>
|
||||
/// <param name="flags">SetDisplayTopologyFlag flag</param>
|
||||
public static void SetGridTopologies(
|
||||
GridTopology[] grids,
|
||||
SetDisplayTopologyFlag flags = SetDisplayTopologyFlag.NoFlag)
|
||||
{
|
||||
var gridTopologyV2 = grids.Select(grid => grid.GetGridTopologyV2()).Cast<IGridTopology>().ToArray();
|
||||
|
||||
try
|
||||
{
|
||||
MosaicApi.SetDisplayGrids(gridTopologyV2, flags);
|
||||
}
|
||||
catch (NVIDIAApiException ex)
|
||||
{
|
||||
if (ex.Status != Status.IncompatibleStructureVersion)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (NVIDIANotSupportedException)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
var gridTopologyV1 = grids.Select(grid => grid.GetGridTopologyV1()).Cast<IGridTopology>().ToArray();
|
||||
MosaicApi.SetDisplayGrids(gridTopologyV1, flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates a list of grid topologies
|
||||
/// </summary>
|
||||
/// <param name="grids">An array of grid topologies to validate</param>
|
||||
/// <param name="flags">SetDisplayTopologyFlag flag</param>
|
||||
/// <returns>An array of DisplayTopologyStatus object containing the result of the validation</returns>
|
||||
public static DisplayTopologyStatus[] ValidateGridTopologies(
|
||||
GridTopology[] grids,
|
||||
SetDisplayTopologyFlag flags = SetDisplayTopologyFlag.AllowInvalid)
|
||||
{
|
||||
var gridTopologyV2 = grids.Select(grid => grid.GetGridTopologyV2()).Cast<IGridTopology>().ToArray();
|
||||
|
||||
try
|
||||
{
|
||||
return MosaicApi.ValidateDisplayGrids(gridTopologyV2, flags);
|
||||
}
|
||||
catch (NVIDIAApiException ex)
|
||||
{
|
||||
if (ex.Status != Status.IncompatibleStructureVersion)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (NVIDIANotSupportedException)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
var gridTopologyV1 = grids.Select(grid => grid.GetGridTopologyV1()).Cast<IGridTopology>().ToArray();
|
||||
|
||||
return MosaicApi.ValidateDisplayGrids(gridTopologyV1, flags);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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((GridTopology) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = Resolution.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ Frequency;
|
||||
hashCode = (hashCode * 397) ^ Rows;
|
||||
hashCode = (hashCode * 397) ^ Columns;
|
||||
hashCode = (hashCode * 397) ^ (Displays?.GetHashCode() ?? 0);
|
||||
hashCode = (hashCode * 397) ^ ApplyWithBezelCorrectedResolution.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ ImmersiveGaming.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ BaseMosaicPanoramic.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ AcceleratePrimaryDisplay.GetHashCode();
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a DisplaySettingsV1 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created DisplaySettingsV1 object</returns>
|
||||
public DisplaySettingsV1 GetDisplaySettingsV1()
|
||||
{
|
||||
return new DisplaySettingsV1(Resolution.Width, Resolution.Height, Resolution.ColorDepth, Frequency);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a GridTopologyV1 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created GridTopologyV1 object</returns>
|
||||
public GridTopologyV1 GetGridTopologyV1()
|
||||
{
|
||||
var displaySettings = GetDisplaySettingsV1();
|
||||
|
||||
return new GridTopologyV1(Rows, Columns,
|
||||
Displays.Select(display => display.GetGridTopologyDisplayV1()).ToArray(), displaySettings,
|
||||
ApplyWithBezelCorrectedResolution, ImmersiveGaming, BaseMosaicPanoramic, DriverReloadAllowed,
|
||||
AcceleratePrimaryDisplay);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a GridTopologyV2 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created GridTopologyV2 object</returns>
|
||||
public GridTopologyV2 GetGridTopologyV2()
|
||||
{
|
||||
var displaySettings = GetDisplaySettingsV1();
|
||||
|
||||
return new GridTopologyV2(Rows, Columns,
|
||||
Displays.Select(display => display.GetGridTopologyDisplayV2()).ToArray(), displaySettings,
|
||||
ApplyWithBezelCorrectedResolution, ImmersiveGaming, BaseMosaicPanoramic, DriverReloadAllowed,
|
||||
AcceleratePrimaryDisplay,
|
||||
Displays.Any(display => display.PixelShiftType != PixelShiftType.NoPixelShift));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a list of possible display settings for this topology
|
||||
/// </summary>
|
||||
/// <returns>An array of IDisplaySettings implamented objects</returns>
|
||||
public IDisplaySettings[] GetPossibleDisplaySettings()
|
||||
{
|
||||
var gridTopologyV2 = GetGridTopologyV2();
|
||||
|
||||
try
|
||||
{
|
||||
return MosaicApi.EnumDisplayModes(gridTopologyV2);
|
||||
}
|
||||
catch (NVIDIAApiException ex)
|
||||
{
|
||||
if (ex.Status != Status.IncompatibleStructureVersion)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (NVIDIANotSupportedException)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
var gridTopologyV1 = GetGridTopologyV1();
|
||||
|
||||
return MosaicApi.EnumDisplayModes(gridTopologyV1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes topology arrangement and displays
|
||||
/// </summary>
|
||||
/// <param name="rows">Mosaic rows</param>
|
||||
/// <param name="columns">Mosaic columns</param>
|
||||
/// <param name="displays">Topology displays</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Invalid display arrangement.</exception>
|
||||
/// <exception cref="ArgumentException">Number of displays should match the arrangement.</exception>
|
||||
public void SetDisplays(int rows, int columns, GridTopologyDisplay[] displays)
|
||||
{
|
||||
if (rows * columns <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException($"{nameof(rows)}, {nameof(columns)}",
|
||||
"Invalid display arrangement.");
|
||||
}
|
||||
|
||||
if (displays.Length != rows * columns)
|
||||
{
|
||||
throw new ArgumentException("Number of displays should match the arrangement.", nameof(displays));
|
||||
}
|
||||
|
||||
Rows = rows;
|
||||
Columns = columns;
|
||||
Displays = displays;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes display settings for the topology
|
||||
/// </summary>
|
||||
/// <param name="displaySettings">Display settings to use</param>
|
||||
public void SetDisplaySettings(IDisplaySettings displaySettings)
|
||||
{
|
||||
Resolution = new Resolution(displaySettings.Width, displaySettings.Height, displaySettings.BitsPerPixel);
|
||||
Frequency = displaySettings.Frequency;
|
||||
}
|
||||
}
|
||||
}
|
||||
192
app/NvAPIWrapper/Mosaic/GridTopologyDisplay.cs
Normal file
192
app/NvAPIWrapper/Mosaic/GridTopologyDisplay.cs
Normal file
@@ -0,0 +1,192 @@
|
||||
using System;
|
||||
using NvAPIWrapper.Display;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Interfaces.Mosaic;
|
||||
using NvAPIWrapper.Native.Mosaic;
|
||||
using NvAPIWrapper.Native.Mosaic.Structures;
|
||||
|
||||
namespace NvAPIWrapper.Mosaic
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a display in a mosaic grid topology
|
||||
/// </summary>
|
||||
public class GridTopologyDisplay : IEquatable<GridTopologyDisplay>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a mew GridTopologyDisplay
|
||||
/// </summary>
|
||||
/// <param name="displayId">Corresponding display identification</param>
|
||||
/// <param name="overlap">The overlap values</param>
|
||||
/// <param name="rotation">The display rotation</param>
|
||||
/// <param name="cloneGroup">The display clone group</param>
|
||||
/// <param name="pixelShiftType">The display pixel shift type</param>
|
||||
public GridTopologyDisplay(
|
||||
uint displayId,
|
||||
Overlap overlap = default(Overlap),
|
||||
Rotate rotation = Rotate.Degree0,
|
||||
uint cloneGroup = 0,
|
||||
PixelShiftType pixelShiftType = PixelShiftType.NoPixelShift)
|
||||
: this(new DisplayDevice(displayId), overlap, rotation, cloneGroup, pixelShiftType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a mew GridTopologyDisplay
|
||||
/// </summary>
|
||||
/// <param name="display">Corresponding display device</param>
|
||||
/// <param name="overlap">The overlap values</param>
|
||||
/// <param name="rotation">The display rotation</param>
|
||||
/// <param name="cloneGroup">The display clone group</param>
|
||||
/// <param name="pixelShiftType">The display pixel shift type</param>
|
||||
public GridTopologyDisplay(
|
||||
DisplayDevice display,
|
||||
Overlap overlap = default(Overlap),
|
||||
Rotate rotation = Rotate.Degree0,
|
||||
uint cloneGroup = 0,
|
||||
PixelShiftType pixelShiftType = PixelShiftType.NoPixelShift)
|
||||
{
|
||||
DisplayDevice = display;
|
||||
Overlap = overlap;
|
||||
Rotation = rotation;
|
||||
CloneGroup = cloneGroup;
|
||||
PixelShiftType = pixelShiftType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a mew GridTopologyDisplay
|
||||
/// </summary>
|
||||
/// <param name="gridTopologyDisplay">IGridTopologyDisplay implamented object</param>
|
||||
public GridTopologyDisplay(IGridTopologyDisplay gridTopologyDisplay)
|
||||
: this(
|
||||
new DisplayDevice(gridTopologyDisplay.DisplayId),
|
||||
new Overlap(gridTopologyDisplay.OverlapX, gridTopologyDisplay.OverlapY),
|
||||
gridTopologyDisplay.Rotation, gridTopologyDisplay.CloneGroup, gridTopologyDisplay.PixelShiftType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the clone group identification; Reserved, must be 0
|
||||
/// </summary>
|
||||
public uint CloneGroup { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the corresponding DisplayDevice
|
||||
/// </summary>
|
||||
public DisplayDevice DisplayDevice { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the overlap values
|
||||
/// </summary>
|
||||
public Overlap Overlap { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of display pixel shift
|
||||
/// </summary>
|
||||
public PixelShiftType PixelShiftType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the rotation of the display
|
||||
/// </summary>
|
||||
public Rotate Rotation { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(GridTopologyDisplay other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return DisplayDevice.Equals(other.DisplayDevice) &&
|
||||
Overlap.Equals(other.Overlap) &&
|
||||
Rotation == other.Rotation &&
|
||||
CloneGroup == other.CloneGroup &&
|
||||
PixelShiftType == other.PixelShiftType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(GridTopologyDisplay left, GridTopologyDisplay right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(GridTopologyDisplay left, GridTopologyDisplay right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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((GridTopologyDisplay) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = DisplayDevice?.GetHashCode() ?? 0;
|
||||
hashCode = (hashCode * 397) ^ Overlap.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (int) Rotation;
|
||||
hashCode = (hashCode * 397) ^ (int) CloneGroup;
|
||||
hashCode = (hashCode * 397) ^ (int) PixelShiftType;
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a GridTopologyDisplayV1 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created GridTopologyDisplayV1 object</returns>
|
||||
public GridTopologyDisplayV1 GetGridTopologyDisplayV1()
|
||||
{
|
||||
return new GridTopologyDisplayV1(DisplayDevice.DisplayId, Overlap.HorizontalOverlap,
|
||||
Overlap.VerticalOverlap,
|
||||
Rotation, CloneGroup);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a GridTopologyDisplayV2 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created GridTopologyDisplayV2 object</returns>
|
||||
public GridTopologyDisplayV2 GetGridTopologyDisplayV2()
|
||||
{
|
||||
return new GridTopologyDisplayV2(DisplayDevice.DisplayId, Overlap.HorizontalOverlap,
|
||||
Overlap.VerticalOverlap,
|
||||
Rotation, CloneGroup, PixelShiftType);
|
||||
}
|
||||
}
|
||||
}
|
||||
85
app/NvAPIWrapper/Mosaic/Overlap.cs
Normal file
85
app/NvAPIWrapper/Mosaic/Overlap.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
|
||||
namespace NvAPIWrapper.Mosaic
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds mosaic overlap values
|
||||
/// </summary>
|
||||
public struct Overlap : IEquatable<Overlap>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new Overlap
|
||||
/// </summary>
|
||||
/// <param name="overlapX">Horizontal overlap</param>
|
||||
/// <param name="overlapY">Vertical overlap</param>
|
||||
public Overlap(int overlapX, int overlapY)
|
||||
{
|
||||
HorizontalOverlap = overlapX;
|
||||
VerticalOverlap = overlapY;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets horizontal overlap (OverlapX)
|
||||
/// </summary>
|
||||
public int HorizontalOverlap { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets vertical overlap (OverlapY)
|
||||
/// </summary>
|
||||
public int VerticalOverlap { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(Overlap other)
|
||||
{
|
||||
return HorizontalOverlap == other.HorizontalOverlap && VerticalOverlap == other.VerticalOverlap;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return obj is Overlap && Equals((Overlap) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (HorizontalOverlap * 397) ^ VerticalOverlap;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(Overlap left, Overlap right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(Overlap left, Overlap right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"({HorizontalOverlap}, {VerticalOverlap})";
|
||||
}
|
||||
}
|
||||
}
|
||||
131
app/NvAPIWrapper/Mosaic/OverlapLimit.cs
Normal file
131
app/NvAPIWrapper/Mosaic/OverlapLimit.cs
Normal file
@@ -0,0 +1,131 @@
|
||||
using System;
|
||||
|
||||
namespace NvAPIWrapper.Mosaic
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds maximum and minimum possible values for overlaps
|
||||
/// </summary>
|
||||
public struct OverlapLimit : IEquatable<OverlapLimit>
|
||||
{
|
||||
internal OverlapLimit(int minOverlapX, int maxOverlapX, int minOverlapY, int maxOverlapY)
|
||||
{
|
||||
MinimumHorizontalOverlap = minOverlapX;
|
||||
MaximumHorizontalOverlap = maxOverlapX;
|
||||
MinimumVerticalOverlap = minOverlapY;
|
||||
MaximumVerticalOverlap = maxOverlapY;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minimum value for horizontal overlap (OverlapX) or maximum value of horizontal gap
|
||||
/// </summary>
|
||||
public int MinimumHorizontalOverlap { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximum value for horizontal overlap (OverlapX)
|
||||
/// </summary>
|
||||
public int MaximumHorizontalOverlap { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Minimum value for vertical overlap (OverlapY) or maximum value of vertical gap
|
||||
/// </summary>
|
||||
public int MinimumVerticalOverlap { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximum value for vertical overlap (OverlapY)
|
||||
/// </summary>
|
||||
public int MaximumVerticalOverlap { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(OverlapLimit other)
|
||||
{
|
||||
return MinimumHorizontalOverlap == other.MinimumHorizontalOverlap &&
|
||||
MaximumHorizontalOverlap == other.MaximumHorizontalOverlap &&
|
||||
MinimumVerticalOverlap == other.MinimumVerticalOverlap &&
|
||||
MaximumVerticalOverlap == other.MaximumVerticalOverlap;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return obj is OverlapLimit && Equals((OverlapLimit) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = MinimumHorizontalOverlap;
|
||||
hashCode = (hashCode * 397) ^ MaximumHorizontalOverlap;
|
||||
hashCode = (hashCode * 397) ^ MinimumVerticalOverlap;
|
||||
hashCode = (hashCode * 397) ^ MaximumVerticalOverlap;
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(OverlapLimit left, OverlapLimit right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(OverlapLimit left, OverlapLimit right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return
|
||||
$"[{MinimumHorizontalOverlap}, {MaximumHorizontalOverlap}], [{MinimumVerticalOverlap}, {MaximumVerticalOverlap}]";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the value falls in to the acceptable horizontal overlap range
|
||||
/// </summary>
|
||||
/// <param name="overlapX">The horizontal overlap value</param>
|
||||
/// <returns>true if the value falls into the range, otherwise false</returns>
|
||||
public bool IsInHorizontalRange(int overlapX)
|
||||
{
|
||||
return overlapX >= MinimumHorizontalOverlap && overlapX <= MaximumHorizontalOverlap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the value falls in to the acceptable vertical overlap range
|
||||
/// </summary>
|
||||
/// <param name="overlapY">The vertical overlap value</param>
|
||||
/// <returns>true if the value falls into the range, otherwise false</returns>
|
||||
public bool IsInVerticalRange(int overlapY)
|
||||
{
|
||||
return overlapY >= MinimumVerticalOverlap && overlapY <= MaximumVerticalOverlap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the overlap values fall in to the acceptable overlap ranges
|
||||
/// </summary>
|
||||
/// <param name="overlap">The overlap values</param>
|
||||
/// <returns>true if the values fall into the range, otherwise false</returns>
|
||||
public bool IsInRange(Overlap overlap)
|
||||
{
|
||||
return IsInHorizontalRange(overlap.HorizontalOverlap) && IsInVerticalRange(overlap.VerticalOverlap);
|
||||
}
|
||||
}
|
||||
}
|
||||
361
app/NvAPIWrapper/Mosaic/Topology.cs
Normal file
361
app/NvAPIWrapper/Mosaic/Topology.cs
Normal file
@@ -0,0 +1,361 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.Exceptions;
|
||||
using NvAPIWrapper.Native.General;
|
||||
using NvAPIWrapper.Native.Interfaces.Mosaic;
|
||||
using NvAPIWrapper.Native.Mosaic;
|
||||
using NvAPIWrapper.Native.Mosaic.Structures;
|
||||
|
||||
namespace NvAPIWrapper.Mosaic
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a mosaic topology
|
||||
/// </summary>
|
||||
[Obsolete("Using Mosaic API Phase 1, please consider using TopologyGrid class on newer drivers", false)]
|
||||
public class Topology : IEquatable<Topology>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new Topology
|
||||
/// </summary>
|
||||
/// <param name="resolution">Mosaic displays resolution</param>
|
||||
/// <param name="frequency">Mosaic displays frequency</param>
|
||||
/// <param name="topology">Topology arrangement</param>
|
||||
/// <param name="overlap">Mosaic overlap</param>
|
||||
public Topology(
|
||||
Resolution resolution,
|
||||
int frequency,
|
||||
Native.Mosaic.Topology topology,
|
||||
Overlap overlap)
|
||||
{
|
||||
Resolution = resolution;
|
||||
Frequency = frequency;
|
||||
FrequencyInMillihertz = (uint) (Frequency * 1000);
|
||||
TopologyMode = topology;
|
||||
Overlap = overlap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Topology
|
||||
/// </summary>
|
||||
/// <param name="resolution">>Mosaic displays resolution</param>
|
||||
/// <param name="frequency">Mosaic frequency</param>
|
||||
/// <param name="frequencyInMillihertz">Mosaic frequency x 1000</param>
|
||||
/// <param name="topology">Topology arrangement</param>
|
||||
/// <param name="overlap">Mosaic overlap</param>
|
||||
public Topology(
|
||||
Resolution resolution,
|
||||
int frequency,
|
||||
uint frequencyInMillihertz,
|
||||
Native.Mosaic.Topology topology,
|
||||
Overlap overlap)
|
||||
: this(resolution, frequency, topology, overlap)
|
||||
{
|
||||
FrequencyInMillihertz = frequencyInMillihertz;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mosaic displays frequency
|
||||
/// </summary>
|
||||
public int Frequency { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mosaic displays frequency x 1000 (Millihertz)
|
||||
/// </summary>
|
||||
public uint FrequencyInMillihertz { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the topology overlap
|
||||
/// </summary>
|
||||
public Overlap Overlap { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mosaic displays resolution
|
||||
/// </summary>
|
||||
public Resolution Resolution { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the topology arrangement
|
||||
/// </summary>
|
||||
public Native.Mosaic.Topology TopologyMode { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(Topology other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Resolution.Equals(other.Resolution) &&
|
||||
Frequency == other.Frequency &&
|
||||
FrequencyInMillihertz == other.FrequencyInMillihertz &&
|
||||
TopologyMode == other.TopologyMode &&
|
||||
Overlap.Equals(other.Overlap);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables the current topology
|
||||
/// </summary>
|
||||
public static void DisableCurrent()
|
||||
{
|
||||
MosaicApi.EnableCurrentTopology(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the current topology
|
||||
/// </summary>
|
||||
public static void EnableCurrent()
|
||||
{
|
||||
MosaicApi.EnableCurrentTopology(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current topology settings
|
||||
/// </summary>
|
||||
/// <returns>The current Topology object</returns>
|
||||
public static Topology GetCurrentTopology()
|
||||
{
|
||||
TopologyBrief brief;
|
||||
IDisplaySettings displaySettings;
|
||||
int overlapX;
|
||||
int overlapY;
|
||||
MosaicApi.GetCurrentTopology(out brief, out displaySettings, out overlapX, out overlapY);
|
||||
|
||||
return
|
||||
new Topology(
|
||||
new Resolution(displaySettings.Width, displaySettings.Height, displaySettings.BitsPerPixel),
|
||||
displaySettings.Frequency, displaySettings.FrequencyInMillihertz, brief.Topology,
|
||||
new Overlap(overlapX, overlapY));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves all the supported topology modes that are now possible to apply
|
||||
/// </summary>
|
||||
/// <param name="type">The type of the topology mode to limit quary</param>
|
||||
/// <returns>An array of Topology modes</returns>
|
||||
public static Native.Mosaic.Topology[] GetSupportedTopologyModes(TopologyType type = TopologyType.All)
|
||||
{
|
||||
return
|
||||
MosaicApi.GetSupportedTopologiesInfo(type)
|
||||
.TopologyBriefs.Where(topologyBrief => topologyBrief.IsPossible)
|
||||
.Select(topologyBrief => topologyBrief.Topology)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves all the supported display settings
|
||||
/// </summary>
|
||||
/// <param name="type">The type of the topology mode to limit quary</param>
|
||||
/// <returns>An array of IDisplaySettings implamented objects</returns>
|
||||
public static IDisplaySettings[] GetSupportedTopologySettings(TopologyType type = TopologyType.All)
|
||||
{
|
||||
return MosaicApi.GetSupportedTopologiesInfo(type).DisplaySettings.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the current topology is now active
|
||||
/// </summary>
|
||||
/// <returns>true if the current topology is now enable, otherwise false</returns>
|
||||
public static bool IsCurrentTopologyEnabled()
|
||||
{
|
||||
TopologyBrief brief;
|
||||
IDisplaySettings displaySettings;
|
||||
int overlapX;
|
||||
int overlapY;
|
||||
MosaicApi.GetCurrentTopology(out brief, out displaySettings, out overlapX, out overlapY);
|
||||
|
||||
return brief.IsEnable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the current topology is possible to apply
|
||||
/// </summary>
|
||||
/// <returns>true if the current topology is possible to apply, otherwise false</returns>
|
||||
public static bool IsCurrentTopologyPossible()
|
||||
{
|
||||
TopologyBrief brief;
|
||||
IDisplaySettings displaySettings;
|
||||
int overlapX;
|
||||
int overlapY;
|
||||
MosaicApi.GetCurrentTopology(out brief, out displaySettings, out overlapX, out overlapY);
|
||||
|
||||
return brief.IsPossible;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(Topology left, Topology right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(Topology left, Topology right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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((Topology) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = Resolution.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ Frequency;
|
||||
hashCode = (hashCode * 397) ^ (int) FrequencyInMillihertz;
|
||||
hashCode = (hashCode * 397) ^ (int) TopologyMode;
|
||||
hashCode = (hashCode * 397) ^ Overlap.GetHashCode();
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves topology details
|
||||
/// </summary>
|
||||
/// <returns>An array of TopologyDetails</returns>
|
||||
public TopologyDetails[] GetDetails()
|
||||
{
|
||||
var brief = GetTopologyBrief();
|
||||
|
||||
return
|
||||
MosaicApi.GetTopologyGroup(brief)
|
||||
.TopologyDetails.Select(detail => new TopologyDetails(detail))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a DisplaySettingsV1 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created DisplaySettingsV1 object</returns>
|
||||
public DisplaySettingsV1 GetDisplaySettingsV1()
|
||||
{
|
||||
return new DisplaySettingsV1(Resolution.Width, Resolution.Height, Resolution.ColorDepth, Frequency);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a DisplaySettingsV2 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created DisplaySettingsV2 object</returns>
|
||||
public DisplaySettingsV2 GetDisplaySettingsV2()
|
||||
{
|
||||
return new DisplaySettingsV2(Resolution.Width, Resolution.Height, Resolution.ColorDepth, Frequency,
|
||||
FrequencyInMillihertz);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the topology overlap limits
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public OverlapLimit GetOverlapLimits()
|
||||
{
|
||||
int minX;
|
||||
int maxX;
|
||||
int minY;
|
||||
int maxY;
|
||||
var brief = GetTopologyBrief();
|
||||
var displaySettingsV2 = GetDisplaySettingsV2();
|
||||
|
||||
try
|
||||
{
|
||||
MosaicApi.GetOverlapLimits(brief, displaySettingsV2, out minX, out maxX, out minY, out maxY);
|
||||
|
||||
return new OverlapLimit(minX, maxX, minY, maxY);
|
||||
}
|
||||
catch (NVIDIAApiException ex)
|
||||
{
|
||||
if (ex.Status != Status.IncompatibleStructureVersion)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (NVIDIANotSupportedException)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
var displaySettingsV1 = GetDisplaySettingsV1();
|
||||
MosaicApi.GetOverlapLimits(brief, displaySettingsV1, out minX, out maxX, out minY, out maxY);
|
||||
|
||||
return new OverlapLimit(minX, maxX, minY, maxY);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a TopologyBrief object
|
||||
/// </summary>
|
||||
/// <returns>The newly created TopologyBrief object</returns>
|
||||
public TopologyBrief GetTopologyBrief()
|
||||
{
|
||||
return new TopologyBrief(TopologyMode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets this topology as the current topology
|
||||
/// </summary>
|
||||
/// <param name="apply">if true, will apply the topology right now</param>
|
||||
public void SetAsCurrentTopology(bool apply = false)
|
||||
{
|
||||
var brief = GetTopologyBrief();
|
||||
var displaySettingsV2 = GetDisplaySettingsV2();
|
||||
|
||||
try
|
||||
{
|
||||
MosaicApi.SetCurrentTopology(brief, displaySettingsV2, Overlap.HorizontalOverlap,
|
||||
Overlap.VerticalOverlap, apply);
|
||||
}
|
||||
catch (NVIDIAApiException ex)
|
||||
{
|
||||
if (ex.Status != Status.IncompatibleStructureVersion)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (NVIDIANotSupportedException)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
var displaySettingsV1 = GetDisplaySettingsV1();
|
||||
MosaicApi.SetCurrentTopology(brief, displaySettingsV1, Overlap.HorizontalOverlap, Overlap.VerticalOverlap,
|
||||
apply);
|
||||
}
|
||||
}
|
||||
}
|
||||
124
app/NvAPIWrapper/Mosaic/TopologyDetails.cs
Normal file
124
app/NvAPIWrapper/Mosaic/TopologyDetails.cs
Normal file
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.GPU;
|
||||
using NvAPIWrapper.Native.Mosaic;
|
||||
|
||||
namespace NvAPIWrapper.Mosaic
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds extra information about a topology
|
||||
/// </summary>
|
||||
public class TopologyDetails : IEquatable<TopologyDetails>
|
||||
{
|
||||
internal TopologyDetails(Native.Mosaic.Structures.TopologyDetails details)
|
||||
{
|
||||
Rows = details.Rows;
|
||||
Columns = details.Columns;
|
||||
LogicalGPU = !details.LogicalGPUHandle.IsNull ? new LogicalGPU(details.LogicalGPUHandle) : null;
|
||||
ValidityFlags = details.ValidityFlags;
|
||||
Displays =
|
||||
details.Layout.Select(cells => cells.Select(cell => new TopologyDisplay(cell)).ToArray()).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of columns in the topology
|
||||
/// </summary>
|
||||
public int Columns { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of topology displays
|
||||
/// </summary>
|
||||
public TopologyDisplay[][] Displays { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the logical GPU in charge of controling the topology
|
||||
/// </summary>
|
||||
public LogicalGPU LogicalGPU { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of rows in the topology
|
||||
/// </summary>
|
||||
public int Rows { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the validity status of this topology
|
||||
/// </summary>
|
||||
public TopologyValidity ValidityFlags { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(TopologyDetails other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Rows == other.Rows &&
|
||||
Columns == other.Columns &&
|
||||
LogicalGPU.Equals(other.LogicalGPU) &&
|
||||
Displays.SequenceEqual(other.Displays);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(TopologyDetails left, TopologyDetails right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(TopologyDetails left, TopologyDetails right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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((TopologyDetails) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = Rows;
|
||||
hashCode = (hashCode * 397) ^ Columns;
|
||||
hashCode = (hashCode * 397) ^ (LogicalGPU != null ? LogicalGPU.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ (Displays?.GetHashCode() ?? 0);
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
107
app/NvAPIWrapper/Mosaic/TopologyDisplay.cs
Normal file
107
app/NvAPIWrapper/Mosaic/TopologyDisplay.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using NvAPIWrapper.GPU;
|
||||
|
||||
namespace NvAPIWrapper.Mosaic
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information about a display in a topology
|
||||
/// </summary>
|
||||
public class TopologyDisplay : IEquatable<TopologyDisplay>
|
||||
{
|
||||
internal TopologyDisplay(Native.Mosaic.Structures.TopologyDetails.LayoutCell layoutCell)
|
||||
{
|
||||
PhysicalGPU = !layoutCell.PhysicalGPUHandle.IsNull ? new PhysicalGPU(layoutCell.PhysicalGPUHandle) : null;
|
||||
Output = new GPUOutput(layoutCell.DisplayOutputId, PhysicalGPU);
|
||||
Overlap = new Overlap(layoutCell.OverlapX, layoutCell.OverlapY);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GPU output used for this display
|
||||
/// </summary>
|
||||
public GPUOutput Output { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display overlap values
|
||||
/// </summary>
|
||||
public Overlap Overlap { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the corresponding physical GPU of this display
|
||||
/// </summary>
|
||||
public PhysicalGPU PhysicalGPU { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(TopologyDisplay other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return PhysicalGPU.Equals(other.PhysicalGPU) &&
|
||||
Output.Equals(other.Output) &&
|
||||
Overlap.Equals(other.Overlap);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(TopologyDisplay left, TopologyDisplay right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(TopologyDisplay left, TopologyDisplay right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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((TopologyDisplay) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = PhysicalGPU != null ? PhysicalGPU.GetHashCode() : 0;
|
||||
hashCode = (hashCode * 397) ^ (Output != null ? Output.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ Overlap.GetHashCode();
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user