GPU (Windows): try improving performance

This commit is contained in:
李通洲
2023-02-04 01:53:08 +08:00
parent eead4cf70e
commit d2460d8e85
6 changed files with 169 additions and 134 deletions
+1
View File
@@ -17,6 +17,7 @@ Bugfixes:
Other:
* Simplified wmtheme output format (Windows)
* Improved GPU detection performance on Windows 11
# 1.9.1
-3
View File
@@ -726,9 +726,6 @@ elseif(WIN32)
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
+1 -1
View File
@@ -17,7 +17,7 @@
--terminal-font-format Pretty: {}; Name: {}; Size: {}; Styles: {}
--cpu-format Name: {}, Vendor: {}, CoresPhysical: {}, CoresLogical: {}, CoresOnline: {}, FrequencyMin: {}, FrequencyMax: {}, Temperature: {}
--cpu-usage-format Percentage: {}
--gpu-format Vendor: {}; Name: {}; Driver: {}; Temperature: {}; CoreCount: {}
--gpu-format Vendor: {}; Name: {}; Driver: {}; Temperature: {}; CoreCount: {}; Type: {}
--memory-format Used: {}; Total: {}; Percentage: {}
--disk-format SizeUsed: {}; SizeTotal: {}; SizePercentage: {}; FilesUsed: {}; FilesTotal: {}; FilesPercentage: {}; Removable: {}; Hidden: {}; Filesystem: {}; Name: {}
--battery-format Manufactor: {}; Model: {}; Technology: {}; Capacity: {}; Status: {}
+67 -48
View File
@@ -1,13 +1,75 @@
extern "C" {
#include "gpu.h"
#include "util/windows/unicode.h"
#include "util/windows/registry.h"
}
#ifdef FF_USE_WIN_GPU_DXGI
#include <dxgi.h>
#include <wchar.h>
static const char* detectWithRegistry(FFlist* gpus)
{
// Ref: https://github.com/lptstr/winfetch/pull/155
FF_HKEY_AUTO_DESTROY hKey = NULL;
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\DirectX", &hKey, nullptr))
return "Open \"SOFTWARE\\Microsoft\\DirectX\" failed";
uint64_t lastSeen;
if(!ffRegReadUint64(hKey, L"LastSeen", &lastSeen, nullptr))
return "Read \"SOFTWARE\\Microsoft\\DirectX\\LastSeen\" failed";
DWORD index = 0;
wchar_t subKeyName[64];
while(true)
{
DWORD subKeySize = sizeof(subKeyName) / sizeof(*subKeyName);
if(RegEnumKeyExW(hKey, index++, subKeyName, &subKeySize, nullptr, nullptr, nullptr, nullptr) != ERROR_SUCCESS)
break;
FF_HKEY_AUTO_DESTROY hSubKey = NULL;
if(!ffRegOpenKeyForRead(hKey, subKeyName, &hSubKey, nullptr))
continue;
uint64_t adapterLastSeen;
if(!ffRegReadUint64(hSubKey, L"LastSeen", &adapterLastSeen, nullptr) || lastSeen != adapterLastSeen)
continue;
uint32_t softwareAdapter;
if(!ffRegReadUint(hSubKey, L"SoftwareAdapter", &softwareAdapter, nullptr) || softwareAdapter)
continue;
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
ffStrbufInit(&gpu->vendor);
ffStrbufInit(&gpu->name);
ffStrbufInit(&gpu->driver);
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->type = FF_GPU_TYPE_UNKNOWN;
ffRegReadStrbuf(hSubKey, L"Description", &gpu->name, nullptr);
uint32_t vendorId;
if(ffRegReadUint(hSubKey, L"VendorId", &vendorId, nullptr))
{
if(wmemchr((const wchar_t[]) {0x1002, 0x1022}, (wchar_t)vendorId, 2))
ffStrbufAppendS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
else if(wmemchr((const wchar_t[]) {0x03e7, 0x8086, 0x8087}, (wchar_t)vendorId, 3))
ffStrbufAppendS(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
else if(wmemchr((const wchar_t[]) {0x0955, 0x10de, 0x12d2}, (wchar_t)vendorId, 3))
ffStrbufAppendS(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
}
uint64_t dedicatedVideoMemory;
if(ffRegReadUint64(hSubKey, L"DedicatedVideoMemory", &dedicatedVideoMemory, nullptr))
{
gpu->type = dedicatedVideoMemory >= 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
}
}
return nullptr;
}
static const char* detectWithDxgi(FFlist* gpus)
{
IDXGIFactory1* pFactory;
@@ -50,56 +112,13 @@ static const char* detectWithDxgi(FFlist* gpus)
pFactory->Release();
return NULL;
}
#else
#include "util/windows/wmi.hpp"
static const char* detectWithWmi(FFlist* gpus)
{
FFWmiQuery query(L"SELECT Name, AdapterCompatibility, DriverVersion FROM Win32_VideoController", nullptr);
if(!query)
return "Query WMI service failed";
while(FFWmiRecord record = query.next())
{
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
gpu->type = FF_GPU_TYPE_UNKNOWN;
ffStrbufInit(&gpu->vendor);
record.getString(L"AdapterCompatibility", &gpu->vendor);
if(ffStrbufStartsWithS(&gpu->vendor, "Intel "))
{
//Intel returns "Intel Corporation", not sure about AMD
ffStrbufSetS(&gpu->vendor, "Intel");
}
ffStrbufInit(&gpu->name);
record.getString(L"Name", &gpu->name);
ffStrbufInit(&gpu->driver);
record.getString(L"DriverVersion", &gpu->driver);
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
}
return nullptr;
}
#endif
extern "C"
const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
const char* ffDetectGPUImpl(FFlist* gpus, FF_MAYBE_UNUSED const FFinstance* instance)
{
FF_UNUSED(instance);
#ifdef FF_USE_WIN_GPU_DXGI
if (!detectWithRegistry(gpus))
return nullptr;
return detectWithDxgi(gpus);
#else
return detectWithWmi(gpus);
#endif
}
+99 -82
View File
@@ -1,82 +1,99 @@
#include "registry.h"
#include "unicode.h"
#include "util/mallocHelper.h"
static const char* hKey2Str(HKEY hKey)
{
#define HKEY_CASE(compareKey) if(hKey == compareKey) return #compareKey;
HKEY_CASE(HKEY_CLASSES_ROOT)
HKEY_CASE(HKEY_CURRENT_USER)
HKEY_CASE(HKEY_LOCAL_MACHINE)
HKEY_CASE(HKEY_USERS)
HKEY_CASE(HKEY_PERFORMANCE_DATA)
HKEY_CASE(HKEY_PERFORMANCE_TEXT)
HKEY_CASE(HKEY_PERFORMANCE_NLSTEXT)
HKEY_CASE(HKEY_CURRENT_CONFIG)
HKEY_CASE(HKEY_DYN_DATA)
HKEY_CASE(HKEY_CURRENT_USER_LOCAL_SETTINGS)
#undef HKEY_CASE
return "UNKNOWN";
}
bool ffRegOpenKeyForRead(HKEY hKey, const wchar_t* subKeyW, HKEY* result, FFstrbuf* error)
{
if(RegOpenKeyExW(hKey, subKeyW, 0, KEY_READ, result) != ERROR_SUCCESS)
{
if(error)
{
FF_STRBUF_AUTO_DESTROY subKeyA = ffStrbufCreateWS(subKeyW);
ffStrbufAppendF(error, "RegOpenKeyExW(%s\\%s) failed", hKey2Str(hKey), subKeyA.chars);
}
return false;
}
return true;
}
bool ffRegReadStrbuf(HKEY hKey, const wchar_t* valueNameW, FFstrbuf* result, FFstrbuf* error)
{
DWORD bufSize; //with tailing '\0'
if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_REG_SZ, NULL, NULL, &bufSize) != ERROR_SUCCESS)
{
if(error)
{
if(!valueNameW)
valueNameW = L"(default)";
FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW);
ffStrbufAppendF(error, "RegGetValueA(%s, NULL, RRF_RT_REG_SZ) failed", valueNameA.chars);
}
return false;
}
wchar_t* FF_AUTO_FREE resultW = (wchar_t*)malloc(bufSize);
if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_REG_SZ, NULL, resultW, &bufSize) != ERROR_SUCCESS)
{
if(error)
{
if(!valueNameW)
valueNameW = L"(default)";
FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW);
ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_REG_SZ) failed", valueNameA.chars);
}
return false;
}
ffStrbufSetWS(result, resultW);
return true;
}
bool ffRegReadUint(HKEY hKey, const wchar_t* valueNameW, uint32_t* result, FFstrbuf* error)
{
DWORD bufSize = sizeof(*result);
if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_DWORD, NULL, result, &bufSize) != ERROR_SUCCESS)
{
if(error)
{
if(!valueNameW)
valueNameW = L"(default)";
FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW);
ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_DWORD) failed", valueNameA.chars);
}
return false;
}
return true;
}
#include "registry.h"
#include "unicode.h"
#include "util/mallocHelper.h"
static const char* hKey2Str(HKEY hKey)
{
#define HKEY_CASE(compareKey) if(hKey == compareKey) return #compareKey;
HKEY_CASE(HKEY_CLASSES_ROOT)
HKEY_CASE(HKEY_CURRENT_USER)
HKEY_CASE(HKEY_LOCAL_MACHINE)
HKEY_CASE(HKEY_USERS)
HKEY_CASE(HKEY_PERFORMANCE_DATA)
HKEY_CASE(HKEY_PERFORMANCE_TEXT)
HKEY_CASE(HKEY_PERFORMANCE_NLSTEXT)
HKEY_CASE(HKEY_CURRENT_CONFIG)
HKEY_CASE(HKEY_DYN_DATA)
HKEY_CASE(HKEY_CURRENT_USER_LOCAL_SETTINGS)
#undef HKEY_CASE
return "UNKNOWN";
}
bool ffRegOpenKeyForRead(HKEY hKey, const wchar_t* subKeyW, HKEY* result, FFstrbuf* error)
{
if(RegOpenKeyExW(hKey, subKeyW, 0, KEY_READ, result) != ERROR_SUCCESS)
{
if(error)
{
FF_STRBUF_AUTO_DESTROY subKeyA = ffStrbufCreateWS(subKeyW);
ffStrbufAppendF(error, "RegOpenKeyExW(%s\\%s) failed", hKey2Str(hKey), subKeyA.chars);
}
return false;
}
return true;
}
bool ffRegReadStrbuf(HKEY hKey, const wchar_t* valueNameW, FFstrbuf* result, FFstrbuf* error)
{
DWORD bufSize; //with tailing '\0'
if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_REG_SZ, NULL, NULL, &bufSize) != ERROR_SUCCESS)
{
if(error)
{
if(!valueNameW)
valueNameW = L"(default)";
FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW);
ffStrbufAppendF(error, "RegGetValueW(%s, NULL, RRF_RT_REG_SZ) failed", valueNameA.chars);
}
return false;
}
wchar_t* FF_AUTO_FREE resultW = (wchar_t*)malloc(bufSize);
if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_REG_SZ, NULL, resultW, &bufSize) != ERROR_SUCCESS)
{
if(error)
{
if(!valueNameW)
valueNameW = L"(default)";
FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW);
ffStrbufAppendF(error, "RegGetValueW(%s, result, RRF_RT_REG_SZ) failed", valueNameA.chars);
}
return false;
}
ffStrbufSetWS(result, resultW);
return true;
}
bool ffRegReadUint(HKEY hKey, const wchar_t* valueNameW, uint32_t* result, FFstrbuf* error)
{
DWORD bufSize = sizeof(*result);
if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_DWORD, NULL, result, &bufSize) != ERROR_SUCCESS)
{
if(error)
{
if(!valueNameW)
valueNameW = L"(default)";
FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW);
ffStrbufAppendF(error, "RegGetValueW(%s, result, RRF_RT_DWORD) failed", valueNameA.chars);
}
return false;
}
return true;
}
bool ffRegReadUint64(HKEY hKey, const wchar_t* valueNameW, uint64_t* result, FFstrbuf* error)
{
DWORD bufSize = sizeof(*result);
if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_QWORD, NULL, result, &bufSize) != ERROR_SUCCESS)
{
if(error)
{
if(!valueNameW)
valueNameW = L"(default)";
FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW);
ffStrbufAppendF(error, "RegGetValueW(%s, result, RRF_RT_QWORD) failed", valueNameA.chars);
}
return false;
}
return true;
}
+1
View File
@@ -18,5 +18,6 @@ static inline void wrapRegCloseKey(HKEY* phKey)
bool ffRegOpenKeyForRead(HKEY hKey, const wchar_t* subKeyW, HKEY* result, FFstrbuf* error);
bool ffRegReadStrbuf(HKEY hKey, const wchar_t* valueNameW, FFstrbuf* result, FFstrbuf* error);
bool ffRegReadUint(HKEY hKey, const wchar_t* valueNameW, uint32_t* result, FFstrbuf* error);
bool ffRegReadUint64(HKEY hKey, const wchar_t* valueNameW, uint64_t* result, FFstrbuf* error);
#endif