Hardware/Nvidia/NvidiaGPU.cs
author moel.mich
Thu, 11 Nov 2010 21:22:24 +0000
changeset 241 52007c404f32
parent 182 4801e9eaf979
child 275 35788ddd1825
permissions -rw-r--r--
Fixed a problem, where the MainForm location and size was lost when the application is started minimized and exited without ever showing the form. This caused MainForm_Load to be never called (location and size was not loaded), but the default size and location were still saved. The new implementation only saves the location and size when one of the two is changed.
moel@1
     1
/*
moel@1
     2
  
moel@1
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@1
     4
moel@1
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@1
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@1
     7
  the License. You may obtain a copy of the License at
moel@1
     8
 
moel@1
     9
  http://www.mozilla.org/MPL/
moel@1
    10
moel@1
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@1
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@1
    13
  for the specific language governing rights and limitations under the License.
moel@1
    14
moel@1
    15
  The Original Code is the Open Hardware Monitor code.
moel@1
    16
moel@1
    17
  The Initial Developer of the Original Code is 
moel@1
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@1
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2010
moel@1
    20
  the Initial Developer. All Rights Reserved.
moel@1
    21
moel@1
    22
  Contributor(s):
moel@1
    23
moel@1
    24
  Alternatively, the contents of this file may be used under the terms of
moel@1
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@1
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@1
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@1
    28
  of those above. If you wish to allow use of your version of this file only
moel@1
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@1
    30
  use your version of this file under the terms of the MPL, indicate your
moel@1
    31
  decision by deleting the provisions above and replace them with the notice
moel@1
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@1
    33
  the provisions above, a recipient may use your version of this file under
moel@1
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@1
    35
 
moel@1
    36
*/
moel@1
    37
moel@1
    38
using System;
moel@166
    39
using System.Globalization;
moel@140
    40
using System.Text;
moel@1
    41
moel@1
    42
