GPU: detect current pcie link speed

This commit is contained in:
Carter Li
2026-06-14 17:36:54 +08:00
committed by 李通洲
parent 107f39eb15
commit 22f9948497
18 changed files with 190 additions and 79 deletions
+13 -3
View File
@@ -7,7 +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_PCIE_SPEED_UNSET 0
#define FF_GPU_CORE_USAGE_UNSET (-DBL_MAX)
#define FF_GPU_INDEX_UNSET ((uint32_t) -1)
@@ -35,6 +35,11 @@ typedef struct FFGPUMemory {
uint64_t used;
} FFGPUMemory;
typedef struct FFGPUPcieSpeed {
uint16_t gen;
uint16_t lanes;
} FFGPUPcieSpeed;
typedef struct FFGPUResult {
uint32_t index;
FFGPUType type;
@@ -47,8 +52,13 @@ typedef struct FFGPUResult {
double coreUsage;
int32_t coreCount;
uint32_t frequency; // Maximum time clock frequency in MHz
uint16_t pcieGen;
uint16_t pcieLanes;
union {
struct {
FFGPUPcieSpeed psMax;
FFGPUPcieSpeed psCurr;
};
uint64_t pcieSpeed;
};
FFGPUMemory dedicated;
FFGPUMemory shared;
uint64_t deviceId;
+22 -8
View File
@@ -235,20 +235,34 @@ 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) {
if (result.psMax || result.psCurr) {
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);
FF_DEBUG("Chipset info - iBusSpeedType: %d, iMaxPCIELaneWidth: %d", chipSetInfo.iBusSpeedType, chipSetInfo.iMaxPCIELaneWidth);
if (result.psMax) {
if (chipSetInfo.iBusSpeedType >= 2) {
result.psMax->gen = (uint16_t) (chipSetInfo.iBusSpeedType - 2);
FF_DEBUG("Got PCIe Max Gen: %u", result.psMax->gen);
}
if (chipSetInfo.iMaxPCIELaneWidth > 0) {
result.psMax->lanes = (uint16_t) chipSetInfo.iMaxPCIELaneWidth;
FF_DEBUG("Got PCIe Max Lanes: %u", result.psMax->lanes);
}
}
if (result.pcieLanes && chipSetInfo.iMaxPCIELaneWidth > 0) {
*result.pcieLanes = (uint16_t) chipSetInfo.iMaxPCIELaneWidth;
FF_DEBUG("Got PCIe Lanes: %u", *result.pcieLanes);
FF_DEBUG("Chipset info - iBusType: %d, iCurrentPCIELaneWidth: %d", chipSetInfo.iBusType, chipSetInfo.iCurrentPCIELaneWidth);
if (result.psCurr) {
if (chipSetInfo.iBusType >= 2) {
result.psCurr->gen = (uint16_t) (chipSetInfo.iBusType - 2);
FF_DEBUG("Got PCIe Current Gen: %u", result.psCurr->gen);
}
if (chipSetInfo.iCurrentPCIELaneWidth > 0) {
result.psCurr->lanes = (uint16_t) chipSetInfo.iCurrentPCIELaneWidth;
FF_DEBUG("Got PCIe Current Lanes: %u", result.psCurr->lanes);
}
}
} else {
FF_DEBUG("Failed to get chipset information");
+1 -1
View File
@@ -118,7 +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;
gpu->pcieSpeed = FF_GPU_PCIE_SPEED_UNSET;
IORegistryEntryGetRegistryEntryID(registryEntry, &gpu->deviceId);
ffStrbufInitStatic(&gpu->platformApi, "IOKit");
+1 -1
View File
@@ -148,7 +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;
gpu->pcieSpeed = FF_GPU_PCIE_SPEED_UNSET;
char driverName[64];
driverName[0] = '\0';
+2 -2
View File
@@ -36,8 +36,8 @@ typedef struct FFGpuDriverResult {
FFGPUType* type;
uint32_t* frequency;
FFstrbuf* name;
uint16_t* pcieGen;
uint16_t* pcieLanes;
FFGPUPcieSpeed* psMax;
FFGPUPcieSpeed* psCurr;
} FFGpuDriverResult;
const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName);
+6 -4
View File
@@ -113,8 +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;
gpu->psMax.gen = (uint16_t) devInfo.pcie_gen;
gpu->psMax.lanes = (uint16_t) devInfo.pcie_num_lanes;
#define FF_VRAM_CASE(name, value) \
case value /* AMDGPU_VRAM_TYPE_ ## name */: \
ffStrbufSetStatic(&gpu->memoryType, #name); \
@@ -370,13 +370,15 @@ const char* ffGPUDetectDriverSpecific(const FFGPUOptions* options, FFGPUResult*
.index = &gpu->index,
.temp = options->temp ? &gpu->temperature : NULL,
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
.sharedMemory = options->driverSpecific ? &gpu->shared : NULL,
.memoryType = options->driverSpecific ? &gpu->memoryType : NULL,
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
.coreUsage = options->driverSpecific ? &gpu->coreUsage : NULL,
.type = &gpu->type,
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
.name = &gpu->name,
.pcieGen = options->driverSpecific ? &gpu->pcieGen : NULL,
.pcieLanes = options->driverSpecific ? &gpu->pcieLanes : NULL,
.psCurr = options->driverSpecific ? &gpu->psCurr : NULL,
.psMax = options->driverSpecific ? &gpu->psMax : NULL,
},
soName);
}
+1 -1
View File
@@ -130,7 +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;
gpu->pcieSpeed = FF_GPU_PCIE_SPEED_UNSET;
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD) {
ffGPUQueryAmdGpuName(deviceId, revision, gpu);
+1 -1
View File
@@ -37,7 +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;
gpu->pcieSpeed = FF_GPU_PCIE_SPEED_UNSET;
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD) {
ffGPUQueryAmdGpuName(dev.device_id, dev.revision, gpu);
+18 -5
View File
@@ -17,6 +17,7 @@ struct FFIgclData {
FF_LIBRARY_SYMBOL(ctlEnumFrequencyDomains)
FF_LIBRARY_SYMBOL(ctlFrequencyGetProperties)
FF_LIBRARY_SYMBOL(ctlPciGetProperties)
FF_LIBRARY_SYMBOL(ctlPciGetState)
bool inited;
ctl_api_handle_t apiHandle;
@@ -45,6 +46,7 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
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)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlPciGetState)
if (ffctlInit(&(ctl_init_args_t) {
.AppVersion = CTL_IMPL_VERSION,
@@ -229,14 +231,25 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
ffStrbufSetS(result.name, properties.name);
}
if (result.pcieGen || result.pcieLanes) {
if (result.psMax) {
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 (pciProps.maxSpeed.gen > 0) {
result.psMax->gen = (uint16_t) pciProps.maxSpeed.gen;
}
if (result.pcieLanes && pciProps.maxSpeed.width > 0) {
*result.pcieLanes = (uint16_t) pciProps.maxSpeed.width;
if (pciProps.maxSpeed.width > 0) {
result.psMax->lanes = (uint16_t) pciProps.maxSpeed.width;
}
}
}
if (result.psCurr) {
ctl_pci_state_t pciState = { .Size = sizeof(pciState), .Version = 0 };
if (igclData.ffctlPciGetState(device, &pciState) == CTL_RESULT_SUCCESS) {
if (pciState.speed.gen > 0) {
result.psMax->gen = (uint16_t) pciState.speed.gen;
}
if (pciState.speed.width > 0) {
result.psMax->lanes = (uint16_t) pciState.speed.width;
}
}
}
+44 -20
View File
@@ -313,6 +313,32 @@ static const char* pciDetectZxSpecific(const FFGPUOptions* options, FFGPUResult*
return NULL;
}
static inline uint16_t pcieLinkSpeedToGen(const FFstrbuf* buffer) {
int64_t speed = ffStrbufToSInt(buffer, FF_GPU_PCIE_SPEED_UNSET);
if (speed >= 64) {
return 6;
} else if (speed >= 32) {
return 5;
} else if (speed >= 16) {
return 4;
} else if (speed >= 8) {
return 3;
} else if (speed >= 5) {
return 2;
} else if (speed >= 2) { // 2.5
return 1;
}
return FF_GPU_PCIE_SPEED_UNSET;
}
static inline uint16_t pcieWidthToLanes(const FFstrbuf* buffer) {
int64_t width = ffStrbufToSInt(buffer, FF_GPU_PCIE_SPEED_UNSET);
if (width > 0 && width < 255) { // kernel returns 255 if the value is unknown
return (uint16_t) width;
}
return FF_GPU_PCIE_SPEED_UNSET;
}
static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf* buffer, FFstrbuf* deviceDir, const char* drmKey) {
const uint32_t drmDirPathLength = deviceDir->length;
uint32_t vendorId, deviceId, subVendorId, subDeviceId;
@@ -368,7 +394,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;
gpu->pcieSpeed = FF_GPU_PCIE_SPEED_UNSET;
char drmKeyBuffer[8];
if (!drmKey) {
@@ -396,30 +422,28 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
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;
}
gpu->psMax.gen = pcieLinkSpeedToGen(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
if (gpu->pcieGen != FF_GPU_PCI_INFO_UNSET) {
if (gpu->psMax.gen != FF_GPU_PCIE_SPEED_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;
}
gpu->psMax.lanes = pcieWidthToLanes(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
ffStrbufAppendS(deviceDir, "/current_link_speed");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psCurr.gen = pcieLinkSpeedToGen(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
if (gpu->psCurr.gen != FF_GPU_PCIE_SPEED_UNSET) {
ffStrbufAppendS(deviceDir, "/current_link_width");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psCurr.lanes = pcieWidthToLanes(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
+1 -1
View File
@@ -97,7 +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;
gpu->pcieSpeed = FF_GPU_PCIE_SPEED_UNSET;
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD) {
ffGPUQueryAmdGpuName(PCI_PRODUCT(pciid), PCI_REVISION(pciid), gpu);
+15 -5
View File
@@ -16,6 +16,8 @@ struct FFNvmlData {
FF_LIBRARY_SYMBOL(nvmlDeviceGetUtilizationRates)
FF_LIBRARY_SYMBOL(nvmlDeviceGetMaxPcieLinkGeneration)
FF_LIBRARY_SYMBOL(nvmlDeviceGetMaxPcieLinkWidth)
FF_LIBRARY_SYMBOL(nvmlDeviceGetCurrPcieLinkGeneration)
FF_LIBRARY_SYMBOL(nvmlDeviceGetCurrPcieLinkWidth)
FF_LIBRARY_SYMBOL(nvmlDeviceGetBrand)
FF_LIBRARY_SYMBOL(nvmlDeviceGetIndex)
FF_LIBRARY_SYMBOL(nvmlDeviceGetName)
@@ -163,6 +165,8 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
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, nvmlDeviceGetCurrPcieLinkGeneration)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetCurrPcieLinkWidth)
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)
@@ -292,17 +296,23 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
}
}
if (result.pcieGen) {
if (result.psMax) {
unsigned int value;
if (nvmlData.ffnvmlDeviceGetMaxPcieLinkGeneration(device, &value) == NVML_SUCCESS) {
*result.pcieGen = (uint16_t) value;
result.psMax->gen = (uint16_t) value;
}
if (nvmlData.ffnvmlDeviceGetMaxPcieLinkWidth(device, &value) == NVML_SUCCESS) {
result.psMax->lanes = (uint16_t) value;
}
}
if (result.pcieLanes) {
if (result.psCurr) {
unsigned int value;
if (nvmlData.ffnvmlDeviceGetMaxPcieLinkWidth(device, &value) == NVML_SUCCESS) {
*result.pcieLanes = (uint16_t) value;
if (nvmlData.ffnvmlDeviceGetCurrPcieLinkGeneration(device, &value) == NVML_SUCCESS) {
result.psCurr->gen = (uint16_t) value;
}
if (nvmlData.ffnvmlDeviceGetCurrPcieLinkWidth(device, &value) == NVML_SUCCESS) {
result.psCurr->lanes = (uint16_t) value;
}
}
+1 -1
View File
@@ -86,7 +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;
gpu->pcieSpeed = FF_GPU_PCIE_SPEED_UNSET;
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD) {
ffGPUQueryAmdGpuName(PCI_PRODUCT(pciid), PCI_REVISION(pciid), gpu);
+1 -1
View File
@@ -21,7 +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;
gpu->pcieSpeed = FF_GPU_PCIE_SPEED_UNSET;
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD) {
int* revId;
+33 -8
View File
@@ -27,6 +27,8 @@ static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds
static FFlist deviceIdsCache;
static bool initialized;
typedef struct {
uint32_t currentLinkSpeed;
uint32_t currentLinkWidth;
uint32_t maxLinkSpeed;
uint32_t maxLinkWidth;
D3DKMT_DEVICE_IDS deviceIds;
@@ -105,17 +107,18 @@ static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds
FF_DEBUG("Failed to get PCI bus number");
}
pciBufLen = sizeof(entry->maxLinkSpeed);
DEVPROPTYPE propType;
pciBufLen = sizeof(entry->maxLinkSpeed);
// 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);
FF_DEBUG("PCIe max GEN: %u", entry->maxLinkSpeed);
} else {
FF_DEBUG("Failed to get PCIe GEN: %s", ffDebugConfigRet(ret));
FF_DEBUG("Failed to get PCIe max GEN: %s", ffDebugConfigRet(ret));
}
if (entry->maxLinkSpeed != FF_GPU_PCI_INFO_UNSET) {
if (entry->maxLinkSpeed != FF_GPU_PCIE_SPEED_UNSET) {
pciBufLen = sizeof(entry->maxLinkWidth);
ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_MaxLinkWidth, &propType, (PBYTE) &entry->maxLinkWidth, &pciBufLen, 0);
if (ret == CR_SUCCESS) {
@@ -124,6 +127,24 @@ static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds
FF_DEBUG("Failed to get PCIe max link width: %s", ffDebugConfigRet(ret));
}
}
pciBufLen = sizeof(entry->currentLinkSpeed);
ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_CurrentLinkSpeed, &propType, (PBYTE) &entry->currentLinkSpeed, &pciBufLen, 0);
if (ret == CR_SUCCESS) {
FF_DEBUG("PCIe GEN: %u", entry->currentLinkSpeed);
} else {
FF_DEBUG("Failed to get PCIe GEN: %s", ffDebugConfigRet(ret));
}
if (entry->currentLinkSpeed != FF_GPU_PCIE_SPEED_UNSET) {
pciBufLen = sizeof(entry->currentLinkWidth);
ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_CurrentLinkWidth, &propType, (PBYTE) &entry->currentLinkWidth, &pciBufLen, 0);
if (ret == CR_SUCCESS) {
FF_DEBUG("PCIe current link width: %u", entry->currentLinkWidth);
} else {
FF_DEBUG("Failed to get PCIe current link width: %s", ffDebugConfigRet(ret));
}
}
}
}
@@ -133,8 +154,10 @@ static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds
if (outDeviceIds->VendorID != -1u) {
*outDeviceIds = entry->deviceIds;
}
gpu->pcieGen = (uint16_t) entry->maxLinkSpeed;
gpu->pcieLanes = (uint16_t) entry->maxLinkWidth;
gpu->psMax.gen = (uint16_t) entry->maxLinkSpeed;
gpu->psMax.lanes = (uint16_t) entry->maxLinkWidth;
gpu->psCurr.gen = (uint16_t) entry->currentLinkSpeed;
gpu->psCurr.lanes = (uint16_t) entry->currentLinkWidth;
return true;
}
}
@@ -291,7 +314,7 @@ ffGPUDetectWsl2
: adapterType.HybridDiscrete
? FF_GPU_TYPE_DISCRETE
: FF_GPU_TYPE_UNKNOWN;
gpu->pcieGen = gpu->pcieLanes = FF_GPU_PCI_INFO_UNSET;
gpu->pcieSpeed = FF_GPU_PCIE_SPEED_UNSET;
D3DKMT_DRIVERVERSION wddmVersion = KMT_DRIVERVERSION_WDDM_2_0;
status = D3DKMTQueryAdapterInfo(&(D3DKMT_QUERYADAPTERINFO) {
@@ -407,8 +430,10 @@ ffGPUDetectWsl2
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
.coreUsage = options->driverSpecific ? &gpu->coreUsage : NULL,
.type = &gpu->type,
.name = &gpu->name,
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
.name = &gpu->name,
.psCurr = options->driverSpecific ? &gpu->psCurr : NULL,
.psMax = options->driverSpecific ? &gpu->psMax : NULL,
},
dllName);
FF_DEBUG("Driver-specific detection completed: %s", error ?: "Success");
+10
View File
@@ -248,3 +248,13 @@ typedef struct 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);
// https://intel.github.io/drivers.gpu.control-library/Control/api.html#ctl-pci-state-t
typedef struct _ctl_pci_state_t {
uint32_t Size;
uint8_t Version;
ctl_pci_speed_t speed;
} ctl_pci_state_t;
// https://intel.github.io/drivers.gpu.control-library/Control/api.html#ctlpcigetstate
extern ctl_result_t ctlPciGetState(ctl_device_adapter_handle_t hDAhandle, ctl_pci_state_t* pState);
+5 -1
View File
@@ -145,7 +145,11 @@ extern nvmlReturn_t nvmlDeviceGetMaxClockInfo(nvmlDevice_t device, nvmlClockType
// 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);
extern nvmlReturn_t nvmlDeviceGetMaxPcieLinkWidth(nvmlDevice_t device, unsigned int* maxLinkWidth);
// Retrieves the current PCIe link generation
extern nvmlReturn_t nvmlDeviceGetCurrPcieLinkGeneration(nvmlDevice_t device, unsigned int* currLinkGen);
// Retrieves the current PCIe link width
extern nvmlReturn_t nvmlDeviceGetCurrPcieLinkWidth(nvmlDevice_t device, unsigned int* currLinkWidth);
// Retrieves the brand of this device
extern nvmlReturn_t nvmlDeviceGetBrand(nvmlDevice_t device, nvmlBrandType_t* type);
// Retrieves the current utilization rates for the device
+15 -16
View File
@@ -139,9 +139,10 @@ 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);
char maxSpeed[32] = "", currSpeed[32] = "";
if (gpu->pcieSpeed != FF_GPU_PCIE_SPEED_UNSET) {
snprintf(maxSpeed, sizeof(maxSpeed), "%d x%d", gpu->psMax.gen, gpu->psMax.lanes);
snprintf(currSpeed, sizeof(currSpeed), "%d x%d", gpu->psCurr.gen, gpu->psCurr.lanes);
}
FF_PRINT_FORMAT_CHECKED(FF_GPU_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, ((FFformatarg[]) {
@@ -165,7 +166,8 @@ 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"),
FF_ARG(maxSpeed, "pcie-max-speed"),
FF_ARG(currSpeed, "pcie-curr-speed"),
}));
}
}
@@ -427,18 +429,14 @@ 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) {
if (gpu->pcieSpeed != FF_GPU_PCIE_SPEED_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");
}
yyjson_mut_val* maxSpeed = yyjson_mut_obj_add_obj(doc, pcieSpeed, "max");
yyjson_mut_obj_add_uint(doc, maxSpeed, "gen", gpu->psMax.gen);
yyjson_mut_obj_add_uint(doc, maxSpeed, "lanes", gpu->psMax.lanes);
yyjson_mut_val* currSpeed = yyjson_mut_obj_add_obj(doc, pcieSpeed, "current");
yyjson_mut_obj_add_uint(doc, currSpeed, "gen", gpu->psCurr.gen);
yyjson_mut_obj_add_uint(doc, currSpeed, "lanes", gpu->psCurr.lanes);
} else {
yyjson_mut_obj_add_null(doc, obj, "pcieSpeed");
}
@@ -506,6 +504,7 @@ 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" },
{ "PCIe maximum speed in gen and lanes", "pcie-max-speed" },
{ "PCIe current speed in gen and lanes", "pcie-curr-speed" },
})),
};