Hardware/ATI/ATIGPU.cs
author moel.mich
Sat, 25 Jun 2011 14:46:28 +0000
changeset 304 16a86362c2ca
parent 280 2bc456906ad6
child 344 3145aadca3d2
permissions -rw-r--r--
Changed the maximum buffer size for double buffering of controls that isn't disposed after each draw call to the size of the screen. This should reduce the memory allocation and disposing on each sensor update. Also page faults are no longer increasing with this change.
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@275
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2011
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@1
    40
moel@1
    41
namespace OpenHardwareMonitor.Hardware.ATI {
moel@166
    42
  internal sealed class ATIGPU : Hardware {
moel@1
    43
moel@195
    44
    private readonly int adapterIndex;
moel@195
    45
    private readonly int busNumber;
moel@195
    46
    private readonly int deviceNumber;
moel@195
    47
    private readonly Sensor temperature;
moel@195
    48
    private readonly Sensor fan;
moel@195
    49
    private readonly Sensor coreClock;
moel@195
    50
    private readonly Sensor memoryClock;
moel@195
    51
    private readonly Sensor coreVoltage;
moel@195
    52
    private readonly Sensor coreLoad;
moel@247
    53
    private readonly Sensor controlSensor;
moel@247
    54
    private readonly Control fanControl;
moel@247
    55
moel@248
    56
    private bool restoreDefaultFanSpeedRequired = false;
moel@248
    57
    private ADLFanSpeedValue initialFanSpeedValue;    
moel@1
    58
moel@3
    59
    public ATIGPU(string name, int adapterIndex, int busNumber, 
moel@165
    60
      int deviceNumber, ISettings settings) 
moel@275
    61
      : base(name, new Identifier("atigpu", 
moel@275
    62
        adapterIndex.ToString(CultureInfo.InvariantCulture)), settings)
moel@3
    63
    {
moel@1
    64
      this.adapterIndex = adapterIndex;
moel@3
    65
      this.busNumber = busNumber;
moel@3
    66
      this.deviceNumber = deviceNumber;
moel@1
    67
moel@165
    68
      this.temperature = new Sensor("GPU Core", 0, SensorType.Temperature, this, settings);
moel@165
    69
      this.fan = new Sensor("GPU Fan", 0, SensorType.Fan, this, settings);
moel@165
    70
      this.coreClock = new Sensor("GPU Core", 0, SensorType.Clock, this, settings);
moel@165
    71
      this.memoryClock = new Sensor("GPU Memory", 1, SensorType.Clock, this, settings);
moel@165
    72
      this.coreVoltage = new Sensor("GPU Core", 0, SensorType.Voltage, this, settings);
moel@165
    73
      this.coreLoad = new Sensor("GPU Core", 0, SensorType.Load, this, settings);
moel@247
    74
      this.controlSensor = new Sensor("GPU Fan", 0, SensorType.Control, this, settings);
moel@247
    75
moel@247
    76
      ADLFanSpeedInfo afsi = new ADLFanSpeedInfo();
moel@247
    77
      if (ADL.ADL_Overdrive5_FanSpeedInfo_Get(adapterIndex, 0, ref afsi)
moel@247
    78
        != ADL.ADL_OK) 
moel@247
    79
      {
moel@247
    80
        afsi.MaxPercent = 100;
moel@247
    81
        afsi.MinPercent = 0;
moel@247
    82
      }
moel@247
    83
moel@247
    84
      this.fanControl = new Control(controlSensor, settings, afsi.MinPercent, 
moel@247
    85
        afsi.MaxPercent);
moel@247
    86
      this.fanControl.ControlModeChanged += ControlModeChanged;
moel@247
    87
      this.fanControl.SoftwareControlValueChanged += 
moel@247
    88
        SoftwareControlValueChanged;
moel@247
    89
      ControlModeChanged(fanControl);
moel@247
    90
      this.controlSensor.Control = fanControl;
moel@1
    91
      Update();                   
moel@1
    92
    }
moel@1
    93
moel@248
    94
    private void SaveDefaultFanSpeed() {
moel@248
    95
      if (!restoreDefaultFanSpeedRequired) {        
moel@248
    96
        initialFanSpeedValue = new ADLFanSpeedValue();
moel@248
    97
        initialFanSpeedValue.SpeedType =
moel@248
    98
          ADL.ADL_DL_FANCTRL_SPEED_TYPE_PERCENT;
moel@248
    99
        restoreDefaultFanSpeedRequired = 
moel@248
   100
          ADL.ADL_Overdrive5_FanSpeed_Get(adapterIndex, 0,
moel@248
   101
          ref initialFanSpeedValue) == ADL.ADL_OK;
moel@248
   102
      }
moel@248
   103
    }
moel@248
   104
moel@248
   105
    private void RestoreDefaultFanSpeed() {
moel@248
   106
      if (restoreDefaultFanSpeedRequired) {        
moel@248
   107
        ADL.ADL_Overdrive5_FanSpeed_Set(adapterIndex, 0,
moel@248
   108
          ref this.initialFanSpeedValue);
moel@280
   109
        if ((initialFanSpeedValue.Flags &
moel@280
   110
          ADL.ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED) == 0)
moel@280
   111
          ADL.ADL_Overdrive5_FanSpeedToDefault_Set(adapterIndex, 0);
moel@248
   112
        restoreDefaultFanSpeedRequired = false;
moel@248
   113
      }
moel@248
   114
    }
moel@248
   115
moel@247
   116
    private void SoftwareControlValueChanged(IControl control) {
moel@247
   117
      if (control.ControlMode == ControlMode.Software) {
moel@248
   118
        SaveDefaultFanSpeed();
moel@247
   119
        ADLFanSpeedValue adlf = new ADLFanSpeedValue();
moel@247
   120
        adlf.SpeedType = ADL.ADL_DL_FANCTRL_SPEED_TYPE_PERCENT;
moel@247
   121
        adlf.Flags = ADL.ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED;
moel@247
   122
        adlf.FanSpeed = (int)control.SoftwareValue;
moel@247
   123
        ADL.ADL_Overdrive5_FanSpeed_Set(adapterIndex, 0, ref adlf);
moel@247
   124
      }
moel@247
   125
    }
moel@247
   126
moel@247
   127
    private void ControlModeChanged(IControl control) {
moel@247
   128
      if (control.ControlMode == ControlMode.Default) {
moel@248
   129
        RestoreDefaultFanSpeed();     
moel@247
   130
      } else {
moel@248
   131
        SoftwareControlValueChanged(control);
moel@247
   132
      }
moel@247
   133
    }
moel@247
   134
moel@3
   135
    public int BusNumber { get { return busNumber; } }
moel@3
   136
moel@3
   137
    public int DeviceNumber { get { return deviceNumber; } }
moel@3
   138
moel@1
   139
moel@165
   140
    public override HardwareType HardwareType {
moel@176
   141
      get { return HardwareType.GpuAti; }
moel@1
   142
    }
moel@1
   143
moel@110
   144
    public override void Update() {
moel@1
   145
      ADLTemperature adlt = new ADLTemperature();
moel@15
   146
      if (ADL.ADL_Overdrive5_Temperature_Get(adapterIndex, 0, ref adlt)
moel@15
   147
        == ADL.ADL_OK) 
moel@15
   148
      {
moel@15
   149
        temperature.Value = 0.001f * adlt.Temperature;
moel@15
   150
        ActivateSensor(temperature);
moel@15
   151
      } else {
moel@164
   152
        temperature.Value = null;
moel@15
   153
      }
moel@1
   154
moel@1
   155
      ADLFanSpeedValue adlf = new ADLFanSpeedValue();
moel@1
   156
      adlf.SpeedType = ADL.ADL_DL_FANCTRL_SPEED_TYPE_RPM;
moel@15
   157
      if (ADL.ADL_Overdrive5_FanSpeed_Get(adapterIndex, 0, ref adlf)
moel@15
   158
        == ADL.ADL_OK) 
moel@15
   159
      {
moel@15
   160
        fan.Value = adlf.FanSpeed;
moel@15
   161
        ActivateSensor(fan);
moel@15
   162
      } else {
moel@164
   163
        fan.Value = null;
moel@164
   164
      }
moel@164
   165
moel@164
   166
      adlf = new ADLFanSpeedValue();
moel@164
   167
      adlf.SpeedType = ADL.ADL_DL_FANCTRL_SPEED_TYPE_PERCENT;
moel@164
   168
      if (ADL.ADL_Overdrive5_FanSpeed_Get(adapterIndex, 0, ref adlf)
moel@164
   169
        == ADL.ADL_OK) {
moel@247
   170
        controlSensor.Value = adlf.FanSpeed;
moel@247
   171
        ActivateSensor(controlSensor);
moel@164
   172
      } else {
moel@247
   173
        controlSensor.Value = null;
moel@15
   174
      }
moel@1
   175
moel@1
   176
      ADLPMActivity adlp = new ADLPMActivity();
moel@15
   177
      if (ADL.ADL_Overdrive5_CurrentActivity_Get(adapterIndex, ref adlp)
moel@15
   178
        == ADL.ADL_OK) 
moel@15
   179
      {
moel@80
   180
        if (adlp.EngineClock > 0) {
moel@80
   181
          coreClock.Value = 0.01f * adlp.EngineClock;
moel@80
   182
          ActivateSensor(coreClock);
moel@270
   183
        } else {
moel@270
   184
          coreClock.Value = null;
moel@80
   185
        }
moel@80
   186
moel@80
   187
        if (adlp.MemoryClock > 0) {
moel@80
   188
          memoryClock.Value = 0.01f * adlp.MemoryClock;
moel@80
   189
          ActivateSensor(memoryClock);
moel@270
   190
        } else {
moel@270
   191
          memoryClock.Value = null;
moel@80
   192
        }
moel@80
   193
moel@80
   194
        if (adlp.Vddc > 0) {
moel@80
   195
          coreVoltage.Value = 0.001f * adlp.Vddc;
moel@80
   196
          ActivateSensor(coreVoltage);
moel@270
   197
        } else {
moel@270
   198
          coreVoltage.Value = null;
moel@80
   199
        }
moel@80
   200
moel@126
   201
        coreLoad.Value = Math.Min(adlp.ActivityPercent, 100);                        
moel@24
   202
        ActivateSensor(coreLoad);
moel@15
   203
      } else {
moel@164
   204
        coreClock.Value = null;
moel@164
   205
        memoryClock.Value = null;
moel@164
   206
        coreVoltage.Value = null;
moel@164
   207
        coreLoad.Value = null;
moel@15
   208
      }
moel@1
   209
    }
moel@247
   210
moel@298
   211
    public override void Close() {
moel@247
   212
      this.fanControl.ControlModeChanged -= ControlModeChanged;
moel@247
   213
      this.fanControl.SoftwareControlValueChanged -=
moel@247
   214
        SoftwareControlValueChanged;
moel@247
   215
moel@248
   216
      RestoreDefaultFanSpeed();
moel@298
   217
      base.Close();
moel@247
   218
    }
moel@1
   219
  }
moel@1
   220
}