mirror of
https://github.com/Lurkki14/tuxclocker.git
synced 2025-02-25 18:55:24 -06:00
Start adding GPU feature detection to the UI
This commit is contained in:
parent
2ac0d2d1e9
commit
de195cbf0b
@ -17,40 +17,56 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
queryGPUSettings();
|
||||
loadProfileSettings();
|
||||
queryDriverSettings();
|
||||
//getGPUName();
|
||||
queryGPUs();
|
||||
setupMonitorTab();
|
||||
setupGraphMonitorTab();
|
||||
tabHandler(ui->tabWidget->currentIndex());
|
||||
|
||||
ui->frequencySlider->setRange(minCoreClkOfsInt, maxCoreClkOfsInt);
|
||||
ui->frequencySpinBox->setRange(minCoreClkOfsInt, maxCoreClkOfsInt);
|
||||
// Create persistent nvidia pointer
|
||||
nvidia *nvd = new nvidia;
|
||||
nv = nvd;
|
||||
nv->setupXNVCtrl();
|
||||
nv->setupNVML(0);
|
||||
nv->queryGPUFeatures();
|
||||
qDebug() << nv->GPUList.size() << nv->GPUList[0].name << "gpus from main";
|
||||
|
||||
// Enable sliders according to GPU properties
|
||||
if (nv->GPUList[0].overClockAvailable) {
|
||||
ui->frequencySlider->setRange(nv->GPUList[0].minCoreClkOffset, nv->GPUList[0].maxCoreClkOffset);
|
||||
ui->frequencySpinBox->setRange(nv->GPUList[0].minCoreClkOffset, nv->GPUList[0].maxCoreClkOffset);
|
||||
ui->frequencySlider->setValue(coreFreqOfsInt);
|
||||
ui->frequencySpinBox->setValue(coreFreqOfsInt);
|
||||
|
||||
ui->memClkSlider->setRange(nv->GPUList[0].minMemClkOffset, nv->GPUList[0].maxMemClkOffset);
|
||||
ui->memClkSpinBox->setRange(nv->GPUList[0].minMemClkOffset, nv->GPUList[0].maxMemClkOffset);
|
||||
ui->memClkSlider->setValue(memClkOfsInt);
|
||||
ui->memClkSpinBox->setValue(memClkOfsInt);
|
||||
} else {
|
||||
ui->frequencySlider->setEnabled(false);
|
||||
ui->frequencySpinBox->setEnabled(false);
|
||||
}
|
||||
|
||||
ui->powerLimSlider->setRange(minPowerLimInt, maxPowerLimInt);
|
||||
ui->powerLimSpinBox->setRange(minPowerLimInt, maxPowerLimInt);
|
||||
ui->powerLimSlider->setValue(curPowerLimInt);
|
||||
ui->powerLimSpinBox->setValue(curPowerLimInt);
|
||||
|
||||
ui->memClkSlider->setRange(minMemClkOfsInt, maxMemClkOfsInt);
|
||||
ui->memClkSpinBox->setRange(minMemClkOfsInt, maxMemClkOfsInt);
|
||||
ui->memClkSlider->setValue(memClkOfsInt);
|
||||
ui->memClkSpinBox->setValue(memClkOfsInt);
|
||||
|
||||
ui->voltageSlider->setRange(minVoltOfsInt, maxVoltOfsInt);
|
||||
ui->voltageSpinBox->setRange(minVoltOfsInt, maxVoltOfsInt);
|
||||
if (nv->GPUList[0].overVoltAvailable) {
|
||||
ui->voltageSlider->setRange(nv->GPUList[0].minVoltageOffset, nv->GPUList[0].maxVoltageOffset);
|
||||
ui->voltageSpinBox->setRange(nv->GPUList[0].minVoltageOffset, nv->GPUList[0].maxVoltageOffset);
|
||||
ui->voltageSlider->setValue(voltOfsInt);
|
||||
ui->voltageSpinBox->setValue(voltOfsInt);
|
||||
} else {
|
||||
ui->voltageSlider->setEnabled(false);
|
||||
ui->voltageSpinBox->setEnabled(false);
|
||||
}
|
||||
|
||||
ui->fanSlider->setValue(fanSpeed);
|
||||
ui->fanSpinBox->setValue(fanSpeed);
|
||||
ui->fanSlider->setRange(0, 100);
|
||||
ui->fanSpinBox->setRange(0, 100);
|
||||
|
||||
//QTimer *fanUpdateTimer = new QTimer(this);
|
||||
connect(fanUpdateTimer, SIGNAL(timeout()), this, SLOT(fanSpeedUpdater()));
|
||||
//connect(fanUpdateTimer, SIGNAL(timeout()), this, SLOT(tempUpdater()));
|
||||
fanUpdateTimer->start(2000);
|
||||
|
||||
connect(ui->frequencySpinBox, SIGNAL(valueChanged(int)), SLOT(resetTimer()));
|
||||
@ -60,9 +76,6 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
|
||||
connect(ui->tabWidget, SIGNAL(currentChanged(int)), SLOT(tabHandler(int)));
|
||||
connect(monitorUpdater, SIGNAL(timeout()), SLOT(updateMonitor()));
|
||||
|
||||
nvidia nv;
|
||||
nv.setupXNVCtrl();
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
@ -322,15 +335,31 @@ void MainWindow::setupGraphMonitorTab()
|
||||
}
|
||||
void MainWindow::updateMonitor()
|
||||
{
|
||||
// This function takes around 300ms to complete, so it would be smoother to execute it in another thread
|
||||
// Update the values for plots
|
||||
nv->queryGPUTemp(0);
|
||||
nv->queryGPUPowerDraw(0);
|
||||
nv->queryGPUFrequencies(0);
|
||||
nv->queryGPUUtils(0);
|
||||
nv->queryGPUVoltage(0);
|
||||
nv->queryGPUFanSpeed(0);
|
||||
|
||||
monitor mon;
|
||||
plotCmdsList[0].valueq = nv->GPUList[0].temp;
|
||||
plotCmdsList[1].valueq = nv->GPUList[0].powerDraw/1000;
|
||||
plotCmdsList[2].valueq = nv->GPUList[0].coreFreq;
|
||||
plotCmdsList[3].valueq = nv->GPUList[0].memFreq;
|
||||
plotCmdsList[4].valueq = nv->GPUList[0].coreUtil;
|
||||
plotCmdsList[5].valueq = nv->GPUList[0].memUtil;
|
||||
plotCmdsList[6].valueq = nv->GPUList[0].voltage/1000;
|
||||
plotCmdsList[7].valueq = nv->GPUList[0].fanSpeed;
|
||||
|
||||
qDebug() << monitorUpdater->remainingTime();
|
||||
//monitor mon;
|
||||
//QThread *thread = new QThread(this);
|
||||
//mon.moveToThread(thread);
|
||||
//thread->start();
|
||||
mon.queryValues();
|
||||
fanSpeedUpdater();
|
||||
gputemp->setText(1, mon.temp + "°C");
|
||||
//mon.queryValues();
|
||||
//fanSpeedUpdater();
|
||||
/*gputemp->setText(1, mon.temp + "°C");
|
||||
powerdraw->setText(1, mon.powerdraw + "W");
|
||||
voltage->setText(1, mon.voltage + "mV");
|
||||
coreclock->setText(1, mon.coreclock + " MHz");
|
||||
@ -338,7 +367,7 @@ void MainWindow::updateMonitor()
|
||||
coreutil->setText(1, mon.coreutil + " %");
|
||||
memutil->setText(1, mon.memutil + " %");
|
||||
fanspeed->setText(1, QString::number(fanSpeed) + " %");
|
||||
memusage->setText(1, mon.usedmem + "/" + mon.totalmem);
|
||||
memusage->setText(1, mon.usedmem + "/" + mon.totalmem);*/
|
||||
|
||||
|
||||
// Decrement all time values by one
|
||||
@ -355,15 +384,6 @@ void MainWindow::updateMonitor()
|
||||
if (qv_time.size() > plotVectorSize) {
|
||||
qv_time.removeFirst();
|
||||
}
|
||||
// Update the values for plots
|
||||
plotCmdsList[0].valueq = mon.temp.toDouble();
|
||||
plotCmdsList[1].valueq = mon.powerdraw.toDouble();
|
||||
plotCmdsList[2].valueq = mon.coreclock.toDouble();
|
||||
plotCmdsList[3].valueq = mon.memclock.toDouble();
|
||||
plotCmdsList[4].valueq = mon.coreutil.toDouble();
|
||||
plotCmdsList[5].valueq = mon.memutil.toDouble();
|
||||
plotCmdsList[6].valueq = mon.voltage.toDouble();
|
||||
plotCmdsList[7].valueq = fanSpeed;
|
||||
|
||||
for (int i=0; i<plotCmdsList.size(); i++) {
|
||||
// Check if the max/min values need to be updated
|
||||
@ -440,12 +460,7 @@ void MainWindow::updateMonitor()
|
||||
}
|
||||
void MainWindow::plotHovered(QMouseEvent *event)
|
||||
{
|
||||
//plotHoverUpdater->start(1000);
|
||||
QPoint cursor = event->pos();
|
||||
//qDebug() << childAt(cursor);
|
||||
//QWidget *widget = childAt(cursor);
|
||||
//QCustomPlot *plot = widget->findChild<QCustomPlot*>(QString(), Qt::FindDirectChildrenOnly);
|
||||
//plot->xAxis->setRange(-15, 0);
|
||||
|
||||
int plotIndex = 0;
|
||||
for (int i=0; i<plotCmdsList.size(); i++) {
|
||||
@ -455,7 +470,6 @@ void MainWindow::plotHovered(QMouseEvent *event)
|
||||
}
|
||||
}
|
||||
double pointerxcoord = plotCmdsList[plotIndex].plot->xAxis->pixelToCoord(cursor.x());
|
||||
//qDebug() << pointerxcoord << plotVectorSize;
|
||||
plotCmdsList[plotIndex].tracer->position->setCoords(pointerxcoord, plotCmdsList[plotIndex].plot->yAxis->range().upper);
|
||||
// Find the y-value for the corresponding coordinate
|
||||
int valIndex = 0;
|
||||
@ -467,8 +481,6 @@ void MainWindow::plotHovered(QMouseEvent *event)
|
||||
valIndex = i;
|
||||
}
|
||||
}
|
||||
//qDebug() << plotCmdsList[plotIndex].vector[valIndex];
|
||||
//QCPItemText *text = new QCPItemText(plotCmdsList[plotIndex].plot);
|
||||
plotCmdsList[plotIndex].valText->setText(QString::number(plotCmdsList[plotIndex].vector[valIndex]));
|
||||
// Make the text stay inside the plot
|
||||
if (pointerxcoord > -plotVectorSize*0.06) {
|
||||
@ -478,7 +490,7 @@ void MainWindow::plotHovered(QMouseEvent *event)
|
||||
} else {
|
||||
plotCmdsList[plotIndex].valText->position->setCoords(pointerxcoord, plotCmdsList[plotIndex].plot->yAxis->range().upper - plotCmdsList[plotIndex].plot->yAxis->range().size()*0.05);
|
||||
}
|
||||
//QThread::msleep(10);
|
||||
QThread::msleep(10);
|
||||
} else {
|
||||
// If the cursor is not within the x-range, clear the text
|
||||
plotCmdsList[plotIndex].valText->setText("");
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <QProcess>
|
||||
#include <QList>
|
||||
#include <QByteArray>
|
||||
#include "nvidia.h"
|
||||
//#include <NVCtrl/NVCtrl.h>
|
||||
|
||||
namespace Ui {
|
||||
@ -158,6 +159,7 @@ private:
|
||||
bool noProfiles = true;
|
||||
QStringList UUIDList;
|
||||
QString latestUUID;
|
||||
nvidia *nv;
|
||||
|
||||
QTimer *resettimer = new QTimer(this);
|
||||
QTimer *fanUpdateTimer = new QTimer(this);
|
||||
@ -242,6 +244,8 @@ private:
|
||||
plotCmds voltageplot;
|
||||
plotCmds fanspeedplot;
|
||||
QVector <plotCmds> plotCmdsList;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
111
nvidia.cpp
111
nvidia.cpp
@ -9,7 +9,6 @@ nvidia::nvidia(QObject *parent) : QObject(parent)
|
||||
}
|
||||
bool nvidia::setupXNVCtrl()
|
||||
{
|
||||
setupNVML();
|
||||
// Open the x-server connection and check if the extension exists
|
||||
dpy = XOpenDisplay(nullptr);
|
||||
Bool ret;
|
||||
@ -39,7 +38,8 @@ void nvidia::queryGPUCount()
|
||||
GPU gpu;
|
||||
GPUList.append(gpu);
|
||||
}
|
||||
qDebug() << gpuCount;
|
||||
qDebug() << GPUList.size() << "gpus";
|
||||
//setupNVML(0);
|
||||
}
|
||||
void nvidia::queryGPUNames()
|
||||
{
|
||||
@ -148,17 +148,26 @@ void nvidia::queryGPUFeatures()
|
||||
qDebug() << "fanctl on";
|
||||
GPUList[i].manualFanCtrl = true;
|
||||
}
|
||||
// Query amount of VRAM
|
||||
ret = XNVCTRLQueryTargetAttribute(dpy,
|
||||
NV_CTRL_TARGET_TYPE_GPU,
|
||||
i,
|
||||
0,
|
||||
NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY,
|
||||
&GPUList[i].totalVRAM);
|
||||
qDebug() << GPUList[i].totalVRAM << "vram";
|
||||
}
|
||||
|
||||
queryGPUVoltage(0);
|
||||
queryGPUTemp(0);
|
||||
queryGPUFrequencies(0);
|
||||
queryGPUFanSpeed(0);
|
||||
//queryGPUVoltage(0);
|
||||
//queryGPUTemp(0);
|
||||
//queryGPUFrequencies(0);
|
||||
//queryGPUFanSpeed(0);
|
||||
//queryGPUUsedVRAM(0);
|
||||
//assignGPUFanSpeed(0, 60);
|
||||
//assignGPUFreqOffset(0, 10);
|
||||
//assignGPUMemClockOffset(0, 10);
|
||||
//assignGPUVoltageOffset(0, 5000);
|
||||
assignGPUFanCtlMode(0, NV_CTRL_GPU_COOLER_MANUAL_CONTROL_TRUE);
|
||||
//assignGPUFanCtlMode(0, NV_CTRL_GPU_COOLER_MANUAL_CONTROL_TRUE);
|
||||
}
|
||||
void nvidia::queryGPUVoltage(int GPUIndex)
|
||||
{
|
||||
@ -176,6 +185,7 @@ void nvidia::queryGPUVoltage(int GPUIndex)
|
||||
}
|
||||
void nvidia::queryGPUTemp(int GPUIndex)
|
||||
{
|
||||
qDebug() << GPUList.size();
|
||||
Bool ret;
|
||||
ret = XNVCTRLQueryTargetAttribute(dpy,
|
||||
NV_CTRL_TARGET_TYPE_THERMAL_SENSOR,
|
||||
@ -183,6 +193,9 @@ void nvidia::queryGPUTemp(int GPUIndex)
|
||||
0,
|
||||
NV_CTRL_THERMAL_SENSOR_READING,
|
||||
&GPUList[GPUIndex].temp);
|
||||
if (!ret) {
|
||||
qDebug() << "failed to query GPU temperature";
|
||||
}
|
||||
qDebug() << GPUList[GPUIndex].temp;
|
||||
}
|
||||
void nvidia::queryGPUFrequencies(int GPUIndex)
|
||||
@ -216,6 +229,19 @@ void nvidia::queryGPUFanSpeed(int GPUIndex)
|
||||
|
||||
qDebug() << GPUList[GPUIndex].fanSpeed;
|
||||
}
|
||||
void nvidia::queryGPUUsedVRAM(int GPUIndex)
|
||||
{
|
||||
Bool ret = XNVCTRLQueryTargetAttribute(dpy,
|
||||
NV_CTRL_TARGET_TYPE_GPU,
|
||||
GPUIndex,
|
||||
0,
|
||||
NV_CTRL_USED_DEDICATED_GPU_MEMORY,
|
||||
&GPUList[GPUIndex].usedVRAM);
|
||||
if (!ret) {
|
||||
qDebug() << "failed to query used VRAM";
|
||||
}
|
||||
qDebug() << GPUList[GPUIndex].usedVRAM << "usedvram";
|
||||
}
|
||||
bool nvidia::assignGPUFanSpeed(int GPUIndex, int targetValue)
|
||||
{
|
||||
Bool ret;
|
||||
@ -283,21 +309,74 @@ bool nvidia::assignGPUVoltageOffset(int GPUIndex, int targetValue)
|
||||
qDebug() << temp;
|
||||
return true;
|
||||
}*/
|
||||
bool nvidia::setupNVML()
|
||||
bool nvidia::setupNVML(int GPUIndex)
|
||||
{
|
||||
nvmlDevice_t dev;
|
||||
nvmlDevice_t *dev = new nvmlDevice_t;
|
||||
device = dev;
|
||||
nvmlReturn_t ret = nvmlInit();
|
||||
int i;
|
||||
char name[64];
|
||||
nvmlDeviceGetHandleByIndex(i, &dev);
|
||||
nvmlDeviceGetName(dev, name, sizeof(name)/sizeof(name[0]));
|
||||
nvmlDeviceGetHandleByIndex(GPUIndex, dev);
|
||||
//nvmlDeviceGetName(dev, name, sizeof(name)/sizeof(name[0]));
|
||||
qDebug() << name << "from nvml";
|
||||
if (NVML_SUCCESS != ret) {
|
||||
return false;
|
||||
}
|
||||
//queryGPUUtils(0);
|
||||
//queryGPUPowerLimitLimits(0);
|
||||
//queryGPUPowerDraw(0);
|
||||
//qDebug() << assignGPUPowerLimit(150000);
|
||||
return true;
|
||||
}
|
||||
void nvidia::queryGPUUtils(int GPUIndex)
|
||||
{
|
||||
nvmlUtilization_t utils;
|
||||
nvmlReturn_t ret = nvmlDeviceGetUtilizationRates(*device, &utils);
|
||||
if (NVML_SUCCESS != ret) {
|
||||
qDebug() << "failed to query GPU utilizations";
|
||||
}
|
||||
qDebug() << utils.gpu << utils.memory << "utils";
|
||||
GPUList[GPUIndex].memUtil = utils.memory;
|
||||
GPUList[GPUIndex].coreUtil = utils.gpu;
|
||||
}
|
||||
void nvidia::queryGPUPowerDraw(int GPUIndex)
|
||||
{
|
||||
uint usg;
|
||||
nvmlReturn_t ret = nvmlDeviceGetPowerUsage(*device, &usg);
|
||||
if (NVML_SUCCESS != ret) {
|
||||
qDebug() << "failed to query power usage";
|
||||
} else {
|
||||
GPUList[GPUIndex].powerDraw = usg;
|
||||
qDebug() << usg << "pwrusg";
|
||||
}
|
||||
}
|
||||
void nvidia::queryGPUPowerLimitLimits(int GPUIndex)
|
||||
{
|
||||
uint maxlim;
|
||||
uint minlim;
|
||||
nvmlReturn_t ret = nvmlDeviceGetPowerManagementLimitConstraints(*device, &minlim, &maxlim);
|
||||
if (NVML_SUCCESS != ret) {
|
||||
qDebug() << "failed to query power limit constraints";
|
||||
} else {
|
||||
GPUList[GPUIndex].minPowerLim = minlim;
|
||||
GPUList[GPUIndex].maxPowerLim = maxlim;
|
||||
qDebug() << minlim << maxlim << "powerlims";
|
||||
}
|
||||
}
|
||||
void nvidia::queryGPUPowerLimit(int GPUIndex)
|
||||
{
|
||||
uint lim;
|
||||
nvmlReturn_t ret = nvmlDeviceGetPowerManagementLimit(*device, &lim);
|
||||
if (NVML_SUCCESS != ret) {
|
||||
qDebug() << "failed to query power limit";
|
||||
} else {
|
||||
GPUList[GPUIndex].powerLim = lim;
|
||||
}
|
||||
}
|
||||
bool nvidia::assignGPUPowerLimit(uint targetValue)
|
||||
{
|
||||
nvmlReturn_t ret = nvmlDeviceSetPowerManagementLimit(*device, targetValue);
|
||||
if (NVML_SUCCESS != ret) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void nvidia::queryGPUUtils(int GPUIndex)
|
||||
{
|
||||
|
||||
}
|
||||
|
18
nvidia.h
18
nvidia.h
@ -4,6 +4,7 @@
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
#include <QtX11Extras/QX11Info>
|
||||
#include <QProcess>
|
||||
#include "/opt/cuda/include/nvml.h"
|
||||
|
||||
class nvidia : public QObject
|
||||
@ -38,6 +39,12 @@ public:
|
||||
int temp;
|
||||
int voltage;
|
||||
int fanSpeed;
|
||||
uint powerDraw;
|
||||
uint coreUtil;
|
||||
uint memUtil;
|
||||
uint minPowerLim;
|
||||
uint maxPowerLim;
|
||||
uint powerLim;
|
||||
|
||||
int totalVRAM;
|
||||
int usedVRAM;
|
||||
@ -46,11 +53,13 @@ public:
|
||||
int gpuCount = 0;
|
||||
private:
|
||||
Display *dpy;
|
||||
|
||||
nvmlDevice_t *device;
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
bool setupXNVCtrl();
|
||||
bool setupNVML();
|
||||
bool setupNVML(int GPUIndex);
|
||||
void queryGPUCount();
|
||||
void queryGPUNames();
|
||||
void queryGPUUIDs();
|
||||
@ -59,13 +68,20 @@ public slots:
|
||||
void queryGPUTemp(int GPUIndex);
|
||||
void queryGPUFrequencies(int GPUIndex);
|
||||
void queryGPUFanSpeed(int GPUIndex);
|
||||
void queryGPUUsedVRAM(int GPUIndex);
|
||||
|
||||
void queryGPUUtils(int GPUIndex);
|
||||
void queryGPUPowerDraw(int GPUIndex);
|
||||
void queryGPUPowerLimit(int GPUIndex);
|
||||
void queryGPUPowerLimitLimits(int GPUIndex);
|
||||
|
||||
bool assignGPUFanSpeed(int GPUIndex, int targetValue);
|
||||
bool assignGPUFanCtlMode(int GPUIndex, int targetValue);
|
||||
bool assignGPUFreqOffset(int GPUIndex, int targetValue);
|
||||
bool assignGPUMemClockOffset(int GPUIndex, int targetValue);
|
||||
bool assignGPUVoltageOffset(int GPUIndex, int targetValue);
|
||||
// NVML functions know the GPU index already based on the dev object passed in setupNVML()
|
||||
bool assignGPUPowerLimit(uint targetValue);
|
||||
private slots:
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user