GPU (Windows): detection with intel driver (WIP)

This commit is contained in:
李通洲
2023-12-20 00:49:56 +08:00
parent 2f4b210f33
commit 961e9a6a5f
7 changed files with 7874 additions and 0 deletions
+1
View File
@@ -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
+15
View File
@@ -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
+7649
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -0,0 +1,6 @@
{
"home": "https://github.com/intel/drivers.gpu.control-library",
"license": "README.md",
"version": "e1776b7be2ceead1296204371447b27860d25a66",
"author": "Intel Corporation"
}
+152
View File
@@ -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;
}
+23
View File
@@ -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);
+28
View File
@@ -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;