Hardware/Nvidia/NvidiaGPU.cs
author moel.mich
Sun, 23 Sep 2012 18:37:43 +0000
changeset 380 573f1fff48b2
parent 334 013e148e8f12
child 428 3c1cdc197b24
permissions -rw-r--r--
Fixed Issue 387. The new implementation does not try to start a ring 0 driver that already exists, but could not be opened. It tries to delete the driver and install it new. The driver is now stored temporarily in the application folder. The driver is not correctly removed on system shutdown.
moel@1
     1
/*
moel@1
     2
 
moel@344
     3
  This Source Code Form is subject to the terms of the Mozilla Public
moel@344
     4
  License, v. 2.0. If a copy of the MPL was not distributed with this
moel@344
     5
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
moel@344
     6
 
moel@344
     7
  Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
moel@344
     8
	Copyright (C) 2011 Christian Vallières
moel@1
     9
 
moel@1
    10
*/
moel@1
    11
moel@1
    12
using System;
moel@166
    13
using System.Globalization;
moel@140
    14
using System.Text;
moel@1
    15
moel@1
    16
namespace OpenHardwareMonitor.Hardware.Nvidia {
moel@195
    17
  internal class NvidiaGPU : Hardware {
moel@1
    18
moel@195
    19
    private readonly int adapterIndex;
moel@195
    20
    private readonly NvPhysicalGpuHandle handle;
moel@195
    21
    private readonly NvDisplayHandle? displayHandle;
moel@1
    22
moel@195
    23
    private readonly Sensor[] temperatures;
moel@195
    24
    private readonly Sensor fan;
moel@195
    25
    private readonly Sensor[] clocks;
moel@195
    26
    private readonly Sensor[] loads;
moel@195
    27
    private readonly Sensor control;
moel@195
    28
    private readonly Sensor memoryLoad;
moel@309
    29
    private readonly Control fanControl;
moel@38
    30
moel@309
    31
    private bool restoreDefaultFanSpeedRequired;
moel@309
    32
    private NvLevel initialFanSpeedValue;
moel@309
    33
moel@309
    34
    public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle,
moel@309
    35
      NvDisplayHandle? displayHandle, ISettings settings)
moel@309
    36
      : base(GetName(handle), new Identifier("nvidiagpu",
moel@309
    37
          adapterIndex.ToString(CultureInfo.InvariantCulture)), settings) {
moel@56
    38
      this.adapterIndex = adapterIndex;
moel@56
    39
      this.handle = handle;
moel@140
    40
      this.displayHandle = displayHandle;
moel@1
    41
moel@165
    42
      NvGPUThermalSettings thermalSettings = GetThermalSettings();
moel@165
    43
      temperatures = new Sensor[thermalSettings.Count];
moel@56
    44
      for (int i = 0; i < temperatures.Length; i++) {
moel@165
    45
        NvSensor sensor = thermalSettings.Sensor[i];
moel@56
    46
        string name;
moel@56
    47
        switch (sensor.Target) {
moel@56
    48
          case NvThermalTarget.BOARD: name = "GPU Board"; break;
moel@56
    49
          case NvThermalTarget.GPU: name = "GPU Core"; break;
moel@56
    50
          case NvThermalTarget.MEMORY: name = "GPU Memory"; break;
moel@56
    51
          case NvThermalTarget.POWER_SUPPLY: name = "GPU Power Supply"; break;
moel@56
    52
          case NvThermalTarget.UNKNOWN: name = "GPU Unknown"; break;
moel@56
    53
          default: name = "GPU"; break;
moel@38
    54
        }
moel@165
    55
        temperatures[i] = new Sensor(name, i, SensorType.Temperature, this,
moel@165
    56
          new ParameterDescription[0], settings);
moel@56
    57
        ActivateSensor(temperatures[i]);
moel@56
    58
      }
moel@1
    59
moel@56
    60
      int value;
moel@56
    61
      if (NVAPI.NvAPI_GPU_GetTachReading != null &&
moel@56
    62
        NVAPI.NvAPI_GPU_GetTachReading(handle, out value) == NvStatus.OK) {
moel@56
    63
        if (value > 0) {
moel@165
    64
          fan = new Sensor("GPU", 0, SensorType.Fan, this, settings);
moel@56
    65
          ActivateSensor(fan);
moel@1
    66
        }
moel@1
    67
      }
moel@140
    68
moel@140
    69
      clocks = new Sensor[3];
moel@165
    70
      clocks[0] = new Sensor("GPU Core", 0, SensorType.Clock, this, settings);
moel@165
    71
      clocks[1] = new Sensor("GPU Memory", 1, SensorType.Clock, this, settings);
moel@165
    72
      clocks[2] = new Sensor("GPU Shader", 2, SensorType.Clock, this, settings);
moel@140
    73
      for (int i = 0; i < clocks.Length; i++)
moel@140
    74
        ActivateSensor(clocks[i]);
moel@140
    75
moel@140
    76
      loads = new Sensor[3];
moel@165
    77
      loads[0] = new Sensor("GPU Core", 0, SensorType.Load, this, settings);
moel@165
    78
      loads[1] = new Sensor("GPU Memory Controller", 1, SensorType.Load, this, settings);
moel@165
    79
      loads[2] = new Sensor("GPU Video Engine", 2, SensorType.Load, this, settings);
moel@165
    80
      memoryLoad = new Sensor("GPU Memory", 3, SensorType.Load, this, settings);
moel@140
    81
moel@165
    82
      control = new Sensor("GPU Fan", 0, SensorType.Control, this, settings);
moel@309
    83
moel@309
    84
      NvGPUCoolerSettings coolerSettings = GetCoolerSettings();
moel@309
    85
      if (coolerSettings.Count > 0) {
moel@309
    86
        fanControl = new Control(control, settings,
moel@309
    87
          coolerSettings.Cooler[0].DefaultMin, 
moel@309
    88
          coolerSettings.Cooler[0].DefaultMax);
moel@309
    89
        fanControl.ControlModeChanged += ControlModeChanged;
moel@309
    90
        fanControl.SoftwareControlValueChanged += SoftwareControlValueChanged;
moel@309
    91
        ControlModeChanged(fanControl);
moel@309
    92
        control.Control = fanControl;
moel@309
    93
      }
moel@309
    94
      Update();
moel@1
    95
    }
moel@1
    96
moel@275
    97
    private static string GetName(NvPhysicalGpuHandle handle) {
moel@275
    98
      string gpuName;
moel@275
    99
      if (NVAPI.NvAPI_GPU_GetFullName(handle, out gpuName) == NvStatus.OK) {
moel@275
   100
        return "NVIDIA " + gpuName.Trim();
moel@275
   101
      } else {
moel@275
   102
        return "NVIDIA";
moel@166
   103
      }
moel@1
   104
    }
moel@1
   105
moel@165
   106
    public override HardwareType HardwareType {
moel@176
   107
      get { return HardwareType.GpuNvidia; }
moel@1
   108
    }
moel@1
   109
moel@1
   110
    private NvGPUThermalSettings GetThermalSettings() {
moel@1
   111
      NvGPUThermalSettings settings = new NvGPUThermalSettings();
moel@1
   112
      settings.Version = NVAPI.GPU_THERMAL_SETTINGS_VER;
moel@1
   113
      settings.Count = NVAPI.MAX_THERMAL_SENSORS_PER_GPU;
moel@1
   114
      settings.Sensor = new NvSensor[NVAPI.MAX_THERMAL_SENSORS_PER_GPU];
moel@309
   115
      if (!(NVAPI.NvAPI_GPU_GetThermalSettings != null &&
moel@140
   116
        NVAPI.NvAPI_GPU_GetThermalSettings(handle, (int)NvThermalTarget.ALL,
moel@309
   117
          ref settings) == NvStatus.OK)) 
moel@309
   118
      {
moel@309
   119
        settings.Count = 0;
moel@309
   120
      }       
moel@309
   121
      return settings;    
moel@309
   122
    }
moel@309
   123
moel@309
   124
    private NvGPUCoolerSettings GetCoolerSettings() {
moel@309
   125
      NvGPUCoolerSettings settings = new NvGPUCoolerSettings();
moel@309
   126
      settings.Version = NVAPI.GPU_COOLER_SETTINGS_VER;
moel@309
   127
      settings.Cooler = new NvCooler[NVAPI.MAX_COOLER_PER_GPU];
moel@309
   128
      if (!(NVAPI.NvAPI_GPU_GetCoolerSettings != null &&
moel@309
   129
        NVAPI.NvAPI_GPU_GetCoolerSettings(handle, 0, 
moel@309
   130
          ref settings) == NvStatus.OK)) 
moel@309
   131
      {
moel@309
   132
        settings.Count = 0;
moel@38
   133
      }
moel@309
   134
      return settings;  
moel@1
   135
    }
moel@1
   136
moel@140
   137
    private uint[] GetClocks() {
moel@166
   138
      NvClocks allClocks = new NvClocks();
moel@166
   139
      allClocks.Version = NVAPI.GPU_CLOCKS_VER;
moel@166
   140
      allClocks.Clock = new uint[NVAPI.MAX_CLOCKS_PER_GPU];
moel@140
   141
      if (NVAPI.NvAPI_GPU_GetAllClocks != null &&
moel@166
   142
        NVAPI.NvAPI_GPU_GetAllClocks(handle, ref allClocks) == NvStatus.OK) {
moel@166
   143
        return allClocks.Clock;
moel@140
   144
      }
moel@140
   145
      return null;
moel@140
   146
    }
moel@140
   147
moel@110
   148
    public override void Update() {
moel@1
   149
      NvGPUThermalSettings settings = GetThermalSettings();
moel@309
   150
      foreach (Sensor sensor in temperatures)
moel@38
   151
        sensor.Value = settings.Sensor[sensor.Index].CurrentTemp;
moel@38
   152
moel@38
   153
      if (fan != null) {
moel@38
   154
        int value = 0;
moel@38
   155
        NVAPI.NvAPI_GPU_GetTachReading(handle, out value);
moel@38
   156
        fan.Value = value;
moel@38
   157
      }
moel@140
   158
moel@140
   159
      uint[] values = GetClocks();
moel@140
   160
      if (values != null) {
moel@140
   161
        clocks[0].Value = 0.001f * values[0];
moel@140
   162
        clocks[1].Value = 0.001f * values[8];
moel@140
   163
        clocks[2].Value = 0.001f * values[14];
moel@140
   164
        if (values[30] != 0) {
moel@140
   165
          clocks[0].Value = 0.0005f * values[30];
moel@140
   166
          clocks[2].Value = 0.001f * values[30];
moel@140
   167
        }
moel@140
   168
      }
moel@140
   169
moel@140
   170
      NvPStates states = new NvPStates();
moel@140
   171
      states.Version = NVAPI.GPU_PSTATES_VER;
moel@140
   172
      states.PStates = new NvPState[NVAPI.MAX_PSTATES_PER_GPU];
moel@309
   173
      if (NVAPI.NvAPI_GPU_GetPStates != null &&
moel@140
   174
        NVAPI.NvAPI_GPU_GetPStates(handle, ref states) == NvStatus.OK) {
moel@140
   175
        for (int i = 0; i < 3; i++)
moel@140
   176
          if (states.PStates[i].Present) {
moel@140
   177
            loads[i].Value = states.PStates[i].Percentage;
moel@140
   178
            ActivateSensor(loads[i]);
moel@140
   179
          }
moel@140
   180
      } else {
moel@140
   181
        NvUsages usages = new NvUsages();
moel@140
   182
        usages.Version = NVAPI.GPU_USAGES_VER;
moel@140
   183
        usages.Usage = new uint[NVAPI.MAX_USAGES_PER_GPU];
moel@140
   184
        if (NVAPI.NvAPI_GPU_GetUsages != null &&
moel@140
   185
          NVAPI.NvAPI_GPU_GetUsages(handle, ref usages) == NvStatus.OK) {
moel@140
   186
          loads[0].Value = usages.Usage[2];
moel@140
   187
          loads[1].Value = usages.Usage[6];
moel@140
   188
          loads[2].Value = usages.Usage[10];
moel@140
   189
          for (int i = 0; i < 3; i++)
moel@140
   190
            ActivateSensor(loads[i]);
moel@140
   191
        }
moel@140
   192
      }
moel@140
   193
moel@309
   194
moel@309
   195
      NvGPUCoolerSettings coolerSettings = GetCoolerSettings();
moel@309
   196
      if (coolerSettings.Count > 0) {
moel@140
   197
        control.Value = coolerSettings.Cooler[0].CurrentLevel;
moel@140
   198
        ActivateSensor(control);
moel@140
   199
      }
moel@140
   200
moel@140
   201
      NvMemoryInfo memoryInfo = new NvMemoryInfo();
moel@140
   202
      memoryInfo.Version = NVAPI.GPU_MEMORY_INFO_VER;
moel@140
   203
      memoryInfo.Values = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU];
moel@140
   204
      if (NVAPI.NvAPI_GPU_GetMemoryInfo != null && displayHandle.HasValue &&
moel@309
   205
        NVAPI.NvAPI_GPU_GetMemoryInfo(displayHandle.Value, ref memoryInfo) ==
moel@309
   206
        NvStatus.OK) {
moel@140
   207
        uint totalMemory = memoryInfo.Values[0];
moel@140
   208
        uint freeMemory = memoryInfo.Values[4];
moel@140
   209
        float usedMemory = Math.Max(totalMemory - freeMemory, 0);
moel@140
   210
        memoryLoad.Value = 100f * usedMemory / totalMemory;
moel@140
   211
        ActivateSensor(memoryLoad);
moel@140
   212
      }
moel@140
   213
    }