namespace OpenHardwareMonitor.Hardware.Nvidia {
moel@195
    43
  internal class NvidiaGPU : Hardware {
moel@1
    44
moel@195
    45
    private readonly string name;
moel@195
    46
    private readonly int adapterIndex;
moel@195
    47
    private readonly NvPhysicalGpuHandle handle;
moel@195
    48
    private readonly NvDisplayHandle? displayHandle;
moel@1
    49
moel@195
    50
    private readonly Sensor[] temperatures;
moel@195
    51
    private readonly Sensor fan;
moel@195
    52
    private readonly Sensor[] clocks;
moel@195
    53
    private readonly Sensor[] loads;
moel@195
    54
    private readonly Sensor control;
moel@195
    55
    private readonly Sensor memoryLoad;
moel@38
    56
moel@140
    57
    public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle, 
moel@165
    58
      NvDisplayHandle? displayHandle, ISettings settings) 
moel@140
    59
    {
moel@56
    60
      string gpuName;
moel@56
    61
      if (NVAPI.NvAPI_GPU_GetFullName(handle, out gpuName) == NvStatus.OK) {
moel@56
    62
        this.name = "NVIDIA " + gpuName.Trim();
moel@56
    63
      } else {
moel@56
    64
        this.name = "NVIDIA";
moel@56
    65
      }
moel@56
    66
      this.adapterIndex = adapterIndex;
moel@56
    67
      this.handle = handle;
moel@140
    68
      this.displayHandle = displayHandle;
moel@1
    69
moel@165
    70
      NvGPUThermalSettings thermalSettings = GetThermalSettings();
moel@165
    71
      temperatures = new Sensor[thermalSettings.Count];
moel@56
    72
      for (int i = 0; i < temperatures.Length; i++) {
moel@165
    73
        NvSensor sensor = thermalSettings.Sensor[i];
moel@56
    74
        string name;
moel@56
    75
        switch (sensor.Target) {
moel@56
    76
          case NvThermalTarget.BOARD: name = "GPU Board"; break;
moel@56
    77
          case NvThermalTarget.GPU: name = "GPU Core"; break;
moel@56
    78
          case NvThermalTarget.MEMORY: name = "GPU Memory"; break;
moel@56
    79
          case NvThermalTarget.POWER_SUPPLY: name = "GPU Power Supply"; break;
moel@56
    80
          case NvThermalTarget.UNKNOWN: name = "GPU Unknown"; break;
moel@56
    81
          default: name = "GPU"; break;
moel@38
    82
        }
moel@165
    83
        temperatures[i] = new Sensor(name, i, SensorType.Temperature, this,
moel@165
    84
          new ParameterDescription[0], settings);
moel@56
    85
        ActivateSensor(temperatures[i]);
moel@56
    86
      }
moel@1
    87
moel@56
    88
      int value;
moel@56
    89
      if (NVAPI.NvAPI_GPU_GetTachReading != null &&
moel@56
    90
        NVAPI.NvAPI_GPU_GetTachReading(handle, out value) == NvStatus.OK) {
moel@56
    91
        if (value > 0) {
moel@165
    92
          fan = new Sensor("GPU", 0, SensorType.Fan, this, settings);
moel@56
    93
          ActivateSensor(fan);
moel@1
    94
        }
moel@1
    95
      }
moel@140
    96
moel@140
    97
      clocks = new Sensor[3];
moel@165
    98
      clocks[0] = new Sensor("GPU Core", 0, SensorType.Clock, this, settings);
moel@165
    99
      clocks[1] = new Sensor("GPU Memory", 1, SensorType.Clock, this, settings);
moel@165
   100
      clocks[2] = new Sensor("GPU Shader", 2, SensorType.Clock, this, settings);
moel@140
   101
      for (int i = 0; i < clocks.Length; i++)
moel@140
   102
        ActivateSensor(clocks[i]);
moel@140
   103
moel@140
   104
      loads = new Sensor[3];
moel@165
   105
      loads[0] = new Sensor("GPU Core", 0, SensorType.Load, this, settings);
moel@165
   106
      loads[1] = new Sensor("GPU Memory Controller", 1, SensorType.Load, this, settings);
moel@165
   107
      loads[2] = new Sensor("GPU Video Engine", 2, SensorType.Load, this, settings);
moel@165
   108
      memoryLoad = new Sensor("GPU Memory", 3, SensorType.Load, this, settings);
moel@140
   109
moel@165
   110
      control = new Sensor("GPU Fan", 0, SensorType.Control, this, settings);
moel@1
   111
    }
moel@1
   112
moel@110
   113
    public override string Name {
moel@1
   114
      get { return name; }
moel@1
   115
    }
moel@1
   116
moel@110
   117
    public override Identifier Identifier {
moel@166
   118
      get { 
moel@166
   119
        return new Identifier("nvidiagpu", 
moel@166
   120
          adapterIndex.ToString(CultureInfo.InvariantCulture)); 
moel@166
   121
      }
moel@1
   122
    }
moel@1
   123
moel@165
   124
    public override HardwareType HardwareType {
moel@176
   125
      get { return HardwareType.GpuNvidia; }
moel@1
   126
    }
moel@1
   127
moel@1
   128
    private NvGPUThermalSettings GetThermalSettings() {
moel@1
   129
      NvGPUThermalSettings settings = new NvGPUThermalSettings();
moel@1
   130
      settings.Version = NVAPI.GPU_THERMAL_SETTINGS_VER;
moel@1
   131
      settings.Count = NVAPI.MAX_THERMAL_SENSORS_PER_GPU;
moel@1
   132
      settings.Sensor = new NvSensor[NVAPI.MAX_THERMAL_SENSORS_PER_GPU];
moel@140
   133
      if (NVAPI.NvAPI_GPU_GetThermalSettings != null &&
moel@140
   134
        NVAPI.NvAPI_GPU_GetThermalSettings(handle, (int)NvThermalTarget.ALL,
moel@38
   135
        ref settings) != NvStatus.OK) {
moel@38
   136
        settings.Count = 0;        
moel@38
   137
      }
moel@1
   138
      return settings;
moel@1
   139
    }
moel@1
   140
moel@140
   141
    private uint[] GetClocks() {
moel@166
   142
      NvClocks allClocks = new NvClocks();
moel@166
   143
      allClocks.Version = NVAPI.GPU_CLOCKS_VER;
moel@166
   144
      allClocks.Clock = new uint[NVAPI.MAX_CLOCKS_PER_GPU];
moel@140
   145
      if (NVAPI.NvAPI_GPU_GetAllClocks != null &&
moel@166
   146
        NVAPI.NvAPI_GPU_GetAllClocks(handle, ref allClocks) == NvStatus.OK) {
moel@166
   147
        return allClocks.Clock;
moel@140
   148
      }
moel@140
   149
      return null;
moel@140
   150
    }
moel@140
   151
moel@110
   152
    public override void Update() {
moel@1
   153
      NvGPUThermalSettings settings = GetThermalSettings();
moel@1
   154
      foreach (Sensor sensor in temperatures) 
moel@38
   155
        sensor.Value = settings.Sensor[sensor.Index].CurrentTemp;
moel@38
   156
moel@38
   157
      if (fan != null) {
moel@38
   158
        int value = 0;
moel@38
   159
        NVAPI.NvAPI_GPU_GetTachReading(handle, out value);
moel@38
   160
        fan.Value = value;
moel@38
   161
      }
moel@140
   162
moel@140
   163
      uint[] values = GetClocks();
moel@140
   164
      if (values != null) {
moel@140
   165
        clocks[0].Value = 0.001f * values[0];
moel@140
   166
        clocks[1].Value = 0.001f * values[8];
moel@140
   167
        clocks[2].Value = 0.001f * values[14];
moel@140
   168
        if (values[30] != 0) {
moel@140
   169
          clocks[0].Value = 0.0005f * values[30];
moel@140
   170
          clocks[2].Value = 0.001f * values[30];
moel@140
   171
        }
moel@140
   172
      }
moel@140
   173
moel@140
   174
      NvPStates states = new NvPStates();
moel@140
   175
      states.Version = NVAPI.GPU_PSTATES_VER;
moel@140
   176
      states.PStates = new NvPState[NVAPI.MAX_PSTATES_PER_GPU];
moel@140
   177
      if (NVAPI.NvAPI_GPU_GetPStates != null && 
moel@140
   178
        NVAPI.NvAPI_GPU_GetPStates(handle, ref states) == NvStatus.OK) {
moel@140
   179
        for (int i = 0; i < 3; i++)
moel@140
   180
          if (states.PStates[i].Present) {
moel@140
   181
            loads[i].Value = states.PStates[i].Percentage;
moel@140
   182
            ActivateSensor(loads[i]);
moel@140
   183
          }
moel@140
   184
      } else {
moel@140
   185
        NvUsages usages = new NvUsages();
moel@140
   186
        usages.Version = NVAPI.GPU_USAGES_VER;
moel@140
   187
        usages.Usage = new uint[NVAPI.MAX_USAGES_PER_GPU];
moel@140
   188
        if (NVAPI.NvAPI_GPU_GetUsages != null &&
moel@140
   189
          NVAPI.NvAPI_GPU_GetUsages(handle, ref usages) == NvStatus.OK) {
moel@140
   190
          loads[0].Value = usages.Usage[2];
moel@140
   191
          loads[1].Value = usages.Usage[6];
moel@140
   192
          loads[2].Value = usages.Usage[10];
moel@140
   193
          for (int i = 0; i < 3; i++)
moel@140
   194
            ActivateSensor(loads[i]);
moel@140
   195
        }
moel@140
   196
      }
moel@140
   197
moel@140
   198
      NvGPUCoolerSettings coolerSettings = new NvGPUCoolerSettings();
moel@140
   199
      coolerSettings.Version = NVAPI.GPU_COOLER_SETTINGS_VER;
moel@140
   200
      coolerSettings.Cooler = new NvCooler[NVAPI.MAX_COOLER_PER_GPU];
moel@140
   201
      if (NVAPI.NvAPI_GPU_GetCoolerSettings != null && 
moel@140
   202
        NVAPI.NvAPI_GPU_GetCoolerSettings(handle, 0, ref coolerSettings) ==
moel@140
   203
        NvStatus.OK && coolerSettings.Count > 0) {
moel@140
   204
        control.Value = coolerSettings.Cooler[0].CurrentLevel;
moel@140
   205
        ActivateSensor(control);
moel@140
   206
      }
moel@140
   207
moel@140
   208
      NvMemoryInfo memoryInfo = new NvMemoryInfo();
moel@140
   209
      memoryInfo.Version = NVAPI.GPU_MEMORY_INFO_VER;
moel@140
   210
      memoryInfo.Values = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU];
moel@140
   211
      if (NVAPI.NvAPI_GPU_GetMemoryInfo != null && displayHandle.HasValue &&
moel@140
   212
        NVAPI.NvAPI_GPU_GetMemoryInfo(displayHandle.Value, ref memoryInfo) == 
moel@140
   213
        NvStatus.OK) 
moel@140
   214
      {
moel@140
   215
        uint totalMemory = memoryInfo.Values[0];
moel@140
   216
        uint freeMemory = memoryInfo.Values[4];
moel@140
   217
        float usedMemory = Math.Max(totalMemory - freeMemory, 0);
moel@140
   218
        memoryLoad.Value = 100f * usedMemory / totalMemory;
moel@140
   219
        ActivateSensor(memoryLoad);
moel@140
   220
      }
moel@140
   221
    }
