Polishing for first release

This commit is contained in:
jussi 2019-01-22 15:35:17 +02:00
parent 5d72355dcc
commit a2e56302db
12 changed files with 205 additions and 131 deletions

37
README.md Normal file
View File

@ -0,0 +1,37 @@
TuxClocker - A GUI overclocking utility for GNU/Linux
========================================
TuxClocker is a Qt5 overclocking tool. Currently supported cards are nvidia 600-series cards and newer. Support for AMD GPUs is planned.
# Current features
- GPU monitoring (list and graph)
- Overclocking
- Overvolting
- Change power limit
- Fan mode selection
- Custom fan curve
- Profiles
# Planned features
- Multi-GPU support
- AMD support
- Rewrite nvidia controlling using libxnvctrl
# Requirements
- nvidia-smi
- nvidia-settings
- Qt libraries
- Coolbits set to the value you want (31 for all functionality)
# Installation
### Compilation
```
git clone https://github.com/Lurkki14/tuxclocker
cd tuxclocker
qmake rojekti.pro
make
make install (installs into /opt/tuxclocker/bin)
```

View File

@ -54,7 +54,7 @@ editProfile::editProfile(QWidget *parent) :
ui->curvePlot->xAxis->setBasePen(tickPen);
ui->curvePlot->yAxis->setBasePen(tickPen);
ui->curvePlot->xAxis->setLabel("Temperature");
ui->curvePlot->xAxis->setLabel("Temperature (°C)");
ui->curvePlot->yAxis->setLabel("Fan speed (%)");
ui->curvePlot->xAxis->setRange(x_lower, (x_upper+5));
@ -66,6 +66,7 @@ editProfile::editProfile(QWidget *parent) :
connect(ui->curvePlot, SIGNAL(mouseMove(QMouseEvent*)), SLOT(detectMove(QMouseEvent*)));
connect(ui->curvePlot, SIGNAL(mouseRelease(QMouseEvent*)), SLOT(detectRelease(QMouseEvent*)));
connect(ui->curvePlot, SIGNAL(mouseMove(QMouseEvent*)), SLOT(getClosestCoords(QMouseEvent*)));
connect(ui->curvePlot, SIGNAL(mouseMove(QMouseEvent*)), SLOT(drawPointHoveredText(QMouseEvent*)));
// Load the existing points to the graph
MainWindow mw;
@ -78,6 +79,7 @@ editProfile::editProfile(QWidget *parent) :
QCPItemText *text = new QCPItemText(ui->curvePlot);
coordText = text;
coordText->setColor(textColor);
}
editProfile::~editProfile()
@ -90,7 +92,7 @@ void editProfile::addPoint(double x, double y)
y = round(y);
x = round(x);
if (qv_x.length() != 0) {
checkForDuplicatePoint(x, y);
checkForDuplicatePoint(x, y);
}
if ((x_lower<=x) && (x<=x_upper) && (y_lower<=y) && (y<=y_upper) && !duplicatePoint) {
qv_x.append(x);
@ -138,26 +140,43 @@ void editProfile::clickedPoint(QCPAbstractPlottable *plottable, int dataIndex, Q
bool editProfile::checkForNearbyPoints(QMouseEvent *event)
{
if (qv_x.length() != 0) {
QPoint point = event->pos();
double pointerxcoord = ui->curvePlot->xAxis->pixelToCoord(point.x());
double pointerycoord = ui->curvePlot->yAxis->pixelToCoord(point.y());
for (int i=0; i<qv_x.length(); i++) {
if ((abs(pointerxcoord - qv_x[i]) < selectionPrecision) && abs(pointerycoord - qv_y[i]) < selectionPrecision) {
isNearbyPoint = true;
break;
QPoint point = event->pos();
double pointerxcoord = ui->curvePlot->xAxis->pixelToCoord(point.x());
double pointerycoord = ui->curvePlot->yAxis->pixelToCoord(point.y());
for (int i=0; i<qv_x.length(); i++) {
if ((abs(pointerxcoord - qv_x[i]) < selectionPrecision) && abs(pointerycoord - qv_y[i]) < selectionPrecision) {
isNearbyPoint = true;
break;
} else {
isNearbyPoint = false;
}
}
else {
isNearbyPoint = false;
}
}
return isNearbyPoint;
}
}
void editProfile::drawPointHoveredText(QMouseEvent *event)
{
checkForNearbyPoints(event);
if (isNearbyPoint && !draggingPoint) {
if (xcoord < x_upper*0.1) {
coordText->position->setCoords(x_upper*0.1, xcoord + 4);
} else if (xcoord > x_upper*0.9) {
coordText->position->setCoords(x_upper*0.9, xcoord + 4);
} else {
coordText->position->setCoords(xcoord, ycoord + 4);
}
coordText->setText(QString::number(xcoord) + ", " + QString::number(ycoord));
rePlot();
}
if (!isNearbyPoint && !draggingPoint) {
coordText->setText("");
rePlot();
}
}
int editProfile::getDataIndex(QCPAbstractPlottable *plottable, int dataIndex)
{
dataIndex = pointIndex;
qDebug() << pointIndex;
return pointIndex;
}
@ -212,9 +231,13 @@ bool editProfile::detectPress(QMouseEvent *event)
bool editProfile::initializeDragging(QMouseEvent *event)
{
// Decides whether to start dragging the point
if (!pressTimer->isActive() && !mouseDragging) {
pressTimer->start(20);
pressTimer->setSingleShot(true);
}
mouseDragging = true;
checkForNearbyPoints(event);
if (isNearbyPoint || draggingPoint) {
if ((isNearbyPoint || draggingPoint) && pressTimer->remainingTime() <= 0) {
dragPoint(index_x, index_y, event);
draggingPoint = true;
}
@ -255,16 +278,16 @@ void editProfile::dragPoint(int index_x, int index_y, QMouseEvent* event)
qv_y[index_y] = y_lower;
}
// Display the coordinates
QPalette palette;
palette.setCurrentColorGroup(QPalette::Active);
QColor textColor = palette.color(QPalette::Text);
coordText->position->setType(QCPItemPosition::ptPlotCoords);
coordText->position->setCoords(qv_x[index_x], qv_y[index_y] + 4);
if (ui->curvePlot->xAxis->pixelToCoord(point.x()) < x_upper*0.1) {
coordText->position->setCoords(x_upper*0.1, qv_y[index_y] + 4);
} else if (ui->curvePlot->xAxis->pixelToCoord(point.x()) > x_upper*0.9) {
coordText->position->setCoords(x_upper*0.9, qv_y[index_y] + 4);
} else {
coordText->position->setCoords(qv_x[index_x], qv_y[index_y] + 4);
}
QString xString = QString::number(qv_x[index_x]);
QString yString = QString::number(qv_y[index_y]);
coordText->setText(xString + ", " + yString);
coordText->setColor(textColor);
ui->curvePlot->graph(0)->setData(qv_x, qv_y);
drawFillerLines();
@ -298,12 +321,6 @@ void editProfile::detectRelease(QMouseEvent *event)
rePlot();
}
void editProfile::on_pushButton_clicked()
{
qDebug() << draggingPoint;
coordText->setText("");
}
void editProfile::on_saveButton_clicked()
{
QString xString;
@ -316,24 +333,27 @@ void editProfile::on_saveButton_clicked()
}
MainWindow mw;
QVariant xarray = xString;
QVariant yarray = yString;
qDebug() << xarray.toString() << yarray.toString();
QSettings settings("nvfancurve");
QString xsetting = mw.currentProfile;
QString ysetting = mw.currentProfile;
ysetting.append("/ypoints");
xsetting.append("/xpoints");
settings.setValue(xsetting, xarray);
settings.setValue(ysetting, yarray);
QSettings settings("tuxclocker");
settings.beginGroup("General");
QString currentProfile = settings.value("currentProfile").toString();
QString latestUUID = settings.value("latestUUID").toString();
settings.endGroup();
settings.beginGroup(currentProfile);
settings.beginGroup(latestUUID);
settings.setValue("ypoints", yString);
settings.setValue("xpoints", xString);
close();
}
void editProfile::on_clearButton_clicked()
{
MainWindow mw;
qv_x.clear();
qv_y.clear();
qDebug() << mw.currentProfile;
ui->curvePlot->graph(0)->setData(qv_x, qv_y);
drawFillerLines();
}
void editProfile::on_cancelButton_pressed()
{
close();
}

View File

@ -29,7 +29,6 @@ private slots:
void clickedGraph(QMouseEvent *event);
void rePlot();
void addPoint(double x, double y);
void on_pushButton_clicked();
void clickedPoint(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event);
void on_saveButton_clicked();
bool initializeDragging(QMouseEvent *event);
@ -44,6 +43,9 @@ private slots:
void dragPoint(int index_x, int index_y, QMouseEvent *event);
void drawFillerLines();
void on_clearButton_clicked();
void drawPointHoveredText(QMouseEvent *event);
void on_cancelButton_pressed();
private:
Ui::editProfile *ui;
@ -76,6 +78,8 @@ private:
int index_y = 0;
bool indicesSet = false;
bool draggingPoint = false;
QTimer *pressTimer = new QTimer(this);
int timerTime = 1000;
};
#endif // EDITPROFILE_H

View File

@ -6,12 +6,18 @@
<rect>
<x>0</x>
<y>0</y>
<width>663</width>
<height>565</height>
<width>642</width>
<height>557</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>599</width>
<height>523</height>
</size>
</property>
<property name="windowTitle">
<string>Dialog</string>
<string>Edit fan curve</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="3">
@ -21,14 +27,14 @@
</property>
</widget>
</item>
<item row="1" column="0">
<item row="1" column="2">
<widget class="QPushButton" name="clearButton">
<property name="text">
<string>Clear curve points</string>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="1" column="0">
<widget class="QPushButton" name="saveButton">
<property name="maximumSize">
<size>
@ -41,10 +47,10 @@
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="pushButton">
<item row="1" column="1">
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>testinappi</string>
<string>Cancel</string>
</property>
</widget>
</item>

BIN
icon2.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@ -11,6 +11,7 @@ MainWindow::MainWindow(QWidget *parent) :
ui(new Ui::MainWindow)
{
ui->setupUi(this);
checkForRoot();
checkForProfiles();
queryGPUSettings();
loadProfileSettings();
@ -71,11 +72,6 @@ void MainWindow::on_actionEdit_current_profile_triggered(bool)
editprof->show();
}
void MainWindow::on_pushButton_clicked()
{
qDebug() << xCurvePoints;
}
void MainWindow::checkForRoot()
{
QProcess process;
@ -507,7 +503,7 @@ void MainWindow::clearExtremeValues()
void MainWindow::checkForProfiles()
{
// If there are no profiles, create one, then list all the entries whose isProfile is true in the profile selection combo box
QSettings settings("nvfancurve");
QSettings settings("tuxclocker");
QStringList groups = settings.childGroups();
QString isProfile = "/isProfile";
@ -540,7 +536,12 @@ void MainWindow::checkForProfiles()
void MainWindow::on_profileComboBox_activated(const QString &arg1)
{
// Change currentProfile to combobox selection
currentProfile = arg1;
if (currentProfile != arg1) {
currentProfile = arg1;
QSettings settings("tuxclocker");
settings.setValue("General/currentProfile", currentProfile);
loadProfileSettings();
}
}
void MainWindow::getGPUDriver()
@ -660,6 +661,8 @@ void MainWindow::applyFanMode()
void MainWindow::queryGPUSettings()
{
QProcess process;
process.setReadChannelMode(QProcess::ForwardedErrorChannel);
process.setReadChannel(QProcess::StandardOutput);
process.start(nvVoltQ);
process.waitForFinished(-1);
voltInt = process.readLine().toInt()/1000;
@ -675,6 +678,7 @@ void MainWindow::queryGPUSettings()
process.waitForFinished(-1);
for (int i=0; i<process.size(); i++) {
if (process.readLine().toInt()/1000 > maxVoltOfsInt) {
qDebug() << process.readLine();
maxVoltOfsInt = process.readLine().toInt()/1000;
}
}
@ -835,7 +839,7 @@ void MainWindow::applyGPUSettings()
void MainWindow::loadProfileSettings()
{
QSettings settings("nvfancurve");
QSettings settings("tuxclocker");
currentProfile = settings.value("General/currentProfile").toString();
latestUUID = settings.value("General/latestUUID").toString();
settings.beginGroup(currentProfile);
@ -870,15 +874,27 @@ void MainWindow::loadProfileSettings()
}
if (settings.contains("voltageOffset")) {
latestVoltOfs = settings.value("voltageOffset").toInt();
ui->voltageSlider->setValue(latestVoltOfs);
ui->voltageSpinBox->setValue(latestVoltOfs);
}
if (settings.contains("powerLimit")) {
latestPowerLim = settings.value("powerLimit").toInt();
ui->powerLimSlider->setValue(latestPowerLim);
ui->powerLimSlider->setValue(latestPowerLim);
}
if (settings.contains("clockFrequencyOffset")) {
latestClkOfs = settings.value("clockFrequencyOffset").toInt();
ui->frequencySlider->setValue(latestClkOfs);
ui->frequencySpinBox->setValue(latestClkOfs);
}
if (settings.contains("memoryClockOffset")) {
latestMemClkOfs=settings.value("memoryClockOffset").toInt();
ui->memClkSlider->setValue(latestMemClkOfs);
ui->memClkSlider->setValue(latestMemClkOfs);
}
if (settings.contains("fanControlMode")) {
fanControlMode = settings.value("fanControlMode").toInt();
@ -892,7 +908,7 @@ void MainWindow::loadProfileSettings()
void MainWindow::on_newProfile_closed()
{
// If currentProfile doesn't exist anymore the first profile will be the first entry
QSettings settings("nvfancurve");
QSettings settings("tuxclocker");
QStringList groups = settings.childGroups();
if (!groups.contains(currentProfile)) {
for (int i=0; i<groups.size(); i++) {
@ -915,7 +931,7 @@ void MainWindow::on_newProfile_closed()
}
void MainWindow::saveProfileSettings()
{
QSettings settings("nvfancurve");
QSettings settings("tuxclocker");
settings.beginGroup("General");
settings.setValue("latestUUID", UUIDList[0]);
settings.endGroup();
@ -1022,14 +1038,16 @@ void MainWindow::enableFanUpdater()
}
void MainWindow::on_applyButton_clicked()
{
QSettings settings;
QSettings settings("tuxclocker");
settings.beginGroup("General");
QString prevProfile = settings.value("currentProfile").toString();
settings.setValue("currentProfile", currentProfile);
applyGPUSettings();
saveProfileSettings();
applyFanMode();
setupMonitorTab();
applyGPUSettings();
saveProfileSettings();
applyFanMode();
setupMonitorTab();
}
void MainWindow::on_editFanCurveButton_pressed()
{
@ -1052,3 +1070,17 @@ void MainWindow::on_fanModeComboBox_currentIndexChanged(int index)
{
fanControlMode = index;
}
void MainWindow::on_actionManage_profiles_triggered()
{
newProfile *np = new newProfile(this);
np->setAttribute(Qt::WA_DeleteOnClose);
connect(np, SIGNAL(destroyed(QObject*)), SLOT(on_newProfile_closed()));
np->setModal(false);
np->exec();
}
/*void MainWindow::on_profileComboBox_currentTextChanged(const QString &arg1)
{
}*/

View File

@ -6,8 +6,7 @@
#include "monitor.h"
#include <QProcess>
#include <QList>
#include <QtConcurrent/QtConcurrent>
//#include "/opt/cuda/include/nvml.h"
#include <QByteArray>
//#include <NVCtrl/NVCtrl.h>
namespace Ui {
@ -98,7 +97,6 @@ public slots:
private slots:
void on_actionEdit_current_profile_triggered(bool checked);
void on_pushButton_clicked();
void on_profileComboBox_activated(const QString &arg1);
void queryGPUSettings();
@ -153,6 +151,8 @@ private slots:
void plotHovered(QMouseEvent *event);
void clearPlots();
void clearExtremeValues();
void on_actionManage_profiles_triggered();
private:
Ui::MainWindow *ui;
bool noProfiles = true;
@ -177,6 +177,7 @@ private:
QTreeWidgetItem *memusage = new QTreeWidgetItem;
QTreeWidgetItem *curmaxclk = new QTreeWidgetItem;
QTreeWidgetItem *curmaxmemclk = new QTreeWidgetItem;
QTreeWidgetItem *curpowerlim = new QTreeWidgetItem;
// Widgets for the graph monitor
QWidget *plotWidget = new QWidget(this);

View File

@ -11,11 +11,11 @@
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
<string>TuxClocker</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="tabShape">
<enum>QTabWidget::Rounded</enum>
@ -28,13 +28,6 @@
<string>Performance</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="4" colspan="2">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>testinappi</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="6">
<widget class="QLabel" name="GPUNameLabel">
<property name="maximumSize">
@ -76,13 +69,6 @@
</property>
</widget>
</item>
<item row="13" column="0" colspan="2">
<widget class="QPushButton" name="applyButton">
<property name="text">
<string>Apply changes</string>
</property>
</widget>
</item>
<item row="11" column="0" colspan="3">
<widget class="QLabel" name="clockFreqLabel">
<property name="text">
@ -119,6 +105,9 @@
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Edit fan curve&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
@ -180,19 +169,19 @@
<item row="4" column="5">
<widget class="QSpinBox" name="fanSpinBox"/>
</item>
<item row="13" column="2">
<widget class="QPushButton" name="newProfile">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="13" column="3" colspan="3">
<widget class="QComboBox" name="profileComboBox"/>
</item>
<item row="6" column="5">
<widget class="QSpinBox" name="voltageSpinBox"/>
</item>
<item row="13" column="0" colspan="3">
<widget class="QPushButton" name="applyButton">
<property name="text">
<string>Apply changes</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="monitorTab">
@ -239,19 +228,11 @@
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>Fi&amp;le</string>
<string>Profi&amp;les</string>
</property>
<addaction name="actionQuit"/>
</widget>
<widget class="QMenu" name="menuProfiles">
<property name="title">
<string>P&amp;rofiles</string>
</property>
<addaction name="actionEdit_current_profile"/>
<addaction name="actionAdd_new_profile"/>
<addaction name="actionManage_profiles"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuProfiles"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="actionQuit">
@ -274,6 +255,11 @@
<string>&amp;Add new profile</string>
</property>
</action>
<action name="actionManage_profiles">
<property name="text">
<string>&amp;Manage profiles</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>

View File

@ -28,21 +28,18 @@ void newProfile::on_profileNameEdit_textChanged(const QString &arg1)
}
void newProfile::saveChange()
{
qDebug() << "edit finished";
//qDebug() << "edit finished";
//QListWidgetItem *item = ui->profileList->item(latestIndex);
newProfileList.clear();
for (int i=0; i<ui->profileList->count(); i++) {
newProfileList.append(ui->profileList->item(i)->text());
qDebug() << newProfileList[i];
//qDebug() << newProfileList[i];
ui->profileList->item(i)->setFlags(Qt::ItemIsEnabled);
}
}
void newProfile::on_saveButton_clicked()
{
QSettings settings("nvfancurve");
//settings.beginGroup("rtgerdg");
//settings.remove("");
qDebug() << removedList;
QSettings settings("tuxclocker");
// Add the new ones
for (int i=0; i<newProfileList.size(); i++) {
settings.setValue(newProfileList[i] + "/isProfile", true);
@ -52,21 +49,22 @@ void newProfile::on_saveButton_clicked()
settings.remove("");
settings.endGroup();
}
close();
}
void newProfile::listProfiles()
{
QSettings settings("nvfancurve");
QSettings settings("tuxclocker");
QString isProfile = "/isProfile";
QStringList groups = settings.childGroups();
qDebug() << "testi";
//qDebug() << "testi";
for (int i=0; i<groups.length(); i++) {
// Make a query $profile/isProfile
QString group = groups[i];
QString query = group.append(isProfile);
qDebug() << query;
//qDebug() << query;
if (settings.value(query).toBool()) {
qDebug() << groups[i];
//qDebug() << groups[i];
ui->profileList->addItem(groups[i]);
origProfileList.append(groups[i]);
newProfileList.append(groups[i]);
@ -102,22 +100,10 @@ void newProfile::on_removeButton_pressed()
{
if (ui->profileList->count() > 1) {
int index = ui->profileList->currentRow();
qDebug() << index;
//QListWidgetItem *item = new QListWidgetItem(ui->profileList);
QListWidgetItem *item = ui->profileList->item(index);
removedList.append(item->text());
newProfileList.removeAt(index);
//newProfileList.removeAt(index);
//item = ui->profileList->item(index);
ui->profileList->takeItem(index);
/*if (ui->profileList->currentRow() == ui->profileList->count()-1) {
ui->profileList->model()->removeRow(index);
} else {
ui->profileList->model()->removeRow(index +1);
}*/
//ui->profileList->model()->removeRow(ui->profileList->count()-1);
delete item;
}
}

View File

@ -11,7 +11,7 @@
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
<string>Manage profiles</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="4">

View File

@ -1,8 +1,8 @@
<RCC>
<qresource prefix="/icons">
<file>cog.png</file>
<file>icon2.ico</file>
<file>plusicon.png</file>
<file>minusicon.png</file>
<file>gpuonfire.svg</file>
</qresource>
</RCC>

View File

@ -4,11 +4,11 @@
#
#-------------------------------------------------
QT += core gui x11extras
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
TARGET = rojekti
TARGET = tuxclocker
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
@ -23,7 +23,9 @@ DEFINES += QT_DEPRECATED_WARNINGS
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++11
#CONFIG (release, debug|release) {
# DEFINES += QT_NO_DEBUG_OUTPUT
# }
SOURCES += \
main.cpp \
mainwindow.cpp \
@ -48,9 +50,9 @@ FORMS += \
editprofile.ui \
newprofile.ui
INCLUDEPATH += "/usr/lib"
#INCLUDEPATH += "/usr/lib"
LIBS += -lXext -lXNVCtrl -lX11
#LIBS += -lXext -lXNVCtrl -lX11
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin