mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
GPU (Windows): try improving performance
This commit is contained in:
@@ -17,6 +17,7 @@ Bugfixes:
|
||||
Other:
|
||||
|
||||
* Simplified wmtheme output format (Windows)
|
||||
* Improved GPU detection performance on Windows 11
|
||||
|
||||
# 1.9.1
|
||||
|
||||
|
||||
@@ -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
@@ -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: {}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user