mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 09:58:03 +02:00
GPU: detects max PCI gen & link width
This commit is contained in:
@@ -33,5 +33,6 @@ static inline const char* ffFindFileName(const char* file) {
|
||||
#if _WIN32
|
||||
const char* ffDebugWin32Error(DWORD errorCode);
|
||||
const char* ffDebugNtStatus(NTSTATUS status);
|
||||
const char* ffDebugConfigRet(unsigned long /*CONFIGRET*/ ret);
|
||||
const char* ffDebugHResult(HRESULT hr);
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "common/windows/nt.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <cfgmgr32.h>
|
||||
|
||||
const char* ffDebugWin32Error(DWORD errorCode) {
|
||||
static char buffer[512];
|
||||
@@ -34,6 +35,10 @@ const char* ffDebugWin32Error(DWORD errorCode) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
const char* ffDebugConfigRet(CONFIGRET ret) {
|
||||
return ffDebugWin32Error(CM_MapCrToWin32Err(ret, ERROR_INTERNAL_ERROR));
|
||||
}
|
||||
|
||||
const char* ffDebugNtStatus(NTSTATUS status) {
|
||||
return ffDebugWin32Error(RtlNtStatusToDosError(status));
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@ extern int ADL2_Adapter_DedicatedVRAMUsage_Get(ADL_CONTEXT_HANDLE context, int i
|
||||
// Function to get the ASICFamilyType from the adapter.
|
||||
extern int ADL2_Adapter_ASICFamilyType_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* lpAsicTypes, int* lpValids);
|
||||
|
||||
// This function retrieves the chipset information for a specified adapter.
|
||||
extern int ADL2_Adapter_ChipSetInfo_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLChipSetInfo* lpChipSetInfo);
|
||||
|
||||
// Function to retrieve current power management capabilities.
|
||||
extern int ADL2_Overdrive_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* iSupported, int* iEnabled, int* iVersion);
|
||||
|
||||
|
||||
@@ -152,6 +152,18 @@ typedef struct _D3DKMT_QUERY_DEVICE_IDS {
|
||||
D3DKMT_DEVICE_IDS DeviceIds; // out:
|
||||
} D3DKMT_QUERY_DEVICE_IDS;
|
||||
|
||||
typedef enum _D3DKMT_PNP_KEY_TYPE {
|
||||
D3DKMT_PNP_KEY_HARDWARE,
|
||||
D3DKMT_PNP_KEY_SOFTWARE
|
||||
} D3DKMT_PNP_KEY_TYPE;
|
||||
|
||||
typedef struct _D3DKMT_QUERY_PHYSICAL_ADAPTER_PNP_KEY {
|
||||
UINT PhysicalAdapterIndex;
|
||||
D3DKMT_PNP_KEY_TYPE PnPKeyType;
|
||||
WCHAR* pDest;
|
||||
UINT* pCchDest;
|
||||
} D3DKMT_QUERY_PHYSICAL_ADAPTER_PNP_KEY;
|
||||
|
||||
typedef enum _QAI_DRIVERVERSION {
|
||||
KMT_DRIVERVERSION_WDDM_1_0 = 1000, // Windows Vista
|
||||
KMT_DRIVERVERSION_WDDM_1_1_PRERELEASE = 1102, // Windows Vista with prereleased Win7 features
|
||||
@@ -187,6 +199,7 @@ typedef enum _KMTQUERYADAPTERINFOTYPE {
|
||||
KMTQAITYPE_UMD_DRIVER_VERSION = 18,
|
||||
KMTQAITYPE_NODEMETADATA = 25, // WDDM 2.0, Windows 10
|
||||
KMTQAITYPE_PHYSICALADAPTERDEVICEIDS = 31,
|
||||
KMTQAITYPE_PHYSICALADAPTERPNPKEY = 41, // WDDM 2.2, Windows 10 (1703)
|
||||
KMTQAITYPE_QUERY_ADAPTER_UNIQUE_GUID = 60, // WDDM 2.4, Windows 10 (1803)
|
||||
KMTQAITYPE_NODEPERFDATA = 61,
|
||||
KMTQAITYPE_ADAPTERPERFDATA = 62,
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#define FF_GPU_CORE_COUNT_UNSET -1
|
||||
#define FF_GPU_VMEM_SIZE_UNSET ((uint64_t) -1)
|
||||
#define FF_GPU_FREQUENCY_UNSET 0
|
||||
#define FF_GPU_PCI_INFO_UNSET 0
|
||||
#define FF_GPU_CORE_USAGE_UNSET (-DBL_MAX)
|
||||
#define FF_GPU_INDEX_UNSET ((uint32_t) -1)
|
||||
|
||||
@@ -46,6 +47,8 @@ typedef struct FFGPUResult {
|
||||
double coreUsage;
|
||||
int32_t coreCount;
|
||||
uint32_t frequency; // Maximum time clock frequency in MHz
|
||||
uint16_t pcieGen;
|
||||
uint16_t pcieLanes;
|
||||
FFGPUMemory dedicated;
|
||||
FFGPUMemory shared;
|
||||
uint64_t deviceId;
|
||||
|
||||
@@ -52,6 +52,7 @@ struct FFAdlData {
|
||||
FF_LIBRARY_SYMBOL(ADL2_Adapter_MemoryInfo2_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_Adapter_DedicatedVRAMUsage_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_Adapter_ASICFamilyType_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_Adapter_ChipSetInfo_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_Overdrive_Caps)
|
||||
FF_LIBRARY_SYMBOL(ADL2_OverdriveN_CapabilitiesX2_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_OverdriveN_SystemClocksX2_Get)
|
||||
@@ -89,6 +90,7 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Adapter_MemoryInfo2_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Adapter_DedicatedVRAMUsage_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Adapter_ASICFamilyType_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Adapter_ChipSetInfo_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Overdrive_Caps)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_OverdriveN_CapabilitiesX2_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_OverdriveN_SystemClocksX2_Get)
|
||||
@@ -233,6 +235,26 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu
|
||||
FF_DEBUG("Setting adapter name: %s; UDID: %s, Present: %d, Exist: %d", device->strAdapterName, device->strUDID, device->iPresent, device->iExist);
|
||||
}
|
||||
|
||||
if (result.pcieGen || result.pcieLanes) {
|
||||
ADLChipSetInfo chipSetInfo;
|
||||
int status = adlData.ffADL2_Adapter_ChipSetInfo_Get(adlData.apiHandle, device->iAdapterIndex, &chipSetInfo);
|
||||
FF_DEBUG("ADL2_Adapter_ChipSetInfo_Get returned %s (%d)", ffAdlStatusToString(status), status);
|
||||
|
||||
if (status == ADL_OK) {
|
||||
FF_DEBUG("Chipset info - Bus Type: %d, PCIe Lane Width: %d", chipSetInfo.iBusType, chipSetInfo.iMaxPCIELaneWidth);
|
||||
if (result.pcieGen && chipSetInfo.iBusType >= 2) {
|
||||
*result.pcieGen = (uint16_t) (chipSetInfo.iBusType - 2);
|
||||
FF_DEBUG("Got PCIe Gen: %u", *result.pcieGen);
|
||||
}
|
||||
if (result.pcieLanes && chipSetInfo.iMaxPCIELaneWidth > 0) {
|
||||
*result.pcieLanes = (uint16_t) chipSetInfo.iMaxPCIELaneWidth;
|
||||
FF_DEBUG("Got PCIe Lanes: %u", *result.pcieLanes);
|
||||
}
|
||||
} else {
|
||||
FF_DEBUG("Failed to get chipset information");
|
||||
}
|
||||
}
|
||||
|
||||
int odVersion = 0;
|
||||
|
||||
{
|
||||
|
||||
@@ -118,6 +118,7 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus) {
|
||||
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
|
||||
gpu->type = FF_GPU_TYPE_UNKNOWN;
|
||||
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
||||
gpu->pcieGen = gpu->pcieLanes = FF_GPU_PCI_INFO_UNSET;
|
||||
IORegistryEntryGetRegistryEntryID(registryEntry, &gpu->deviceId);
|
||||
ffStrbufInitStatic(&gpu->platformApi, "IOKit");
|
||||
|
||||
|
||||
@@ -148,6 +148,7 @@ const char* ffGPUDetectByDrmBSD(const FFGPUOptions* options, FFlist* gpus) {
|
||||
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
|
||||
gpu->deviceId = ffGPUPciAddr2Id(pciInfo.domain, pciInfo.bus, pciInfo.dev, pciInfo.func);
|
||||
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
||||
gpu->pcieGen = gpu->pcieLanes = FF_GPU_PCI_INFO_UNSET;
|
||||
|
||||
char driverName[64];
|
||||
driverName[0] = '\0';
|
||||
|
||||
@@ -36,6 +36,8 @@ typedef struct FFGpuDriverResult {
|
||||
FFGPUType* type;
|
||||
uint32_t* frequency;
|
||||
FFstrbuf* name;
|
||||
uint16_t* pcieGen;
|
||||
uint16_t* pcieLanes;
|
||||
} FFGpuDriverResult;
|
||||
|
||||
const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName);
|
||||
|
||||
@@ -113,6 +113,8 @@ const char* ffDrmDetectAmdgpu(const FFGPUOptions* options, FFGPUResult* gpu, con
|
||||
gpu->frequency = (uint32_t) (devInfo.max_engine_clock / 1000u);
|
||||
gpu->index = FF_GPU_INDEX_UNSET;
|
||||
gpu->type = devInfo.ids_flags & AMDGPU_IDS_FLAGS_FUSION ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
|
||||
gpu->pcieGen = (uint16_t) devInfo.pcie_gen;
|
||||
gpu->pcieLanes = (uint16_t) devInfo.pcie_num_lanes;
|
||||
#define FF_VRAM_CASE(name, value) \
|
||||
case value /* AMDGPU_VRAM_TYPE_ ## name */: \
|
||||
ffStrbufSetStatic(&gpu->memoryType, #name); \
|
||||
@@ -373,6 +375,8 @@ const char* ffGPUDetectDriverSpecific(const FFGPUOptions* options, FFGPUResult*
|
||||
.type = &gpu->type,
|
||||
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
|
||||
.name = &gpu->name,
|
||||
.pcieGen = options->driverSpecific ? &gpu->pcieGen : NULL,
|
||||
.pcieLanes = options->driverSpecific ? &gpu->pcieLanes : NULL,
|
||||
},
|
||||
soName);
|
||||
}
|
||||
|
||||
@@ -130,6 +130,7 @@ const char* ffDetectGPUImpl(FF_A_UNUSED const FFGPUOptions* options, FFlist* gpu
|
||||
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
|
||||
gpu->deviceId = ffGPUPciAddr2Id(0, pciBus, pciDev, pciFunc);
|
||||
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
||||
gpu->pcieGen = gpu->pcieLanes = FF_GPU_PCI_INFO_UNSET;
|
||||
|
||||
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD) {
|
||||
ffGPUQueryAmdGpuName(deviceId, revision, gpu);
|
||||
|
||||
@@ -37,6 +37,7 @@ const char* ffDetectGPUImpl(FF_A_UNUSED const FFGPUOptions* options, FFlist* gpu
|
||||
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
|
||||
gpu->deviceId = ffGPUPciAddr2Id(0, dev.bus, dev.device, dev.function);
|
||||
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
||||
gpu->pcieGen = gpu->pcieLanes = FF_GPU_PCI_INFO_UNSET;
|
||||
|
||||
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD) {
|
||||
ffGPUQueryAmdGpuName(dev.device_id, dev.revision, gpu);
|
||||
|
||||
@@ -16,6 +16,7 @@ struct FFIgclData {
|
||||
FF_LIBRARY_SYMBOL(ctlMemoryGetState)
|
||||
FF_LIBRARY_SYMBOL(ctlEnumFrequencyDomains)
|
||||
FF_LIBRARY_SYMBOL(ctlFrequencyGetProperties)
|
||||
FF_LIBRARY_SYMBOL(ctlPciGetProperties)
|
||||
|
||||
bool inited;
|
||||
ctl_api_handle_t apiHandle;
|
||||
@@ -43,6 +44,7 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlMemoryGetState)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlEnumFrequencyDomains)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlFrequencyGetProperties)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlPciGetProperties)
|
||||
|
||||
if (ffctlInit(&(ctl_init_args_t) {
|
||||
.AppVersion = CTL_IMPL_VERSION,
|
||||
@@ -227,5 +229,17 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
|
||||
ffStrbufSetS(result.name, properties.name);
|
||||
}
|
||||
|
||||
if (result.pcieGen || result.pcieLanes) {
|
||||
ctl_pci_properties_t pciProps = { .Size = sizeof(pciProps), .Version = 0 };
|
||||
if (igclData.ffctlPciGetProperties(device, &pciProps) == CTL_RESULT_SUCCESS) {
|
||||
if (result.pcieGen && pciProps.maxSpeed.gen > 0) {
|
||||
*result.pcieGen = (uint16_t) pciProps.maxSpeed.gen;
|
||||
}
|
||||
if (result.pcieLanes && pciProps.maxSpeed.width > 0) {
|
||||
*result.pcieLanes = (uint16_t) pciProps.maxSpeed.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -368,6 +368,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
|
||||
gpu->deviceId = ffGPUPciAddr2Id(pciDomain, pciBus, pciDevice, pciFunc);
|
||||
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
||||
gpu->pcieGen = gpu->pcieLanes = FF_GPU_PCI_INFO_UNSET;
|
||||
|
||||
char drmKeyBuffer[8];
|
||||
if (!drmKey) {
|
||||
@@ -393,6 +394,36 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
pciDetectDriver(&gpu->driver, deviceDir, buffer, drmKey);
|
||||
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
|
||||
|
||||
ffStrbufAppendS(deviceDir, "/max_link_speed");
|
||||
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
|
||||
int32_t maxLinkSpeed = (int32_t) ffStrbufToSInt(buffer, FF_GPU_PCI_INFO_UNSET);
|
||||
if (maxLinkSpeed >= 64) {
|
||||
gpu->pcieGen = 6;
|
||||
} else if (maxLinkSpeed >= 32) {
|
||||
gpu->pcieGen = 5;
|
||||
} else if (maxLinkSpeed >= 16) {
|
||||
gpu->pcieGen = 4;
|
||||
} else if (maxLinkSpeed >= 8) {
|
||||
gpu->pcieGen = 3;
|
||||
} else if (maxLinkSpeed >= 5) {
|
||||
gpu->pcieGen = 2;
|
||||
} else if (maxLinkSpeed >= 2) { // 2.5
|
||||
gpu->pcieGen = 1;
|
||||
}
|
||||
}
|
||||
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
|
||||
|
||||
if (gpu->pcieGen != FF_GPU_PCI_INFO_UNSET) {
|
||||
ffStrbufAppendS(deviceDir, "/max_link_width");
|
||||
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
|
||||
int32_t maxLinkWidth = (int32_t) ffStrbufToSInt(buffer, FF_GPU_PCI_INFO_UNSET);
|
||||
if (maxLinkWidth > 0 && maxLinkWidth < 255) { // kernel returns 255 if the value is unknown
|
||||
gpu->pcieLanes = (uint16_t) maxLinkWidth;
|
||||
}
|
||||
}
|
||||
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
|
||||
}
|
||||
|
||||
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD) {
|
||||
bool ok = false;
|
||||
if (drmKey && options->driverSpecific) {
|
||||
|
||||
@@ -97,6 +97,7 @@ const char* ffDetectGPUImpl(FF_A_UNUSED const FFGPUOptions* options, FFlist* gpu
|
||||
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
|
||||
gpu->deviceId = ffGPUPciAddr2Id(0, bus, dev, func);
|
||||
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
||||
gpu->pcieGen = gpu->pcieLanes = FF_GPU_PCI_INFO_UNSET;
|
||||
|
||||
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD) {
|
||||
ffGPUQueryAmdGpuName(PCI_PRODUCT(pciid), PCI_REVISION(pciid), gpu);
|
||||
|
||||
@@ -14,6 +14,8 @@ struct FFNvmlData {
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetNumGpuCores)
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetMaxClockInfo)
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetUtilizationRates)
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetMaxPcieLinkGeneration)
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetMaxPcieLinkWidth)
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetBrand)
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetIndex)
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetName)
|
||||
@@ -159,6 +161,8 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMemoryInfo)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetNumGpuCores)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMaxClockInfo)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMaxPcieLinkGeneration)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMaxPcieLinkWidth)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetUtilizationRates)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetBrand)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetIndex)
|
||||
@@ -288,6 +292,20 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
|
||||
}
|
||||
}
|
||||
|
||||
if (result.pcieGen) {
|
||||
unsigned int value;
|
||||
if (nvmlData.ffnvmlDeviceGetMaxPcieLinkGeneration(device, &value) == NVML_SUCCESS) {
|
||||
*result.pcieGen = (uint16_t) value;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.pcieLanes) {
|
||||
unsigned int value;
|
||||
if (nvmlData.ffnvmlDeviceGetMaxPcieLinkWidth(device, &value) == NVML_SUCCESS) {
|
||||
*result.pcieLanes = (uint16_t) value;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
#else
|
||||
|
||||
@@ -86,6 +86,7 @@ const char* detectByPci(FF_A_UNUSED const FFGPUOptions* options, FFlist* gpus) {
|
||||
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
|
||||
gpu->deviceId = ffGPUPciAddr2Id(0, bus, dev, func);
|
||||
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
||||
gpu->pcieGen = gpu->pcieLanes = FF_GPU_PCI_INFO_UNSET;
|
||||
|
||||
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD) {
|
||||
ffGPUQueryAmdGpuName(PCI_PRODUCT(pciid), PCI_REVISION(pciid), gpu);
|
||||
|
||||
@@ -21,6 +21,7 @@ static int walkDevTree(di_node_t node, FF_A_UNUSED di_minor_t minor, FFlist* gpu
|
||||
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
|
||||
gpu->deviceId = strtoul(di_bus_addr(node), NULL, 16);
|
||||
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
||||
gpu->pcieGen = gpu->pcieLanes = FF_GPU_PCI_INFO_UNSET;
|
||||
|
||||
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD) {
|
||||
int* revId;
|
||||
|
||||
@@ -11,31 +11,26 @@
|
||||
#if _WIN32
|
||||
#include "common/windows/unicode.h"
|
||||
#include "common/windows/registry.h"
|
||||
#include "common/mallocHelper.h"
|
||||
|
||||
#if FF_WIN81_COMPAT
|
||||
#include "common/mallocHelper.h"
|
||||
#include <windows.h>
|
||||
#include <cfgmgr32.h>
|
||||
#include <devguid.h>
|
||||
#define INITGUID
|
||||
#include <windows.h>
|
||||
#include <cfgmgr32.h>
|
||||
#include <devguid.h>
|
||||
#include <pciprop.h>
|
||||
|
||||
#define GUID_DEVCLASS_DISPLAY_STRING L"{4d36e968-e325-11ce-bfc1-08002be10318}" // Found in <devguid.h>
|
||||
#define GUID_DEVCLASS_DISPLAY_STRING L"{4d36e968-e325-11ce-bfc1-08002be10318}" // Found in <devguid.h>
|
||||
|
||||
static bool queryDeviceIdsFallback(D3DKMT_ADAPTERADDRESS adapterAddress, D3DKMT_DEVICE_IDS* outDeviceIds) {
|
||||
FF_DEBUG("KMTQAITYPE_PHYSICALADAPTERDEVICEIDS failed. Attempting queryDeviceIdsFallback: bus=%u device=%u function=%u",
|
||||
adapterAddress.BusNumber,
|
||||
adapterAddress.DeviceNumber,
|
||||
adapterAddress.FunctionNumber);
|
||||
|
||||
if (adapterAddress.BusNumber == -1u) {
|
||||
FF_DEBUG("Invalid adapter address, cannot query device IDs");
|
||||
return false;
|
||||
}
|
||||
static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds) {
|
||||
FF_DEBUG("Query PCI device info: %08llX", gpu->deviceId);
|
||||
|
||||
static FFlist deviceIdsCache;
|
||||
static bool initialized;
|
||||
typedef struct {
|
||||
uint32_t maxLinkSpeed;
|
||||
uint32_t maxLinkWidth;
|
||||
D3DKMT_DEVICE_IDS deviceIds;
|
||||
D3DKMT_ADAPTERADDRESS adapterAddress;
|
||||
uint64_t adapterAddress;
|
||||
} CacheEntry;
|
||||
|
||||
if (!initialized) {
|
||||
@@ -79,34 +74,29 @@ static bool queryDeviceIdsFallback(D3DKMT_ADAPTERADDRESS adapterAddress, D3DKMT_
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t pciBus = 0;
|
||||
CacheEntry* entry = FF_LIST_ADD(CacheEntry, deviceIdsCache);
|
||||
*entry = (CacheEntry) {};
|
||||
|
||||
// L"PCI\\VEN_10DE&DEV_2782&SUBSYS_513417AA&REV_A1\\4&3674a6b9&0&0008"
|
||||
if (swscanf(devId + 4, L"VEN_%x&DEV_%x&SUBSYS_%4x%4x&REV_%x", &entry->deviceIds.VendorID, &entry->deviceIds.DeviceID, &entry->deviceIds.SubSystemID, &entry->deviceIds.SubVendorID, &entry->deviceIds.RevisionID) >= 2) {
|
||||
FF_DEBUG("Parsed PCI IDs - Vendor: 0x%04x, Device: 0x%04x, SubVendor: 0x%04x, SubSystem: 0x%04x, Rev: 0x%04x", entry->deviceIds.VendorID, entry->deviceIds.DeviceID, entry->deviceIds.SubVendorID, entry->deviceIds.SubSystemID, entry->deviceIds.RevisionID);
|
||||
// I thought it was DXGKMDT_OPM_BUS_TYPE_PCI, but it turns out to be false
|
||||
// Who TF knows what 1 actually means. It's just reported by most graphic cards
|
||||
// And yeah, DXGKMDT_OPM_BUS_TYPE_PCIEXPRESS (3) exists
|
||||
entry->deviceIds.BusType = 1;
|
||||
} else {
|
||||
FF_DEBUG("Failed to parse PCI IDs from device ID string");
|
||||
deviceIdsCache.length--; // remove the cache entry since it's not valid
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t pciBus = 0;
|
||||
ULONG pciBufLen = sizeof(pciBus);
|
||||
if (CM_Get_DevNode_Registry_PropertyW(devInst, CM_DRP_BUSNUMBER, NULL, &pciBus, &pciBufLen, 0) == CR_SUCCESS) {
|
||||
uint32_t pciAddr = 0;
|
||||
pciBufLen = sizeof(pciAddr);
|
||||
if (CM_Get_DevNode_Registry_PropertyW(devInst, CM_DRP_ADDRESS, NULL, &pciAddr, &pciBufLen, 0) == CR_SUCCESS) {
|
||||
CacheEntry* entry = FF_LIST_ADD(CacheEntry, deviceIdsCache);
|
||||
|
||||
entry->deviceIds = (D3DKMT_DEVICE_IDS) {};
|
||||
// L"PCI\\VEN_10DE&DEV_2782&SUBSYS_513417AA&REV_A1\\4&3674a6b9&0&0008"
|
||||
if (swscanf(devId + 4, L"VEN_%x&DEV_%x&SUBSYS_%4x%4x&REV_%x", &entry->deviceIds.VendorID, &entry->deviceIds.DeviceID, &entry->deviceIds.SubSystemID, &entry->deviceIds.SubVendorID, &entry->deviceIds.RevisionID) >= 2) {
|
||||
FF_DEBUG("Parsed PCI IDs - Vendor: 0x%04x, Device: 0x%04x, SubVendor: 0x%04x, SubSystem: 0x%04x, Rev: 0x%04x", entry->deviceIds.VendorID, entry->deviceIds.DeviceID, entry->deviceIds.SubVendorID, entry->deviceIds.SubSystemID, entry->deviceIds.RevisionID);
|
||||
// I thought it was DXGKMDT_OPM_BUS_TYPE_PCI, but it turns out to be false
|
||||
// Who TF knows what 1 actually means. It's just reported by most graphic cards
|
||||
// And yeah, DXGKMDT_OPM_BUS_TYPE_PCIEXPRESS (3) exists
|
||||
entry->deviceIds.BusType = 1;
|
||||
} else {
|
||||
FF_DEBUG("Failed to parse PCI IDs from device ID string");
|
||||
deviceIdsCache.length--; // remove the cache entry since it's not valid
|
||||
continue;
|
||||
}
|
||||
|
||||
entry->adapterAddress = (D3DKMT_ADAPTERADDRESS) {
|
||||
.BusNumber = pciBus,
|
||||
.DeviceNumber = (pciAddr >> 16) & 0xFFFF,
|
||||
.FunctionNumber = pciAddr & 0xFFFF,
|
||||
};
|
||||
entry->adapterAddress = ffGPUPciAddr2Id(0, pciBus, (pciAddr >> 16) & 0xFFFF, pciAddr & 0xFFFF);
|
||||
FF_DEBUG("Cached device IDs for PCI bus %u: vendor=0x%04x device=0x%04x", pciBus, entry->deviceIds.VendorID, entry->deviceIds.DeviceID);
|
||||
} else {
|
||||
FF_DEBUG("Failed to get PCI address");
|
||||
@@ -114,21 +104,44 @@ static bool queryDeviceIdsFallback(D3DKMT_ADAPTERADDRESS adapterAddress, D3DKMT_
|
||||
} else {
|
||||
FF_DEBUG("Failed to get PCI bus number");
|
||||
}
|
||||
|
||||
pciBufLen = sizeof(entry->maxLinkSpeed);
|
||||
DEVPROPTYPE propType;
|
||||
// Reports PCEe gen despite the PKEY name
|
||||
CONFIGRET ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_MaxLinkSpeed, &propType, (PBYTE) &entry->maxLinkSpeed, &pciBufLen, 0);
|
||||
if (ret == CR_SUCCESS) {
|
||||
FF_DEBUG("PCIe GEN: %u", entry->maxLinkSpeed);
|
||||
} else {
|
||||
FF_DEBUG("Failed to get PCIe GEN: %s", ffDebugConfigRet(ret));
|
||||
}
|
||||
|
||||
if (entry->maxLinkSpeed != FF_GPU_PCI_INFO_UNSET) {
|
||||
pciBufLen = sizeof(entry->maxLinkWidth);
|
||||
ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_MaxLinkWidth, &propType, (PBYTE) &entry->maxLinkWidth, &pciBufLen, 0);
|
||||
if (ret == CR_SUCCESS) {
|
||||
FF_DEBUG("PCIe max link width: %u", entry->maxLinkWidth);
|
||||
} else {
|
||||
FF_DEBUG("Failed to get PCIe max link width: %s", ffDebugConfigRet(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FF_LIST_FOR_EACH (CacheEntry, entry, deviceIdsCache) {
|
||||
if (memcmp(&entry->adapterAddress, &adapterAddress, sizeof(adapterAddress)) == 0) {
|
||||
FF_DEBUG("Cache hit for adapter address: bus=%u device=%u function=%u", adapterAddress.BusNumber, adapterAddress.DeviceNumber, adapterAddress.FunctionNumber);
|
||||
*outDeviceIds = entry->deviceIds;
|
||||
if (gpu->deviceId == entry->adapterAddress) {
|
||||
FF_DEBUG("Cache hit for adapter address: %08llX", gpu->deviceId);
|
||||
if (outDeviceIds->VendorID != -1u) {
|
||||
*outDeviceIds = entry->deviceIds;
|
||||
}
|
||||
gpu->pcieGen = (uint16_t) entry->maxLinkSpeed;
|
||||
gpu->pcieLanes = (uint16_t) entry->maxLinkWidth;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
FF_DEBUG("Cache miss for adapter address: bus=%u device=%u function=%u", adapterAddress.BusNumber, adapterAddress.DeviceNumber, adapterAddress.FunctionNumber);
|
||||
FF_DEBUG("Cache miss for adapter address: %08llX", gpu->deviceId);
|
||||
return false;
|
||||
}
|
||||
#endif // FF_WIN81_COMPAT
|
||||
|
||||
static bool queryVendorNameViaRegistry(FFstrbuf* vendor, D3DKMT_HANDLE hAdapter) {
|
||||
// `KMTQAITYPE_QUERY_ADAPTER_UNIQUE_GUID` reports the GUID value used by the adapter's registry key (DirectX and Video)
|
||||
@@ -278,6 +291,7 @@ ffGPUDetectWsl2
|
||||
: adapterType.HybridDiscrete
|
||||
? FF_GPU_TYPE_DISCRETE
|
||||
: FF_GPU_TYPE_UNKNOWN;
|
||||
gpu->pcieGen = gpu->pcieLanes = FF_GPU_PCI_INFO_UNSET;
|
||||
|
||||
D3DKMT_DRIVERVERSION wddmVersion = KMT_DRIVERVERSION_WDDM_2_0;
|
||||
status = D3DKMTQueryAdapterInfo(&(D3DKMT_QUERYADAPTERINFO) {
|
||||
@@ -323,11 +337,7 @@ ffGPUDetectWsl2
|
||||
.pPrivateDriverData = &deviceIds,
|
||||
.PrivateDriverDataSize = sizeof(deviceIds),
|
||||
});
|
||||
if (NT_SUCCESS(status)
|
||||
#if FF_WIN81_COMPAT
|
||||
|| queryDeviceIdsFallback(adapterAddress, &deviceIds.DeviceIds)
|
||||
#endif
|
||||
) {
|
||||
if (NT_SUCCESS(status)) {
|
||||
ffStrbufSetStatic(&gpu->vendor, ffGPUGetVendorString(deviceIds.DeviceIds.VendorID));
|
||||
FF_DEBUG("Adapter #%u vendor/device IDs: vendor=0x%04x device=0x%04x",
|
||||
i,
|
||||
@@ -338,6 +348,14 @@ ffGPUDetectWsl2
|
||||
FF_DEBUG("KMTQAITYPE_PHYSICALADAPTERDEVICEIDS query failed for adapter #%u: %s", i, ffDebugNtStatus(status));
|
||||
}
|
||||
|
||||
#if _WIN32
|
||||
if (adapterAddress.BusNumber != -1u) {
|
||||
if (queryPciDeviceInfo(gpu, &deviceIds.DeviceIds) && gpu->vendor.length == 0) {
|
||||
ffStrbufSetStatic(&gpu->vendor, ffGPUGetVendorString(deviceIds.DeviceIds.VendorID));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
D3DKMT_UMD_DRIVER_VERSION umdDriverVersion;
|
||||
status = D3DKMTQueryAdapterInfo(&(D3DKMT_QUERYADAPTERINFO) {
|
||||
.hAdapter = adapter->hAdapter,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// DOCUMENTATION REFERENCED BELOW, IN ORDER TO MAKE FASTFETCH MIT COMPLIANT.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// https://intel.github.io/drivers.gpu.control-library/Control/api.html#_CPPv412ctl_result_t
|
||||
typedef enum ctl_result_t {
|
||||
@@ -73,7 +74,7 @@ typedef struct ctl_adapter_bdf_t {
|
||||
} ctl_adapter_bdf_t;
|
||||
|
||||
#define IGCL_CTL_MAX_DEVICE_NAME_LEN 100
|
||||
#define IGCL_CTL_MAX_RESERVED_SIZE 112
|
||||
#define IGCL_CTL_MAX_RESERVED_SIZE 108
|
||||
|
||||
typedef enum ctl_adapter_properties_flag_t {
|
||||
CTL_ADAPTER_PROPERTIES_FLAG_INTEGRATED = 1,
|
||||
@@ -101,6 +102,7 @@ typedef struct ctl_device_adapter_properties_t {
|
||||
uint16_t pci_subsys_id;
|
||||
uint16_t pci_subsys_vendor_id;
|
||||
ctl_adapter_bdf_t adapter_bdf;
|
||||
uint32_t num_xe_cores;
|
||||
char reserved[IGCL_CTL_MAX_RESERVED_SIZE];
|
||||
} ctl_device_adapter_properties_t;
|
||||
|
||||
@@ -214,3 +216,35 @@ typedef struct ctl_freq_properties_t {
|
||||
|
||||
// https://intel.github.io/drivers.gpu.control-library/Control/api.html#_CPPv425ctlFrequencyGetProperties17ctl_freq_handle_tP21ctl_freq_properties_t
|
||||
extern ctl_result_t ctlFrequencyGetProperties(ctl_freq_handle_t hFrequency, ctl_freq_properties_t* pProperties);
|
||||
|
||||
// https://intel.github.io/drivers.gpu.control-library/Control/api.html#_CPPv415ctl_pci_speed_t
|
||||
typedef struct ctl_pci_speed_t {
|
||||
uint32_t Size;
|
||||
uint8_t Version;
|
||||
int32_t gen;
|
||||
int32_t width;
|
||||
int64_t maxBandwidth;
|
||||
} ctl_pci_speed_t;
|
||||
|
||||
// https://intel.github.io/drivers.gpu.control-library/Control/api.html#_CPPv417ctl_pci_address_t
|
||||
typedef struct ctl_pci_address_t {
|
||||
uint32_t Size;
|
||||
uint8_t Version;
|
||||
uint32_t domain;
|
||||
uint32_t bus;
|
||||
uint32_t device;
|
||||
uint32_t function;
|
||||
} ctl_pci_address_t;
|
||||
|
||||
// https://intel.github.io/drivers.gpu.control-library/Control/api.html#_CPPv420ctl_pci_properties_t
|
||||
typedef struct ctl_pci_properties_t {
|
||||
uint32_t Size;
|
||||
uint8_t Version;
|
||||
ctl_pci_address_t address;
|
||||
ctl_pci_speed_t maxSpeed;
|
||||
bool resizable_bar_supported;
|
||||
bool resizable_bar_enabled;
|
||||
} ctl_pci_properties_t;
|
||||
|
||||
// https://intel.github.io/drivers.gpu.control-library/Control/api.html#ctlpcigetproperties
|
||||
extern ctl_result_t ctlPciGetProperties(ctl_device_adapter_handle_t hDAhandle, ctl_pci_properties_t* pProperties);
|
||||
|
||||
@@ -142,6 +142,10 @@ extern nvmlReturn_t nvmlDeviceGetMemoryInfo(nvmlDevice_t device, nvmlMemory_t* m
|
||||
extern nvmlReturn_t nvmlDeviceGetNumGpuCores(nvmlDevice_t device, unsigned int* numCores);
|
||||
// Retrieves the maximum clock speeds for the device
|
||||
extern nvmlReturn_t nvmlDeviceGetMaxClockInfo(nvmlDevice_t device, nvmlClockType_t type, unsigned int* clock);
|
||||
// Retrieves the maximum PCIe link generation possible with this device and system
|
||||
extern nvmlReturn_t nvmlDeviceGetMaxPcieLinkGeneration(nvmlDevice_t device, unsigned int* maxLinkGen);
|
||||
// Retrieves the maximum PCIe link width possible with this device and system
|
||||
extern nvmlReturn_t nvmlDeviceGetMaxPcieLinkWidth (nvmlDevice_t device, unsigned int* maxLinkWidth);
|
||||
// Retrieves the brand of this device
|
||||
extern nvmlReturn_t nvmlDeviceGetBrand(nvmlDevice_t device, nvmlBrandType_t* type);
|
||||
// Retrieves the current utilization rates for the device
|
||||
|
||||
@@ -139,6 +139,11 @@ static void printGPUResult(FFGPUOptions* options, uint8_t index, const FFGPUResu
|
||||
}
|
||||
}
|
||||
|
||||
char pcieSpeed[32] = "";
|
||||
if (gpu->pcieGen != FF_GPU_PCI_INFO_UNSET && gpu->pcieLanes != FF_GPU_PCI_INFO_UNSET) {
|
||||
snprintf(pcieSpeed, sizeof(pcieSpeed), "PCI Gen %d x%d", gpu->pcieGen, gpu->pcieLanes);
|
||||
}
|
||||
|
||||
FF_PRINT_FORMAT_CHECKED(FF_GPU_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, ((FFformatarg[]) {
|
||||
FF_ARG(gpu->vendor, "vendor"),
|
||||
FF_ARG(gpu->name, "name"),
|
||||
@@ -160,6 +165,7 @@ static void printGPUResult(FFGPUOptions* options, uint8_t index, const FFGPUResu
|
||||
FF_ARG(coreUsageNum, "core-usage-num"),
|
||||
FF_ARG(coreUsageBar, "core-usage-bar"),
|
||||
FF_ARG(gpu->memoryType, "memory-type"),
|
||||
FF_ARG(pcieSpeed, "pcie-speed"),
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -420,6 +426,22 @@ bool ffGenerateGPUJsonResult(FFGPUOptions* options, yyjson_mut_doc* doc, yyjson_
|
||||
}
|
||||
|
||||
yyjson_mut_obj_add_uint(doc, obj, "deviceId", gpu->deviceId);
|
||||
|
||||
if (gpu->pcieGen != FF_GPU_PCI_INFO_UNSET || gpu->pcieLanes != FF_GPU_PCI_INFO_UNSET) {
|
||||
yyjson_mut_val* pcieSpeed = yyjson_mut_obj_add_obj(doc, obj, "pcieSpeed");
|
||||
if (gpu->pcieGen != FF_GPU_PCI_INFO_UNSET) {
|
||||
yyjson_mut_obj_add_uint(doc, pcieSpeed, "gen", gpu->pcieGen);
|
||||
} else {
|
||||
yyjson_mut_obj_add_null(doc, pcieSpeed, "gen");
|
||||
}
|
||||
if (gpu->pcieLanes != FF_GPU_PCI_INFO_UNSET) {
|
||||
yyjson_mut_obj_add_uint(doc, pcieSpeed, "lanes", gpu->pcieLanes);
|
||||
} else {
|
||||
yyjson_mut_obj_add_null(doc, pcieSpeed, "lanes");
|
||||
}
|
||||
} else {
|
||||
yyjson_mut_obj_add_null(doc, obj, "pcieSpeed");
|
||||
}
|
||||
}
|
||||
|
||||
FF_LIST_FOR_EACH (FFGPUResult, gpu, gpus) {
|
||||
@@ -484,5 +506,6 @@ FFModuleBaseInfo ffGPUModuleInfo = {
|
||||
{ "Core usage percentage num", "core-usage-num" },
|
||||
{ "Core usage percentage bar", "core-usage-bar" },
|
||||
{ "Memory type (Windows only)", "memory-type" },
|
||||
{ "Maximum PCIe speed in gen and lanes", "pcie-speed" },
|
||||
})),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user