moel@140
   214
moel@140
   215
    public override string GetReport() {
moel@140
   216
      StringBuilder r = new StringBuilder();
moel@140
   217
moel@140
   218
      r.AppendLine("Nvidia GPU");
moel@140
   219
      r.AppendLine();
moel@140
   220
moel@140
   221
      r.AppendFormat("Name: {0}{1}", name, Environment.NewLine);
moel@140
   222
      r.AppendFormat("Index: {0}{1}", adapterIndex, Environment.NewLine);
moel@309
   223
moel@309
   224
      if (displayHandle.HasValue && NVAPI.NvAPI_GetDisplayDriverVersion != null) {
moel@140
   225
        NvDisplayDriverVersion driverVersion = new NvDisplayDriverVersion();
moel@140
   226
        driverVersion.Version = NVAPI.DISPLAY_DRIVER_VERSION_VER;
moel@140
   227
        if (NVAPI.NvAPI_GetDisplayDriverVersion(displayHandle.Value,
moel@140
   228
          ref driverVersion) == NvStatus.OK) {
moel@140
   229
          r.Append("Driver Version: ");
moel@140
   230
          r.Append(driverVersion.DriverVersion / 100);
moel@140
   231
          r.Append(".");
moel@309
   232
          r.Append((driverVersion.DriverVersion % 100).ToString("00",
moel@167
   233
            CultureInfo.InvariantCulture));
moel@140
   234
          r.AppendLine();
moel@140
   235
          r.Append("Driver Branch: ");
moel@140
   236
          r.AppendLine(driverVersion.BuildBranch);
moel@140
   237
        }
moel@140
   238
      }
moel@140
   239
      r.AppendLine();
moel@140
   240
moel@334
   241
      if (NVAPI.NvAPI_GPU_GetPCIIdentifiers != null) {
moel@334
   242
        uint deviceId, subSystemId, revisionId, extDeviceId;
moel@334
   243
moel@334
   244
        NvStatus status = NVAPI.NvAPI_GPU_GetPCIIdentifiers(handle, 
moel@334
   245
          out deviceId, out subSystemId, out revisionId, out extDeviceId);
moel@334
   246
moel@334
   247
        if (status == NvStatus.OK) {
moel@334
   248
          r.Append("DeviceID: 0x");
moel@334
   249
          r.AppendLine(deviceId.ToString("X", CultureInfo.InvariantCulture));
moel@334
   250
          r.Append("SubSystemID: 0x");
moel@334
   251
          r.AppendLine(subSystemId.ToString("X", CultureInfo.InvariantCulture));
moel@334
   252
          r.Append("RevisionID: 0x");
moel@334
   253
          r.AppendLine(revisionId.ToString("X", CultureInfo.InvariantCulture));
moel@334
   254
          r.Append("ExtDeviceID: 0x");
moel@334
   255
          r.AppendLine(extDeviceId.ToString("X", CultureInfo.InvariantCulture));
moel@334
   256
          r.AppendLine();
moel@334
   257
        }
moel@334
   258
      }
moel@334
   259
moel@140
   260
      if (NVAPI.NvAPI_GPU_GetThermalSettings != null) {
moel@140
   261
        NvGPUThermalSettings settings = new NvGPUThermalSettings();
moel@140
   262
        settings.Version = NVAPI.GPU_THERMAL_SETTINGS_VER;
moel@140
   263
        settings.Count = NVAPI.MAX_THERMAL_SENSORS_PER_GPU;
moel@140
   264
        settings.Sensor = new NvSensor[NVAPI.MAX_THERMAL_SENSORS_PER_GPU];
moel@140
   265
moel@140
   266
        NvStatus status = NVAPI.NvAPI_GPU_GetThermalSettings(handle,
moel@140
   267
          (int)NvThermalTarget.ALL, ref settings);
moel@140
   268
moel@140
   269
        r.AppendLine("Thermal Settings");
moel@140
   270
        r.AppendLine();
moel@140
   271
        if (status == NvStatus.OK) {
moel@140
   272
          for (int i = 0; i < settings.Count; i++) {
moel@140
   273
            r.AppendFormat(" Sensor[{0}].Controller: {1}{2}", i,
moel@140
   274
              settings.Sensor[i].Controller, Environment.NewLine);
moel@140
   275
            r.AppendFormat(" Sensor[{0}].DefaultMinTemp: {1}{2}", i,
moel@140
   276
              settings.Sensor[i].DefaultMinTemp, Environment.NewLine);
moel@140
   277
            r.AppendFormat(" Sensor[{0}].DefaultMaxTemp: {1}{2}", i,
moel@140
   278
              settings.Sensor[i].DefaultMaxTemp, Environment.NewLine);
moel@140
   279
            r.AppendFormat(" Sensor[{0}].CurrentTemp: {1}{2}", i,
moel@140
   280
              settings.Sensor[i].CurrentTemp, Environment.NewLine);
moel@140
   281
            r.AppendFormat(" Sensor[{0}].Target: {1}{2}", i,
moel@140
   282
              settings.Sensor[i].Target, Environment.NewLine);
moel@140
   283
          }
moel@140
   284
        } else {
moel@140
   285
          r.Append(" Status: ");
moel@140
   286
          r.AppendLine(status.ToString());
moel@140
   287
        }
moel@140
   288
        r.AppendLine();
moel@309
   289
      }
moel@140
   290
moel@140
   291
      if (NVAPI.NvAPI_GPU_GetAllClocks != null) {
moel@166
   292
        NvClocks allClocks = new NvClocks();
moel@166
   293
        allClocks.Version = NVAPI.GPU_CLOCKS_VER;
moel@166
   294
        allClocks.Clock = new uint[NVAPI.MAX_CLOCKS_PER_GPU];
moel@166
   295
        NvStatus status = NVAPI.NvAPI_GPU_GetAllClocks(handle, ref allClocks);
moel@140
   296
moel@140
   297
        r.AppendLine("Clocks");
moel@140
   298
        r.AppendLine();
moel@140
   299
        if (status == NvStatus.OK) {
moel@166
   300
          for (int i = 0; i < allClocks.Clock.Length; i++)
moel@166
   301
            if (allClocks.Clock[i] > 0) {
moel@166
   302
              r.AppendFormat(" Clock[{0}]: {1}{2}", i, allClocks.Clock[i],
moel@140
   303
                Environment.NewLine);
moel@140
   304
            }
moel@140
   305
        } else {
moel@140
   306
          r.Append(" Status: ");
moel@140
   307
          r.AppendLine(status.ToString());
moel@140
   308
        }
moel@140
   309
        r.AppendLine();
moel@309
   310
      }
moel@309
   311
moel@140
   312
      if (NVAPI.NvAPI_GPU_GetTachReading != null) {
moel@309
   313
        int tachValue;
moel@140
   314
        NvStatus status = NVAPI.NvAPI_GPU_GetTachReading(handle, out tachValue);
moel@140
   315
moel@140
   316
        r.AppendLine("Tachometer");
moel@140
   317
        r.AppendLine();
moel@140
   318
        if (status == NvStatus.OK) {
moel@140
   319
          r.AppendFormat(" Value: {0}{1}", tachValue, Environment.NewLine);
moel@140
   320
        } else {
moel@140
   321
          r.Append(" Status: ");
moel@140
   322
          r.AppendLine(status.ToString());
moel@140
   323
        }
moel@140
   324
        r.AppendLine();
moel@140
   325
      }
moel@140
   326
moel@140
   327
      if (NVAPI.NvAPI_GPU_GetPStates != null) {
moel@140
   328
        NvPStates states = new NvPStates();
moel@140
   329
        states.Version = NVAPI.GPU_PSTATES_VER;
moel@140
   330
        states.PStates = new NvPState[NVAPI.MAX_PSTATES_PER_GPU];
moel@140
   331
        NvStatus status = NVAPI.NvAPI_GPU_GetPStates(handle, ref states);
moel@140
   332
moel@140
   333
        r.AppendLine("P-States");
moel@140
   334
        r.AppendLine();
moel@140
   335
        if (status == NvStatus.OK) {
moel@140
   336
          for (int i = 0; i < states.PStates.Length; i++)
moel@140
   337
            if (states.PStates[i].Present)
moel@140
   338
              r.AppendFormat(" Percentage[{0}]: {1}{2}", i,
moel@140
   339
                states.PStates[i].Percentage, Environment.NewLine);
moel@140
   340
        } else {
moel@140
   341
          r.Append(" Status: ");
moel@140
   342
          r.AppendLine(status.ToString());
moel@140
   343
        }
moel@140
   344
        r.AppendLine();
moel@140
   345
      }
moel@140
   346
moel@140
   347
      if (NVAPI.NvAPI_GPU_GetUsages != null) {
moel@140
   348
        NvUsages usages = new NvUsages();
moel@140
   349
        usages.Version = NVAPI.GPU_USAGES_VER;
moel@140
   350
        usages.Usage = new uint[NVAPI.MAX_USAGES_PER_GPU];
moel@140
   351
        NvStatus status = NVAPI.NvAPI_GPU_GetUsages(handle, ref usages);
moel@309
   352
moel@140
   353
        r.AppendLine("Usages");
moel@140
   354
        r.AppendLine();
moel@140
   355
        if (status == NvStatus.OK) {
moel@140
   356
          for (int i = 0; i < usages.Usage.Length; i++)
moel@140
   357
            if (usages.Usage[i] > 0)
moel@140
   358
              r.AppendFormat(" Usage[{0}]: {1}{2}", i,
moel@140
   359
                usages.Usage[i], Environment.NewLine);
moel@140
   360
        } else {
moel@140
   361
          r.Append(" Status: ");
moel@140
   362
          r.AppendLine(status.ToString());
moel@140
   363
        }
moel@140
   364
        r.AppendLine();
moel@140
   365
      }
moel@140
   366
moel@140
   367
      if (NVAPI.NvAPI_GPU_GetCoolerSettings != null) {
moel@140
   368
        NvGPUCoolerSettings settings = new NvGPUCoolerSettings();
moel@140
   369
        settings.Version = NVAPI.GPU_COOLER_SETTINGS_VER;
moel@140
   370
        settings.Cooler = new NvCooler[NVAPI.MAX_COOLER_PER_GPU];
moel@140
   371
        NvStatus status =
moel@140
   372
          NVAPI.NvAPI_GPU_GetCoolerSettings(handle, 0, ref settings);
moel@140
   373
moel@140
   374
        r.AppendLine("Cooler Settings");
moel@140
   375
        r.AppendLine();
moel@140
   376
        if (status == NvStatus.OK) {
moel@140
   377
          for (int i = 0; i < settings.Count; i++) {
moel@140
   378
            r.AppendFormat(" Cooler[{0}].Type: {1}{2}", i,
moel@140
   379
              settings.Cooler[i].Type, Environment.NewLine);
moel@140
   380
            r.AppendFormat(" Cooler[{0}].Controller: {1}{2}", i,
moel@140
   381
              settings.Cooler[i].Controller, Environment.NewLine);
moel@140
   382
            r.AppendFormat(" Cooler[{0}].DefaultMin: {1}{2}", i,
moel@140
   383
              settings.Cooler[i].DefaultMin, Environment.NewLine);
moel@140
   384
            r.AppendFormat(" Cooler[{0}].DefaultMax: {1}{2}", i,
moel@140
   385
              settings.Cooler[i].DefaultMax, Environment.NewLine);
moel@140
   386
            r.AppendFormat(" Cooler[{0}].CurrentMin: {1}{2}", i,
moel@140
   387
              settings.Cooler[i].CurrentMin, Environment.NewLine);
moel@140
   388
            r.AppendFormat(" Cooler[{0}].CurrentMax: {1}{2}", i,
moel@140
   389
              settings.Cooler[i].CurrentMax, Environment.NewLine);
moel@140
   390
            r.AppendFormat(" Cooler[{0}].CurrentLevel: {1}{2}", i,
moel@140
   391
              settings.Cooler[i].CurrentLevel, Environment.NewLine);
moel@140
   392
            r.AppendFormat(" Cooler[{0}].DefaultPolicy: {1}{2}", i,
moel@140
   393
              settings.Cooler[i].DefaultPolicy, Environment.NewLine);
moel@140
   394
            r.AppendFormat(" Cooler[{0}].CurrentPolicy: {1}{2}", i,
moel@140
   395
              settings.Cooler[i].CurrentPolicy, Environment.NewLine);
moel@140
   396
            r.AppendFormat(" Cooler[{0}].Target: {1}{2}", i,
moel@140
   397
              settings.Cooler[i].Target, Environment.NewLine);
moel@140
   398
            r.AppendFormat(" Cooler[{0}].ControlType: {1}{2}", i,
moel@140
   399
              settings.Cooler[i].ControlType, Environment.NewLine);
moel@140
   400
            r.AppendFormat(" Cooler[{0}].Active: {1}{2}", i,
moel@140
   401
              settings.Cooler[i].Active, Environment.NewLine);
moel@140
   402
          }
moel@140
   403
        } else {
moel@140
   404
          r.Append(" Status: ");
moel@140
   405
          r.AppendLine(status.ToString());
moel@140
   406
        }
moel@140
   407
        r.AppendLine();
moel@140
   408
      }
moel@140
   409
moel@140
   410
      if (NVAPI.NvAPI_GPU_GetMemoryInfo != null && displayHandle.HasValue) {
moel@140
   411
        NvMemoryInfo memoryInfo = new NvMemoryInfo();
moel@140
   412
        memoryInfo.Version = NVAPI.GPU_MEMORY_INFO_VER;
moel@140
   413
        memoryInfo.Values = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU];
moel@309
   414
        NvStatus status = NVAPI.NvAPI_GPU_GetMemoryInfo(displayHandle.Value,
moel@140
   415
          ref memoryInfo);
moel@140
   416
moel@140
   417
        r.AppendLine("Memory Info");
moel@140
   418
        r.AppendLine();
moel@140
   419
        if (status == NvStatus.OK) {
moel@140
   420
          for (int i = 0; i < memoryInfo.Values.Length; i++)
moel@140
   421
            r.AppendFormat(" Value[{0}]: {1}{2}", i,
moel@140
   422
                memoryInfo.Values[i], Environment.NewLine);
moel@140
   423
        } else {
moel@140
   424
          r.Append(" Status: ");
moel@140
   425
          r.AppendLine(status.ToString());
moel@140
   426
        }
moel@140
   427
        r.AppendLine();
moel@140
   428
      }
