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 IDictionary Clocks { get { var clocks = (int) _NumberOfClocks; return PerformanceStates.ToDictionary( state20 => state20.StateId, state20 => state20._Clocks.Take(clocks).ToArray() ); } } /// IDictionary 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); } } } }