diff --git a/src/detection/gpu/gpu.h b/src/detection/gpu/gpu.h index e993b512e..84e1467a1 100644 --- a/src/detection/gpu/gpu.h +++ b/src/detection/gpu/gpu.h @@ -64,6 +64,9 @@ typedef struct FFGPUResult { uint64_t deviceId; } FFGPUResult; +static_assert(sizeof(((FFGPUResult*) NULL)->pcieSpeed) == 8, "pcieSpeed is not 8 bytes"); +static_assert(sizeof(((FFGPUResult*) NULL)->psMax) == 4, "psMax has padding"); + const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result); const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus); diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index 8cadb9e31..7183b903b 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -410,34 +410,6 @@ 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)) { - gpu->psMax.gen = pcieLinkSpeedToGen(buffer); - } - ffStrbufSubstrBefore(deviceDir, drmDirPathLength); - - if (gpu->psMax.gen != FF_GPU_PCIE_SPEED_UNSET) { - ffStrbufAppendS(deviceDir, "/max_link_width"); - if (ffReadFileBuffer(deviceDir->chars, buffer)) { - 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); - } - if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD) { bool ok = false; if (drmKey && options->driverSpecific) { @@ -473,7 +445,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf pciDetectTempGeneral(options, gpu, deviceDir, buffer); pciDetectZxSpecific(options, gpu, deviceDir, buffer); } else { - ffGPUDetectDriverSpecific(options, gpu, (FFGpuDriverPciBusId) { + ffGPUDetectDriverSpecific(options, gpu, (FFGpuDriverPciBusId){ .domain = pciDomain, .bus = pciBus, .device = pciDevice, @@ -487,11 +459,41 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf ffGPUFillVendorByDeviceName(gpu); + if (options->driverSpecific && gpu->pcieSpeed == FF_GPU_PCIE_SPEED_UNSET) { + ffStrbufAppendS(deviceDir, "/max_link_speed"); + if (ffReadFileBuffer(deviceDir->chars, buffer)) { + gpu->psMax.gen = pcieLinkSpeedToGen(buffer); + } + ffStrbufSubstrBefore(deviceDir, drmDirPathLength); + + if (gpu->psMax.gen != FF_GPU_PCIE_SPEED_UNSET) { + ffStrbufAppendS(deviceDir, "/max_link_width"); + if (ffReadFileBuffer(deviceDir->chars, buffer)) { + 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); + } + } + return NULL; } #if __aarch64__ -#include "detection/cpu/cpu.h" + #include "detection/cpu/cpu.h" FF_A_UNUSED static const char* drmDetectAsahiSpecific(FFGPUResult* gpu, const char* name, FF_A_UNUSED FFstrbuf* buffer, FF_A_UNUSED const char* drmKey) { if (sscanf(name, "agx-t%lu", &gpu->deviceId) == 1) { diff --git a/src/detection/gpu/gpu_windows.c b/src/detection/gpu/gpu_windows.c index 18f07d2d5..c50cfecdb 100644 --- a/src/detection/gpu/gpu_windows.c +++ b/src/detection/gpu/gpu_windows.c @@ -21,7 +21,7 @@ #define GUID_DEVCLASS_DISPLAY_STRING L"{4d36e968-e325-11ce-bfc1-08002be10318}" // Found in -static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds) { +static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds, bool queryPcieGen) { FF_DEBUG("Query PCI device info: %08llX", gpu->deviceId); static FFlist deviceIdsCache; @@ -107,42 +107,44 @@ static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds FF_DEBUG("Failed to get PCI bus number"); } - DEVPROPTYPE propType; + if (queryPcieGen) { + 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 max GEN: %u", entry->maxLinkSpeed); - } else { - FF_DEBUG("Failed to get PCIe max GEN: %s", ffDebugConfigRet(ret)); - } - - 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); + 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 max link width: %u", entry->maxLinkWidth); + FF_DEBUG("PCIe max GEN: %u", entry->maxLinkSpeed); } else { - FF_DEBUG("Failed to get PCIe max link width: %s", ffDebugConfigRet(ret)); + FF_DEBUG("Failed to get PCIe max GEN: %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->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) { + FF_DEBUG("PCIe max link width: %u", entry->maxLinkWidth); + } else { + FF_DEBUG("Failed to get PCIe max link width: %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); + 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 current link width: %u", entry->currentLinkWidth); + FF_DEBUG("PCIe GEN: %u", entry->currentLinkSpeed); } else { - FF_DEBUG("Failed to get PCIe current link width: %s", ffDebugConfigRet(ret)); + 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)); + } } } } @@ -154,10 +156,13 @@ static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds if (outDeviceIds->VendorID != -1u) { *outDeviceIds = entry->deviceIds; } - 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; + + if (queryPcieGen) { + 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; } } @@ -371,9 +376,9 @@ 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) { + #if _WIN32 && FF_WIN81_COMPAT + if (adapterAddress.BusNumber != -1u && (deviceIds.DeviceIds.VendorID == -1u || options->driverSpecific)) { + if (queryPciDeviceInfo(gpu, &deviceIds.DeviceIds, options->driverSpecific) && gpu->vendor.length == 0) { ffStrbufSetStatic(&gpu->vendor, ffGPUGetVendorString(deviceIds.DeviceIds.VendorID)); } } @@ -448,6 +453,12 @@ ffGPUDetectWsl2 FF_DEBUG("Attempting to query vendor name via registry for adapter #%u", i); queryVendorNameViaRegistry(&gpu->vendor, adapter->hAdapter); } + + #if !FF_WIN81_COMPAT + if (adapterAddress.BusNumber != -1u && options->driverSpecific && gpu->pcieSpeed == FF_GPU_PCIE_SPEED_UNSET) { + queryPciDeviceInfo(gpu, &deviceIds.DeviceIds, options->driverSpecific); + } + #endif #endif if (gpu->name.length == 0) {