moel@140
   222
moel@140
   223
    public override string GetReport() {
moel@140
   224
      StringBuilder r = new StringBuilder();
moel@140
   225
moel@140
   226
      r.AppendLine("Nvidia GPU");
moel@140
   227
      r.AppendLine();
moel@140
   228
moel@140
   229
      r.AppendFormat("Name: {0}{1}", name, Environment.NewLine);
moel@140
   230
      r.AppendFormat("Index: {0}{1}", adapterIndex, Environment.NewLine);
moel@140
   231
      
moel@140
   232
      if (displayHandle.HasValue && NVAPI.NvAPI_GetDisplayDriverVersion != null) 
moel@140
   233
      {
moel@140
   234
        NvDisplayDriverVersion driverVersion = new NvDisplayDriverVersion();
moel@140
   235
        driverVersion.Version = NVAPI.DISPLAY_DRIVER_VERSION_VER;
moel@140
   236
        if (NVAPI.NvAPI_GetDisplayDriverVersion(displayHandle.Value,
moel@140
   237
          ref driverVersion) == NvStatus.OK) {
moel@140
   238
          r.Append("Driver Version: ");
moel@140
   239
          r.Append(driverVersion.DriverVersion / 100);
moel@140
   240
          r.Append(".");
moel@167
   241
          r.Append((driverVersion.DriverVersion % 100).ToString("00", 
moel@167
   242
            CultureInfo.InvariantCulture));
moel@140
   243
          r.AppendLine();
moel@140
   244
          r.Append("Driver Branch: ");
moel@140
   245
          r.AppendLine(driverVersion.BuildBranch);
moel@140
   246
        }
moel@140
   247
      }
moel@140
   248
      r.AppendLine();
moel@140
   249
moel@140
   250
      if (NVAPI.NvAPI_GPU_GetThermalSettings != null) {
moel@140
   251
        NvGPUThermalSettings settings = new NvGPUThermalSettings();
moel@140
   252
        settings.Version = NVAPI.GPU_THERMAL_SETTINGS_VER;
moel@140
   253
        settings.Count = NVAPI.MAX_THERMAL_SENSORS_PER_GPU;
moel@140
   254
        settings.Sensor = new NvSensor[NVAPI.MAX_THERMAL_SENSORS_PER_GPU];
moel@140
   255
moel@140
   256
        NvStatus status = NVAPI.NvAPI_GPU_GetThermalSettings(handle,
moel@140
   257
          (int)NvThermalTarget.ALL, ref settings);
moel@140
   258
moel@140
   259
        r.AppendLine("Thermal Settings");
moel@140
   260
        r.AppendLine();
moel@140
   261
        if (status == NvStatus.OK) {
moel@140
   262
          for (int i = 0; i < settings.Count; i++) {
moel@140
   263
            r.AppendFormat(" Sensor[{0}].Controller: {1}{2}", i,
moel@140
   264
              settings.Sensor[i].Controller, Environment.NewLine);
moel@140
   265
            r.AppendFormat(" Sensor[{0}].DefaultMinTemp: {1}{2}", i,
moel@140
   266
              settings.Sensor[i].DefaultMinTemp, Environment.NewLine);
moel@140
   267
            r.AppendFormat(" Sensor[{0}].DefaultMaxTemp: {1}{2}", i,
moel@140
   268
              settings.Sensor[i].DefaultMaxTemp, Environment.NewLine);
moel@140
   269
            r.AppendFormat(" Sensor[{0}].CurrentTemp: {1}{2}", i,
moel@140
   270
              settings.Sensor[i].CurrentTemp, Environment.NewLine);
moel@140
   271
            r.AppendFormat(" Sensor[{0}].Target: {1}{2}", i,
moel@140
   272
              settings.Sensor[i].Target, Environment.NewLine);
moel@140
   273
          }
moel@140
   274
        } else {
moel@140
   275
          r.Append(" Status: ");
moel@140
   276
          r.AppendLine(status.ToString());
moel@140
   277
        }
moel@140
   278
        r.AppendLine();
moel@140
   279
      }      
moel@140
   280
moel@140
   281
      if (NVAPI.NvAPI_GPU_GetAllClocks != null) {
moel@166
   282
        NvClocks allClocks = new NvClocks();
moel@166
   283
        allClocks.Version = NVAPI.GPU_CLOCKS_VER;
moel@166
   284
        allClocks.Clock = new uint[NVAPI.MAX_CLOCKS_PER_GPU];
moel@166
   285
        NvStatus status = NVAPI.NvAPI_GPU_GetAllClocks(handle, ref allClocks);
moel@140
   286
moel@140
   287
        r.AppendLine("Clocks");
moel@140
   288
        r.AppendLine();
moel@140
   289
        if (status == NvStatus.OK) {
moel@166
   290
          for (int i = 0; i < allClocks.Clock.Length; i++)
moel@166
   291
            if (allClocks.Clock[i] > 0) {
moel@166
   292
              r.AppendFormat(" Clock[{0}]: {1}{2}", i, allClocks.Clock[i],
moel@140
   293
                Environment.NewLine);
moel@140
   294
            }
moel@140
   295
        } else {
moel@140
   296
          r.Append(" Status: ");
moel@140
   297
          r.AppendLine(status.ToString());
moel@140
   298
        }
moel@140
   299
        r.AppendLine();
moel@140
   300
      }         
moel@140
   301
           
moel@140
   302
      if (NVAPI.NvAPI_GPU_GetTachReading != null) {
moel@140
   303
        int tachValue; 
moel@140
   304
        NvStatus status = NVAPI.NvAPI_GPU_GetTachReading(handle, out tachValue);
moel@140
   305
moel@140
   306
        r.AppendLine("Tachometer");
moel@140
   307
        r.AppendLine();
moel@140
   308
        if (status == NvStatus.OK) {
moel@140
   309
          r.AppendFormat(" Value: {0}{1}", tachValue, Environment.NewLine);
moel@140
   310
        } else {
moel@140
   311
          r.Append(" Status: ");
moel@140
   312
          r.AppendLine(status.ToString());
moel@140
   313
        }
moel@140
   314
        r.AppendLine();
moel@140
   315
      }
moel@140
   316
moel@140
   317
      if (NVAPI.NvAPI_GPU_GetPStates != null) {
moel@140
   318
        NvPStates states = new NvPStates();
moel@140
   319
        states.Version = NVAPI.GPU_PSTATES_VER;
moel@140
   320
        states.PStates = new NvPState[NVAPI.MAX_PSTATES_PER_GPU];
moel@140
   321
        NvStatus status = NVAPI.NvAPI_GPU_GetPStates(handle, ref states);
moel@140
   322
moel@140
   323
        r.AppendLine("P-States");
moel@140
   324
        r.AppendLine();
moel@140
   325
        if (status == NvStatus.OK) {
moel@140
   326
          for (int i = 0; i < states.PStates.Length; i++)
moel@140
   327
            if (states.PStates[i].Present)
moel@140
   328
              r.AppendFormat(" Percentage[{0}]: {1}{2}", i,
moel@140
   329
                states.PStates[i].Percentage, Environment.NewLine);
moel@140
   330
        } else {
moel@140
   331
          r.Append(" Status: ");
moel@140
   332
          r.AppendLine(status.ToString());
moel@140
   333
        }
moel@140
   334
        r.AppendLine();
moel@140
   335
      }
moel@140
   336
moel@140
   337
      if (NVAPI.NvAPI_GPU_GetUsages != null) {
moel@140
   338
        NvUsages usages = new NvUsages();
moel@140
   339
        usages.Version = NVAPI.GPU_USAGES_VER;
moel@140
   340
        usages.Usage = new uint[NVAPI.MAX_USAGES_PER_GPU];
moel@140
   341
        NvStatus status = NVAPI.NvAPI_GPU_GetUsages(handle, ref usages);
moel@140
   342
     
moel@140
   343
        r.AppendLine("Usages");
moel@140
   344
        r.AppendLine();
moel@140
   345
        if (status == NvStatus.OK) {
moel@140
   346
          for (int i = 0; i < usages.Usage.Length; i++)
moel@140
   347
            if (usages.Usage[i] > 0)
moel@140
   348
              r.AppendFormat(" Usage[{0}]: {1}{2}", i,
moel@140
   349
                usages.Usage[i], Environment.NewLine);
moel@140
   350
        } else {
moel@140
   351
          r.Append(" Status: ");
moel@140
   352
          r.AppendLine(status.ToString());
moel@140
   353
        }
moel@140
   354
        r.AppendLine();
moel@140
   355
      }
moel@140
   356
moel@140
   357
      if (NVAPI.NvAPI_GPU_GetCoolerSettings != null) {
moel@140
   358
        NvGPUCoolerSettings settings = new NvGPUCoolerSettings();
moel@140
   359
        settings.Version = NVAPI.GPU_COOLER_SETTINGS_VER;
moel@140
   360
        settings.Cooler = new NvCooler[NVAPI.MAX_COOLER_PER_GPU];
moel@140
   361
        NvStatus status =
moel@140
   362
          NVAPI.NvAPI_GPU_GetCoolerSettings(handle, 0, ref settings);
moel@140
   363
moel@140
   364
        r.AppendLine("Cooler Settings");
moel@140
   365
        r.AppendLine();
moel@140
   366
        if (status == NvStatus.OK) {
moel@140
   367
          for (int i = 0; i < settings.Count; i++) {
moel@140
   368
            r.AppendFormat(" Cooler[{0}].Type: {1}{2}", i,
moel@140
   369
              settings.Cooler[i].Type, Environment.NewLine);
moel@140
   370
            r.AppendFormat(" Cooler[{0}].Controller: {1}{2}", i,
moel@140
   371
              settings.Cooler[i].Controller, Environment.NewLine);
moel@140
   372
            r.AppendFormat(" Cooler[{0}].DefaultMin: {1}{2}", i,
moel@140
   373
              settings.Cooler[i].DefaultMin, Environment.NewLine);
moel@140
   374
            r.AppendFormat(" Cooler[{0}].DefaultMax: {1}{2}", i,
moel@140
   375
              settings.Cooler[i].DefaultMax, Environment.NewLine);
moel@140
   376
            r.AppendFormat(" Cooler[{0}].CurrentMin: {1}{2}", i,
moel@140
   377
              settings.Cooler[i].CurrentMin, Environment.NewLine);
moel@140
   378
            r.AppendFormat(" Cooler[{0}].CurrentMax: {1}{2}", i,
moel@140
   379
              settings.Cooler[i].CurrentMax, Environment.NewLine);
moel@140
   380
            r.AppendFormat(" Cooler[{0}].CurrentLevel: {1}{2}", i,
moel@140
   381
              settings.Cooler[i].CurrentLevel, Environment.NewLine);
moel@140
   382
            r.AppendFormat(" Cooler[{0}].DefaultPolicy: {1}{2}", i,
moel@140
   383
              settings.Cooler[i].DefaultPolicy, Environment.NewLine);
moel@140
   384
            r.AppendFormat(" Cooler[{0}].CurrentPolicy: {1}{2}", i,
moel@140
   385
              settings.Cooler[i].CurrentPolicy, Environment.NewLine);
moel@140
   386
            r.AppendFormat(" Cooler[{0}].Target: {1}{2}", i,
moel@140
   387
              settings.Cooler[i].Target, Environment.NewLine);
moel@140
   388
            r.AppendFormat(" Cooler[{0}].ControlType: {1}{2}", i,
moel@140
   389
              settings.Cooler[i].ControlType, Environment.NewLine);
moel@140
   390
            r.AppendFormat(" Cooler[{0}].Active: {1}{2}", i,
moel@140
   391
              settings.Cooler[i].Active, Environment.NewLine);
moel@140
   392
          }
moel@140
   393
        } else {
moel@140
   394
          r.Append(" Status: ");
moel@140
   395
          r.AppendLine(status.ToString());
moel@140
   396
        }
moel@140
   397
        r.AppendLine();
moel@140
   398
      }
moel@140
   399
moel@140
   400
      if (NVAPI.NvAPI_GPU_GetMemoryInfo != null && displayHandle.HasValue) {
moel@140
   401
        NvMemoryInfo memoryInfo = new NvMemoryInfo();
moel@140
   402
        memoryInfo.Version = NVAPI.GPU_MEMORY_INFO_VER;
moel@140
   403
        memoryInfo.Values = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU];
moel@140
   404
        NvStatus status = NVAPI.NvAPI_GPU_GetMemoryInfo(displayHandle.Value, 
moel@140
   405
          ref memoryInfo);
moel@140
   406
moel@140
   407
        r.AppendLine("Memory Info");
moel@140
   408
        r.AppendLine();
moel@140
   409
        if (status == NvStatus.OK) {
moel@140
   410
          for (int i = 0; i < memoryInfo.Values.Length; i++)
moel@140
   411
            r.AppendFormat(" Value[{0}]: {1}{2}", i,
moel@140
   412
                memoryInfo.Values[i], Environment.NewLine);
moel@140
   413
        } else {
moel@140
   414
          r.Append(" Status: ");
moel@140
   415
          r.AppendLine(status.ToString());
moel@140
   416
        }
moel@140
   417
        r.AppendLine();
moel@140
   418
      }
moel@140
   419
moel@140
   420
      return r.ToString();
moel@1
   421
    }
moel@1
   422
  }
moel@1
   423
}