moel@140
   429
moel@140
   430
      return r.ToString();
moel@1
   431
    }
moel@309
   432
moel@309
   433
    private void SoftwareControlValueChanged(IControl control) {
moel@309
   434
      SaveDefaultFanSpeed();
moel@309
   435
      NvGPUCoolerLevels coolerLevels = new NvGPUCoolerLevels();
moel@309
   436
      coolerLevels.Version = NVAPI.GPU_COOLER_LEVELS_VER;
moel@309
   437
      coolerLevels.Levels = new NvLevel[NVAPI.MAX_COOLER_PER_GPU];
moel@309
   438
      coolerLevels.Levels[0].Level = (int)control.SoftwareValue;
moel@309
   439
      coolerLevels.Levels[0].Policy = 1;
moel@309
   440
      NVAPI.NvAPI_GPU_SetCoolerLevels(handle, 0, ref coolerLevels);
moel@309
   441
    }
moel@309
   442
moel@309
   443
    private void SaveDefaultFanSpeed() {
moel@309
   444
      if (!restoreDefaultFanSpeedRequired) {
moel@309
   445
        NvGPUCoolerSettings coolerSettings = GetCoolerSettings();
moel@309
   446
        if (coolerSettings.Count > 0) {
moel@309
   447
          restoreDefaultFanSpeedRequired = true;
moel@309
   448
          initialFanSpeedValue.Level = coolerSettings.Cooler[0].CurrentLevel;
moel@309
   449
          initialFanSpeedValue.Policy = coolerSettings.Cooler[0].CurrentPolicy;
moel@309
   450
        }
moel@309
   451
      }
moel@309
   452
    }
moel@309
   453
moel@309
   454
    private void ControlModeChanged(IControl control) {
moel@309
   455
      if (control.ControlMode == ControlMode.Default) {
moel@309
   456
        RestoreDefaultFanSpeed();
moel@309
   457
      } else {
moel@309
   458
        SoftwareControlValueChanged(control);
moel@309
   459
      }
moel@309
   460
    }
moel@309
   461
moel@309
   462
    private void RestoreDefaultFanSpeed() {
moel@309
   463
      if (restoreDefaultFanSpeedRequired) {
moel@309
   464
        NvGPUCoolerLevels coolerLevels = new NvGPUCoolerLevels();
moel@309
   465
        coolerLevels.Version = NVAPI.GPU_COOLER_LEVELS_VER;
moel@309
   466
        coolerLevels.Levels = new NvLevel[NVAPI.MAX_COOLER_PER_GPU];
moel@309
   467
        coolerLevels.Levels[0] = initialFanSpeedValue;
moel@309
   468
        NVAPI.NvAPI_GPU_SetCoolerLevels(handle, 0, ref coolerLevels);
moel@309
   469
        restoreDefaultFanSpeedRequired = false;
moel@309
   470
      }
moel@309
   471
    }
moel@1
   472
  }
moel@1
   473
}