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('plugins', type: 'boolean', value: 'true', description: 'Build plugins')
|
||||||
option('library', type: 'boolean', value: 'true', description: 'Build library')
|
option('library', type: 'boolean', value: 'true', description: 'Build library')
|
||||||
option('gui', type: 'boolean', value: 'true', description: 'Build Qt GUI')
|
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 <libdrm/amdgpu_drm.h>
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
|
|
||||||
|
#ifdef WITH_HWDATA
|
||||||
|
#include <HWData.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define _(String) gettext(String)
|
#define _(String) gettext(String)
|
||||||
|
|
||||||
extern int errno;
|
extern int errno;
|
||||||
@ -1242,6 +1246,20 @@ std::vector<TreeNode<DeviceNode>> getUtilizationsRoot(AMDGPUData data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TreeNode<DeviceNode>> getGPUName(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);
|
auto name = amdgpu_get_marketing_name(data.devHandle);
|
||||||
if (name) {
|
if (name) {
|
||||||
return {DeviceNode{
|
return {DeviceNode{
|
||||||
@ -1319,6 +1337,10 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
TreeNode<DeviceNode> AMDPlugin::deviceRootNode() {
|
TreeNode<DeviceNode> AMDPlugin::deviceRootNode() {
|
||||||
|
#ifdef WITH_HWDATA
|
||||||
|
PythonInstance p;
|
||||||
|
#endif
|
||||||
|
|
||||||
TreeNode<DeviceNode> root;
|
TreeNode<DeviceNode> root;
|
||||||
|
|
||||||
auto dataVec = fromFilesystem();
|
auto dataVec = fromFilesystem();
|
||||||
|
@ -192,6 +192,7 @@ std::optional<AMDGPUData> fromRenderDFile(const fs::directory_entry &entry) {
|
|||||||
.devPath = devPath,
|
.devPath = devPath,
|
||||||
.devHandle = dev,
|
.devHandle = dev,
|
||||||
.pciId = std::to_string(info.device_id),
|
.pciId = std::to_string(info.device_id),
|
||||||
|
.deviceFilename = filename,
|
||||||
.identifier = identifier,
|
.identifier = identifier,
|
||||||
.ppTableType = tableType,
|
.ppTableType = tableType,
|
||||||
};
|
};
|
||||||
|
@ -31,6 +31,8 @@ struct AMDGPUData {
|
|||||||
amdgpu_device_handle devHandle;
|
amdgpu_device_handle devHandle;
|
||||||
// PCIe device ID
|
// PCIe device ID
|
||||||
std::string pciId;
|
std::string pciId;
|
||||||
|
// Eg. renderD128
|
||||||
|
std::string deviceFilename;
|
||||||
// Device ID + GPU index
|
// Device ID + GPU index
|
||||||
std::string identifier;
|
std::string identifier;
|
||||||
std::optional<PPTableType> ppTableType;
|
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')
|
patterns_inc = include_directories('../include/deps/patterns/include/mpark')
|
||||||
fplus_inc = include_directories('../include/deps/FunctionalPlus/include')
|
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()
|
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'],
|
override_options : ['cpp_std=c++17'],
|
||||||
include_directories : [incdir, patterns_inc, fplus_inc],
|
include_directories : [incdir, patterns_inc, fplus_inc],
|
||||||
dependencies : [ libdrm_amdgpu, libdrm_dep, boost_dep ],
|
dependencies : deps,
|
||||||
install_dir : get_option('libdir') / 'tuxclocker' / 'plugins',
|
install_dir : get_option('libdir') / 'tuxclocker' / 'plugins',
|
||||||
install : true,
|
install : true,
|
||||||
|
cpp_args : cpp_args,
|
||||||
link_with : libtuxclocker)
|
link_with : libtuxclocker)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user