fix: skip integrated GPU in IGCL enumeration to prevent duplicate hardware entries (#2217)
IGCL's ctlEnumerateDevices returns all Intel graphics devices including the integrated GPU, but IntelDiscreteGpu was created for every device without filtering. This caused the iGPU to appear twice: once from the IGCL path (as IntelDiscreteGpu) and once from the D3D path (as IntelIntegratedGpu), with overlapping sensors. Check the CTL_ADAPTER_PROPERTIES_FLAG_INTEGRATED flag on each device's graphics_adapter_properties and skip integrated adapters, since they are already handled by IntelIntegratedGpu via D3D enumeration. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
// 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.
|
||||
@@ -6,6 +6,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using LibreHardwareMonitor.Hardware.Cpu;
|
||||
using LibreHardwareMonitor.Interop;
|
||||
@@ -21,7 +22,7 @@ internal class IntelGpuGroup : IGroup
|
||||
{
|
||||
if (!Software.OperatingSystem.IsUnix)
|
||||
{
|
||||
// Initialize Intel GCL for discrete GPUs
|
||||
// Initialize Intel GCL for discrete and integrated GPU telemetry
|
||||
bool gclInitialized = false;
|
||||
|
||||
try
|
||||
@@ -56,6 +57,22 @@ internal class IntelGpuGroup : IGroup
|
||||
{
|
||||
try
|
||||
{
|
||||
// Skip integrated GPUs — they are handled separately by IntelIntegratedGpu
|
||||
// via the D3D enumeration path below. IGCL's ctlEnumerateDevices returns all
|
||||
// Intel graphics devices including the iGPU, which would otherwise cause the
|
||||
// same physical device to appear twice with overlapping sensors.
|
||||
var props = new IntelGcl.ctl_device_adapter_properties_t
|
||||
{
|
||||
Size = (uint)Marshal.SizeOf<IntelGcl.ctl_device_adapter_properties_t>(),
|
||||
Version = 2
|
||||
};
|
||||
|
||||
if (IntelGcl.ctlGetDeviceProperties(handle, ref props) == (int)IntelGcl.ctl_result_t.CTL_RESULT_SUCCESS &&
|
||||
(props.graphics_adapter_properties & (uint)IntelGcl.ctl_adapter_properties_flag_t.CTL_ADAPTER_PROPERTIES_FLAG_INTEGRATED) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var gpu = new IntelDiscreteGpu(handle, settings);
|
||||
if (gpu.IsValid)
|
||||
{
|
||||
|
||||
@@ -48,6 +48,17 @@ internal static class IntelGcl
|
||||
CTL_DEVICE_TYPE_MAX
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adapter properties flags from ctl_adapter_properties_flags_t.
|
||||
/// The graphics_adapter_properties field is a bitmask of these values.
|
||||
/// </summary>
|
||||
public enum ctl_adapter_properties_flag_t : uint
|
||||
{
|
||||
CTL_ADAPTER_PROPERTIES_FLAG_INTEGRATED = 1 << 0,
|
||||
CTL_ADAPTER_PROPERTIES_FLAG_LDA_PRIMARY = 1 << 1,
|
||||
CTL_ADAPTER_PROPERTIES_FLAG_LDA_SECONDARY = 1 << 2,
|
||||
}
|
||||
|
||||
public enum ctl_fan_speed_mode_t
|
||||
{
|
||||
CTL_FAN_SPEED_MODE_DEFAULT = 0,
|
||||
|
||||
Reference in New Issue
Block a user