mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
GPU (Windows): detection with intel driver (WIP)
This commit is contained in:
@@ -630,6 +630,7 @@ elseif(WIN32)
|
||||
src/detection/font/font_windows.c
|
||||
src/detection/gpu/gpu_windows.c
|
||||
src/detection/gpu/gpu_nvidia.c
|
||||
src/detection/gpu/gpu_intel.c
|
||||
src/detection/host/host_windows.c
|
||||
src/detection/icons/icons_windows.c
|
||||
src/detection/libc/libc_windows.cpp
|
||||
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
# Intel Graphics Control Library (IGCL)
|
||||
Header, wrapper library and samples of IGCL version 1.0
|
||||
|
||||
|
||||
# Introduction
|
||||
IGCL is meant to be a collection of high level APIs for all control aspects of hardware, primarily graphics. This is replacement of legacy Intel CUISDK which used to be released only to OEM's and selected customers. IGCL allows global control and tweaking of display, media & 3D capabilities.
|
||||
|
||||
# Notes
|
||||
* IGCL binaries are distributed as part of Intel Graphics driver package.
|
||||
* Header & library wrapper code are provided here to help developers with their application development.
|
||||
* For API/spec questions or issues, for now, use the "Issues" tab under Github. For issues related to an already shipped binary of this spec, contact standard Intel customer support for Graphics.
|
||||
* Performance & Telemetry API's, i.e., Engine/Fan/Telemetry/Frequency/Memory/Overclock/PCI/Power/Temperature are limited to 64-bit applications as of now. This is a Level0 limitation.
|
||||
|
||||
# Usage
|
||||
cmake.exe -B <output_folder> -S <cmake_source_folder> -G "Visual Studio 17 2022" -A x64
|
||||
Vendored
+7649
File diff suppressed because it is too large
Load Diff
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"home": "https://github.com/intel/drivers.gpu.control-library",
|
||||
"license": "README.md",
|
||||
"version": "e1776b7be2ceead1296204371447b27860d25a66",
|
||||
"author": "Intel Corporation"
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
#include "gpu_intel.h"
|
||||
|
||||
#include "3rdparty/igcl/igcl_api.h"
|
||||
#include "common/library.h"
|
||||
|
||||
struct FFIgclData {
|
||||
FF_LIBRARY_SYMBOL(ctlClose)
|
||||
|
||||
FF_LIBRARY_SYMBOL(ctlEnumerateDevices)
|
||||
FF_LIBRARY_SYMBOL(ctlGetDeviceProperties)
|
||||
FF_LIBRARY_SYMBOL(ctlEnumTemperatureSensors)
|
||||
FF_LIBRARY_SYMBOL(ctlTemperatureGetState)
|
||||
FF_LIBRARY_SYMBOL(ctlEnumMemoryModules)
|
||||
FF_LIBRARY_SYMBOL(ctlMemoryGetState)
|
||||
|
||||
bool inited;
|
||||
ctl_api_handle_t apiHandle;
|
||||
} igclData;
|
||||
|
||||
static void shutdownIgcl()
|
||||
{
|
||||
if (igclData.apiHandle)
|
||||
{
|
||||
igclData.ffctlClose(igclData.apiHandle);
|
||||
igclData.apiHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char* ffDetectIntelGpuInfo(FFGpuIntelCondition cond, FFGpuIntelResult result, const char* soName)
|
||||
{
|
||||
if (!igclData.inited)
|
||||
{
|
||||
igclData.inited = true;
|
||||
FF_LIBRARY_LOAD(libigcl, NULL, "dlopen igcl (ControlLib) failed", soName , 1);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libigcl, ctlInit)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlClose)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlEnumerateDevices)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlGetDeviceProperties)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlEnumTemperatureSensors)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlTemperatureGetState)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlEnumMemoryModules)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlMemoryGetState)
|
||||
|
||||
if (ffctlInit(&(ctl_init_args_t) {
|
||||
.AppVersion = CTL_MAKE_VERSION(CTL_IMPL_MAJOR_VERSION, CTL_IMPL_MINOR_VERSION),
|
||||
.flags = CTL_INIT_FLAG_USE_LEVEL_ZERO,
|
||||
.Size = sizeof(ctl_init_args_t),
|
||||
.Version = 0,
|
||||
}, &igclData.apiHandle) != CTL_RESULT_SUCCESS)
|
||||
return "loading igcl library failed";
|
||||
atexit(shutdownIgcl);
|
||||
libigcl = NULL; // don't close igcl
|
||||
}
|
||||
|
||||
if (!igclData.apiHandle)
|
||||
return "loading igcl library failed";
|
||||
|
||||
uint32_t deviceCount = 0;
|
||||
if (igclData.ffctlEnumerateDevices(igclData.apiHandle, &deviceCount, NULL))
|
||||
return "ctlEnumerateDevices(NULL) failed";
|
||||
ctl_device_adapter_handle_t devices[16] = {};
|
||||
if (deviceCount == 0 || deviceCount > sizeof(devices) / sizeof(devices[0]))
|
||||
return "Invalid device count";
|
||||
if (igclData.ffctlEnumerateDevices(igclData.apiHandle, &deviceCount, devices))
|
||||
return "ctlEnumerateDevices(devices) failed";
|
||||
|
||||
ctl_device_adapter_handle_t device = NULL;
|
||||
|
||||
LUID deviceId;
|
||||
ctl_device_adapter_properties_t properties = {
|
||||
.Size = sizeof(properties),
|
||||
.pDeviceID = &deviceId,
|
||||
.device_id_size = sizeof(deviceId),
|
||||
.Version = 2,
|
||||
};
|
||||
for (uint32_t iDev = 0; iDev < deviceCount; iDev++)
|
||||
{
|
||||
if (igclData.ffctlGetDeviceProperties(devices[iDev], &properties) != CTL_RESULT_SUCCESS)
|
||||
continue;
|
||||
|
||||
if (properties.device_type != CTL_DEVICE_TYPE_GRAPHICS)
|
||||
continue;
|
||||
|
||||
if (
|
||||
cond.pciDeviceId == properties.pci_device_id &&
|
||||
cond.pciVendorId == properties.pci_vendor_id &&
|
||||
cond.pciSubSystemId == (((uint32_t) properties.pci_subsys_id << 16u) + (uint32_t) properties.pci_subsys_vendor_id) &&
|
||||
cond.revId == properties.rev_id)
|
||||
{
|
||||
device = devices[iDev];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!device)
|
||||
return "Device not found";
|
||||
|
||||
if (result.coreCount)
|
||||
*result.coreCount = properties.num_slices * properties.num_sub_slices_per_slice * properties.num_eus_per_sub_slice;
|
||||
|
||||
if (result.memory)
|
||||
{
|
||||
ctl_mem_handle_t memoryModules[16];
|
||||
uint32_t memoryCount = sizeof(memoryModules) / sizeof(memoryModules[0]);
|
||||
if (igclData.ffctlEnumMemoryModules(device, &memoryCount, memoryModules) == CTL_RESULT_SUCCESS)
|
||||
{
|
||||
result.memory->used = 0;
|
||||
result.memory->total = 0;
|
||||
for (uint32_t iMem = 0; iMem < memoryCount; iMem++)
|
||||
{
|
||||
ctl_mem_state_t memoryState = {
|
||||
.Size = sizeof(ctl_mem_state_t),
|
||||
.Version = 0,
|
||||
};
|
||||
if (igclData.ffctlMemoryGetState(memoryModules[iMem], &memoryState) == CTL_RESULT_SUCCESS)
|
||||
{
|
||||
result.memory->total += memoryState.size;
|
||||
result.memory->used += memoryState.size - memoryState.free;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.type)
|
||||
{
|
||||
*result.type = properties.graphics_adapter_properties & CTL_ADAPTER_PROPERTIES_FLAG_INTEGRATED
|
||||
? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
|
||||
}
|
||||
|
||||
if (result.temp)
|
||||
{
|
||||
ctl_temp_handle_t sensors[16];
|
||||
uint32_t sensorCount = sizeof(sensors) / sizeof(sensors[0]);
|
||||
if (igclData.ffctlEnumTemperatureSensors(device, &sensorCount, sensors) == CTL_RESULT_SUCCESS)
|
||||
{
|
||||
double sumValue = 0;
|
||||
uint32_t availableCount = 0;
|
||||
for (uint32_t iSensor = 0; iSensor < sensorCount; iSensor++)
|
||||
{
|
||||
double value;
|
||||
if (igclData.ffctlTemperatureGetState(sensors[iSensor], &value) == CTL_RESULT_SUCCESS)
|
||||
{
|
||||
sumValue += value;
|
||||
availableCount++;
|
||||
}
|
||||
}
|
||||
*result.temp = sumValue / availableCount;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "gpu.h"
|
||||
|
||||
// Use pciBusId if not NULL; use pciDeviceId and pciSubSystemId otherwise
|
||||
typedef struct FFGpuIntelCondition
|
||||
{
|
||||
uint32_t pciDeviceId;
|
||||
uint32_t pciVendorId;
|
||||
uint32_t pciSubSystemId;
|
||||
uint32_t revId;
|
||||
} FFGpuIntelCondition;
|
||||
|
||||
// detect x if not NULL
|
||||
typedef struct FFGpuIntelResult
|
||||
{
|
||||
double* temp;
|
||||
FFGPUMemory* memory;
|
||||
uint32_t* coreCount;
|
||||
FFGPUType* type;
|
||||
} FFGpuIntelResult;
|
||||
|
||||
const char* ffDetectIntelGpuInfo(FFGpuIntelCondition cond, FFGpuIntelResult result, const char* soName);
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "gpu.h"
|
||||
#include "detection/gpu/gpu_intel.h"
|
||||
#include "detection/gpu/gpu_nvidia.h"
|
||||
#include "util/windows/unicode.h"
|
||||
#include "util/windows/registry.h"
|
||||
@@ -102,6 +103,33 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
}, "nvml.dll");
|
||||
}
|
||||
}
|
||||
|
||||
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL && (options->temp || options->useNvml))
|
||||
{
|
||||
uint32_t vendorId, deviceId, subSystemId, revId;
|
||||
// See: https://download.nvidia.com/XFree86/Linux-x86_64/545.23.06/README/supportedchips.html
|
||||
// displayDevice.DeviceID = MatchingDeviceId "PCI\\VEN_8086&DEV_46A6&SUBSYS_13241462&REV_0C"
|
||||
if (swscanf(displayDevice.DeviceID, L"PCI\\VEN_%x&DEV_%x&SUBSYS_%x&REV_%x", &vendorId, &deviceId, &subSystemId, &revId) == 4)
|
||||
{
|
||||
ffDetectIntelGpuInfo((FFGpuIntelCondition) {
|
||||
.pciDeviceId = deviceId,
|
||||
.pciVendorId = vendorId,
|
||||
.pciSubSystemId = subSystemId,
|
||||
.revId = revId,
|
||||
}, (FFGpuIntelResult) {
|
||||
.temp = options->temp ? &gpu->temperature : NULL,
|
||||
.memory = options->useNvml ? &gpu->dedicated : NULL,
|
||||
.coreCount = options->useNvml ? (uint32_t*) &gpu->coreCount : NULL,
|
||||
.type = options->useNvml ? (uint32_t*) &gpu->type : NULL,
|
||||
},
|
||||
#ifdef _WIN64
|
||||
"ControlLib.dll"
|
||||
#else
|
||||
"ControlLib32.dll"
|
||||
#endif
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
Reference in New Issue
Block a user