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
+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
}