diff --git a/CMakeLists.txt b/CMakeLists.txt index cbe462dc2..a803b726b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -561,7 +561,7 @@ if(LINUX) src/detection/gpu/gpu_linux.c src/detection/gpu/gpu_drm.c src/detection/gpu/gpu_pci.c - src/detection/gpu/gpu_wsl.c + src/detection/gpu/gpu_windows.c src/detection/gtk_qt/gtk.c src/detection/host/host_linux.c src/detection/icons/icons_linux.c diff --git a/src/detection/gpu/d3dkmthk.h b/src/detection/gpu/d3dkmthk.h index d5ce5428e..a71be7b65 100644 --- a/src/detection/gpu/d3dkmthk.h +++ b/src/detection/gpu/d3dkmthk.h @@ -10,6 +10,7 @@ #else # include # include +# include typedef struct _LUID { uint32_t LowPart; @@ -330,24 +331,26 @@ EXTERN_C _Check_return_ NTSTATUS APIENTRY D3DKMTQueryStatistics(_In_ CONST D3DKM # define LX_DXCLOSEADAPTER _IOWR(0x47, 0x15, D3DKMT_CLOSEADAPTER) # define LX_DXQUERYSTATISTICS _IOWR(0x47, 0x43, D3DKMT_QUERYSTATISTICS) -static inline NTSTATUS D3DKMTOpenAdapterFromLuid(int dxgfd, const D3DKMT_OPENADAPTERFROMLUID* params) { - return ioctl(dxgfd, LX_DXOPENADAPTERFROMLUID, params); +extern int dxgfd; // File descriptor for /dev/dxg, initialized in gpu_wsl.c + +static inline NTSTATUS D3DKMTOpenAdapterFromLuid(const D3DKMT_OPENADAPTERFROMLUID* params) { + return ioctl(dxgfd, LX_DXOPENADAPTERFROMLUID, params) < 0 ? -errno : 0; } -static inline NTSTATUS D3DKMTQueryAdapterInfo(int dxgfd, const D3DKMT_QUERYADAPTERINFO* params) { - return ioctl(dxgfd, LX_DXQUERYADAPTERINFO, params); +static inline NTSTATUS D3DKMTQueryAdapterInfo(const D3DKMT_QUERYADAPTERINFO* params) { + return ioctl(dxgfd, LX_DXQUERYADAPTERINFO, params) < 0 ? -errno : 0; } -static inline NTSTATUS D3DKMTCloseAdapter(int dxgfd, const D3DKMT_CLOSEADAPTER* params) { - return ioctl(dxgfd, LX_DXCLOSEADAPTER, params); +static inline NTSTATUS D3DKMTCloseAdapter(const D3DKMT_CLOSEADAPTER* params) { + return ioctl(dxgfd, LX_DXCLOSEADAPTER, params) < 0 ? -errno : 0; } -static inline NTSTATUS D3DKMTEnumAdapters2(int dxgfd, D3DKMT_ENUMADAPTERS2* params) { - return ioctl(dxgfd, LX_DXENUMADAPTERS2, params); +static inline NTSTATUS D3DKMTEnumAdapters2(D3DKMT_ENUMADAPTERS2* params) { + return ioctl(dxgfd, LX_DXENUMADAPTERS2, params) < 0 ? -errno : 0; } -static inline NTSTATUS D3DKMTQueryStatistics(int dxgfd, const D3DKMT_QUERYSTATISTICS* params) { - return ioctl(dxgfd, LX_DXQUERYSTATISTICS, params); +static inline NTSTATUS D3DKMTQueryStatistics(const D3DKMT_QUERYSTATISTICS* params) { + return ioctl(dxgfd, LX_DXQUERYSTATISTICS, params) < 0 ? -errno : 0; } #endif diff --git a/src/detection/gpu/gpu_driver_specific.h b/src/detection/gpu/gpu_driver_specific.h index ade0940ce..074a2c6f9 100644 --- a/src/detection/gpu/gpu_driver_specific.h +++ b/src/detection/gpu/gpu_driver_specific.h @@ -43,36 +43,40 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName); const char* ffDetectMthreadsGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName); +#ifndef FF_GPU_DRIVER_DLLNAME_PATH_PREFIX +# define FF_GPU_DRIVER_DLLNAME_PATH_PREFIX +#endif + FF_MAYBE_UNUSED static inline bool getDriverSpecificDetectionFn(const char* vendor, __typeof__(&ffDetectNvidiaGpuInfo)* pDetectFn, const char** pDllName) { if (vendor == FF_GPU_VENDOR_NAME_NVIDIA) { *pDetectFn = ffDetectNvidiaGpuInfo; #ifdef _WIN32 - *pDllName = "nvml.dll"; + *pDllName = FF_GPU_DRIVER_DLLNAME_PATH_PREFIX "nvml.dll"; #else - *pDllName = "libnvidia-ml.so"; + *pDllName = FF_GPU_DRIVER_DLLNAME_PATH_PREFIX "libnvidia-ml.so"; #endif } else if (vendor == FF_GPU_VENDOR_NAME_MTHREADS) { *pDetectFn = ffDetectMthreadsGpuInfo; #ifdef _WIN32 - *pDllName = "mtml.dll"; + *pDllName = FF_GPU_DRIVER_DLLNAME_PATH_PREFIX "mtml.dll"; #else - *pDllName = "libmtml.so"; + *pDllName = FF_GPU_DRIVER_DLLNAME_PATH_PREFIX "libmtml.so"; #endif } #ifdef _WIN32 else if (vendor == FF_GPU_VENDOR_NAME_INTEL) { *pDetectFn = ffDetectIntelGpuInfo; # ifdef _WIN64 - *pDllName = "ControlLib.dll"; + *pDllName = FF_GPU_DRIVER_DLLNAME_PATH_PREFIX "ControlLib.dll"; # else - *pDllName = "ControlLib32.dll"; + *pDllName = FF_GPU_DRIVER_DLLNAME_PATH_PREFIX "ControlLib32.dll"; # endif } else if (vendor == FF_GPU_VENDOR_NAME_AMD) { *pDetectFn = ffDetectAmdGpuInfo; # ifdef _WIN64 - *pDllName = "atiadlxx.dll"; + *pDllName = FF_GPU_DRIVER_DLLNAME_PATH_PREFIX "atiadlxx.dll"; # else - *pDllName = "atiadlxy.dll"; + *pDllName = FF_GPU_DRIVER_DLLNAME_PATH_PREFIX "atiadlxy.dll"; # endif } #endif diff --git a/src/detection/gpu/gpu_windows.c b/src/detection/gpu/gpu_windows.c index 37e603b82..333982f9e 100644 --- a/src/detection/gpu/gpu_windows.c +++ b/src/detection/gpu/gpu_windows.c @@ -1,12 +1,79 @@ #include "detection/gpu/gpu.h" +#if __linux__ +# define FF_GPU_DRIVER_DLLNAME_PATH_PREFIX "/usr/lib/wsl/lib/" +#endif #include "detection/gpu/gpu_driver_specific.h" -#include "common/windows/unicode.h" #include "common/debug.h" #include #include "d3dkmthk.h" -const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus) { +#if _WIN32 +# include "common/windows/unicode.h" +#else +# include +# include +# include +# include + +int dxgfd = -2; + +static void ffStrbufSetWS(FFstrbuf* strbuf, const char16_t* str) { + ffStrbufClear(strbuf); + + mbstate_t state = {}; + while (*str) { + char buf[5]; + size_t len = c16rtomb(buf, *str, &state); + if (len == (size_t) -1) { + ffStrbufAppendS(strbuf, "�"); // U+FFFD REPLACEMENT CHARACTER + } else if (len > 0) { + ffStrbufAppendNS(strbuf, (uint32_t) len, buf); + } + str++; + } +} + +static void closeDxgfd(void) { + if (dxgfd >= 0) { + close(dxgfd); + dxgfd = 0; + FF_DEBUG("Closed /dev/dxg file descriptor"); + } +} + +static inline const char* ffDebugNtStatus(NTSTATUS status) { + return status < 0 ? strerror(-status) : "Success"; +} +#endif + +const char* +#if _WIN32 +ffDetectGPUImpl +#else +ffGPUDetectWsl2 +#endif + (const FFGPUOptions* options, FFlist* gpus) { +#if __linux__ + if (dxgfd == -2) { + dxgfd = open("/dev/dxg", O_RDWR); // Windows DXCore/D3DKMT adapter driver for WSL + if (dxgfd < 0) { + if (errno == ENOENT) { + FF_DEBUG("/dev/dxg is not available, WSL DXCore GPU driver not detected"); + return "No DXCore GPU driver detected (no /dev/dxg)"; + } else { + FF_DEBUG("Failed to open /dev/dxg: %s", strerror(errno)); + return "Failed to open /dev/dxg"; + } + } + FF_DEBUG("Opened /dev/dxg successfully"); + atexit(closeDxgfd); + } + if (dxgfd < 0) { + return "Failed to open /dev/dxg"; + } +#endif + D3DKMT_ADAPTERINFO adapters[64]; D3DKMT_ENUMADAPTERS2 enumAdapters = { .NumAdapters = ARRAY_SIZE(adapters), @@ -351,6 +418,7 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus) { (uint32_t) gpu->type, (uint64_t) gpu->deviceId); + close_adapter: status = D3DKMTCloseAdapter(&(D3DKMT_CLOSEADAPTER) { .hAdapter = adapter->hAdapter }); if (NT_SUCCESS(status)) { FF_DEBUG("Closed adapter #%u successfully", i); diff --git a/src/detection/gpu/gpu_wsl.c b/src/detection/gpu/gpu_wsl.c deleted file mode 100644 index 56b8c96fe..000000000 --- a/src/detection/gpu/gpu_wsl.c +++ /dev/null @@ -1,338 +0,0 @@ -#if __x86_64__ || __aarch64__ // WSL2 only supports x86_64 and aarch64 - -# include "detection/gpu/gpu.h" -# include "detection/gpu/gpu_driver_specific.h" -# include "common/io.h" -# include "common/debug.h" - -# include "d3dkmthk.h" -# include -# include -# include -# include - -static void ffStrbufAppendUtf16(FFstrbuf* strbuf, const char16_t* str) { - mbstate_t state = {}; - while (*str) { - char buf[5]; - size_t len = c16rtomb(buf, *str, &state); - if (len == (size_t) -1) { - ffStrbufAppendS(strbuf, "�"); // U+FFFD REPLACEMENT CHARACTER - } else if (len > 0) { - ffStrbufAppendNS(strbuf, (uint32_t) len, buf); - } - str++; - } -} - -const char* ffGPUDetectWsl2(const FFGPUOptions* options, FFlist* gpus) { - FF_AUTO_CLOSE_FD int dxg = open("/dev/dxg", O_RDWR); // Windows DXCore/D3DKMT adapter driver for WSL - if (dxg < 0) { - if (errno == ENOENT) { - FF_DEBUG("/dev/dxg is not available, WSL DXCore GPU driver not detected"); - return "No DXCore GPU driver detected (no /dev/dxg)"; - } else { - FF_DEBUG("Failed to open /dev/dxg: %s", strerror(errno)); - return "Failed to open /dev/dxg"; - } - } - - FF_DEBUG("Opened /dev/dxg successfully"); - - D3DKMT_ADAPTERINFO adapters[64]; - D3DKMT_ENUMADAPTERS2 enumAdapters = { - .NumAdapters = ARRAY_SIZE(adapters), - .pAdapters = adapters, - }; - if (!NT_SUCCESS(D3DKMTEnumAdapters2(dxg, &enumAdapters))) { - FF_DEBUG("D3DKMTEnumAdapters2 failed: %s", strerror(errno)); - return "Failed to enumerate adapters with D3DKMTEnumAdapters2"; - } - - FF_DEBUG("D3DKMTEnumAdapters2 succeeded, adapter count: %u", enumAdapters.NumAdapters); - - for (uint32_t i = 0; i < enumAdapters.NumAdapters; i++) { - const D3DKMT_ADAPTERINFO* adapter = &adapters[i]; - FF_DEBUG("Processing adapter #%u", i); - - D3DKMT_ADAPTERTYPE adapterType; - if (!NT_SUCCESS(D3DKMTQueryAdapterInfo(dxg, &(D3DKMT_QUERYADAPTERINFO) { - .hAdapter = adapter->hAdapter, - .Type = KMTQAITYPE_ADAPTERTYPE, - .pPrivateDriverData = &adapterType, - .PrivateDriverDataSize = sizeof(adapterType), - }))) { - FF_DEBUG("KMTQAITYPE_ADAPTERTYPE query failed for adapter #%u: %s", i, strerror(errno)); - continue; - } - if (adapterType.SoftwareDevice) { - FF_DEBUG("Skipping software adapter #%u", i); - continue; - } - - FFGPUResult* gpu = FF_LIST_ADD(FFGPUResult, *gpus); - ffStrbufInit(&gpu->vendor); - ffStrbufInit(&gpu->name); - ffStrbufInit(&gpu->driver); - ffStrbufInit(&gpu->platformApi); - ffStrbufInit(&gpu->memoryType); - gpu->index = FF_GPU_INDEX_UNSET; - gpu->temperature = FF_GPU_TEMP_UNSET; - gpu->coreCount = FF_GPU_CORE_COUNT_UNSET; - gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET; - gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET; - gpu->deviceId = 0; - gpu->frequency = FF_GPU_FREQUENCY_UNSET; - gpu->type = adapterType.HybridIntegrated - ? FF_GPU_TYPE_INTEGRATED - : adapterType.HybridDiscrete - ? FF_GPU_TYPE_DISCRETE - : FF_GPU_TYPE_UNKNOWN; - - const char* vendorStr = NULL; - - D3DKMT_QUERY_DEVICE_IDS deviceIds = { .PhysicalAdapterIndex = 0 }; - if (NT_SUCCESS(D3DKMTQueryAdapterInfo(dxg, &(D3DKMT_QUERYADAPTERINFO) { - .hAdapter = adapter->hAdapter, - .Type = KMTQAITYPE_PHYSICALADAPTERDEVICEIDS, - .pPrivateDriverData = &deviceIds, - .PrivateDriverDataSize = sizeof(deviceIds), - }))) { - vendorStr = ffGPUGetVendorString(deviceIds.DeviceIds.VendorID); - ffStrbufSetStatic(&gpu->vendor, vendorStr); - FF_DEBUG("Adapter #%u vendor/device IDs: vendor=0x%04x device=0x%04x", i, deviceIds.DeviceIds.VendorID, deviceIds.DeviceIds.DeviceID); - } else { - FF_DEBUG("KMTQAITYPE_PHYSICALADAPTERDEVICEIDS query failed for adapter #%u: %s", i, strerror(errno)); - } - - D3DKMT_ADAPTERADDRESS adapterAddress; - if (NT_SUCCESS(D3DKMTQueryAdapterInfo(dxg, &(D3DKMT_QUERYADAPTERINFO) { - .hAdapter = adapter->hAdapter, - .Type = KMTQAITYPE_ADAPTERADDRESS, - .pPrivateDriverData = &adapterAddress, - .PrivateDriverDataSize = sizeof(adapterAddress), - }))) { - gpu->deviceId = ffGPUPciAddr2Id(0, adapterAddress.BusNumber, adapterAddress.DeviceNumber, adapterAddress.FunctionNumber); - FF_DEBUG("Adapter #%u PCI address: bus=%u device=%u function=%u", i, adapterAddress.BusNumber, adapterAddress.DeviceNumber, adapterAddress.FunctionNumber); - } else { - adapterAddress.BusNumber = -1u; - gpu->deviceId = ffGPUGeneral2Id(((uint64_t) adapter->AdapterLuid.HighPart << 32) | (uint64_t) adapter->AdapterLuid.LowPart); - FF_DEBUG("KMTQAITYPE_ADAPTERADDRESS query failed for adapter #%u, fallback to LUID-based deviceId: %s", i, strerror(errno)); - } - - D3DKMT_UMD_DRIVER_VERSION umdDriverVersion; - if (NT_SUCCESS(D3DKMTQueryAdapterInfo(dxg, &(D3DKMT_QUERYADAPTERINFO) { - .hAdapter = adapter->hAdapter, - .Type = KMTQAITYPE_UMD_DRIVER_VERSION, - .pPrivateDriverData = &umdDriverVersion, - .PrivateDriverDataSize = sizeof(umdDriverVersion), - }))) { - ffStrbufSetF(&gpu->driver, "%lu.%lu.%lu.%lu", umdDriverVersion.DriverVersion.QuadPart >> 48ul & 0xFFFF, umdDriverVersion.DriverVersion.QuadPart >> 32ul & 0xFFFF, umdDriverVersion.DriverVersion.QuadPart >> 16ul & 0xFFFF, umdDriverVersion.DriverVersion.QuadPart >> 0ul & 0xFFFF); - FF_DEBUG("Adapter #%u UMD driver version: %08lX", i, (unsigned long) umdDriverVersion.DriverVersion.QuadPart); - } else { - FF_DEBUG("KMTQAITYPE_UMD_DRIVER_VERSION query failed for adapter #%u: %s", i, strerror(errno)); - } - - D3DKMT_DRIVERVERSION wddmVersion = KMT_DRIVERVERSION_WDDM_3_0; - if (NT_SUCCESS(D3DKMTQueryAdapterInfo(dxg, &(D3DKMT_QUERYADAPTERINFO) { - .hAdapter = adapter->hAdapter, - .Type = KMTQAITYPE_DRIVERVERSION, - .pPrivateDriverData = &wddmVersion, - .PrivateDriverDataSize = sizeof(wddmVersion), - }))) { - ffStrbufSetF(&gpu->platformApi, "WDDM %u.%u", wddmVersion / 1000, (wddmVersion % 1000) / 100); - FF_DEBUG("Adapter #%u WDDM version: %u", i, wddmVersion); - } else { - ffStrbufSetStatic(&gpu->platformApi, "WDDM"); - FF_DEBUG("KMTQAITYPE_DRIVERVERSION query failed for adapter #%u", i); - } - - if (gpu->name.length == 0) { - D3DKMT_ADAPTERREGISTRYINFO registryInfo; - if (NT_SUCCESS(D3DKMTQueryAdapterInfo(dxg, &(D3DKMT_QUERYADAPTERINFO) { - .hAdapter = adapter->hAdapter, - .Type = KMTQAITYPE_ADAPTERREGISTRYINFO, - .pPrivateDriverData = ®istryInfo, - .PrivateDriverDataSize = sizeof(registryInfo), - }))) { - ffStrbufAppendUtf16(&gpu->name, registryInfo.AdapterString); - FF_DEBUG("Adapter #%u adapter string: %s", i, gpu->name.chars); - } else { - FF_DEBUG("KMTQAITYPE_ADAPTERREGISTRYINFO query failed for adapter #%u: %s", i, strerror(errno)); - } - } - - if (vendorStr == FF_GPU_VENDOR_NAME_NVIDIA && options->driverSpecific) { - FF_DEBUG("Trying NVIDIA driver-specific detection for adapter #%u", i); - FFGpuDriverCondition cond = { - .type = FF_GPU_DRIVER_CONDITION_TYPE_DEVICE_ID | (adapterAddress.DeviceNumber != -1u ? FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID : 0), - .pciDeviceId = { - .deviceId = deviceIds.DeviceIds.DeviceID, - .vendorId = deviceIds.DeviceIds.VendorID, - .subSystemId = deviceIds.DeviceIds.SubSystemID, - .revId = deviceIds.DeviceIds.RevisionID, - }, - .pciBusId = { - .domain = 0, - .bus = adapterAddress.BusNumber, - .device = adapterAddress.DeviceNumber, - .func = adapterAddress.FunctionNumber, - }, - }; - const char* error = ffDetectNvidiaGpuInfo(&cond, (FFGpuDriverResult) { - .index = &gpu->index, - .temp = options->temp ? &gpu->temperature : NULL, - .memory = options->driverSpecific ? &gpu->dedicated : 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, - }, - "/usr/lib/wsl/lib/libnvidia-ml.so"); - if (error) { - FF_DEBUG("NVIDIA driver-specific detection failed for adapter #%u: %s", i, error); - } else { - FF_DEBUG("NVIDIA driver-specific detection succeeded for adapter #%u", i); - } - } - - if (gpu->dedicated.total == FF_GPU_VMEM_SIZE_UNSET && gpu->shared.total == FF_GPU_VMEM_SIZE_UNSET) { - if (wddmVersion >= KMT_DRIVERVERSION_WDDM_3_1 && options->driverSpecific) { - // Supports memory usage query; requires Windows 11 (22H2) or later - D3DKMT_QUERYSTATISTICS queryStatistics = { - .Type = D3DKMT_QUERYSTATISTICS_SEGMENT_GROUP_USAGE, - .AdapterLuid = adapter->AdapterLuid, - .QuerySegmentGroupUsage = { - .PhysicalAdapterIndex = 0, - .SegmentGroup = D3DKMT_MEMORY_SEGMENT_GROUP_LOCAL, - }, - }; - if (NT_SUCCESS(D3DKMTQueryStatistics(dxg, &queryStatistics))) { - D3DKMT_QUERYSTATISTICS_MEMORY_USAGE* info = &queryStatistics.QueryResult.SegmentGroupUsageInformation; - uint64_t used = info->AllocatedBytes + info->ModifiedBytes + info->StandbyBytes; - uint64_t total = used + info->FreeBytes + info->ZeroBytes; - gpu->dedicated.used = used; - gpu->dedicated.total = total; - FF_DEBUG("Adapter #%u local memory usage: used=%lu total=%lu", i, (unsigned long) used, (unsigned long) total); - } else { - FF_DEBUG("D3DKMT_QUERYSTATISTICS_SEGMENT_GROUP_USAGE (LOCAL) failed for adapter #%u: %s", i, strerror(errno)); - } - - queryStatistics.QuerySegmentGroupUsage.SegmentGroup = D3DKMT_MEMORY_SEGMENT_GROUP_NON_LOCAL; - if (NT_SUCCESS(D3DKMTQueryStatistics(dxg, &queryStatistics))) { - D3DKMT_QUERYSTATISTICS_MEMORY_USAGE* info = &queryStatistics.QueryResult.SegmentGroupUsageInformation; - uint64_t used = info->AllocatedBytes + info->ModifiedBytes + info->StandbyBytes; - uint64_t total = used + info->FreeBytes + info->ZeroBytes; - gpu->shared.used = used; - gpu->shared.total = total; - FF_DEBUG("Adapter #%u non-local memory usage: used=%lu total=%lu", i, (unsigned long) used, (unsigned long) total); - } else { - FF_DEBUG("D3DKMT_QUERYSTATISTICS_SEGMENT_GROUP_USAGE (NON_LOCAL) failed for adapter #%u: %s", i, strerror(errno)); - } - } else { - // Supports basic segment (total) size query - D3DKMT_SEGMENTSIZEINFO segmentSizeInfo = {}; - D3DKMT_QUERYADAPTERINFO queryAdapterInfo = { - .hAdapter = adapter->hAdapter, - .Type = KMTQAITYPE_GETSEGMENTSIZE, - .pPrivateDriverData = &segmentSizeInfo, - .PrivateDriverDataSize = sizeof(segmentSizeInfo), - }; - if (NT_SUCCESS(D3DKMTQueryAdapterInfo(dxg, &queryAdapterInfo))) { - FF_DEBUG("Adapter #%u segment size - DedicatedVideoMemorySize: %lu, DedicatedSystemMemorySize: %lu, SharedSystemMemorySize: %lu", - i, - segmentSizeInfo.DedicatedVideoMemorySize, - segmentSizeInfo.DedicatedSystemMemorySize, - segmentSizeInfo.SharedSystemMemorySize); - gpu->dedicated.total = segmentSizeInfo.DedicatedVideoMemorySize; - gpu->shared.total = segmentSizeInfo.DedicatedSystemMemorySize + segmentSizeInfo.SharedSystemMemorySize; - } else { - FF_DEBUG("Failed to query segment size information for adapter #%u: %s", i, strerror(errno)); - } - } - } - - if (gpu->frequency == FF_GPU_FREQUENCY_UNSET && wddmVersion >= KMT_DRIVERVERSION_WDDM_3_1) { - for (ULONG nodeIdx = 0;; nodeIdx++) { - D3DKMT_NODEMETADATA nodeMetadata = { - .NodeOrdinalAndAdapterIndex = (0 << 16) | nodeIdx, - }; - if (!NT_SUCCESS(D3DKMTQueryAdapterInfo(dxg, &(D3DKMT_QUERYADAPTERINFO) { - .hAdapter = adapter->hAdapter, - .Type = KMTQAITYPE_NODEMETADATA, - .pPrivateDriverData = &nodeMetadata, - .PrivateDriverDataSize = sizeof(nodeMetadata), - }))) { - break; - } - - if (nodeMetadata.NodeData.EngineType != DXGK_ENGINE_TYPE_3D) { - continue; - } - - D3DKMT_QUERYSTATISTICS queryStatistics = { - .Type = D3DKMT_QUERYSTATISTICS_NODE2, - .AdapterLuid = adapter->AdapterLuid, - .QueryNode2 = { .PhysicalAdapterIndex = 0, .NodeOrdinal = (UINT16) nodeIdx }, - }; - if (NT_SUCCESS(D3DKMTQueryStatistics(dxg, &queryStatistics))) { - gpu->frequency = (uint32_t) (queryStatistics.QueryResult.NodeInformation.NodePerfData.MaxFrequency / 1000 / 1000); - FF_DEBUG("Adapter #%u max graphics frequency: %u MHz", i, gpu->frequency); - break; - } else { - FF_DEBUG("Failed to query node performance data for adapter #%u node #%u: %s", i, nodeIdx, strerror(errno)); - } - } - } - - if (options->temp && gpu->temperature == FF_GPU_TEMP_UNSET) { - D3DKMT_QUERYSTATISTICS queryStatistics = { - .Type = D3DKMT_QUERYSTATISTICS_PHYSICAL_ADAPTER, - .AdapterLuid = adapter->AdapterLuid, - .QueryPhysAdapter = { .PhysicalAdapterIndex = 0 }, - }; - if (NT_SUCCESS(D3DKMTQueryStatistics(dxg, &queryStatistics)) && - queryStatistics.QueryResult.PhysAdapterInformation.AdapterPerfData.Temperature != 0) { - gpu->temperature = queryStatistics.QueryResult.PhysAdapterInformation.AdapterPerfData.Temperature / 10.0; - FF_DEBUG("Adapter #%u temperature: %.1f°C", i, gpu->temperature); - } else { - FF_DEBUG("Failed to query temperature for adapter #%u: %s", i, strerror(errno)); - } - } - - if (gpu->type == FF_GPU_TYPE_UNKNOWN) { - if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA) { - if (ffStrbufStartsWithIgnCaseS(&gpu->name, "GeForce") || - ffStrbufStartsWithIgnCaseS(&gpu->name, "Quadro") || - ffStrbufStartsWithIgnCaseS(&gpu->name, "Tesla")) { - gpu->type = FF_GPU_TYPE_DISCRETE; - } - } else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_MTHREADS) { - if (ffStrbufStartsWithIgnCaseS(&gpu->name, "MTT ")) { - gpu->type = FF_GPU_TYPE_DISCRETE; - } - } else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL) { - // 0000:00:02.0 is reserved for Intel integrated graphics - gpu->type = gpu->deviceId == ffGPUPciAddr2Id(0, 0, 2, 0) ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE; - } - } - - FF_DEBUG("Adapter #%u summary: name='%s', vendor='%s', type=%u, deviceId=%lu", - i, - gpu->name.length ? gpu->name.chars : "unknown", - gpu->vendor.length ? gpu->vendor.chars : "unknown", - (unsigned) gpu->type, - (unsigned long) gpu->deviceId); - - if (NT_SUCCESS(D3DKMTCloseAdapter(dxg, &(D3DKMT_CLOSEADAPTER) { .hAdapter = adapter->hAdapter }))) { - FF_DEBUG("Closed adapter #%u successfully", i); - } else { - FF_DEBUG("Failed to close adapter #%u: %s", i, strerror(errno)); - } - } - - return NULL; -} - -#endif