Binary file not shown.
|
After Width: | Height: | Size: 406 B |
@@ -35,6 +35,9 @@ namespace LibreHardwareMonitor.UI
|
||||
case HardwareType.GpuAmd:
|
||||
image = Utilities.EmbeddedResources.GetImage("amd.png");
|
||||
break;
|
||||
case HardwareType.GpuIntel:
|
||||
image = Utilities.EmbeddedResources.GetImage("intel.png");
|
||||
break;
|
||||
case HardwareType.Storage:
|
||||
image = Utilities.EmbeddedResources.GetImage("hdd.png");
|
||||
break;
|
||||
|
||||
@@ -629,6 +629,8 @@ namespace LibreHardwareMonitor.Utilities
|
||||
return "nvidia.png";
|
||||
case HardwareType.GpuAmd:
|
||||
return "ati.png";
|
||||
case HardwareType.GpuIntel:
|
||||
return "intel.png";
|
||||
case HardwareType.Storage:
|
||||
return "hdd.png";
|
||||
case HardwareType.Motherboard:
|
||||
|
||||
@@ -8,12 +8,14 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using LibreHardwareMonitor.Hardware.Battery;
|
||||
using LibreHardwareMonitor.Hardware.Controller.AeroCool;
|
||||
using LibreHardwareMonitor.Hardware.Controller.AquaComputer;
|
||||
using LibreHardwareMonitor.Hardware.Controller.Heatmaster;
|
||||
using LibreHardwareMonitor.Hardware.Controller.Nzxt;
|
||||
using LibreHardwareMonitor.Hardware.Controller.TBalancer;
|
||||
using LibreHardwareMonitor.Hardware.CPU;
|
||||
using LibreHardwareMonitor.Hardware.Gpu;
|
||||
using LibreHardwareMonitor.Hardware.Memory;
|
||||
using LibreHardwareMonitor.Hardware.Motherboard;
|
||||
@@ -145,9 +147,9 @@ namespace LibreHardwareMonitor.Hardware
|
||||
if (_open && value != _cpuEnabled)
|
||||
{
|
||||
if (value)
|
||||
Add(new CPU.CpuGroup(_settings));
|
||||
Add(new CpuGroup(_settings));
|
||||
else
|
||||
RemoveType<CPU.CpuGroup>();
|
||||
RemoveType<CpuGroup>();
|
||||
}
|
||||
|
||||
_cpuEnabled = value;
|
||||
@@ -166,11 +168,13 @@ namespace LibreHardwareMonitor.Hardware
|
||||
{
|
||||
Add(new AmdGpuGroup(_settings));
|
||||
Add(new NvidiaGroup(_settings));
|
||||
Add(new IntelGpuGroup(GetIntelCpus(), _settings));
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveType<AmdGpuGroup>();
|
||||
RemoveType<NvidiaGroup>();
|
||||
RemoveType<IntelGpuGroup>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,7 +501,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
Add(new MotherboardGroup(_smbios, _settings));
|
||||
|
||||
if (_cpuEnabled)
|
||||
Add(new CPU.CpuGroup(_settings));
|
||||
Add(new CpuGroup(_settings));
|
||||
|
||||
if (_memoryEnabled)
|
||||
Add(new MemoryGroup(_settings));
|
||||
@@ -506,6 +510,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
{
|
||||
Add(new AmdGpuGroup(_settings));
|
||||
Add(new NvidiaGroup(_settings));
|
||||
Add(new IntelGpuGroup(GetIntelCpus(), _settings));
|
||||
}
|
||||
|
||||
if (_controllerEnabled)
|
||||
@@ -653,6 +658,16 @@ namespace LibreHardwareMonitor.Hardware
|
||||
}
|
||||
}
|
||||
|
||||
private List<IntelCpu> GetIntelCpus()
|
||||
{
|
||||
// Create a temporary cpu group if one has not been added.
|
||||
lock (_lock)
|
||||
{
|
||||
IGroup cpuGroup = _groups.Find(x => x is CpuGroup) ?? new CpuGroup(_settings);
|
||||
return cpuGroup.Hardware.Select(x => x as IntelCpu).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Computer" /> specific additional settings passed to its <see cref="IHardware" />.
|
||||
/// </summary>
|
||||
|
||||
@@ -30,6 +30,8 @@ namespace LibreHardwareMonitor.Hardware.CPU
|
||||
private readonly Sensor[] _powerSensors;
|
||||
private readonly double _timeStampCounterMultiplier;
|
||||
|
||||
public float EnergyUnitsMultiplier => _energyUnitMultiplier;
|
||||
|
||||
public IntelCpu(int processorIndex, CpuId[][] cpuId, ISettings settings) : base(processorIndex, cpuId, settings)
|
||||
{
|
||||
// set tjMax
|
||||
@@ -401,6 +403,9 @@ namespace LibreHardwareMonitor.Hardware.CPU
|
||||
if (!Ring0.ReadMsr(_energyStatusMsrs[i], out eax, out uint _))
|
||||
continue;
|
||||
|
||||
// Don't show the "GPU Graphics" sensor on windows, it will show up under the GPU instead.
|
||||
if (i == 2 && !Software.OperatingSystem.IsUnix)
|
||||
continue;
|
||||
|
||||
_lastEnergyTime[i] = DateTime.UtcNow;
|
||||
_lastEnergyConsumed[i] = eax;
|
||||
|
||||
@@ -66,6 +66,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
if (!adapterType.Value.HasFlag(D3dkmth.D3DKMT_ADAPTERTYPE_FLAGS.SoftwareDevice))
|
||||
return false;
|
||||
|
||||
deviceInfo.Integrated = !adapterType.Value.HasFlag(D3dkmth.D3DKMT_ADAPTERTYPE_FLAGS.HybridIntegrated);
|
||||
|
||||
GetQueryStatisticsAdapterInformation(out status, adapter, out D3dkmth.D3DKMT_QUERYSTATISTICS_ADAPTER_INFORMATION adapterInformation);
|
||||
if (status != WinNt.STATUS_SUCCESS)
|
||||
@@ -93,13 +94,20 @@ namespace LibreHardwareMonitor.Hardware
|
||||
|
||||
deviceInfo.Nodes[nodeId] = new D3DDeviceNodeInfo
|
||||
{
|
||||
Id = nodeId,
|
||||
Name = GetNodeEngineTypeString(nodeMetaData),
|
||||
RunningTime = nodeInformation.GlobalInformation.RunningTime.QuadPart,
|
||||
Id = nodeId,
|
||||
Name = GetNodeEngineTypeString(nodeMetaData),
|
||||
RunningTime = nodeInformation.GlobalInformation.RunningTime.QuadPart,
|
||||
QueryTime = queryTime
|
||||
};
|
||||
}
|
||||
|
||||
GetSegmentSize(out status, adapter, out D3dkmth.D3DKMT_SEGMENTSIZEINFO segmentSizeInfo);
|
||||
if (status != WinNt.STATUS_SUCCESS)
|
||||
return false;
|
||||
|
||||
deviceInfo.GpuSharedLimit = segmentSizeInfo.SharedSystemMemorySize;
|
||||
deviceInfo.GpuDedicatedLimit = segmentSizeInfo.DedicatedSystemMemorySize;
|
||||
|
||||
for (uint segmentId = 0; segmentId < segmentCount; segmentId++)
|
||||
{
|
||||
GetQueryStatisticsSegment(out status, adapter, segmentId, out D3dkmth.D3DKMT_QUERYSTATISTICS_SEGMENT_INFORMATION segmentInformation);
|
||||
@@ -107,7 +115,6 @@ namespace LibreHardwareMonitor.Hardware
|
||||
return false;
|
||||
|
||||
|
||||
ulong commitLimit = segmentInformation.CommitLimit;
|
||||
ulong bytesResident = segmentInformation.BytesResident;
|
||||
ulong bytesCommitted = segmentInformation.BytesCommitted;
|
||||
|
||||
@@ -115,13 +122,11 @@ namespace LibreHardwareMonitor.Hardware
|
||||
|
||||
if (aperture == 1)
|
||||
{
|
||||
deviceInfo.GpuSharedLimit += commitLimit;
|
||||
deviceInfo.GpuSharedUsed += bytesResident;
|
||||
deviceInfo.GpuSharedMax += bytesCommitted;
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceInfo.GpuDedicatedLimit += commitLimit;
|
||||
deviceInfo.GpuDedicatedUsed += bytesResident;
|
||||
deviceInfo.GpuDedicatedMax += bytesCommitted;
|
||||
}
|
||||
@@ -135,7 +140,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
{
|
||||
return nodeMetaData.NodeData.EngineType switch
|
||||
{
|
||||
D3dkmdt.DXGK_ENGINE_TYPE.DXGK_ENGINE_TYPE_OTHER => "D3D " + nodeMetaData.NodeData.FriendlyName,
|
||||
D3dkmdt.DXGK_ENGINE_TYPE.DXGK_ENGINE_TYPE_OTHER => "D3D " + (!string.IsNullOrWhiteSpace(nodeMetaData.NodeData.FriendlyName) ? nodeMetaData.NodeData.FriendlyName : "Other"),
|
||||
D3dkmdt.DXGK_ENGINE_TYPE.DXGK_ENGINE_TYPE_3D => "D3D 3D",
|
||||
D3dkmdt.DXGK_ENGINE_TYPE.DXGK_ENGINE_TYPE_VIDEO_DECODE => "D3D Video Decode",
|
||||
D3dkmdt.DXGK_ENGINE_TYPE.DXGK_ENGINE_TYPE_VIDEO_ENCODE => "D3D Video Encode",
|
||||
@@ -148,6 +153,29 @@ namespace LibreHardwareMonitor.Hardware
|
||||
};
|
||||
}
|
||||
|
||||
private static void GetSegmentSize
|
||||
(
|
||||
out uint status,
|
||||
D3dkmth.D3DKMT_OPENADAPTERFROMDEVICENAME adapter,
|
||||
out D3dkmth.D3DKMT_SEGMENTSIZEINFO sizeInformation)
|
||||
{
|
||||
IntPtr segmentSizePtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(D3dkmth.D3DKMT_SEGMENTSIZEINFO)));
|
||||
sizeInformation = new D3dkmth.D3DKMT_SEGMENTSIZEINFO();
|
||||
Marshal.StructureToPtr(sizeInformation, segmentSizePtr, true);
|
||||
|
||||
var queryAdapterInfo = new D3dkmth.D3DKMT_QUERYADAPTERINFO
|
||||
{
|
||||
hAdapter = adapter.hAdapter,
|
||||
Type = D3dkmth.KMTQUERYADAPTERINFOTYPE.KMTQAITYPE_GETSEGMENTSIZE,
|
||||
pPrivateDriverData = segmentSizePtr,
|
||||
PrivateDriverDataSize = Marshal.SizeOf(typeof(D3dkmth.D3DKMT_SEGMENTSIZEINFO))
|
||||
};
|
||||
|
||||
status = Gdi32.D3DKMTQueryAdapterInfo(ref queryAdapterInfo);
|
||||
sizeInformation = Marshal.PtrToStructure<D3dkmth.D3DKMT_SEGMENTSIZEINFO>(segmentSizePtr);
|
||||
Marshal.FreeHGlobal(segmentSizePtr);
|
||||
}
|
||||
|
||||
private static void GetNodeMetaData(out uint status, D3dkmth.D3DKMT_OPENADAPTERFROMDEVICENAME adapter, uint nodeId, out D3dkmth.D3DKMT_NODEMETADATA nodeMetaDataResult)
|
||||
{
|
||||
IntPtr nodeMetaDataPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(D3dkmth.D3DKMT_NODEMETADATA)));
|
||||
@@ -261,6 +289,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
public ulong GpuDedicatedMax;
|
||||
|
||||
public D3DDeviceNodeInfo[] Nodes;
|
||||
}
|
||||
public bool Integrated;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
// Copyright (C) LibreHardwareMonitor and Contributors.
|
||||
// All Rights Reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using LibreHardwareMonitor.Hardware.CPU;
|
||||
|
||||
namespace LibreHardwareMonitor.Hardware.Gpu
|
||||
{
|
||||
internal class IntelGpuGroup : IGroup
|
||||
{
|
||||
private readonly List<Hardware> _hardware = new();
|
||||
private readonly StringBuilder _report = new();
|
||||
|
||||
public IntelGpuGroup(List<IntelCpu> intelCpus, ISettings settings)
|
||||
{
|
||||
if (!Software.OperatingSystem.IsUnix && intelCpus?.Count > 0)
|
||||
{
|
||||
_report.AppendLine("Intel GPU (D3D)");
|
||||
_report.AppendLine();
|
||||
|
||||
string[] ids = D3DDisplayDevice.GetDeviceIdentifiers();
|
||||
|
||||
_report.Append("Number of adapters: ");
|
||||
_report.AppendLine(ids.Length.ToString(CultureInfo.InvariantCulture));
|
||||
_report.AppendLine();
|
||||
|
||||
for (int i = 0; i < ids.Length; i++)
|
||||
{
|
||||
string deviceId = ids[i];
|
||||
bool isIntel = deviceId.IndexOf("VEN_8086", StringComparison.Ordinal) != -1;
|
||||
|
||||
_report.Append("AdapterIndex: ");
|
||||
_report.AppendLine(i.ToString(CultureInfo.InvariantCulture));
|
||||
_report.Append("DeviceId: ");
|
||||
_report.AppendLine(deviceId);
|
||||
_report.Append("IsIntel: ");
|
||||
_report.AppendLine(isIntel.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
if (isIntel)
|
||||
{
|
||||
if (D3DDisplayDevice.GetDeviceInfoByIdentifier(deviceId, out D3DDisplayDevice.D3DDeviceInfo deviceInfo))
|
||||
{
|
||||
_report.Append("GpuSharedLimit: ");
|
||||
_report.AppendLine(deviceInfo.GpuSharedLimit.ToString(CultureInfo.InvariantCulture));
|
||||
_report.Append("GpuSharedUsed: ");
|
||||
_report.AppendLine(deviceInfo.GpuSharedUsed.ToString(CultureInfo.InvariantCulture));
|
||||
_report.Append("GpuSharedMax: ");
|
||||
_report.AppendLine(deviceInfo.GpuSharedMax.ToString(CultureInfo.InvariantCulture));
|
||||
_report.Append("GpuDedicatedLimit: ");
|
||||
_report.AppendLine(deviceInfo.GpuDedicatedLimit.ToString(CultureInfo.InvariantCulture));
|
||||
_report.Append("GpuDedicatedUsed: ");
|
||||
_report.AppendLine(deviceInfo.GpuDedicatedUsed.ToString(CultureInfo.InvariantCulture));
|
||||
_report.Append("GpuDedicatedMax: ");
|
||||
_report.AppendLine(deviceInfo.GpuDedicatedMax.ToString(CultureInfo.InvariantCulture));
|
||||
_report.Append("Integrated: ");
|
||||
_report.AppendLine(deviceInfo.Integrated.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
if (deviceInfo.Integrated)
|
||||
{
|
||||
// It may seem strange to only use the first cpu here, but in-case we have a multi cpu system with integrated graphics (does that exist?),
|
||||
// we would pick up the multiple device identifiers above and would add one instance for each CPU.
|
||||
_hardware.Add(new IntelIntegratedGpu(intelCpus[0], deviceId, deviceInfo, settings));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_report.AppendLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyList<IHardware> Hardware => _hardware;
|
||||
|
||||
public string GetReport()
|
||||
{
|
||||
return _report.ToString();
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
foreach (Hardware gpu in _hardware)
|
||||
gpu.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace LibreHardwareMonitor.Hardware.Gpu
|
||||
{
|
||||
internal class IntelIntegratedGpu : Hardware
|
||||
{
|
||||
private readonly string _deviceId;
|
||||
private readonly Sensor _dedicatedMemoryUsage;
|
||||
private readonly D3DDisplayDevice.D3DDeviceInfo _deviceInfo;
|
||||
private readonly float _energyUnitMultiplier;
|
||||
private readonly CPU.IntelCpu _intelCpu;
|
||||
private uint _lastEnergyConsumed;
|
||||
private DateTime _lastEnergyTime;
|
||||
private const uint MSR_RAPL_POWER_UNIT = 0x606;
|
||||
private const uint MSR_PP1_ENERGY_STATUS = 0x641;
|
||||
private readonly Sensor[] _nodeUsage;
|
||||
private readonly DateTime[] _nodeUsagePrevTick;
|
||||
private readonly long[] _nodeUsagePrevValue;
|
||||
private readonly Sensor _powerSensor;
|
||||
private readonly Sensor _sharedMemoryUsage;
|
||||
|
||||
public override HardwareType HardwareType => HardwareType.GpuIntel;
|
||||
|
||||
public IntelIntegratedGpu(CPU.IntelCpu intelCpu, string deviceId, D3DDisplayDevice.D3DDeviceInfo deviceInfo, ISettings settings)
|
||||
: base(GetName(deviceId),
|
||||
new Identifier("gpu-intel-integrated", deviceId.ToString(CultureInfo.InvariantCulture)),
|
||||
settings)
|
||||
{
|
||||
_intelCpu = intelCpu;
|
||||
_deviceId = deviceId;
|
||||
_deviceInfo = deviceInfo;
|
||||
|
||||
var memorySensorIndex = 0;
|
||||
|
||||
if (_deviceInfo.GpuDedicatedLimit > 0)
|
||||
{
|
||||
_dedicatedMemoryUsage = new Sensor("D3D Dedicated Memory Used", memorySensorIndex++, SensorType.SmallData, this, settings);
|
||||
}
|
||||
_sharedMemoryUsage = new Sensor("D3D Shared Memory Used", memorySensorIndex++, SensorType.SmallData, this, settings);
|
||||
|
||||
if (Ring0.ReadMsr(MSR_RAPL_POWER_UNIT, out var eax, out var _))
|
||||
{
|
||||
_energyUnitMultiplier = _intelCpu.EnergyUnitsMultiplier;
|
||||
if (_energyUnitMultiplier != 0)
|
||||
{
|
||||
_lastEnergyTime = DateTime.UtcNow;
|
||||
_lastEnergyConsumed = eax;
|
||||
_powerSensor = new Sensor("GPU Power", 0, SensorType.Power, this, settings);
|
||||
ActivateSensor(_powerSensor);
|
||||
}
|
||||
}
|
||||
|
||||
_nodeUsage = new Sensor[deviceInfo.Nodes.Length];
|
||||
_nodeUsagePrevValue = new long[deviceInfo.Nodes.Length];
|
||||
_nodeUsagePrevTick = new DateTime[deviceInfo.Nodes.Length];
|
||||
|
||||
var nodeSensorIndex = 0;
|
||||
foreach(var node in deviceInfo.Nodes.OrderBy(x => x.Name))
|
||||
{
|
||||
_nodeUsage[node.Id] = new Sensor(node.Name, nodeSensorIndex++, SensorType.Load, this, settings);
|
||||
_nodeUsagePrevValue[node.Id] = node.RunningTime;
|
||||
_nodeUsagePrevTick[node.Id] = node.QueryTime;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (D3DDisplayDevice.GetDeviceInfoByIdentifier(_deviceId, out D3DDisplayDevice.D3DDeviceInfo deviceInfo))
|
||||
{
|
||||
if (_dedicatedMemoryUsage != null)
|
||||
{
|
||||
_dedicatedMemoryUsage.Value = 1f * deviceInfo.GpuDedicatedUsed / 1024 / 1024;
|
||||
ActivateSensor(_dedicatedMemoryUsage);
|
||||
}
|
||||
|
||||
_sharedMemoryUsage.Value = 1f * deviceInfo.GpuSharedUsed / 1024 / 1024;
|
||||
ActivateSensor(_sharedMemoryUsage);
|
||||
|
||||
if (_powerSensor != null && Ring0.ReadMsr(MSR_PP1_ENERGY_STATUS, out var eax, out var _))
|
||||
{
|
||||
var time = DateTime.UtcNow;
|
||||
uint energyConsumed = eax;
|
||||
float deltaTime = (float)(time - _lastEnergyTime).TotalSeconds;
|
||||
if (deltaTime >= 0.01)
|
||||
{
|
||||
_powerSensor.Value = _energyUnitMultiplier * unchecked(energyConsumed - _lastEnergyConsumed) / deltaTime;
|
||||
_lastEnergyTime = time;
|
||||
_lastEnergyConsumed = energyConsumed;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var node in deviceInfo.Nodes)
|
||||
{
|
||||
long runningTimeDiff = node.RunningTime - _nodeUsagePrevValue[node.Id];
|
||||
long timeDiff = node.QueryTime.Ticks - _nodeUsagePrevTick[node.Id].Ticks;
|
||||
|
||||
_nodeUsage[node.Id].Value = 100f * runningTimeDiff / timeDiff;
|
||||
_nodeUsagePrevValue[node.Id] = node.RunningTime;
|
||||
_nodeUsagePrevTick[node.Id] = node.QueryTime;
|
||||
ActivateSensor(_nodeUsage[node.Id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetName(string deviceId)
|
||||
{
|
||||
var path = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\" + D3DDisplayDevice.GetActualDeviceIdentifier(deviceId);
|
||||
|
||||
if (Registry.GetValue(path, "DeviceDesc", null) is string deviceDesc)
|
||||
{
|
||||
return deviceDesc.Split(';').Last();
|
||||
}
|
||||
|
||||
return "Intel Integrated Graphics";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
Memory,
|
||||
GpuNvidia,
|
||||
GpuAmd,
|
||||
GpuIntel,
|
||||
Storage,
|
||||
Network,
|
||||
Cooler,
|
||||
|
||||
Reference in New Issue
Block a user