diff --git a/examples/example.cpp b/examples/example.cpp index db4d1525..f7cf80d9 100644 --- a/examples/example.cpp +++ b/examples/example.cpp @@ -73,6 +73,10 @@ int main(int argc, char** argv) { std::cout << gpu.frequency_MHz() << std::endl; std::cout << std::left << std::setw(20) << " cores:"; std::cout << gpu.num_cores() << std::endl; + std::cout << std::left << std::setw(20) << " vendor_id:"; + std::cout << gpu.vendor_id() << std::endl; + std::cout << std::left << std::setw(20) << " device_id:"; + std::cout << gpu.device_id() << std::endl; } hwinfo::Memory memory; diff --git a/include/hwinfo/gpu.h b/include/hwinfo/gpu.h index 80588770..97e424d4 100644 --- a/include/hwinfo/gpu.h +++ b/include/hwinfo/gpu.h @@ -24,6 +24,8 @@ class GPU { HWI_NODISCARD int64_t frequency_MHz() const; HWI_NODISCARD int num_cores() const; HWI_NODISCARD int id() const; + HWI_NODISCARD const std::string& vendor_id() const; + HWI_NODISCARD const std::string& device_id() const; private: GPU() = default; diff --git a/include/hwinfo/utils/stringutils.h b/include/hwinfo/utils/stringutils.h index dd76e735..58c94504 100644 --- a/include/hwinfo/utils/stringutils.h +++ b/include/hwinfo/utils/stringutils.h @@ -7,12 +7,41 @@ #include #include #include +#include #include #include namespace hwinfo { namespace utils { +/** + * Replaces an occurence once in the entire string. Stops at first match + * + * @param input The input string + * @param from The token to match + * @param to The token to use as a replace with matched ones + */ +inline bool replaceOnce(std::string& input, const std::string& from, const std::string& to) { + size_t start_pos = input.find(from); + + if (start_pos == std::string::npos) return false; + + input.replace(start_pos, from.length(), to); + + return true; +} + +/** + * Replaces all occurences in the entire string. + * + * @param input The input string + * @param from The token to match + * @param to The token to use as a replace with matched ones + */ +inline void replaceAll(std::string& input, const char from, const char to) { + std::replace(input.begin(), input.end(), from, to); +} + /** * remove all white spaces (' ', '\t', '\n') from start and end of input * inplace! diff --git a/src/gpu.cpp b/src/gpu.cpp index fe9cd7fb..a66024b6 100644 --- a/src/gpu.cpp +++ b/src/gpu.cpp @@ -28,4 +28,10 @@ int64_t GPU::frequency_MHz() const { return _frequency_MHz; } // _____________________________________________________________________________________________________________________ int GPU::num_cores() const { return _num_cores; } +// _____________________________________________________________________________________________________________________ +const std::string& GPU::vendor_id() const { return _vendor_id; } + +// _____________________________________________________________________________________________________________________ +const std::string& GPU::device_id() const { return _device_id; } + } // namespace hwinfo \ No newline at end of file diff --git a/src/windows/gpu.cpp b/src/windows/gpu.cpp index 518fc84a..4c8abc61 100644 --- a/src/windows/gpu.cpp +++ b/src/windows/gpu.cpp @@ -24,7 +24,7 @@ namespace hwinfo { std::vector getAllGPUs() { utils::WMI::_WMI wmi; const std::wstring query_string( - L"SELECT Name, AdapterCompatibility, DriverVersion, AdapterRam " + L"SELECT Name, AdapterCompatibility, DriverVersion, AdapterRam, PNPDeviceID " L"FROM WIN32_VideoController"); bool success = wmi.execute_query(query_string); if (!success) { @@ -60,6 +60,21 @@ std::vector getAllGPUs() { if (SUCCEEDED(hr)) { gpu._memory_Bytes = vt_prop.uintVal; } + hr = obj->Get(L"PNPDeviceID", 0, &vt_prop, nullptr, nullptr); + if (SUCCEEDED(hr)) { + std::string ret = utils::wstring_to_std_string(vt_prop.bstrVal); + if (utils::starts_with(ret, "PCI\\")) { + utils::replaceOnce(ret, "PCI\\", ""); + std::vector ids = utils::split(ret, "&"); + gpu._vendor_id = ids[0]; + utils::replaceOnce(gpu._vendor_id, "VEN_", ""); + gpu._device_id = ids[1]; + utils::replaceOnce(gpu._device_id, "DEV_", ""); + } else { + gpu._vendor_id = "0"; + gpu._device_id = "0"; + } + } VariantClear(&vt_prop); obj->Release(); gpus.push_back(std::move(gpu));