From 772dd1e2943f44bb713929108ef7226ede3e58e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 22 Nov 2022 19:25:49 +0800 Subject: [PATCH] GPU: improve performance (Windows) --- CMakeLists.txt | 5 +++ src/detection/gpu/gpu.h | 4 ++ src/detection/gpu/gpu_linux.c | 4 -- src/detection/gpu/gpu_windows.cpp | 71 +++++++++++++++++++++++++++++-- src/detection/vulkan.c | 2 +- 5 files changed, 77 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4726809e7..d5cd54240 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,7 @@ cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR WIN32" OFF cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF) cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND AND NOT ANDROID" OFF) cmake_dependent_option(USE_WIN_NTAPI "Allow using internal NTAPI" ON "WIN32" OFF) +cmake_dependent_option(USE_WIN_GPU_DXGI "Use DXGI to detect GPUs instead of WMI. Faster, but may ignore GPUs that only support DX9" ON "WIN32" OFF) option(BUILD_TESTS "Build tests" OFF) # Also create test executables option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by github actions for release builds @@ -548,10 +549,14 @@ elseif(WIN32) PRIVATE "ntdll" PRIVATE "version" PRIVATE "setupapi" + PRIVATE "dxgi" ) if(USE_WIN_NTAPI) target_compile_definitions(libfastfetch PRIVATE FF_USE_WIN_NTAPI) endif() + if(USE_WIN_GPU_DXGI) + target_compile_definitions(libfastfetch PRIVATE FF_USE_WIN_GPU_DXGI) + endif() endif() target_include_directories(libfastfetch diff --git a/src/detection/gpu/gpu.h b/src/detection/gpu/gpu.h index 08b90d3be..16bd2ff53 100644 --- a/src/detection/gpu/gpu.h +++ b/src/detection/gpu/gpu.h @@ -8,6 +8,10 @@ #define FF_GPU_TEMP_UNSET (0/0.0) #define FF_GPU_CORE_COUNT_UNSET -1 +#define FF_GPU_VENDOR_NAME_AMD "AMD" +#define FF_GPU_VENDOR_NAME_INTEL "Intel" +#define FF_GPU_VENDOR_NAME_NVIDIA "NVIDIA" + typedef struct FFGPUResult { FFstrbuf vendor; diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index 8266357ed..17b40d28a 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -1,10 +1,6 @@ #include "gpu.h" #include "detection/vulkan.h" -#define FF_GPU_VENDOR_NAME_AMD "AMD" -#define FF_GPU_VENDOR_NAME_INTEL "Intel" -#define FF_GPU_VENDOR_NAME_NVIDIA "NVIDIA" - #ifdef FF_HAVE_LIBPCI #include "common/library.h" #include "common/properties.h" diff --git a/src/detection/gpu/gpu_windows.cpp b/src/detection/gpu/gpu_windows.cpp index 374c8e035..7254bc2b4 100644 --- a/src/detection/gpu/gpu_windows.cpp +++ b/src/detection/gpu/gpu_windows.cpp @@ -1,13 +1,62 @@ extern "C" { #include "gpu.h" +#include "util/windows/unicode.h" } + +#ifdef FF_USE_WIN_GPU_DXGI + +#include +#include + +static const char* detectWithDxgi(FFlist* gpus) +{ + IDXGIFactory1* pFactory; + if(FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)(&pFactory)))) + return "CreateDXGIFactory1() failed"; + + for(unsigned iAdapter = 0;; ++iAdapter) + { + IDXGIAdapter1* adapter; + if(FAILED(pFactory->EnumAdapters1(iAdapter, &adapter))) + break; + + DXGI_ADAPTER_DESC1 desc; + if(FAILED(adapter->GetDesc1(&desc)) || (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)) + continue; + + FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus); + + if(wmemchr((const wchar_t[]) {0x1002, 0x1022}, (wchar_t)desc.VendorId, 2)) + ffStrbufInitS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD); + else if(wmemchr((const wchar_t[]) {0x03e7, 0x8086, 0x8087}, (wchar_t)desc.VendorId, 3)) + ffStrbufInitS(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL); + else if(wmemchr((const wchar_t[]) {0x0955, 0x10de, 0x12d2}, (wchar_t)desc.VendorId, 3)) + ffStrbufInitS(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA); + else + ffStrbufInit(&gpu->vendor); + + ffStrbufInit(&gpu->name); + ffWcharToUtf8(desc.Description, &gpu->name); + + ffStrbufInit(&gpu->driver); + + adapter->Release(); + + gpu->temperature = FF_GPU_TEMP_UNSET; + gpu->coreCount = FF_GPU_CORE_COUNT_UNSET; + } + + pFactory->Release(); + + return NULL; +} + +#else + #include "util/windows/wmi.hpp" -extern "C" -const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) +static const char* detectWithWmi(FFlist* gpus) { - FF_UNUSED(instance); - FFWmiQuery query(L"SELECT Name, AdapterCompatibility, DriverVersion FROM Win32_VideoController", nullptr); if(!query) return "Query WMI service failed"; @@ -36,3 +85,17 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) return nullptr; } + +#endif + +extern "C" +const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) +{ + FF_UNUSED(instance); + + #ifdef FF_USE_WIN_GPU_DXGI + return detectWithDxgi(gpus); + #else + return detectWithWmi(gpus); + #endif +} diff --git a/src/detection/vulkan.c b/src/detection/vulkan.c index 685de47b8..200785892 100644 --- a/src/detection/vulkan.c +++ b/src/detection/vulkan.c @@ -182,7 +182,7 @@ static const char* detectVulkan(const FFinstance* instance, FFVulkanResult* resu //Add the device to the list of devices shown by the GPU module - //We don't want softare rasterizers to show up as physical gpu + //We don't want software rasterizers to show up as physical gpu if(physicalDeviceProperties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) continue;