[Windows] Try reading GPU driver information directly from registry.

This commit is contained in:
Pāvels Nadtočajevs 2025-08-06 08:01:05 +03:00
parent c81fd6c512
commit 9f8626ccaa
No known key found for this signature in database
GPG key ID: 8413210218EF35D2
2 changed files with 94 additions and 11 deletions

View file

@ -648,16 +648,79 @@ String OS_Windows::get_version_alias() const {
return ""; return "";
} }
Vector<String> OS_Windows::get_video_adapter_driver_info() const { Vector<String> OS_Windows::_get_video_adapter_driver_info_reg(const String &p_name) const {
if (RenderingServer::get_singleton() == nullptr) { Vector<String> info;
String subkey = "SYSTEM\\CurrentControlSet\\Control\\Class\\{4d36e968-e325-11ce-bfc1-08002be10318}";
HKEY hkey = nullptr;
LSTATUS result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, (LPCWSTR)subkey.utf16().get_data(), 0, KEY_READ, &hkey);
if (result != ERROR_SUCCESS) {
return Vector<String>(); return Vector<String>();
} }
static Vector<String> info; DWORD subkeys = 0;
if (!info.is_empty()) { result = RegQueryInfoKeyW(hkey, nullptr, nullptr, nullptr, &subkeys, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
if (result != ERROR_SUCCESS) {
RegCloseKey(hkey);
return Vector<String>();
}
for (DWORD i = 0; i < subkeys; i++) {
WCHAR key_name[MAX_PATH] = L"";
DWORD key_name_size = MAX_PATH;
result = RegEnumKeyExW(hkey, i, key_name, &key_name_size, nullptr, nullptr, nullptr, nullptr);
if (result != ERROR_SUCCESS) {
continue;
}
String id = String::utf16((const char16_t *)key_name, key_name_size);
if (!id.is_empty()) {
HKEY sub_hkey = nullptr;
result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, (LPCWSTR)(subkey + "\\" + id).utf16().get_data(), 0, KEY_QUERY_VALUE, &sub_hkey);
if (result != ERROR_SUCCESS) {
continue;
}
WCHAR buffer[4096];
DWORD buffer_len = 4096;
DWORD vtype = REG_SZ;
if (RegQueryValueExW(sub_hkey, L"DriverDesc", nullptr, &vtype, (LPBYTE)buffer, &buffer_len) != ERROR_SUCCESS || buffer_len == 0) {
buffer_len = 4096;
if (RegQueryValueExW(sub_hkey, L"HardwareInformation.AdapterString", nullptr, &vtype, (LPBYTE)buffer, &buffer_len) != ERROR_SUCCESS || buffer_len == 0) {
RegCloseKey(sub_hkey);
continue;
}
}
String driver_name = String::utf16((const char16_t *)buffer, buffer_len).strip_edges();
if (driver_name == p_name) {
String driver_provider = driver_name;
String driver_version;
buffer_len = 4096;
if (RegQueryValueExW(sub_hkey, L"ProviderName", nullptr, &vtype, (LPBYTE)buffer, &buffer_len) == ERROR_SUCCESS && buffer_len != 0) {
driver_provider = String::utf16((const char16_t *)buffer, buffer_len).strip_edges();
}
buffer_len = 4096;
if (RegQueryValueExW(sub_hkey, L"DriverVersion", nullptr, &vtype, (LPBYTE)buffer, &buffer_len) == ERROR_SUCCESS && buffer_len != 0) {
driver_version = String::utf16((const char16_t *)buffer, buffer_len).strip_edges();
}
if (!driver_version.is_empty()) {
info.push_back(driver_provider);
info.push_back(driver_version);
RegCloseKey(sub_hkey);
break;
}
}
RegCloseKey(sub_hkey);
}
}
RegCloseKey(hkey);
return info; return info;
} }
Vector<String> OS_Windows::_get_video_adapter_driver_info_wmi(const String &p_name) const {
Vector<String> info;
REFCLSID clsid = CLSID_WbemLocator; // Unmarshaler CLSID REFCLSID clsid = CLSID_WbemLocator; // Unmarshaler CLSID
REFIID uuid = IID_IWbemLocator; // Interface UUID REFIID uuid = IID_IWbemLocator; // Interface UUID
IWbemLocator *wbemLocator = nullptr; // to get the services IWbemLocator *wbemLocator = nullptr; // to get the services
@ -667,11 +730,6 @@ Vector<String> OS_Windows::get_video_adapter_driver_info() const {
String driver_name; String driver_name;
String driver_version; String driver_version;
const String device_name = RenderingServer::get_singleton()->get_video_adapter_name();
if (device_name.is_empty()) {
return Vector<String>();
}
HRESULT hr = CoCreateInstance(clsid, nullptr, CLSCTX_INPROC_SERVER, uuid, (LPVOID *)&wbemLocator); HRESULT hr = CoCreateInstance(clsid, nullptr, CLSCTX_INPROC_SERVER, uuid, (LPVOID *)&wbemLocator);
if (hr != S_OK) { if (hr != S_OK) {
return Vector<String>(); return Vector<String>();
@ -686,7 +744,7 @@ Vector<String> OS_Windows::get_video_adapter_driver_info() const {
return Vector<String>(); return Vector<String>();
} }
const String gpu_device_class_query = vformat("SELECT * FROM Win32_PnPSignedDriver WHERE DeviceName = \"%s\"", device_name); const String gpu_device_class_query = vformat("SELECT * FROM Win32_PnPSignedDriver WHERE DeviceName = \"%s\"", p_name);
BSTR query = SysAllocString((const WCHAR *)gpu_device_class_query.utf16().get_data()); BSTR query = SysAllocString((const WCHAR *)gpu_device_class_query.utf16().get_data());
BSTR query_lang = SysAllocString(L"WQL"); BSTR query_lang = SysAllocString(L"WQL");
hr = wbemServices->ExecQuery(query_lang, query, WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, nullptr, &iter); hr = wbemServices->ExecQuery(query_lang, query, WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, nullptr, &iter);
@ -751,6 +809,28 @@ Vector<String> OS_Windows::get_video_adapter_driver_info() const {
return info; return info;
} }
Vector<String> OS_Windows::get_video_adapter_driver_info() const {
if (RenderingServer::get_singleton() == nullptr) {
return Vector<String>();
}
static Vector<String> info;
if (!info.is_empty()) {
return info;
}
const String device_name = RenderingServer::get_singleton()->get_video_adapter_name();
if (device_name.is_empty()) {
return Vector<String>();
}
info = _get_video_adapter_driver_info_reg(device_name);
if (info.is_empty()) {
info = _get_video_adapter_driver_info_wmi(device_name);
}
return info;
}
bool OS_Windows::get_user_prefers_integrated_gpu() const { bool OS_Windows::get_user_prefers_integrated_gpu() const {
// On Windows 10, the preferred GPU configured in Windows Settings is // On Windows 10, the preferred GPU configured in Windows Settings is
// stored in the registry under the key // stored in the registry under the key

View file

@ -145,6 +145,9 @@ class OS_Windows : public OS {
HashMap<String, int> encodings; HashMap<String, int> encodings;
void _init_encodings(); void _init_encodings();
Vector<String> _get_video_adapter_driver_info_reg(const String &p_name) const;
Vector<String> _get_video_adapter_driver_info_wmi(const String &p_name) const;
// functions used by main to initialize/deinitialize the OS // functions used by main to initialize/deinitialize the OS
protected: protected:
virtual void initialize() override; virtual void initialize() override;