mirror of
https://github.com/Lurkki14/tuxclocker.git
synced 2025-02-25 18:55:24 -06:00
add optional python-hwdata dependency to get AMD GPU names
This commit is contained in:
parent
ae13f1a59d
commit
49fea845f8
@ -4,3 +4,5 @@ option('daemon', type: 'boolean', value: 'true', description: 'Build daemon')
|
||||
option('plugins', type: 'boolean', value: 'true', description: 'Build plugins')
|
||||
option('library', type: 'boolean', value: 'true', description: 'Build library')
|
||||
option('gui', type: 'boolean', value: 'true', description: 'Build Qt GUI')
|
||||
option('require-python-hwdata', type: 'boolean', value: 'false',
|
||||
description: 'Require python-hwdata for prettier AMD GPU names')
|
||||
|
@ -13,6 +13,10 @@
|
||||
#include <libdrm/amdgpu_drm.h>
|
||||
#include <libintl.h>
|
||||
|
||||
#ifdef WITH_HWDATA
|
||||
#include <HWData.hpp>
|
||||
#endif
|
||||
|
||||
#define _(String) gettext(String)
|
||||
|
||||
extern int errno;
|
||||
@ -1242,6 +1246,20 @@ std::vector<TreeNode<DeviceNode>> getUtilizationsRoot(AMDGPUData data) {
|
||||
}
|
||||
|
||||
std::vector<TreeNode<DeviceNode>> getGPUName(AMDGPUData data) {
|
||||
#ifdef WITH_HWDATA
|
||||
// Get GPU name from hwdata
|
||||
static auto pciObj = getPciObject();
|
||||
auto pciData = fromUeventFile(data.deviceFilename);
|
||||
if (pciObj.has_value() && pciData.has_value()) {
|
||||
auto name = hwdataName(*pciObj, *pciData);
|
||||
if (name.has_value())
|
||||
return {DeviceNode{
|
||||
.name = *name,
|
||||
.interface = std::nullopt,
|
||||
.hash = md5(data.identifier),
|
||||
}};
|
||||
}
|
||||
#endif
|
||||
auto name = amdgpu_get_marketing_name(data.devHandle);
|
||||
if (name) {
|
||||
return {DeviceNode{
|
||||
@ -1319,6 +1337,10 @@ private:
|
||||
};
|
||||
|
||||
TreeNode<DeviceNode> AMDPlugin::deviceRootNode() {
|
||||
#ifdef WITH_HWDATA
|
||||
PythonInstance p;
|
||||
#endif
|
||||
|
||||
TreeNode<DeviceNode> root;
|
||||
|
||||
auto dataVec = fromFilesystem();
|
||||
|
@ -192,6 +192,7 @@ std::optional<AMDGPUData> fromRenderDFile(const fs::directory_entry &entry) {
|
||||
.devPath = devPath,
|
||||
.devHandle = dev,
|
||||
.pciId = std::to_string(info.device_id),
|
||||
.deviceFilename = filename,
|
||||
.identifier = identifier,
|
||||
.ppTableType = tableType,
|
||||
};
|
||||
|
@ -31,6 +31,8 @@ struct AMDGPUData {
|
||||
amdgpu_device_handle devHandle;
|
||||
// PCIe device ID
|
||||
std::string pciId;
|
||||
// Eg. renderD128
|
||||
std::string deviceFilename;
|
||||
// Device ID + GPU index
|
||||
std::string identifier;
|
||||
std::optional<PPTableType> ppTableType;
|
||||
|
63
src/plugins/HWData.cpp
Normal file
63
src/plugins/HWData.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
#include "HWData.hpp"
|
||||
|
||||
#include <fplus/fplus.hpp>
|
||||
#include <Utils.hpp>
|
||||
|
||||
std::optional<PciData> fromUeventFile(const std::string &deviceFilename) {
|
||||
/*
|
||||
DRIVER=nvidia
|
||||
PCI_CLASS=30000
|
||||
PCI_ID=10DE:1B80
|
||||
PCI_SUBSYS_ID=1458:3702
|
||||
PCI_SLOT_NAME=0000:01:00.0
|
||||
MODALIAS=pci:v000010DEd00001B80sv00001458sd00003702bc03sc00i00
|
||||
*/
|
||||
|
||||
char path[64];
|
||||
snprintf(path, 64, "/sys/class/drm/%s/device/uevent", deviceFilename.c_str());
|
||||
|
||||
auto contents = fileContents(path);
|
||||
if (!contents.has_value())
|
||||
return std::nullopt;
|
||||
|
||||
auto isNewline = [](char c) { return c == '\n'; };
|
||||
auto lines = fplus::split_by(isNewline, false, *contents);
|
||||
|
||||
if (lines.size() > 5) {
|
||||
auto idWords = fplus::split_one_of(std::string{"=:"}, false, lines[2]);
|
||||
auto subsysWords = fplus::split_one_of(std::string{"="}, false, lines[3]);
|
||||
if (idWords.size() > 2 && subsysWords.size() > 1) {
|
||||
auto device = fplus::to_lower_case(idWords[2]);
|
||||
auto subsystem = fplus::to_lower_case(subsysWords[1]);
|
||||
|
||||
return PciData{device, subsystem};
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<PyObject *> getPciObject() {
|
||||
auto modName = PyUnicode_FromString("hwdata");
|
||||
auto mod = PyImport_Import(modName);
|
||||
|
||||
if (mod) {
|
||||
auto pciObj = PyObject_GetAttrString(mod, "PCI");
|
||||
if (pciObj)
|
||||
return pciObj;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> hwdataName(PyObject *pciObj, PciData data) {
|
||||
// Vendor is always '1002' aka AMD
|
||||
auto subsysStr = PyObject_CallMethod(
|
||||
pciObj, "get_subsystem", "sss", "1002", data.device.c_str(), data.subsystem.c_str());
|
||||
if (subsysStr && PyUnicode_Check(subsysStr))
|
||||
return PyUnicode_AsUTF8(subsysStr);
|
||||
|
||||
// Try to get device name
|
||||
auto devStr = PyObject_CallMethod(pciObj, "get_device", "ss", "1002", data.device.c_str());
|
||||
if (devStr && PyUnicode_Check(devStr))
|
||||
return PyUnicode_AsUTF8(devStr);
|
||||
return std::nullopt;
|
||||
}
|
19
src/plugins/HWData.hpp
Normal file
19
src/plugins/HWData.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include <optional>
|
||||
#include <Python.h>
|
||||
#include <string>
|
||||
|
||||
// Reduces the places we need to ifdef by destroying automatically
|
||||
class PythonInstance {
|
||||
public:
|
||||
PythonInstance() { Py_Initialize(); }
|
||||
~PythonInstance() { Py_Finalize(); }
|
||||
};
|
||||
|
||||
struct PciData {
|
||||
std::string device;
|
||||
std::string subsystem;
|
||||
};
|
||||
|
||||
std::optional<PciData> fromUeventFile(const std::string &deviceFilename);
|
||||
std::optional<PyObject *> getPciObject();
|
||||
std::optional<std::string> hwdataName(PyObject *pciObj, PciData);
|
@ -1,16 +1,37 @@
|
||||
libdrm_amdgpu = cc.find_library('drm_amdgpu', required : false)
|
||||
libdrm_dep = dependency('libdrm', required : false)
|
||||
|
||||
patterns_inc = include_directories('../include/deps/patterns/include/mpark')
|
||||
fplus_inc = include_directories('../include/deps/FunctionalPlus/include')
|
||||
|
||||
libdrm_amdgpu = cc.find_library('drm_amdgpu', required : false)
|
||||
libdrm_dep = dependency('libdrm', required : false)
|
||||
|
||||
python = import('python')
|
||||
python_with_hwdata = python.find_installation('python3',
|
||||
modules : ['hwdata'],
|
||||
required : get_option('require-python-hwdata'))
|
||||
hwdata_version = run_command('python3', '-c',
|
||||
'from importlib.metadata import version; print(version(\'hwdata\'))').stdout().strip()
|
||||
|
||||
if libdrm_dep.found() and libdrm_amdgpu.found()
|
||||
shared_library('amd', 'AMD.cpp', 'AMDUtils.cpp', 'Utils.cpp',
|
||||
sources = ['AMD.cpp', 'AMDUtils.cpp', 'Utils.cpp']
|
||||
cpp_args = []
|
||||
deps = [ libdrm_amdgpu, libdrm_dep, boost_dep ]
|
||||
if (python_with_hwdata.found())
|
||||
if (hwdata_version.version_compare('<2.4.1'))
|
||||
warning('python-hwdata 2.4.1 is recommended for PCI.get_subsystem')
|
||||
endif
|
||||
# Makes us link to libpython
|
||||
deps += python_with_hwdata.dependency(embed : true)
|
||||
cpp_args += '-DWITH_HWDATA'
|
||||
sources += 'HWData.cpp'
|
||||
endif
|
||||
shared_library('amd',
|
||||
sources,
|
||||
override_options : ['cpp_std=c++17'],
|
||||
include_directories : [incdir, patterns_inc, fplus_inc],
|
||||
dependencies : [ libdrm_amdgpu, libdrm_dep, boost_dep ],
|
||||
dependencies : deps,
|
||||
install_dir : get_option('libdir') / 'tuxclocker' / 'plugins',
|
||||
install : true,
|
||||
cpp_args : cpp_args,
|
||||
link_with : libtuxclocker)
|
||||
endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user