diff -Nru radeon-profile-0.1.10~yakkety/daemonComm.cpp radeon-profile-0.1.17~yakkety/daemonComm.cpp --- radeon-profile-0.1.10~yakkety/daemonComm.cpp 2016-06-28 14:42:31.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/daemonComm.cpp 2017-01-25 18:00:11.000000000 +0000 @@ -5,7 +5,7 @@ #include daemonComm::daemonComm() { - signalSender = new QLocalSocket(); + signalSender = new QLocalSocket(this); connect(signalSender,SIGNAL(connected()),this,SLOT(onConnect())); } diff -Nru radeon-profile-0.1.10~yakkety/debian/changelog radeon-profile-0.1.17~yakkety/debian/changelog --- radeon-profile-0.1.10~yakkety/debian/changelog 2016-06-28 14:57:29.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/debian/changelog 2017-01-25 23:10:24.000000000 +0000 @@ -1,9 +1,26 @@ -radeon-profile (0.1.10~yakkety) yakkety; urgency=emergency +radeon-profile (0.1.17~yakkety) yakkety; urgency=emergency - * Some fixes + * Fix libdrm-dev dependencie + + -- Goran Vidovic (gogo) Thu, 26 Jan 2017 00:10:05 +0100 + +radeon-profile (0.1.16~trusty) trusty; urgency=emergency + + * Add libdrm-dev dependencie + + -- Goran Vidovic (gogo) Fri, 15 Jan 2017 23:40:05 +0100 - -- Goran Vidovic (gogo) Sat, 28 Jun 2016 16:57:05 +0100 +radeon-profile (0.1.15~zesty) zesty; urgency=emergency + + * Add ioctl functions + + -- Goran Vidovic (gogo) Fri, 15 Jan 2017 23:16:05 +0100 + +radeon-profile (0.1.11~trusty) trusty; urgency=emergency + + * Some fixes + -- Goran Vidovic (gogo) Sat, 28 Jun 2016 17:07:05 +0100 radeon-profile (0.1.9~trusty) trusty; urgency=emergency diff -Nru radeon-profile-0.1.10~yakkety/debian/control radeon-profile-0.1.17~yakkety/debian/control --- radeon-profile-0.1.10~yakkety/debian/control 2016-06-02 18:53:17.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/debian/control 2017-01-25 23:07:03.000000000 +0000 @@ -4,6 +4,7 @@ Maintainer: gogo Uploaders: gogo Build-Depends: debhelper (>= 9), + build-essential, xserver-xorg-video-ati, gcc, gdb, libqt4-dev, @@ -17,7 +18,7 @@ Package: radeon-profile Architecture: any -Depends: xserver-xorg-video-ati, mesa-utils, x11-utils, libxrandr2, lm-sensors, radeon-profile-daemon +Depends: xserver-xorg-video-ati, mesa-utils, x11-utils, libxrandr2, libdrm-dev, lm-sensors, radeon-profile-daemon Description: AMD graphics card monitoring and tweaking tool. Radeon Profile, open source AMD graphics card monitoring and tweaking tool. It supports open source drivers and fglrx. diff -Nru radeon-profile-0.1.10~yakkety/debian/rules radeon-profile-0.1.17~yakkety/debian/rules --- radeon-profile-0.1.10~yakkety/debian/rules 2016-06-23 07:59:32.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/debian/rules 2017-01-25 17:47:35.000000000 +0000 @@ -1,5 +1,15 @@ #!/usr/bin/make -f +#export DH_VERBOSE=1 +# This is the debhelper compatability version to use. + +#MAKEFLAGS="-j $(grep -c ^processor /proc/cpuinfo)" + +#export DH_COMPAT=3 APPNAME := radeon-profile +DESTDIR := $(CURDIR)/debian/$(APPNAME) +#TR_DIR=$(CURDIR)/debian/$(APPNAME)/usr/share/qt4/translations + + builddir: mkdir -p builddir @@ -11,10 +21,10 @@ build-stamp: builddir/Makefile dh_testdir # Add here commands to compile the package. - cd builddir && $(MAKE) + cd builddir && $(MAKE) #$(MAKEFLAGS) # Generate translations - #lupdate radeon-profile.pro - lrelease radeon-profile.pro + lupdate $(APPNAME).pro + lrelease $(APPNAME).pro touch $@ clean: @@ -23,25 +33,26 @@ rm -f build-stamp # Add here commands to clean up after the build process. rm -rf builddir + #rm translations/*.qm dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs - mkdir $(CURDIR)/debian/$(APPNAME)/usr - mkdir $(CURDIR)/debian/$(APPNAME)/usr/bin - mkdir $(CURDIR)/debian/$(APPNAME)/usr/share - mkdir $(CURDIR)/debian/$(APPNAME)/usr/share/applications - mkdir $(CURDIR)/debian/$(APPNAME)/usr/share/pixmaps - mkdir $(CURDIR)/debian/$(APPNAME)/usr/share/radeon-profile - cp $(CURDIR)/builddir/radeon-profile $(TR_DIR) $(CURDIR)/debian/$(APPNAME)/usr/share/radeon-profile - cp $(CURDIR)/extra/radeon-profile.desktop $(TR_DIR) $(CURDIR)/debian/$(APPNAME)/usr/share/applications - cp $(CURDIR)/extra/radeon-profile.png $(TR_DIR) $(CURDIR)/debian/$(APPNAME)/usr/share/pixmaps - mv $(CURDIR)/*.qm $(TR_DIR) $(CURDIR)/debian/$(APPNAME)/usr/share/radeon-profile + mkdir $(DESTDIR)/usr + mkdir $(DESTDIR)/usr/bin + mkdir $(DESTDIR)/usr/share + mkdir $(DESTDIR)/usr/share/applications + mkdir $(DESTDIR)/usr/share/pixmaps + mkdir $(DESTDIR)/usr/share/$(APPNAME) + cp $(CURDIR)/builddir/$(APPNAME) $(DESTDIR)/usr/share/$(APPNAME) + cp $(CURDIR)/extra/$(APPNAME).desktop $(DESTDIR)/usr/share/applications + cp $(CURDIR)/extra/$(APPNAME).png $(DESTDIR)/usr/share/pixmaps + mv $(CURDIR)/translations/*.qm $(DESTDIR)/usr/share/$(APPNAME) # Add here commands to install the package into debian/your_appname - cd builddir && $(MAKE) INSTALL_ROOT=$(CURDIR)/debian/$(APPNAME) install + cd builddir && $(MAKE) INSTALL_ROOT=$(DESTDIR) install # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. @@ -53,7 +64,7 @@ dh_installdocs dh_installexamples dh_installman - dh_link /usr/share/radeon-profile/radeon-profile /usr/bin/radeon-profile + dh_link /usr/share/$(APPNAME)/$(APPNAME) /usr/bin/$(APPNAME) #dh_strip --dbg-package=my-application-dbg dh_compress dh_fixperms diff -Nru radeon-profile-0.1.10~yakkety/dialog_rpevent.cpp radeon-profile-0.1.17~yakkety/dialog_rpevent.cpp --- radeon-profile-0.1.10~yakkety/dialog_rpevent.cpp 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/dialog_rpevent.cpp 2017-01-25 18:00:11.000000000 +0000 @@ -0,0 +1,142 @@ +#include "dialog_rpevent.h" +#include "ui_dialog_rpevent.h" +#include "radeon_profile.h" +#include "globalStuff.h" + +#include +#include +#include +#include + +Dialog_RPEvent::Dialog_RPEvent(QWidget *parent) : + QDialog(parent), + ui(new Ui::Dialog_RPEvent) +{ + ui->setupUi(this); + setFixedSize(size()); + + setFixedFanSpeedVisibility(false); + ui->spin_fixedFanSpeed->setMinimum(radeon_profile::minFanStepsSpeed); +} + +void Dialog_RPEvent::setFeatures(const globalStuff::driverFeatures &features, const QList &profiles) { + switch (features.pm) { + case globalStuff::powerMethod::DPM: + ui->combo_dpmChange->addItems(globalStuff::createDPMCombo()); + ui->combo_powerLevelChange->addItems(globalStuff::createPowerLevelCombo()); + break; + case globalStuff::powerMethod::PROFILE: + ui->combo_dpmChange->addItems(globalStuff::createProfileCombo()); + ui->combo_powerLevelChange->setVisible(false); + ui->l_powerLevel->setVisible(false); + + ui->l_profile->setText(tr("Set Profile to:")); + break; + default: + break; + } + + ui->combo_fanChange->addItem(tr("Auto")); + ui->combo_fanChange->addItem(tr("Fixed speed")); + + for (QString p : profiles) + ui->combo_fanChange->addItem(p); + + if (!features.pwmAvailable) { + ui->combo_fanChange->setVisible(false); + ui->l_fan->setVisible(false); + } +} + +Dialog_RPEvent::~Dialog_RPEvent() +{ + delete ui; +} + +void Dialog_RPEvent::on_btn_cancel_clicked() +{ + this->reject(); +} + +void Dialog_RPEvent::on_btn_save_clicked() +{ + if (ui->edt_eventName->text().isEmpty()) + return; + + this->setResult(QDialog::Accepted); + + switch (ui->combo_eventTrigger->currentIndex()) { + case 0: + createdEvent.type = rpeventType::TEMPEREATURE; + break; + case 1: + createdEvent.type = rpeventType::BIANRY; + + if (ui->edt_binary->text().isEmpty()) { + QMessageBox::information(this, "", tr("Selected trigger type is Binary, so the binary field cannot be empty."),QMessageBox::Ok); + return; + } + break; + } + + createdEvent.enabled = ui->cb_enabled->isChecked(); + createdEvent.name = ui->edt_eventName->text(); + + createdEvent.activationBinary = ui->edt_binary->text(); + createdEvent.activationTemperature = ui->spin_tempActivate->value(); + + createdEvent.dpmProfileChange = createdEvent.getEnumFromCombo(ui->combo_dpmChange->currentIndex()); + createdEvent.powerLevelChange = createdEvent.getEnumFromCombo(ui->combo_powerLevelChange->currentIndex()); + + createdEvent.fixedFanSpeedChange = ui->spin_fixedFanSpeed->value(); + createdEvent.fanComboIndex = ui->combo_fanChange->currentIndex(); + + if (ui->combo_fanChange->currentIndex() > 1) + createdEvent.fanProfileNameChange = ui->combo_fanChange->currentText(); + + this->accept(); +} + +RPEvent Dialog_RPEvent::getCreatedEvent() { + return createdEvent; +} + +void Dialog_RPEvent::setEditedEvent(const RPEvent &rpe) { + createdEvent = rpe; + + ui->combo_eventTrigger->setCurrentIndex(rpe.type); + ui->cb_enabled->setChecked(rpe.enabled); + ui->edt_eventName->setText(rpe.name); + ui->spin_tempActivate->setValue(rpe.activationTemperature); + ui->edt_binary->setText(rpe.activationBinary); + ui->combo_dpmChange->setCurrentIndex(rpe.dpmProfileChange + 1); + ui->combo_powerLevelChange->setCurrentIndex(rpe.powerLevelChange + 1); + + if (rpe.fanComboIndex > 1) + ui->combo_fanChange->setCurrentIndex(ui->combo_fanChange->findText(rpe.fanProfileNameChange)); + else + ui->combo_fanChange->setCurrentIndex(rpe.fanComboIndex); + + ui->spin_fixedFanSpeed->setValue(rpe.fixedFanSpeedChange); +} + +void Dialog_RPEvent::setFixedFanSpeedVisibility(bool visibility) { + ui->widget_fixedFanSpeed->setVisible(visibility); +} + +void Dialog_RPEvent::on_combo_fanChange_currentIndexChanged(int index) +{ + if (index == 2) + setFixedFanSpeedVisibility(true); + else + setFixedFanSpeedVisibility(false); +} + +void Dialog_RPEvent::on_btn_setBinary_clicked() +{ + QString binaryPath = QFileDialog::getOpenFileName(this, tr("Select binary"), + (!ui->edt_binary->text().isEmpty()) ? QFileInfo(ui->edt_binary->text()).absoluteFilePath() : ""); + + if (!binaryPath.isEmpty()) + ui->edt_binary->setText(binaryPath); +} diff -Nru radeon-profile-0.1.10~yakkety/dialog_rpevent.h radeon-profile-0.1.17~yakkety/dialog_rpevent.h --- radeon-profile-0.1.10~yakkety/dialog_rpevent.h 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/dialog_rpevent.h 2017-01-25 18:00:11.000000000 +0000 @@ -0,0 +1,37 @@ +#ifndef DIALOG_EVENT_H +#define DIALOG_EVENT_H + +#include "radeon_profile.h" + +#include + + +namespace Ui { + class Dialog_RPEvent; +} + +class Dialog_RPEvent : public QDialog +{ + Q_OBJECT + +public: + explicit Dialog_RPEvent(QWidget *parent = 0); + ~Dialog_RPEvent(); + void setFeatures(const globalStuff::driverFeatures &features, const QList &profiles); + void setEditedEvent(const RPEvent &rpe); + RPEvent getCreatedEvent(); + +private slots: + void on_btn_cancel_clicked(); + void on_btn_save_clicked(); + void on_combo_fanChange_currentIndexChanged(int index); + void on_btn_setBinary_clicked(); + +private: + void setFixedFanSpeedVisibility(bool visibility); + + Ui::Dialog_RPEvent *ui; + RPEvent createdEvent; +}; + +#endif // DIALOG_EVENT_H diff -Nru radeon-profile-0.1.10~yakkety/dialog_rpevent.ui radeon-profile-0.1.17~yakkety/dialog_rpevent.ui --- radeon-profile-0.1.10~yakkety/dialog_rpevent.ui 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/dialog_rpevent.ui 2017-01-25 18:00:11.000000000 +0000 @@ -0,0 +1,309 @@ + + + Dialog_RPEvent + + + + 0 + 0 + 400 + 350 + + + + + 0 + 0 + + + + Event definition + + + true + + + + + 310 + 320 + 80 + 21 + + + + Save + + + + + + 220 + 320 + 80 + 21 + + + + Cancel + + + + + + 10 + 170 + 381 + 141 + + + + Modify: + + + + + 10 + 20 + 371 + 111 + + + + + + + Set power level: + + + + + + + + No change + + + + + + + + + No change + + + + + + + + Set fan: + + + + + + + + No change + + + + + + + + Set DPM to: + + + + + + + + + 70 + 0 + 16 + 22 + + + + % + + + + + + 0 + 0 + 61 + 23 + + + + 100 + + + + + + + + + + + 10 + 100 + 381 + 61 + + + + 0 + + + + + + 10 + 10 + 361 + 21 + + + + Activate above this temperature: + + + + + + 10 + 30 + 81 + 21 + + + + QAbstractSpinBox::UpDownArrows + + + + + + + + 10 + 9 + 361 + 21 + + + + Binary (executing this binary will trigger event): + + + + + + 10 + 30 + 321 + 20 + + + + + + + 340 + 30 + 31 + 20 + + + + ... + + + + + + + + 10 + 10 + 381 + 81 + + + + + + + + + + Event name + + + + + + + Qt::RightToLeft + + + Enabled + + + true + + + + + + + + Temperature + + + + + Binary + + + + + + + + Event trigger + + + + + + + + + + combo_eventTrigger + currentIndexChanged(int) + stackedWidget + setCurrentIndex(int) + + + 333 + 71 + + + 333 + 96 + + + + + diff -Nru radeon-profile-0.1.10~yakkety/Doxyfile radeon-profile-0.1.17~yakkety/Doxyfile --- radeon-profile-0.1.10~yakkety/Doxyfile 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/Doxyfile 2017-01-25 18:00:54.000000000 +0000 @@ -0,0 +1,17 @@ +# Doxygen documentation configuration +# Run doxygen in radeon-profile/ to generate documentation +# Then open radeon-profile/html/index.html to see it in the browser +# Add radeon-profile/html/doc.qch to QtCreator (Tools > Options > Help > Documentation > Add) to see it in documentation + +PROJECT_NAME = "Radeon profile" +INPUT = . .. +EXCLUDE = qcustomplot.h qcustomplot.cpp +USE_MDFILE_AS_MAINPAGE = ../README.md + +GENERATE_LATEX = NO +GENERATE_HTML = YES +GENERATE_QHP = YES # Qt Creator Documentation +QHG_LOCATION = /usr/bin/qhelpgenerator +QCH_FILE = doc.qch + +EXTRACT_PRIVATE = YES # Document also private members diff -Nru radeon-profile-0.1.10~yakkety/dxorg.cpp radeon-profile-0.1.17~yakkety/dxorg.cpp --- radeon-profile-0.1.10~yakkety/dxorg.cpp 2016-06-28 14:42:31.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/dxorg.cpp 2017-01-25 18:00:54.000000000 +0000 @@ -1,7 +1,9 @@ // copyright marazmista @ 29.03.2014 #include "dxorg.h" -#include "globalStuff.h" +#include "gpu.h" + +#include "ioctlHandler.hpp" #include #include @@ -13,50 +15,78 @@ dXorg::tempSensor dXorg::currentTempSensor = dXorg::TS_UNKNOWN; globalStuff::powerMethod dXorg::currentPowerMethod; int dXorg::sensorsGPUtempIndex; +short dXorg::rxMatchIndex; +short dXorg::clocksValueDivider; +QString dXorg::driverModuleName; QChar dXorg::gpuSysIndex; QSharedMemory dXorg::sharedMem; dXorg::driverFilePaths dXorg::filePaths; +dXorg::rxPatternsStruct dXorg::rxPatterns; +daemonComm *dXorg::dcomm = new daemonComm(); // end // -daemonComm *dcomm = new daemonComm(); - -void dXorg::configure(QString gpuName) { +void dXorg::configure(const QString &gpuName) { + setupDriverModule(gpuName); + qDebug() << "Using module" << dXorg::driverModuleName; figureOutGpuDataFilePaths(gpuName); currentTempSensor = testSensor(); currentPowerMethod = getPowerMethod(); - if (!globalStuff::globalConfig.rootMode) { - qDebug() << "Running in non-root mode, connecting and configuring the daemon"; - // create the shared mem block. The if comes from that configure method - // is called on every change gpu, so later, shared mem already exists - if (!sharedMem.isAttached()) { - qDebug() << "Shared memory is not attached, creating it"; - sharedMem.setKey("radeon-profile"); - if (!sharedMem.create(SHARED_MEM_SIZE)){ - if(sharedMem.error() == QSharedMemory::AlreadyExists){ - qDebug() << "Shared memory already exists, attaching to it"; - if (!sharedMem.attach()) - qCritical() << "Unable to attach to the shared memory: " << sharedMem.errorString(); - } else - qCritical() << "Unable to create the shared memory: " << sharedMem.errorString(); - } - // If QSharedMemory::create() returns true, it has already automatically attached - } - - dcomm->connectToDaemon(); - if (daemonConnected()) { - qDebug() << "Daemon is connected, configuring it"; - // Configure the daemon to read the data - QString command; // SIGNAL_CONFIG + SEPARATOR + CLOCKS_PATH + SEPARATOR - command.append(DAEMON_SIGNAL_CONFIG).append(SEPARATOR); // Configuration flag - command.append(filePaths.clocksPath).append(SEPARATOR); // Path where the daemon will read clocks + if (globalStuff::globalConfig.rootMode) + return; - qDebug() << "Sending daemon config command: " << command; - dcomm->sendCommand(command); + qDebug() << "Running in non-root mode, connecting and configuring the daemon"; + // create the shared mem block. The if comes from that configure method + // is called on every change gpu, so later, shared mem already exists + if (!sharedMem.isAttached()) { + qDebug() << "Shared memory is not attached, creating it"; + sharedMem.setKey("radeon-profile"); + + if (!sharedMem.create(SHARED_MEM_SIZE)) { + if (sharedMem.error() == QSharedMemory::AlreadyExists){ + qDebug() << "Shared memory already exists, attaching to it"; - reconfigureDaemon(); // Set up timer - } else - qCritical() << "Daemon is not connected, therefore it can't be configured"; + if (!sharedMem.attach()) + qCritical() << "Unable to attach to the shared memory: " << sharedMem.errorString(); + + } else + qCritical() << "Unable to create the shared memory: " << sharedMem.errorString(); + } + // If QSharedMemory::create() returns true, it has already automatically attached + } + + dcomm->connectToDaemon(); + if (daemonConnected()) { + qDebug() << "Daemon is connected, configuring it"; + // Configure the daemon to read the data + QString command; // SIGNAL_CONFIG + SEPARATOR + CLOCKS_PATH + SEPARATOR + command.append(DAEMON_SIGNAL_CONFIG).append(SEPARATOR); // Configuration flag + command.append(filePaths.clocksPath).append(SEPARATOR); // Path where the daemon will read clocks + + qDebug() << "Sending daemon config command: " << command; + dcomm->sendCommand(command); + + reconfigureDaemon(); // Set up timer + } else + qCritical() << "Daemon is not connected, therefore it can't be configured"; +} + +void dXorg::setupDriverModule(const QString &gpuName) { + QFile f("/sys/class/drm/"+gpuName+"/device/uevent"); + if (f.open(QIODevice::ReadOnly)) { + QString line = f.readLine(50).trimmed(); + f.close(); + + if (line == "DRIVER=radeon") { + dXorg::driverModuleName = "radeon"; + return; + } + + + if (line == "DRIVER=amdgpu") { + dXorg::driverModuleName = "amdgpu"; + return; + } } } @@ -82,7 +112,37 @@ return dcomm->connected(); } -void dXorg::figureOutGpuDataFilePaths(QString gpuName) { +void dXorg::figureOutGpuDataFilePaths(const QString &gpuName) { + + /* Example IOCTLs + unsigned index = gpuName[4].toLatin1() - '0'; + ioctlHandler *ioctls; + if(dXorg::driverModuleName == "radeon") + ioctls = new radeonIoctlHandler(index); + else if(dXorg::driverModuleName == "amdgpu") + ioctls = new amdgpuIoctlHandler(index); + else + ioctls = NULL; + + if(ioctls!=NULL && ioctls->isValid()){ + int i; + unsigned u; + unsigned long ul; + float f; + + qDebug() << "Testing IOCTLs"; + qDebug() << "Driver: " << ioctls->getDriverName(); + if(ioctls->getCoreClock(&u)) qDebug() << "Core clock:" << u << "MHz"; + if(ioctls->getMaxCoreClock(&u)) qDebug() << "Max core clock:" << u/1000 << "MHz"; + if(ioctls->getMemoryClock(&u)) qDebug() << "Memory clock:" << u << "MHz"; + if(ioctls->getTemperature(&i)) qDebug() << "Temperature:" << i/1000.0f << "°C"; + if(ioctls->getVramUsage(&ul)) qDebug() << "VRAM usage:" << ul/1024 << "KB"; + if(ioctls->getVramSize(&ul)) qDebug() << "VRAM size:" << ul/1024 << "KB"; + if(ioctls->getGpuUsage(&f, 500000, 150)) qDebug() << "GPU usage:" << f << "%"; + delete ioctls; + } + */ + gpuSysIndex = gpuName.at(gpuName.length()-1); QString devicePath = "/sys/class/drm/"+gpuName+"/device/"; @@ -90,9 +150,8 @@ filePaths.profilePath = devicePath + file_powerProfile; filePaths.dpmStateFilePath = devicePath + file_powerDpmState; filePaths.forcePowerLevelFilePath = devicePath + file_powerDpmForcePerformanceLevel; - filePaths.moduleParamsPath = devicePath + "driver/module/holders/radeon/parameters/"; - filePaths.clocksPath = "/sys/kernel/debug/dri/"+QString(gpuSysIndex)+"/radeon_pm_info"; // this path contains only index - // filePaths.clocksPath = "/tmp/radeon_pm_info"; // testing + filePaths.moduleParamsPath = devicePath + "driver/module/holders/"+dXorg::driverModuleName+"/parameters/"; + filePaths.clocksPath = "/sys/kernel/debug/dri/"+QString(gpuSysIndex)+"/"+dXorg::driverModuleName+"_pm_info"; // this path contains only index filePaths.overDrivePath = devicePath + file_overclockLevel; @@ -119,11 +178,15 @@ // method for gather info about clocks from deamon or from debugfs if root QString dXorg::getClocksRawData(bool resolvingGpuFeatures) { QFile clocksFile(filePaths.clocksPath); - QByteArray data; + QString data; + + if (clocksFile.open(QIODevice::ReadOnly)) { + data = QString(clocksFile.readAll()).trimmed(); + clocksFile.close(); + return data; + } - if (clocksFile.open(QIODevice::ReadOnly)) // check for debugfs access - data = clocksFile.readAll(); - else if (daemonConnected()) { + if (daemonConnected()) { if (!globalStuff::globalConfig.daemonAutoRefresh){ qDebug() << "Asking the daemon to read clocks"; dcomm->sendCommand(QString(DAEMON_SIGNAL_READ_CLOCKS).append(SEPARATOR)); // SIGNAL_READ_CLOCKS + SEPARATOR @@ -132,8 +195,9 @@ // fist call, so notihing is in sharedmem and we need to wait for data // because we need correctly figure out what is available // see: https://stackoverflow.com/a/11487434/2347196 - if (resolvingGpuFeatures) { - QTime delayTime = QTime::currentTime().addMSecs(1000); + if (Q_UNLIKELY(resolvingGpuFeatures)) { + QTime delayTime = QTime::currentTime().addMSecs(1200); + qDebug() << "Waiting for first daemon data read..."; while (QTime::currentTime() < delayTime) QCoreApplication::processEvents(QEventLoop::AllEvents, 100); } @@ -142,7 +206,7 @@ const char *to = (const char*)sharedMem.constData(); if (to != NULL) { qDebug() << "Reading data from shared memory"; - data = QByteArray::fromRawData(to, SHARED_MEM_SIZE); + data = QString(QByteArray::fromRawData(to, SHARED_MEM_SIZE)).trimmed(); } else qWarning() << "Shared memory data pointer is invalid: " << sharedMem.errorString(); sharedMem.unlock(); @@ -150,10 +214,12 @@ qWarning() << "Unable to lock the shared memory: " << sharedMem.errorString(); } - if (data.isEmpty()) - qWarning() << "No data was found"; + #ifdef QT_DEBUG + if (resolvingGpuFeatures) + qDebug() << data; + #endif - return (QString)data.trimmed(); + return data; } globalStuff::gpuClocksStruct dXorg::getClocks(const QString &data) { @@ -169,44 +235,44 @@ case globalStuff::DPM: { QRegExp rx; - rx.setPattern("power\\slevel\\s\\d"); + rx.setPattern(rxPatterns.powerLevel); rx.indexIn(data); if (!rx.cap(0).isEmpty()) tData.powerLevel = rx.cap(0).split(' ')[2].toShort(); - rx.setPattern("sclk:\\s\\d+"); + rx.setPattern(rxPatterns.sclk); rx.indexIn(data); if (!rx.cap(0).isEmpty()) - tData.coreClk = rx.cap(0).split(' ',QString::SkipEmptyParts)[1].toDouble() / 100; + tData.coreClk = rx.cap(0).split(' ',QString::SkipEmptyParts)[rxMatchIndex].toFloat() / dXorg::clocksValueDivider; - rx.setPattern("mclk:\\s\\d+"); + rx.setPattern(rxPatterns.mclk); rx.indexIn(data); if (!rx.cap(0).isEmpty()) - tData.memClk = rx.cap(0).split(' ',QString::SkipEmptyParts)[1].toDouble() / 100; + tData.memClk = rx.cap(0).split(' ',QString::SkipEmptyParts)[rxMatchIndex].toFloat() / dXorg::clocksValueDivider; - rx.setPattern("vclk:\\s\\d+"); + rx.setPattern(rxPatterns.vclk); rx.indexIn(data); if (!rx.cap(0).isEmpty()) { - tData.uvdCClk = rx.cap(0).split(' ',QString::SkipEmptyParts)[1].toDouble() / 100; + tData.uvdCClk = rx.cap(0).split(' ',QString::SkipEmptyParts)[rxMatchIndex].toFloat() / dXorg::clocksValueDivider; tData.uvdCClk = (tData.uvdCClk == 0) ? -1 : tData.uvdCClk; } - rx.setPattern("dclk:\\s\\d+"); + rx.setPattern(rxPatterns.dclk); rx.indexIn(data); if (!rx.cap(0).isEmpty()) { - tData.uvdDClk = rx.cap(0).split(' ',QString::SkipEmptyParts)[1].toDouble() / 100; + tData.uvdDClk = rx.cap(0).split(' ',QString::SkipEmptyParts)[rxMatchIndex].toFloat() / dXorg::clocksValueDivider; tData.uvdDClk = (tData.uvdDClk == 0) ? -1 : tData.uvdDClk; } - rx.setPattern("vddc:\\s\\d+"); + rx.setPattern(rxPatterns.vddc); rx.indexIn(data); if (!rx.cap(0).isEmpty()) - tData.coreVolt = rx.cap(0).split(' ',QString::SkipEmptyParts)[1].toDouble(); + tData.coreVolt = rx.cap(0).split(' ',QString::SkipEmptyParts)[rxMatchIndex].toFloat(); - rx.setPattern("vddci:\\s\\d+"); + rx.setPattern(rxPatterns.vddci); rx.indexIn(data); if (!rx.cap(0).isEmpty()) - tData.memVolt = rx.cap(0).split(' ',QString::SkipEmptyParts)[1].toDouble(); + tData.memVolt = rx.cap(0).split(' ',QString::SkipEmptyParts)[rxMatchIndex].toFloat(); return tData; break; @@ -217,19 +283,19 @@ switch (i) { case 1: { if (clocksData[i].contains("current engine clock")) { - tData.coreClk = QString().setNum(clocksData[i].split(' ',QString::SkipEmptyParts,Qt::CaseInsensitive)[3].toFloat() / 1000).toDouble(); + tData.coreClk = QString().setNum(clocksData[i].split(' ',QString::SkipEmptyParts,Qt::CaseInsensitive)[3].toFloat() / 1000).toFloat(); break; } }; case 3: { if (clocksData[i].contains("current memory clock")) { - tData.memClk = QString().setNum(clocksData[i].split(' ',QString::SkipEmptyParts,Qt::CaseInsensitive)[3].toFloat() / 1000).toDouble(); + tData.memClk = QString().setNum(clocksData[i].split(' ',QString::SkipEmptyParts,Qt::CaseInsensitive)[3].toFloat() / 1000).toFloat(); break; } } case 4: { if (clocksData[i].contains("voltage")) { - tData.coreVolt = QString().setNum(clocksData[i].split(' ',QString::SkipEmptyParts,Qt::CaseInsensitive)[1].toFloat()).toDouble(); + tData.coreVolt = QString().setNum(clocksData[i].split(' ',QString::SkipEmptyParts,Qt::CaseInsensitive)[1].toFloat()).toFloat(); break; } } @@ -257,7 +323,7 @@ hwmon.open(QIODevice::ReadOnly); temp = hwmon.readLine(20); hwmon.close(); - return temp.toDouble() / 1000; + return temp.toFloat() / 1000; break; } case PCI_SENSOR: { @@ -275,10 +341,13 @@ break; } } - return temp.toDouble(); + return temp.toFloat(); } globalStuff::powerMethod dXorg::getPowerMethod() { + if (QFile::exists(filePaths.dpmStateFilePath)) + return globalStuff::DPM; + QFile powerMethodFile(filePaths.powerMethodFilePath); if (powerMethodFile.open(QIODevice::ReadOnly)) { QString s = powerMethodFile.readLine(20); @@ -289,8 +358,9 @@ return globalStuff::PROFILE; else return globalStuff::PM_UNKNOWN; - } else - return globalStuff::PM_UNKNOWN; + } + + return globalStuff::PM_UNKNOWN; } dXorg::tempSensor dXorg::testSensor() { @@ -308,8 +378,8 @@ // if above fails, use lm_sensors QStringList out = globalStuff::grabSystemInfo("sensors"); - if (out.indexOf(QRegExp("radeon-pci.+")) != -1) { - sensorsGPUtempIndex = out.indexOf(QRegExp("radeon-pci.+")); // in order to not search for it again in timer loop + if (out.indexOf(QRegExp(dXorg::driverModuleName+"-pci.+")) != -1) { + sensorsGPUtempIndex = out.indexOf(QRegExp(dXorg::driverModuleName+"-pci.+")); // in order to not search for it again in timer loop return PCI_SENSOR; } else if (out.indexOf(QRegExp("VGA_TEMP.+")) != -1) { @@ -338,12 +408,12 @@ } QStringList dXorg::getGLXInfo(QProcessEnvironment env) { - return globalStuff::grabSystemInfo("glxinfo",env).filter(QRegExp("direct|OpenGL.+:.+")); + return globalStuff::grabSystemInfo("glxinfo -B",env).filter(QRegExp(".+")); } QList dXorg::getModuleInfo() { QList data; - QStringList modInfo = globalStuff::grabSystemInfo("modinfo -p radeon"); + QStringList modInfo = globalStuff::grabSystemInfo("modinfo -p "+dXorg::driverModuleName); modInfo.sort(); for (int i =0; i < modInfo.count(); i++) { @@ -375,7 +445,9 @@ for (char i = 0; i < out.count(); i++) { QFile f("/sys/class/drm/"+out[i]+"/device/uevent"); if (f.open(QIODevice::ReadOnly)) { - if (f.readLine(50).contains("DRIVER=radeon")) + QString line = f.readLine(50).trimmed(); + + if (line == "DRIVER=radeon" || line == "DRIVER=amdgpu") data.append(f.fileName().split('/')[4]); } } @@ -499,7 +571,7 @@ setNewValue(filePaths.forcePowerLevelFilePath, newValue); } -void dXorg::setPwmValue(int value) { +void dXorg::setPwmValue(unsigned int value) { if (daemonConnected()) { QString command; // SIGNAL_SET_VALUE + SEPARATOR + VALUE + SEPARATOR + PATH + SEPARATOR command.append(DAEMON_SIGNAL_SET_VALUE).append(SEPARATOR); // Set value flag @@ -540,11 +612,56 @@ return val; } +void dXorg::setupRegex(const QString &data) { + QRegExp rx; + + rx.setPattern("sclk:\\s\\d+"); + rx.indexIn(data); + if (!rx.cap(0).isEmpty()) { + dXorg::rxPatterns.powerLevel = "power\\slevel\\s\\d", + dXorg::rxPatterns.sclk = "sclk:\\s\\d+", + dXorg::rxPatterns.mclk = "mclk:\\s\\d+", + dXorg::rxPatterns.vclk = "vclk:\\s\\d+", + dXorg::rxPatterns.dclk = "dclk:\\s\\d+", + dXorg::rxPatterns.vddc = "vddc:\\s\\d+", + dXorg::rxPatterns.vddci = "vddci:\\s\\d+"; + + rxMatchIndex = 1; + clocksValueDivider = 100; + + return; + } + + rx.setPattern("\\[\\s+sclk\\s+\\]:\\s\\d+"); + rx.indexIn(data); + if (!rx.cap(0).isEmpty()) { + dXorg::rxPatterns.sclk = "\\[\\s+sclk\\s+\\]:\\s\\d+", + dXorg::rxPatterns.mclk = "\\[\\s+mclk\\s+\\]:\\s\\d+"; + + rxMatchIndex = 3; + clocksValueDivider = 1; + return; + } + + + rx.setPattern("\\d+\\s\\w+\\s\\(SCLK\\)"); + rx.indexIn(data); + if (!rx.cap(0).isEmpty()) { + dXorg::rxPatterns.sclk = "\\d+\\s\\w+\\s\\(SCLK\\)", + dXorg::rxPatterns.mclk = "\\d+\\s\\w+\\s\\(MCLK\\)"; + + rxMatchIndex = 0; + clocksValueDivider = 1; + return; + } +} + globalStuff::driverFeatures dXorg::figureOutDriverFeatures() { globalStuff::driverFeatures features; features.temperatureAvailable = (currentTempSensor == dXorg::TS_UNKNOWN) ? false : true; QString data = getClocksRawData(true); + setupRegex(data); globalStuff::gpuClocksStruct test = dXorg::getClocks(data); // still, sometimes there is miscomunication between daemon, @@ -606,9 +723,9 @@ } globalStuff::gpuClocksStruct dXorg::getFeaturesFallback() { - QFile f("/tmp/radeon_pm_info"); + globalStuff::gpuClocksStruct fallbackFeatures(-1); + QFile f("/tmp/"+dXorg::driverModuleName+"_pm_info"); if (f.open(QIODevice::ReadOnly)) { - globalStuff::gpuClocksStruct fallbackFeatures; QString s = QString(f.readAll()); // just look for it, if it is, the value is not important at this point @@ -617,14 +734,14 @@ if (s.contains("mclk")) fallbackFeatures.memClk = 0; if (s.contains("vddc")) - fallbackFeatures.coreClk = 0; + fallbackFeatures.coreVolt = 0; if (s.contains("vddci")) - fallbackFeatures.memClk = 0; + fallbackFeatures.memVolt = 0; f.close(); - return fallbackFeatures; - } else - return globalStuff::gpuClocksStruct(-1); + } + + return fallbackFeatures; } bool dXorg::overClock(const int percentage){ diff -Nru radeon-profile-0.1.10~yakkety/dxorg.h radeon-profile-0.1.17~yakkety/dxorg.h --- radeon-profile-0.1.10~yakkety/dxorg.h 2016-06-28 14:42:31.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/dxorg.h 2017-01-25 18:00:54.000000000 +0000 @@ -19,8 +19,19 @@ class dXorg { public: - dXorg() {} - ~dXorg() {sharedMem.deleteLater();} // Before being deleted, the class deletes the sharedMem + dXorg() { } + + ~dXorg() { + delete dcomm; + + if(sharedMem.isAttached()){ + // In case the closing signal interrupts a sharedMem lock+read+unlock phase, sharedmem is unlocked + sharedMem.unlock(); + // Before being deleted, the class deletes the sharedMem + sharedMem.detach(); + sharedMem.deleteLater(); + } + } static globalStuff::gpuClocksStruct getClocks(const QString &data); static QString getClocksRawData(bool forFeatures = false); @@ -34,15 +45,17 @@ static void setPowerProfile(globalStuff::powerProfiles _newPowerProfile); static void setForcePowerLevel(globalStuff::forcePowerLevels); static void setPwmManuaControl(bool manual); - static void setPwmValue(int value); + static void setPwmValue(unsigned int value); static QStringList detectCards(); - static void figureOutGpuDataFilePaths(QString gpuName); - static void configure(QString gpuName); + static void figureOutGpuDataFilePaths(const QString &gpuName); + static void configure(const QString &gpuName); static globalStuff::driverFeatures figureOutDriverFeatures(); static void reconfigureDaemon(); static bool daemonConnected(); static globalStuff::gpuClocksStruct getFeaturesFallback(); + static void setupDriverModule(const QString &gpuName); + static void setupRegex(const QString &data); /** * @brief overClock Overclocks the GPU @@ -53,7 +66,6 @@ static void resetOverClock(); - private: enum tempSensor { SYSFS_HWMON = 0, // try to read temp from /sys/class/hwmonX/device/tempX_input @@ -65,6 +77,12 @@ static QChar gpuSysIndex; static QSharedMemory sharedMem; + static QString driverModuleName; + static daemonComm *dcomm; + + static struct rxPatternsStruct { + QString powerLevel, sclk, mclk, vclk, dclk, vddc, vddci; + } rxPatterns; static struct driverFilePaths { QString powerMethodFilePath, @@ -79,7 +97,9 @@ pwmMaxSpeedPath, overDrivePath; } filePaths; + static int sensorsGPUtempIndex; + static short rxMatchIndex, clocksValueDivider; static dXorg::tempSensor currentTempSensor; static globalStuff::powerMethod currentPowerMethod; diff -Nru radeon-profile-0.1.10~yakkety/eventsTab.cpp radeon-profile-0.1.17~yakkety/eventsTab.cpp --- radeon-profile-0.1.10~yakkety/eventsTab.cpp 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/eventsTab.cpp 2017-01-25 18:00:11.000000000 +0000 @@ -0,0 +1,218 @@ + +#include "radeon_profile.h" +#include "ui_radeon_profile.h" + +#include "dialog_rpevent.h" +#include "globalStuff.h" + +#include + +void radeon_profile::on_btn_addEvent_clicked() +{ + Dialog_RPEvent *d = new Dialog_RPEvent(this); + d->setFeatures(device.features, fanProfiles.keys()); + + if (d->exec() == QDialog::Accepted) { + RPEvent rpe = d->getCreatedEvent(); + events.insert(rpe.name, rpe); + + QTreeWidgetItem *item = new QTreeWidgetItem(); + item->setCheckState(0, (rpe.enabled) ? Qt::Checked : Qt::Unchecked); + item->setText(1, rpe.name); + + ui->list_events->addTopLevelItem(item); + } + + delete d; +} + +void radeon_profile::checkEvents() { + checkInfoStruct data; + data.checkTemperature = device.gpuTemeperatureData.current; + + if (savedState != nullptr) { + RPEvent e = events.value(ui->l_currentActiveEvent->text()); + + // one degree handicap to avid constant activation when on the fence + data.checkTemperature += 1; + + if (!e.isActivationConditonFulfilled(data)) + revokeEvent(); + + return; + } + + for (RPEvent e : events) { + if (!e.enabled) + continue; + + if (e.isActivationConditonFulfilled(data)) { + activateEvent(e); + return; + } + } +} + +void radeon_profile::activateEvent(const RPEvent &rpe) { + if (!device.features.canChangeProfile) + return; + + qDebug() << "Activating event: " + rpe.name; + + savedState = new currentStateInfo(); + savedState->profile = static_cast(ui->combo_pProfile->currentIndex()); + savedState->powerLevel = static_cast(ui->combo_pLevel->currentIndex()); + + if (device.features.pwmAvailable) { + switch (ui->fanModesTabs->currentIndex()) { + case 0: + case 1: + savedState->fanIndex = ui->fanModesTabs->currentIndex(); + break; + case 2: + savedState->fanProfileName = ui->l_currentFanProfile->text(); + savedState->fanIndex = ui->fanModesTabs->currentIndex(); + break; + } + } + + hideEventControls(false); + ui->l_currentActiveEvent->setText(rpe.name); + + + if (rpe.dpmProfileChange > -1) + device.setPowerProfile(static_cast(rpe.dpmProfileChange)); + + if (rpe.powerLevelChange > -1) + device.setForcePowerLevel(static_cast(rpe.powerLevelChange)); + + if (rpe.fanComboIndex > 0 && device.features.pwmAvailable) { + switch (rpe.fanComboIndex) { + case 1: + ui->btn_pwmAuto->click(); + break; + case 2: + device.setPwmManualControl(true); + device.setPwmValue(rpe.fixedFanSpeedChange); + break; + default: + if (!fanProfiles.contains(rpe.fanProfileNameChange)) + break; + + ui->l_currentFanProfile->setText(rpe.fanProfileNameChange); + ui->btn_pwmProfile->click(); + break; + } + } +} + +void radeon_profile::revokeEvent() { + qDebug() << "Deactivating event: " + ui->l_currentActiveEvent->text(); + + device.setPowerProfile(static_cast(savedState->profile)); + device.setForcePowerLevel(static_cast(savedState->powerLevel)); + + if (device.features.pwmAvailable) { + switch (savedState->fanIndex) { + case 0: + ui->btn_pwmAuto->click(); + break; + case 1: + ui->btn_pwmFixed->click(); + break; + default: + if (!fanProfiles.contains(savedState->fanProfileName)) + break; + + ui->l_currentFanProfile->setText(savedState->fanProfileName); + ui->btn_pwmProfile->click(); + } + + } + + ui->l_currentActiveEvent->clear(); + hideEventControls(true); + + delete savedState; + savedState = nullptr; +} + +void radeon_profile::hideEventControls(bool hide) { + ui->l_currentActiveEvent->setVisible(!hide); + ui->label_18->setVisible(!hide); + ui->btn_revokeEvent->setVisible(!hide); +} + +void radeon_profile::on_list_events_itemChanged(QTreeWidgetItem *item, int column) +{ + RPEvent e = events.value(item->text(1)); + e.enabled = (item->checkState(column) == Qt::Checked); + + events.insert(e.name, e); +} + +void radeon_profile::on_btn_eventsInfo_clicked() +{ + QMessageBox::information(this, tr("Events info"), + tr("Here you can define events. Each event has a defined condition, and when this condition is fulfilled, event is activated. \n\n" + "After activation, defined power profile, power level and fan profile are applied. When one of events is activated, tracking is suspended.\n\n" + "When active event condition is no longer true, event is revoked and power profile, power level and fan profile are restored to state before event was activated."), + QMessageBox::Ok); +} + +void radeon_profile::on_btn_modifyEvent_clicked() +{ + if (!ui->list_events->currentItem()) + return; + + Dialog_RPEvent *d = new Dialog_RPEvent(this); + d->setFeatures(device.features, fanProfiles.keys()); + d->setEditedEvent(events.value(ui->list_events->currentItem()->text(1))); + + if (d->exec() == QDialog::Accepted) { + RPEvent rpe = d->getCreatedEvent(); + events.insert(rpe.name, rpe); + + if (rpe.name == ui->list_events->currentItem()->text(1)) { + ui->list_events->currentItem()->setCheckState(0, (rpe.enabled) ? Qt::Checked : Qt::Unchecked); + ui->list_events->currentItem()->setText(1, rpe.name); + } else { + QTreeWidgetItem *item = new QTreeWidgetItem(); + item->setCheckState(0, (rpe.enabled) ? Qt::Checked : Qt::Unchecked); + item->setText(1, rpe.name); + ui->list_events->addTopLevelItem(item); + } + } + + delete d; +} + +void radeon_profile::on_btn_removeEvent_clicked() +{ + if (!ui->list_events->currentItem()) + return; + + if (ui->list_events->currentItem()->text(1) == ui->l_currentActiveEvent->text()) { + QMessageBox::information(this, "", tr("Cannot remove event that is currently active.")); + return; + } + + if (!askConfirmation("", tr("Do you want to remove event: ")+ui->list_events->currentItem()->text(1)+"?")) + return; + + events.remove(ui->list_events->currentItem()->text(1)); + delete ui->list_events->currentItem(); +} + +void radeon_profile::on_btn_revokeEvent_clicked() +{ + revokeEvent(); +} + +void radeon_profile::on_list_events_itemDoubleClicked(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(item) + Q_UNUSED(column); + + ui->btn_modifyEvent->click(); +} diff -Nru radeon-profile-0.1.10~yakkety/execbin.cpp radeon-profile-0.1.17~yakkety/execbin.cpp --- radeon-profile-0.1.10~yakkety/execbin.cpp 2016-06-28 14:42:31.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/execbin.cpp 2017-01-25 18:00:11.000000000 +0000 @@ -38,13 +38,13 @@ p->setProcessChannelMode(QProcess::MergedChannels); - this->btnSave->setText(label_saveOutputToFile); + this->btnSave->setText(tr("Save output to file")); // just two labels out of nowhere, forget it QLabel *l1 = new QLabel(); - l1->setText(label_command); + l1->setText(tr("Command")); QLabel *l2 = new QLabel(); - l2->setText(label_output); + l2->setText(tr("Output")); btnLay->addWidget(lStatus); btnLay->addWidget(btnSave); @@ -74,7 +74,7 @@ } void execBin::execProcesStart() { - this->lStatus->setText(label_processRunning); + this->lStatus->setText(tr("Process state: running")); } void execBin::execProcesFinished() { @@ -86,11 +86,11 @@ this->logData.log.clear(); } - this->lStatus->setText(label_processNotRunning); + this->lStatus->setText(tr("Process state: not running")); } void execBin::saveToFile() { - QString filename = QFileDialog::getSaveFileName(0, label_save, QDir::homePath()+"/output_"+this->name); + QString filename = QFileDialog::getSaveFileName(0, tr("Save"), QDir::homePath()+"/output_"+this->name); if (!filename.isEmpty()) { QFile f(filename); f.open(QIODevice::WriteOnly); diff -Nru radeon-profile-0.1.10~yakkety/execTab.cpp radeon-profile-0.1.17~yakkety/execTab.cpp --- radeon-profile-0.1.10~yakkety/execTab.cpp 2016-06-28 14:42:31.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/execTab.cpp 2017-01-25 18:00:11.000000000 +0000 @@ -37,7 +37,7 @@ ui->label_15->setVisible(false); ui->cb_manualEdit->setChecked(false); - if (ui->list_execProfiles->selectedItems().count() == 0) + if (!ui->list_execProfiles->currentItem()) return; ui->txt_profileName->setText(ui->list_execProfiles->currentItem()->text(PROFILE_NAME)); @@ -56,12 +56,12 @@ void radeon_profile::on_btn_ok_clicked() { if (ui->txt_profileName->text().isEmpty()) { - QMessageBox::critical(this, label_error, label_emptyProfileName, QMessageBox::Ok); + QMessageBox::critical(this, tr("Error"), tr("Profile name can't be empty!"), QMessageBox::Ok); return; } if (ui->txt_binary->text().isEmpty()) { - QMessageBox::critical(this, label_error, label_noBinarySelected, QMessageBox::Ok); + QMessageBox::critical(this, tr("Error"), tr("No binary is selected!"), QMessageBox::Ok); return; } @@ -71,7 +71,7 @@ if (QFile::exists(tmpS)) ui->txt_binary->setText(tmpS); else { - QMessageBox::critical(this, label_error, label_binaryNotFound + ui->txt_binary->text()); + QMessageBox::critical(this, tr("Error"), tr("Binary not found in /usr/bin: ") + ui->txt_binary->text()); return; } } @@ -128,7 +128,7 @@ // if value for this variable is 'user_input' display a window for input if (values[0] == "user_input") { bool ok; - QString input = QInputDialog::getText(this, label_enterValue, label_valueFor + ui->list_variables->currentItem()->text(), QLineEdit::Normal,"",&ok); + QString input = QInputDialog::getText(this, tr("Enter value"), tr("Enter valid value for ") + ui->list_variables->currentItem()->text(), QLineEdit::Normal,"",&ok); // look for this variable in list int varIndex = selectedVariableVaules.indexOf(QRegExp(ui->list_variables->currentItem()->text()+".+",Qt::CaseInsensitive),0); @@ -143,7 +143,7 @@ } else { // hehe, looks weird but check ok status is for, when input was empty, and whether user click ok or cancel, dispaly quesion if ((varIndex != -1) || ok) { - if (QMessageBox::question(this, label_question, label_askRemoveItem, QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes) == QMessageBox::Yes) + if (QMessageBox::question(this, tr("Question"), tr("Remove this item?"), QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes) == QMessageBox::Yes) selectedVariableVaules.removeAt(varIndex); } } @@ -179,6 +179,7 @@ void radeon_profile::on_list_vaules_itemClicked(QListWidgetItem *item) { + Q_UNUSED(item) ui->txt_summary->clear(); QStringList selectedValues; @@ -200,18 +201,18 @@ void radeon_profile::on_btn_removeExecProfile_clicked() { - if (ui->list_execProfiles->selectedItems().count() == 0) + if (!ui->list_execProfiles->currentItem()) + return; + + if (QMessageBox::question(this, tr("Remove"), tr("Remove this item?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::No) return; - if (QMessageBox::question(this, label_remove, label_askRemoveItem, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) - delete ui->list_execProfiles->selectedItems()[0]; - else - return; + delete ui->list_execProfiles->currentItem(); } void radeon_profile::on_btn_selectBinary_clicked() { - QString binaryPath = QFileDialog::getOpenFileName(this, label_selectBinary); + QString binaryPath = QFileDialog::getOpenFileName(this, tr("Select binary")); if (!binaryPath.isEmpty()) ui->txt_binary->setText(binaryPath); @@ -219,7 +220,7 @@ void radeon_profile::on_btn_selectLog_clicked() { - QString logFile = QFileDialog::getSaveFileName(this, label_selectLogFile, QDir::homePath()+"/"+ui->txt_profileName->text()); + QString logFile = QFileDialog::getSaveFileName(this, tr("Select log file"), QDir::homePath()+"/"+ui->txt_profileName->text()); if (!logFile.isEmpty()) ui->txt_logFile->setText(logFile); @@ -281,11 +282,11 @@ exe->appendToLog("Profile: " +item->text(PROFILE_NAME) +"; App: " + item->text(BINARY) + "; Params: " + item->text(BINARY_PARAMS) + "; Env: " + item->text(ENV_SETTINGS)); exe->appendToLog("Date and time; power level; GPU core clk; mem clk; uvd core clk; uvd decoder clk; core voltage (vddc); mem voltage (vddci); temp"); } - execsRunning->append(exe); + execsRunning.append(exe); ui->tabs_execOutputs->setCurrentIndex(ui->tabs_execOutputs->count() - 1); } else { - QMessageBox::critical(this, label_error, label_cantRunNotExists); + QMessageBox::critical(this, tr("Error"), tr("Can't run something that not exists!")); delete exe; } } @@ -310,10 +311,11 @@ } void radeon_profile::on_list_execProfiles_itemDoubleClicked(QTreeWidgetItem *item, int column) { + Q_UNUSED(column) switch (ui->cb_execDbcAction->currentIndex()) { default: case 0: - if (QMessageBox::question(this, label_run, label_askRunStart + item->text(0) + label_askRunEnd, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) + if (QMessageBox::question(this, tr("Run"), tr("Run: \"") + item->text(0) + "?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) ui->btn_runExecProfile->click(); break; case 1: diff -Nru radeon-profile-0.1.10~yakkety/extra/radeon-profile.desktop radeon-profile-0.1.17~yakkety/extra/radeon-profile.desktop --- radeon-profile-0.1.10~yakkety/extra/radeon-profile.desktop 2016-06-02 15:31:29.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/extra/radeon-profile.desktop 2017-01-25 17:32:58.000000000 +0000 @@ -1,11 +1,13 @@ [Desktop Entry] Name=Radeon Profile Name[hr]=Radeon profil +GenericName=Control panel +GenericName[hr]=Upravljačka ploča Comment=Monitor Radeon GPU parameters and switch power profiles Comment[hr]=Nadgledanje Radeon GPU parametara i odabir profila štednje energije Exec=radeon-profile Icon=radeon-profile Terminal=false Type=Application -Categories=System; +Categories=System;Monitor;HardwareSettings;TrayIcon; StartupNotify=false diff -Nru radeon-profile-0.1.10~yakkety/fanControlTab.cpp radeon-profile-0.1.17~yakkety/fanControlTab.cpp --- radeon-profile-0.1.10~yakkety/fanControlTab.cpp 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/fanControlTab.cpp 2017-01-25 18:00:11.000000000 +0000 @@ -0,0 +1,272 @@ +#include "radeon_profile.h" +#include "ui_radeon_profile.h" + +#include +#include +#include + +void radeon_profile::createDefaultFanProfile() { + fanProfileSteps p; + p.insert(0,minFanStepsSpeed); + p.insert(65,maxFanStepsSpeed); + p.insert(90,maxFanStepsSpeed); + + fanProfiles.insert("default", p); + ui->combo_fanProfiles->addItem("default"); + ui->l_currentFanProfile->setText("default"); +} + +void radeon_profile::makeFanProfileListaAndGraph(const fanProfileSteps &profile) { + ui->plotFanProfile->graph(0)->clearData(); + ui->list_fanSteps->clear(); + + for (int temperature : profile.keys()) { + ui->plotFanProfile->graph(0)->addData(temperature, profile.value(temperature)); + ui->list_fanSteps->addTopLevelItem(new QTreeWidgetItem(QStringList() << QString::number(temperature) << QString::number(profile.value(temperature)))); + } + + ui->plotFanProfile->replot(); +} + +void radeon_profile::makeFanProfilePlot() { + ui->plotFanProfile->graph(0)->clearData(); + + for (int i = 0; i < ui->list_fanSteps->topLevelItemCount(); ++i) + ui->plotFanProfile->graph(0)->addData(ui->list_fanSteps->topLevelItem(i)->text(0).toInt(), + ui->list_fanSteps->topLevelItem(i)->text(1).toInt()); + + ui->plotFanProfile->replot(); +} + +bool radeon_profile::isFanStepValid(const unsigned int temperature, const unsigned int fanSpeed) { + return temperature <= maxFanStepsTemp && + fanSpeed >= minFanStepsSpeed && + fanSpeed <= maxFanStepsSpeed; +} + +void radeon_profile::addFanStep(const int temperature, const int fanSpeed) { + + if (!isFanStepValid(temperature, fanSpeed)) { + qWarning() << "Invalid value, can't be inserted into the fan step list:" << temperature << fanSpeed; + return; + } + + const QString temperatureString = QString::number(temperature), + speedString = QString::number(fanSpeed); + const QList existing = ui->list_fanSteps->findItems(temperatureString,Qt::MatchExactly); + + if (existing.isEmpty()) { // The element does not exist + ui->list_fanSteps->addTopLevelItem(new QTreeWidgetItem(QStringList() << temperatureString << speedString)); + ui->list_fanSteps->sortItems(0, Qt::AscendingOrder); + } else // The element exists already, overwrite it + existing.first()->setText(1,speedString); + + markFanProfileUnsaved(true); + makeFanProfilePlot(); +} + +void radeon_profile::markFanProfileUnsaved(bool unsaved) { + ui->l_fanProfileUnsavedIndicator->setVisible(unsaved); +} + +void radeon_profile::on_cb_zeroPercentFanSpeed_clicked(bool checked) +{ + if (checked && !askConfirmation(tr("Question"), tr("This option may cause overheat of your card and it is your responsibility if this happens. Do you want to enable it?"))) { + ui->cb_zeroPercentFanSpeed->setChecked(false); + return; + } + + setupMinFanSpeedSetting((checked) ? 0 : 10); +} + +void radeon_profile::on_combo_fanProfiles_currentIndexChanged(const QString &arg1) +{ + makeFanProfileListaAndGraph(fanProfiles.value(arg1)); +} + +void radeon_profile::on_btn_removeFanProfile_clicked() +{ + if (ui->combo_fanProfiles->currentText() == "default") { + QMessageBox::information(this, "", tr("Cannot remove default profile."), QMessageBox::Ok); + return; + } + + if (!askConfirmation("", tr("Remove profile: ")+ui->combo_fanProfiles->currentText()+"?")) + return; + + + fanProfiles.remove(ui->combo_fanProfiles->currentText()); + ui->combo_fanProfiles->removeItem(ui->combo_fanProfiles->currentIndex()); + setupFanProfilesMenu(true); + setCurrentFanProfile("default", fanProfiles.value("default")); +} + +void radeon_profile::on_btn_saveFanProfile_clicked() +{ + markFanProfileUnsaved(false); + fanProfiles.insert(ui->combo_fanProfiles->currentText(), stepsListToMap()); +} + +int radeon_profile::findCurrentFanProfileMenuIndex() { + for (int i = 0; i < fanProfilesMenu->actions().count(); ++i) { + if (fanProfilesMenu->actions()[i]->text() == ui->l_currentFanProfile->text()) + return i; + } + + return 0; +} + +void radeon_profile::on_btn_saveAsFanProfile_clicked() +{ + QString name = QInputDialog::getText(this, "", tr("Fan profile name:")); + + if (name.contains('|')) { + QMessageBox::information(this, "", tr("Profile name musn't contain '|' character."), QMessageBox::Ok); + return; + } + + if (fanProfiles.contains(name)) { + QMessageBox::information(this, "", tr("Cannot add another profile with the same name that already exists."),QMessageBox::Ok); + return; + } + + markFanProfileUnsaved(false); + + fanProfiles.insert(name, stepsListToMap()); + ui->combo_fanProfiles->addItem(name); + ui->combo_fanProfiles->setCurrentIndex(ui->combo_fanProfiles->findText(name)); + setupFanProfilesMenu(true); + fanProfilesMenu->actions()[findCurrentFanProfileMenuIndex()]->setChecked(true); +} + +void radeon_profile::on_btn_activateFanProfile_clicked() +{ + if (ui->l_fanProfileUnsavedIndicator->isVisible()) { + if (!askConfirmation("", tr("Cannot activate unsaved profile. Do you want to save it?"))) + return; + + ui->btn_saveFanProfile->click(); + } + + setCurrentFanProfile(ui->combo_fanProfiles->currentText(), fanProfiles.value(ui->combo_fanProfiles->currentText())); + fanProfilesMenu->actions()[findCurrentFanProfileMenuIndex()]->setChecked(true); +} + +void radeon_profile::setCurrentFanProfile(const QString &profileName, const fanProfileSteps &profile) { + ui->l_currentFanProfile->setText(profileName); + fanProfilesMenu->actions()[findCurrentFanProfileMenuIndex()]->setChecked(true); + + currentFanProfile = profile; + adjustFanSpeed(); +} + +radeon_profile::fanProfileSteps radeon_profile::stepsListToMap() { + fanProfileSteps steps; + for (int i = 0; i < ui->list_fanSteps->topLevelItemCount(); ++ i) + steps.insert(ui->list_fanSteps->topLevelItem(i)->text(0).toInt(),ui->list_fanSteps->topLevelItem(i)->text(1).toInt()); + + return steps; +} + +void radeon_profile::fanProfileMenuActionClicked(QAction *a) { + if (a->isSeparator()) + return; + + if (a == fanProfilesMenu->actions()[0] || a == fanProfilesMenu->actions()[1]) + return; + + if (!ui->btn_pwmProfile->isChecked()) { + ui->btn_pwmProfile->click(); + ui->btn_pwmProfile->setChecked(true); + } + + setCurrentFanProfile(a->text(),fanProfiles.value(a->text())); +} + +void radeon_profile::on_btn_fanInfo_clicked() +{ + QMessageBox::information(this,tr("Fan control information"), tr("Don't overheat your card! Be careful! Don't use this if you don't know what you're doing! \n\nHovewer, looks like card won't apply too low values due its internal protection. \n\nClosing application will restore fan control to Auto. If application crashes, last fan value will remain, so you have been warned!")); +} + +void radeon_profile::on_btn_addFanStep_clicked() +{ + const int temperature = askNumber(0, minFanStepsTemp, maxFanStepsTemp, tr("Temperature")); + if (temperature == -1) // User clicked Cancel + return; + + if (currentFanProfile.contains(temperature)) // A step with this temperature already exists + QMessageBox::warning(this, tr("Error"), tr("This step already exists. Double click on it, to change its value")); + else { // This step does not exist, proceed + const int fanSpeed = askNumber(0, minFanStepsSpeed, maxFanStepsSpeed, tr("Speed [%]")); + if (fanSpeed == -1) // User clicked Cancel + return; + + addFanStep(temperature,fanSpeed); + } +} + +void radeon_profile::on_btn_removeFanStep_clicked() +{ + QTreeWidgetItem *current = ui->list_fanSteps->currentItem(); + + if (ui->list_fanSteps->indexOfTopLevelItem(current) == 0 || ui->list_fanSteps->indexOfTopLevelItem(current) == ui->list_fanSteps->topLevelItemCount()-1) { + // The selected item is the first or the last, it can't be deleted + QMessageBox::warning(this, tr("Error"), tr("You can't delete the first and the last item")); + return; + } + + // The selected item can be removed, remove it + int temperature = current->text(0).toInt(); + + currentFanProfile.remove(temperature); + adjustFanSpeed(); + + // Remove the step from the list and from the graph + delete current; + ui->plotFanProfile->graph(0)->removeData(temperature); + ui->plotFanProfile->replot(); +} + + +void radeon_profile::on_list_fanSteps_itemDoubleClicked(QTreeWidgetItem *item, int column) +{ + if (ui->list_fanSteps->indexOfTopLevelItem(item) == ui->list_fanSteps->topLevelItemCount()-1) { + // The selected item is the first or the last, it can't be edited + QMessageBox::warning(this, tr("Error"), tr("You can't edit the last item")); + return; + } + + if (ui->list_fanSteps->indexOfTopLevelItem(item) == 0 && column == 0) { + QMessageBox::warning(this, tr("Error"), tr("You can't edit temperature of the first item")); + return; + } + + switch (column) { + case 0: { + int newTemp = askNumber(item->text(column).toInt(), minFanStepsTemp, maxFanStepsTemp, tr("Temperature")); + + if (newTemp == -1) + return; + + item->setText(column, QString::number(newTemp)); + break; + } + case 1: { + int newSpeed = askNumber(item->text(column).toInt(), minFanStepsSpeed, maxFanStepsSpeed, tr("Speed [%]")); + + if (newSpeed == -1) + return; + + item->setText(column, QString::number(newSpeed)); + break; + } + } + + markFanProfileUnsaved(true); + makeFanProfilePlot(); +} + +void radeon_profile::on_fanSpeedSlider_valueChanged(int value) +{ + ui->labelFixedSpeed->setText(QString().setNum(value)+"%"); +} diff -Nru radeon-profile-0.1.10~yakkety/globalStuff.h radeon-profile-0.1.17~yakkety/globalStuff.h --- radeon-profile-0.1.10~yakkety/globalStuff.h 2016-06-28 14:42:31.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/globalStuff.h 2017-01-25 18:00:11.000000000 +0000 @@ -32,120 +32,8 @@ #define file_powerDpmForcePerformanceLevel "power_dpm_force_performance_level" #define file_overclockLevel "pp_sclk_od" -#define label_currentPowerLevel QObject::tr("Power level") -#define label_currentGPUClock QObject::tr("GPU clock") -#define label_currentMemClock QObject::tr("Memory clock") -#define label_uvdVideoCoreClock QObject::tr("UVD core clock (cclk)") -#define label_uvdDecoderClock QObject::tr("UVD decoder clock (dclk)") -#define label_vddc QObject::tr("GPU voltage (vddc)") -#define label_vddci QObject::tr("I/O voltage (vddci)") -#define label_currentGPUTemperature QObject::tr("GPU temperature") -#define label_temperature QObject::tr("Temperature") - -// uiElements.cpp -#define label_timeAxis QObject::tr("Time (s)") -#define label_temperatureAxis QObject::tr("Temperature (°C)") -#define label_clockAxis QObject::tr("Clock (MHz)") -#define label_voltageAxis QObject::tr("Voltage (mV)") -#define label_fanSpeed QObject::tr("Fan speed") -#define label_dpm QObject::tr("DPM") -#define label_changeProfile QObject::tr("Change standard profile") -#define label_quit QObject::tr("Quit") -#define label_refreshWhenHidden QObject::tr("Keep refreshing when hidden") -#define label_battery QObject::tr("Battery") -#define label_balanced QObject::tr("Balanced") -#define label_performance QObject::tr("Performance") -#define label_resetMinMax QObject::tr("Reset min/max temperature") -#define label_resetGraphs QObject::tr("Reset graphs vertical scale") -#define label_showLegend QObject::tr("Show legend") -#define label_graphOffset QObject::tr("Graph offset on right") -#define label_auto QObject::tr("Auto") -#define label_low QObject::tr("Low") -#define label_high QObject::tr("High") -#define label_forcePowerLevel QObject::tr("Force power level") -#define label_copyToClipboard QObject::tr("Copy to clipboard") -#define label_resetStatistics QObject::tr("Reset statistics") - -// uiEvents.cpp -#define label_dataDisabled QObject::tr("GPU data is disabled") -#define label_fanControlInfo QObject::tr("Fan control information") -#define label_fanControlWarning QObject::tr("Don't overheat your card! Be careful! Don't use this if you don't know what you're doing! \n\nHovewer, looks like card won't apply too low values due its internal protection. \n\nClosing application will restore fan control to Auto. If application crashes, last fan value will remain, so you have been warned!") -#define label_fanSpeedRange QObject::tr("Speed [%] (20-100)") -#define label_selectProfile QObject::tr("Select new power profile") -#define label_profileSelection QObject::tr("Profile selection") -#define label_processStillRunning QObject::tr("Process is still running. Close tab?") -#define label_howToEdit QObject::tr("This step already exists. To edit it double click it") -#define label_cantDeleteThisItem QObject::tr("You can't delete the first and the last item") -#define label_cantEditThisItem QObject::tr("You can't edit the first and the last item") -#define label_overclockFailed QObject::tr("An error occurred, overclock failed") - -// execbin.cpp -#define label_processRunning QObject::tr("Process state: running") -#define label_processNotRunning QObject::tr("Process state: not running") -#define label_saveOutputToFile QObject::tr("Save output to file") -#define label_command QObject::tr("Command") -#define label_output QObject::tr("Output") -#define label_save QObject::tr("Save") - -// execTab.cpp -#define label_error QObject::tr("Error") -#define label_emptyProfileName QObject::tr("Profile name can't be empty!") -#define label_noBinarySelected QObject::tr("No binary is selected!") -#define label_binaryNotFound QObject::tr("Binary not found in /usr/bin: ") -#define label_enterValue QObject::tr("Enter value") -#define label_valueFor QObject::tr("Enter valid value for ") -#define label_question QObject::tr("Question") -#define label_askRemoveItem QObject::tr("Remove this item?") -#define label_remove QObject::tr("Remove") -#define label_selectBinary QObject::tr("Select binary") -#define label_selectLogFile QObject::tr("Select log file") -#define label_cantRunNotExists QObject::tr("Can't run something that not exists!") -#define label_run QObject::tr("Run") -#define label_askRunStart QObject::tr("Run: \"") -#define label_askRunEnd QObject::tr("\"?") - -// gpu.cpp -#define label_unknown QObject::tr ("Unknown") -#define label_resolution QObject::tr("Resolution") -#define label_minimumRes QObject::tr("Minimum resolution") -#define label_maximumRes QObject::tr("Maximum resolution") -#define label_virtualSize QObject::tr("Virtual size") -#define label_outputs QObject::tr("Outputs") -#define label_active QObject::tr("Active") -#define label_verticalHz QObject::tr(" Hz vertical, ") -#define label_horizontalKHz QObject::tr(" KHz horizontal, ") -#define label_dotClock QObject::tr(" MHz dot clock") -#define label_yes QObject::tr("Yes") -#define label_no QObject::tr("No") -#define label_refreshRate QObject::tr("Refresh rate") -#define label_offset QObject::tr("Offset") -#define label_softBrightness QObject::tr("Brightness (software)") -#define label_size QObject::tr("Size") -#define label_supportedModes QObject::tr("Supported modes") -#define label_properties QObject::tr("Properties") -#define label_serialNumber QObject::tr("Serial number") -#define label_notAvailable QObject::tr("Not available") -#define label_connectedWith QObject::tr("Connected with ") -#define label_disconnected QObject::tr("Disconnected") -#define format_screenIndex QObject::tr("Virtual screen n°%n", NULL, screenIndex) -#define format_scrWidthMM QObject::tr("%n mm x ", NULL, DisplayWidthMM(display, screenIndex)) -#define format_scrHeightMM QObject::tr("%n mm", NULL, DisplayHeightMM(display, screenIndex)) -#define format_monWidth QObject::tr("%n mm x ", NULL, outputInfo->mm_width) -#define format_monHeight QObject::tr("%n mm ", NULL, outputInfo->mm_height) -#define format_monDiagonal QObject::tr("(%n inches)", NULL, diagonal) -#define format_outputConnected QObject::tr("%n connected, ", NULL, screenConnectedOutputs) -#define format_outputActive QObject::tr("%n active", NULL, screenActiveOutputs) -#define label_noInfo QObject::tr("No info") - -// radeon_profile.cpp -#define label_backToProfiles QObject::tr("Back to profiles") // As "return to profiles" -#define label_errorReadingData QObject::tr("Can't read data") -#define label_howToReadData QObject::tr("You need debugfs mounted and either root rights or the daemon running") - #define logDateFormat "yyyy-MM-dd_hh-mm-ss" -#define appVersion 20160527 -#define format_version QObject::tr("version %n", NULL, appVersion) class globalStuff { @@ -175,6 +63,18 @@ return a.split('\n'); } + static QStringList createDPMCombo() { + return QStringList() << dpm_battery << dpm_balanced << dpm_performance; + } + + static QStringList createPowerLevelCombo() { + return QStringList() << dpm_auto << dpm_low << dpm_high; + } + + static QStringList createProfileCombo() { + return QStringList() << profile_auto << profile_default << profile_high << profile_mid << profile_low; + } + enum powerProfiles { BATTERY, BALANCED, PERFORMANCE, AUTO, DEFAULT, LOW, MID, HIGH }; diff -Nru radeon-profile-0.1.10~yakkety/gpu.cpp radeon-profile-0.1.17~yakkety/gpu.cpp --- radeon-profile-0.1.10~yakkety/gpu.cpp 2016-06-28 14:42:31.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/gpu.cpp 2017-01-25 18:00:11.000000000 +0000 @@ -27,27 +27,18 @@ // List of files mapping PnP IDs to vendor names // List found through pkgfile --verbose --search pnp.ids (on arch linux) -#define PNP_ID_FILE_COUNT 6 +#define PNP_ID_FILE_COUNT 8 static const char * pnpIdFiles [PNP_ID_FILE_COUNT] = { + "/usr/share/misc/pnp.ids", "/usr/share/libgnome-desktop-3.0/pnp.ids", "/usr/share/libgnome-desktop/pnp.ids", "/usr/share/libcinnamon-desktop/pnp.ids", "/usr/share/dispcalGUI/pnp.ids", + "/usr/share/DisplayCAL/pnp.ids", "/usr/share/libmate-desktop/pnp.ids", "/usr/share/hwdata/pnp.ids" }; -gpu::driver gpu::detectDriver() { - QStringList out = globalStuff::grabSystemInfo("lsmod"); - - if (!out.filter("radeon").isEmpty()) - return XORG; - if (!out.filter("fglrx").isEmpty()) - return FGLRX; - - return DRIVER_UNKNOWN; -} - void gpu::reconfigureDaemon() { dXorg::reconfigureDaemon(); } @@ -58,36 +49,51 @@ // method for resolve which driver gpu instance will use // and call some things that need to be done before read data -QStringList gpu::initialize(bool skipDetectDriver) { - if (!skipDetectDriver) - currentDriver = detectDriver(); +QStringList gpu::initialize() { QStringList gpuList; + gpuList = gpu::initialize(gpu::XORG); + if (gpuList.length() > 0) + return gpuList; + + gpuList = gpu::initialize(gpu::FGLRX); + if (gpuList.length() > 0) + return gpuList; + + gpuList = gpu::initialize(gpu::DRIVER_UNKNOWN); + return gpuList; +} + +QStringList gpu::initialize(gpu::driver driver) { + currentDriver = driver; + QStringList gpuList; + switch (currentDriver) { - case XORG: { - gpuList = dXorg::detectCards(); - dXorg::configure(gpuList[currentGpuIndex]); - features = dXorg::figureOutDriverFeatures(); - break; - } - case FGLRX: { - gpuList = dFglrx::detectCards(); - dFglrx::configure(currentGpuIndex); - features = dFglrx::figureOutDriverFeatures(); - break; - } - case DRIVER_UNKNOWN: { - globalStuff::driverFeatures f; - f.pm = globalStuff::PM_UNKNOWN; - f.canChangeProfile = f.temperatureAvailable = f.coreVoltAvailable = f.coreClockAvailable = false; - features = f; - gpuList << label_unknown; - } + case gpu::XORG: + gpuList = dXorg::detectCards(); + if(currentGpuIndex < gpuList.size()){ + dXorg::configure(gpuList[currentGpuIndex]); + features = dXorg::figureOutDriverFeatures(); + } + break; + case gpu::FGLRX: + dFglrx::configure(currentGpuIndex); + features = dFglrx::figureOutDriverFeatures(); + break; + case gpu::DRIVER_UNKNOWN: + globalStuff::driverFeatures f; + f.pm = globalStuff::PM_UNKNOWN; + f.canChangeProfile = f.temperatureAvailable = f.coreVoltAvailable = f.coreClockAvailable = false; + features = f; + gpuList << QObject::tr("Unknown"); + break; } + return gpuList; } + globalStuff::gpuClocksStructString gpu::convertClocks(const globalStuff::gpuClocksStruct &data) { globalStuff::gpuClocksStructString tmp; @@ -126,10 +132,6 @@ return tmp; } -void gpu::driverByParam(gpu::driver paramDriver) { - this->currentDriver = paramDriver; -} - void gpu::changeGpu(char index) { currentGpuIndex = index; @@ -447,13 +449,13 @@ qDebug() << "Analyzing screen " << screenIndex; // Create root QTreeWidgetItem item for this screen - QTreeWidgetItem * screenItem = new QTreeWidgetItem(QStringList() << format_screenIndex); + QTreeWidgetItem * screenItem = new QTreeWidgetItem(QStringList() << QObject::tr("Virtual screen n°%n", NULL, screenIndex)); cardConnectorsList.append(screenItem); // Add resolution QString screenResolution = QString::number(DisplayWidth(display,screenIndex)); screenResolution += " x " + QString::number(DisplayHeight(display, screenIndex)); - addChild(screenItem, label_resolution, screenResolution); + addChild(screenItem, QObject::tr("Resolution"), screenResolution); // Add screen minimum and maximum resolutions int screenMinWidth, screenMinHeight, screenMaxWidth, screenMaxHeight; @@ -461,13 +463,13 @@ XRRGetScreenSizeRange(display, screenRoot, &screenMinWidth, &screenMinHeight, &screenMaxWidth, &screenMaxHeight); QString screenMinResolution = QString::number(screenMinWidth) + " x " + QString::number(screenMinHeight); - addChild(screenItem, label_minimumRes, screenMinResolution); + addChild(screenItem, QObject::tr("Minimum resolution"), screenMinResolution); QString screenMaxResolution = QString::number(screenMaxWidth) + " x " + QString::number(screenMaxHeight); - addChild(screenItem, label_maximumRes, screenMaxResolution); + addChild(screenItem, QObject::tr("Maximum resolution"), screenMaxResolution); // Adding screen virtual dimension - addChild(screenItem, label_virtualSize, format_scrWidthMM + format_scrHeightMM); + addChild(screenItem, QObject::tr("Virtual size"), QObject::tr("%n mm x ", NULL, DisplayWidthMM(display, screenIndex)) + QObject::tr("%n mm", NULL, DisplayHeightMM(display, screenIndex))); // Retrieve screen resources (connectors, configurations, timestamps etc.) XRRScreenResources * screenResources = XRRGetScreenResources(display, screenRoot); @@ -477,7 +479,7 @@ } // Creating root QTreeWidgetItem for this screen's outputs - QTreeWidgetItem * outputListItem = new QTreeWidgetItem(QStringList() << label_outputs); + QTreeWidgetItem * outputListItem = new QTreeWidgetItem(QStringList() << QObject::tr("Outputs")); screenItem->addChild(outputListItem); int screenConnectedOutputs = 0, screenActiveOutputs = 0; @@ -498,7 +500,7 @@ // Check the output connection state if(outputInfo->connection != 0){ // No connection - outputItem->setText(1, label_disconnected); + outputItem->setText(1, QObject::tr("Disconnected")); XRRFreeOutputInfo(outputInfo); // Deallocate the memory of this output's info continue; // Next output } @@ -511,9 +513,9 @@ if(configInfo == NULL) { // This output is not active qDebug() << "Output" << outputIndex << "has no active mode"; - addChild(outputItem, label_active, label_no); + addChild(outputItem, QObject::tr("Active"), QObject::tr("No")); } else { // The output is active: add resolution, refresh rate and the offset - addChild(outputItem, label_active, label_yes); + addChild(outputItem, QObject::tr("Active"), QObject::tr("Yes")); qDebug() << " Analyzing active mode"; screenActiveOutputs++; @@ -522,19 +524,19 @@ // Add current resolution QString outputResolution = QString::number(configInfo->width) + " x " + QString::number(configInfo->height); outputResolution += " (" + getAspectRatio(configInfo->width, configInfo->height) + ')'; - addChild(outputItem, label_resolution, outputResolution); + addChild(outputItem, QObject::tr("Resolution"), outputResolution); //Add refresh rate float vRefreshRate = getVerticalRefreshRate(getModeInfo(screenResources, *activeMode)); if(vRefreshRate != -1){ QString outputVRate = QString::number(vRefreshRate, 'g', 3) + " Hz"; - addChild(outputItem, label_refreshRate, outputVRate); + addChild(outputItem, QObject::tr("Refresh rate"), outputVRate); } // Add the position in the current configuration (useful only in multi-head) // It's the offset from the top left corner QString outputOffset = QString::number(configInfo->x) + ", " + QString::number(configInfo->y); - addChild(outputItem, label_offset, outputOffset); + addChild(outputItem, QObject::tr("Offset"), outputOffset); // Calculate and add the screen software brightness level XRRCrtcGamma * gammaInfo = XRRGetCrtcGamma(display, outputInfo->crtc); @@ -546,7 +548,7 @@ // Source of the brightness formula: https://en.wikipedia.org/wiki/Relative_luminance if(brightnessPercent > 0){ QString softBrightness = QString::number(brightnessPercent, 'g', 3) + " %"; - addChild(outputItem, label_softBrightness, softBrightness); + addChild(outputItem, QObject::tr("Brightness (software)"), softBrightness); } XRRFreeGamma(gammaInfo); } @@ -561,15 +563,13 @@ // Get other details (monitor size, possible configurations and properties) // Add monitor size double diagonal = sqrt(pow(outputInfo->mm_width, 2) + pow(outputInfo->mm_height, 2)) * MILLIMETERS_PER_INCH; - addChild(outputItem, label_size, format_monWidth + format_monHeight + format_monDiagonal); + addChild(outputItem, QObject::tr("Size"), QObject::tr("%n mm x ", NULL, outputInfo->mm_width) + QObject::tr("%n mm ", NULL, outputInfo->mm_height) + QObject::tr("(%n inches)", NULL, diagonal)); // Create the root QTreeWidgetItem of the possible modes (resolution, Refresh rate, HSync, VSync, etc) list - QTreeWidgetItem * modeListItem = new QTreeWidgetItem(QStringList() << label_supportedModes); + QTreeWidgetItem * modeListItem = new QTreeWidgetItem(QStringList() << QObject::tr("Supported modes")); outputItem->addChild(modeListItem); for(int modeIndex = 0; modeIndex < outputInfo->nmode; modeIndex++){ // For each possible mode - qDebug() << " Analyzing available mode" << modeIndex; - XRRModeInfo * modeInfo = getModeInfo(screenResources, outputInfo->modes[modeIndex]); if(modeInfo == NULL) // Mode info not found continue; // Proceed to next mode @@ -589,13 +589,13 @@ horizontalRefreshRate = getHorizontalRefreshRate(modeInfo); if(verticalRefreshRate > 0) - modeDetails += QString::number(verticalRefreshRate, 'g', 3) + label_verticalHz; + modeDetails += QString::number(verticalRefreshRate, 'g', 3) + QObject::tr(" Hz vertical, "); if(horizontalRefreshRate > 0) - modeDetails += QString::number(horizontalRefreshRate / 1000, 'g', 3) + label_horizontalKHz; + modeDetails += QString::number(horizontalRefreshRate / 1000, 'g', 3) + QObject::tr(" KHz horizontal, "); if(modeInfo->dotClock > 0) - modeDetails += QString::number((float) modeInfo->dotClock / 1000000, 'g', 3) + label_dotClock; + modeDetails += QString::number((float) modeInfo->dotClock / 1000000, 'g', 3) + QObject::tr(" MHz dot clock"); } // Check possible mode flags @@ -613,7 +613,7 @@ } // Create the root QTreeWidgetItem of the property list - QTreeWidgetItem * propertyListItem = new QTreeWidgetItem(QStringList() << label_properties); + QTreeWidgetItem * propertyListItem = new QTreeWidgetItem(QStringList() << QObject::tr("Properties")); outputItem->addChild(propertyListItem); // Get this output properties (EDID, audio, scaling mode, etc) @@ -622,8 +622,6 @@ // Cycle through this output's properties for(int propertyIndex = 0; propertyIndex < propertyCount; propertyIndex++){ - qDebug() << " Analyzing property" << propertyIndex; - // Prepare this property's name and value char * propertyAtomName = XGetAtomName(display, properties[propertyIndex]); QString propertyName = QString::fromLocal8Bit(propertyAtomName); @@ -672,7 +670,7 @@ qWarning() << screenIndex << '/' << outputInfo->name << ": can't parse EDID, invalid header"; } else { // Valid header // Add the monitor name to the tree as value of the Output Item - outputItem->setText(1, label_connectedWith + getMonitorName(propertyRawData)); + outputItem->setText(1, QObject::tr("Connected with ") + getMonitorName(propertyRawData)); // Get the serial number // For reference: https://github.com/KDE/libkscreen/blob/master/src/edid.cpp#L288-L295 @@ -680,8 +678,8 @@ serialNumber += propertyRawData[EDID_OFFSET_SERIAL_NUMBER + 1] * 0x100; serialNumber += propertyRawData[EDID_OFFSET_SERIAL_NUMBER + 2] * 0x10000; serialNumber += propertyRawData[EDID_OFFSET_SERIAL_NUMBER + 3] * 0x1000000; - QString serial = (serialNumber > 0) ? QString::number(serialNumber) : label_notAvailable; - addChild(propertyListItem, label_serialNumber, serial); + QString serial = (serialNumber > 0) ? QString::number(serialNumber) : QObject::tr("Not available"); + addChild(propertyListItem, QObject::tr("Serial number"), serial); } //End of EDID } else { //Not EDID @@ -705,8 +703,6 @@ for(int valuesIndex = 0; valuesIndex < propertyInfo->num_values; valuesIndex++){ // Until there is another alternative/range available - qDebug() << " Printing alternative " << valuesIndex; - if(propertyInfo->range) { // This is a range, print the maximum value propertyValue += translateProperty(display, 32, // Value data has 32-bit format @@ -742,7 +738,7 @@ XRRFreeOutputInfo(outputInfo); } // Screen completed: print output count (connected and active) and deallocate screenResources - outputListItem->setText(1, format_outputConnected + format_outputActive); + outputListItem->setText(1, QObject::tr("%n connected, ", NULL, screenConnectedOutputs) + QObject::tr("%n active", NULL, screenActiveOutputs)); XRRFreeScreenResources(screenResources); } @@ -758,7 +754,7 @@ break; case FGLRX: case DRIVER_UNKNOWN: { - list.append(new QTreeWidgetItem(QStringList() << label_noInfo)); + list.append(new QTreeWidgetItem(QStringList() << QObject::tr("No info"))); } } @@ -842,10 +838,10 @@ } } -void gpu::setPwmValue(int value) const { +void gpu::setPwmValue(unsigned int value) const { switch (currentDriver) { case XORG: - dXorg::setPwmValue(value); + dXorg::setPwmValue(features.pwmMaxSpeed * value / 100); break; case FGLRX: case DRIVER_UNKNOWN: diff -Nru radeon-profile-0.1.10~yakkety/gpu.h radeon-profile-0.1.17~yakkety/gpu.h --- radeon-profile-0.1.10~yakkety/gpu.h 2016-06-28 14:42:31.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/gpu.h 2017-01-25 18:00:11.000000000 +0000 @@ -49,13 +49,13 @@ void getPwmSpeed(); void changeGpu(char index); - void driverByParam(gpu::driver); void setPowerProfile(globalStuff::powerProfiles _newPowerProfile) const; void setForcePowerLevel(globalStuff::forcePowerLevels _newForcePowerLevel) const; void setPwmManualControl(bool manual) const; - void setPwmValue(int value) const; + void setPwmValue(unsigned int value) const; - QStringList initialize(bool skipDetectDriver = false); + QStringList initialize(gpu::driver); + QStringList initialize(); void reconfigureDaemon(); bool daemonConnected(); @@ -64,7 +64,6 @@ private: driver currentDriver; - driver detectDriver(); }; diff -Nru radeon-profile-0.1.10~yakkety/ioctl_amdgpu.cpp radeon-profile-0.1.17~yakkety/ioctl_amdgpu.cpp --- radeon-profile-0.1.10~yakkety/ioctl_amdgpu.cpp 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/ioctl_amdgpu.cpp 2017-01-25 18:00:54.000000000 +0000 @@ -0,0 +1,138 @@ +#include "ioctlHandler.hpp" + +#ifndef NO_IOCTL // Include libdrm headers only if NO_IOCTL is not defined +# ifndef NO_AMDGPU_IOCTL // Include libdrm amdgpu headers only if NO_AMDGPU_IOCTL is not declared +# include // amdgpu ioctl codes and structs +# endif +#endif + + +amdgpuIoctlHandler::amdgpuIoctlHandler(unsigned cardIndex) : ioctlHandler(cardIndex){} + +bool amdgpuIoctlHandler::getValue(void *data, unsigned dataSize, unsigned command) const { + // https://cgit.freedesktop.org/mesa/drm/tree/include/drm/amdgpu_drm.h#n437 + // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/drm/amdgpu_drm.h#n471 + // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c#n212 + +#ifdef DRM_IOCTL_AMDGPU_INFO + struct drm_amdgpu_info buffer; + CLEAN(buffer); + buffer.query = command; + buffer.return_pointer = (uint64_t)data; + buffer.return_size = dataSize; + bool success = !ioctl(fd, DRM_IOCTL_AMDGPU_INFO, &buffer); + if(Q_UNLIKELY(!success)) + DESCRIBE_ERROR("ioctl"); + return success; +#else + Q_UNUSED(data); + Q_UNUSED(command); + Q_UNUSED(dataSize); + return false; +#endif +} + + +bool amdgpuIoctlHandler::isValid() const { + if(fd < 0){ + qDebug() << "Ioctl: file descriptor not available"; + return false; + } + +#ifdef DRM_IOCTL_AMDGPU_INFO + if(ioctl(fd, DRM_IOCTL_AMDGPU_INFO) && (errno == EACCES)){ + qDebug() << "Ioctl: drm render node not available and no root access"; + return false; + } +#else + return false; +#endif + + return true; +} + + +bool amdgpuIoctlHandler::getTemperature(int *data) const { + return false; + Q_UNUSED(data); +} + + +bool amdgpuIoctlHandler::getCoreClock(unsigned *data) const { +#ifdef AMDGPU_INFO_VCE_CLOCK_TABLE // Linux >= 4.10 + struct drm_amdgpu_info_vce_clock_table table; + CLEAN(table); + bool success = getValue(&table, sizeof(table), AMDGPU_INFO_VCE_CLOCK_TABLE); + if(success && table.num_valid_entries > 0) + *data = table.entries[0].sclk; + return success; +#else + return false; + Q_UNUSED(data); +#endif +} + + +bool amdgpuIoctlHandler::getMaxCoreClock(unsigned *data) const { +#ifdef AMDGPU_INFO_DEV_INFO + struct drm_amdgpu_info_device info; + CLEAN(info); + bool success = getValue(&info, sizeof(info), AMDGPU_INFO_DEV_INFO); + if(success) + *data = info.max_engine_clock; + return success; +#else + return false; + Q_UNUSED(data); +#endif +} + + +bool amdgpuIoctlHandler::getMemoryClock(unsigned *data) const { +#ifdef AMDGPU_INFO_VCE_CLOCK_TABLE // Linux >= 4.10 + struct drm_amdgpu_info_vce_clock_table table; + CLEAN(table); + bool success = getValue(&table, sizeof(table), AMDGPU_INFO_VCE_CLOCK_TABLE); + if(success && table.num_valid_entries > 0) + *data = table.entries[0].mclk; + return success; +#else + return false; + Q_UNUSED(data); +#endif +} + + +bool amdgpuIoctlHandler::getVramUsage(unsigned long *data) const { +#ifdef AMDGPU_INFO_VRAM_USAGE + return getValue(data, sizeof(*data), AMDGPU_INFO_VRAM_USAGE); +#else + return false; + Q_UNUSED(data); +#endif +} + + +bool amdgpuIoctlHandler::getVramSize(unsigned long *data) const { +#ifdef AMDGPU_INFO_VRAM_GTT + struct drm_amdgpu_info_vram_gtt info; + CLEAN(info); + bool success = getValue(&info, sizeof(info), AMDGPU_INFO_VRAM_GTT); + if(success) + *data = info.vram_size; + return success; +#else + return false; + Q_UNUSED(data); +#endif +} + + +bool amdgpuIoctlHandler::readRegistry(unsigned *data) const { +#ifdef AMDGPU_INFO_READ_MMR_REG + return getValue(data, sizeof(*data), AMDGPU_INFO_READ_MMR_REG); +#else + return false; + Q_UNUSED(data); +#endif +} diff -Nru radeon-profile-0.1.10~yakkety/ioctlHandler.cpp radeon-profile-0.1.17~yakkety/ioctlHandler.cpp --- radeon-profile-0.1.10~yakkety/ioctlHandler.cpp 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/ioctlHandler.cpp 2017-01-25 18:00:54.000000000 +0000 @@ -0,0 +1,113 @@ +#include "ioctlHandler.hpp" + +#include // snprintf() +#include // close(), usleep() +#include // open() + +#ifndef NO_IOCTL // Include libdrm headers only if NO_IOCTL is not defined +# include +#endif + + +#define PATH_SIZE 20 +#define NAME_SIZE 10 + + +int ioctlHandler::openPath(const char *prefix, unsigned index) const { + char path[PATH_SIZE]; + snprintf(path, PATH_SIZE, "%s%u", prefix, index); + + int res = open(path, O_RDONLY); + if(res < 0) // Open failed + DESCRIBE_ERROR(path); + else + qDebug() << "Opened" << path << ", fd number:" << res; + + return res; +} + +ioctlHandler::ioctlHandler(unsigned card){ +#ifdef NO_IOCTL + qWarning() << "radeon profile was compiled with NO_IOCTL, ioctls won't work"; + fd = -1; + Q_UNUSED(card); +#else + /* Open file descriptor to card device + * Information ioctls can be accessed in two ways: + * The kernel generates for the card with index N the files /dev/dri/card and /dev/dri/renderD<128+N> + * Both can be opened without root access + * Executing ioctls on /dev/dri/card requires either root access or being DRM Master + * /dev/dri/renderD<128+N> does not require these permissions, but legacy kernels (Linux < 3.15) do not support it + * For more details: + * https://en.wikipedia.org/wiki/Direct_Rendering_Manager#DRM-Master_and_DRM-Auth + * https://en.wikipedia.org/wiki/Direct_Rendering_Manager#Render_nodes + * https://www.x.org/wiki/Events/XDC2013/XDC2013DavidHerrmannDRMSecurity/slides.pdf#page=15 + */ + fd = openPath("/dev/dri/renderD", 128+card); // Try /dev/dri/renderD<128+N> + if(fd < 0) // /dev/dri/renderD<128+N> not available + fd = openPath("/dev/dri/card", card); // Try /dev/dri/card +#endif +} + + +QString ioctlHandler::getDriverName() const { + if(fd < 0) + return ""; + + char driver[NAME_SIZE] = ""; + +#ifdef DRM_IOCTL_VERSION + drm_version_t v; + CLEAN(v); + v.name = driver; + v.name_len = NAME_SIZE; + if(ioctl(fd, DRM_IOCTL_VERSION, &v)){ + DESCRIBE_ERROR("ioctl version"); + return ""; + } +#endif + + return QString(driver); +} + + +ioctlHandler::~ioctlHandler(){ + qDebug() << "Closing ioctl fd, number:" << fd; + if((fd >= 0) && close(fd)) + DESCRIBE_ERROR("fd close"); +} + + +bool ioctlHandler::getGpuUsage(float *data, unsigned time, unsigned frequency) const { + /* Sample the GPU status register N times and check how many of these samples have the GPU busy + * Register documentation: + * http://support.amd.com/TechDocs/46142.pdf#page=246 (address 0x8010, 31st bit) + */ +#define REGISTRY_ADDRESS 0x8010 +#define REGISTRY_MASK 1<<31 +#define ONE_SECOND 1000000 + const unsigned int sleep = ONE_SECOND/frequency; + unsigned int remaining, activeCount = 0, totalCount = 0, buffer; + for(remaining = time; (remaining > 0) && (remaining <= time); // Cycle until the time has finished + remaining -= (sleep - usleep(sleep)), totalCount++){ // On each cycle sleep and subtract the slept time from the remaining + buffer = REGISTRY_ADDRESS; + bool success = readRegistry(&buffer); + + if(Q_UNLIKELY(!success)) // Read failed + return false; + + if(REGISTRY_MASK & buffer) // Check if the activity bit is 1 + activeCount++; + } + + if(Q_UNLIKELY(totalCount == 0)) + return false; + + *data = (100.0f * activeCount) / totalCount; + + // qDebug() << activeCount << "active moments out of" << totalCount << "(" << *data << "%) in" << time/1000 << "mS (Sampling at" << frequency << "Hz)"; + return true; +} + + + diff -Nru radeon-profile-0.1.10~yakkety/ioctlHandler.h radeon-profile-0.1.17~yakkety/ioctlHandler.h --- radeon-profile-0.1.10~yakkety/ioctlHandler.h 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/ioctlHandler.h 2017-01-25 18:00:54.000000000 +0000 @@ -0,0 +1,188 @@ +#ifndef RADEON_IOCTL_H +#define RADEON_IOCTL_H + + +#include +#include +#include // ioctl() +#include // memset(), strerror() +#include // errno +#define DESCRIBE_ERROR(title) qWarning() << (title) << ':' << strerror(errno) +#define CLEAN(object) memset(&(object), 0, sizeof(object)) + +// Define NO _IOCTL if libdrm headers can't be installed (all ioctl functions will fail) +// Define NO_AMDGPU_IOCTL if libdrm headers are installed but amdgpu is not available (Linux < 4.2) + +/** + * @brief The ioctlHandler class is an interface to the kernel IOCTL system that allows to retrieve informations from the driver. + */ +class ioctlHandler +{ +protected: + /** + * @brief File descriptor for the card device, used by all IOCTLs. + */ + int fd; + + /** + * @brief Execute an ioctl call to the driver. + * @param data Points to the memory area to store input/output data. + * @param dataSize Size of the memory area. + * @param command Driver request identifier. + * @return Success. + */ + virtual bool getValue(void *data, unsigned dataSize, unsigned command) const = 0; + + /** + * @brief Read the content of a GPU register. + * @param data When called must contain the registry address. On success is filled with the content of the register. + * @return Success. + */ + virtual bool readRegistry(unsigned *data) const = 0; + + /** + * @brief Open a file descriptor to a file in the path $prefix$index + * @param prefix Text prefix of the file to open (for example '/dev/dri/card' or '/dev/dri/renderD') + * @param index Index to append to the prefix + * @return The file descriptor + */ + int openPath(const char *prefix, unsigned index) const; + + + /** + * @brief Open the communication with the device and initialize the ioctl handler. + * @note You can check if it worked out with isValid(). + * @param card Index of the card to be opened (for example 'card0' --> 0). + * @note You can find the list of available cards by running 'ls /dev/dri/ | grep card'. + */ + ioctlHandler(unsigned card); + +public: + /** + * @brief Close the communication with the device. + */ + virtual ~ioctlHandler(); + + /** + * @brief Check if the ioctlHandler has been initialized correctly. + * @return Validity. + */ + virtual bool isValid() const = 0; + + /** + * @brief Get GPU temperature. + * @param data On success is filled with the value, in °mC (milliCelsius). + * @return Success. + */ + virtual bool getTemperature(int *data) const = 0; + + /** + * @brief Get GPU current clock (sclk). + * @param data On success is filled with the value, in MHz. + * @return Success. + */ + virtual bool getCoreClock(unsigned *data) const = 0; + + /** + * @brief Get GPU maximum clock. + * @param data On success is filled with the value, in KHz. + * @return Success. + */ + virtual bool getMaxCoreClock(unsigned *data) const = 0; + + /** + * @brief Get how busy the GPU is. + * Sample the GPU status register N times and check how many of these samples have the GPU busy + * @param data On success is filled with the value, as percentage of time (o%=idle, 100%=full). + * @param time How much time to consider, in μS (microSeconds). + * @warning This function blocks the process for the whole time indicated in 'time'. + * @param frequency How frequently to check if the GPU is busy during the time, in Hz. + * @note A frequency > 100 Hz is suggested (A low sampling frequency reduces precision). + * @return Success. + */ + bool getGpuUsage(float *data, unsigned time, unsigned frequency) const; + + /** + * @brief Get VRAM memory current clock (mclk). + * @param data On success is filled with the value, in MHz. + * @return Success. + */ + virtual bool getMemoryClock(unsigned *data) const = 0; + + /** + * @brief Get VRAM memory current usage. + * @param data On success is filled with the value, in bytes. + * @return Success. + */ + virtual bool getVramUsage(unsigned long *data) const = 0; + + /** + * @brief Get VRAM memory total size. + * @param data On success is filled with the value, in bytes. + * @return Success. + */ + virtual bool getVramSize(unsigned long *data) const = 0; + + /** + * @brief Get the name of driver + * @return Driver name on success, empty on failure + */ + QString getDriverName() const; + +}; + + + +/** + * @brief The radeonIoctlHandler class implements ioctlHandler for the radeon driver + */ +class radeonIoctlHandler : public ioctlHandler { +protected: + bool getValue(void *data, unsigned dataSize, unsigned command) const override; + bool readRegistry(unsigned *data) const override; + +public: + /** + * @brief Open the communication with the device and initialize the ioctl handler. + * @note You can check if it worked out with isValid(). + * @param card Index of the card to be opened (for example 'card0' --> 0). + * @note You can find the list of available cards by running 'ls /dev/dri/ | grep card'. + */ + radeonIoctlHandler(unsigned cardIndex) : ioctlHandler(cardIndex){} + bool isValid() const override; + bool getCoreClock(unsigned *data) const override; + bool getMaxCoreClock(unsigned *data) const override; + bool getMemoryClock(unsigned *data) const override; + bool getTemperature(int *data) const override; + bool getVramSize(unsigned long *data) const override; + bool getVramUsage(unsigned long *data) const override; +}; + + + +/** + * @brief The amdgpuIoctlHandler class implements ioctlHandler for the amdgpu driver + */ +class amdgpuIoctlHandler : public ioctlHandler { +protected: + bool getValue(void *data, unsigned dataSize, unsigned command) const override; + bool readRegistry(unsigned *data) const override; + +public: + /** + * @brief Open the communication with the device and initialize the ioctl handler. + * @note You can check if it worked out with isValid(). + * @param card Index of the card to be opened (for example 'card0' --> 0). + * @note You can find the list of available cards by running 'ls /dev/dri/ | grep card'. + */ + amdgpuIoctlHandler(unsigned cardIndex) : ioctlHandler(cardIndex){} + bool isValid() const override; + bool getCoreClock(unsigned *data) const override; + bool getMaxCoreClock(unsigned *data) const override; + bool getMemoryClock(unsigned *data) const override; + bool getTemperature(int *data) const override; + bool getVramSize(unsigned long *data) const override; + bool getVramUsage(unsigned long *data) const override; +}; + +#endif diff -Nru radeon-profile-0.1.10~yakkety/ioctlHandler.hpp radeon-profile-0.1.17~yakkety/ioctlHandler.hpp --- radeon-profile-0.1.10~yakkety/ioctlHandler.hpp 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/ioctlHandler.hpp 2017-01-25 18:00:54.000000000 +0000 @@ -0,0 +1,189 @@ +#ifndef RADEON_IOCTL_H +#define RADEON_IOCTL_H + + +#include +#include +#include // ioctl() +#include // memset(), strerror() +#include // errno +#define DESCRIBE_ERROR(title) qWarning() << (title) << ':' << strerror(errno) +#define CLEAN(object) memset(&(object), 0, sizeof(object)) + + +/** + * @brief The ioctlHandler class is an interface to the kernel IOCTL system that allows to retrieve informations from the driver. + */ +class ioctlHandler +{ +protected: + /** + * @brief File descriptor for the card device, used by all IOCTLs. + */ + int fd; + + /** + * @brief Execute an ioctl call to the driver. + * @param data Points to the memory area to store input/output data. + * @param dataSize Size of the memory area. + * @param command Driver request identifier. + * @return Success. + */ + virtual bool getValue(void *data, unsigned dataSize, unsigned command) const = 0; + + /** + * @brief Read the content of a GPU register. + * @param data When called must contain the registry address. On success is filled with the content of the register. + * @return Success. + */ + virtual bool readRegistry(unsigned *data) const = 0; + + /** + * @brief Open a file descriptor to a file in the path $prefix$index + * @param prefix Text prefix of the file to open (for example '/dev/dri/card' or '/dev/dri/renderD') + * @param index Index to append to the prefix + * @return The file descriptor + */ + int openPath(const char *prefix, unsigned index) const; + + + /** + * @brief Open the communication with the device and initialize the ioctl handler. + * @note You can check if it worked out with isValid(). + * @param card Index of the card to be opened (for example 'card0' --> 0). + * @note You can find the list of available cards by running 'ls /dev/dri/ | grep card'. + */ + ioctlHandler(unsigned card); + +public: + /** + * @brief Close the communication with the device. + */ + virtual ~ioctlHandler(); + + /** + * @brief Check if the ioctlHandler has been initialized correctly. + * @return Validity. + */ + virtual bool isValid() const = 0; + + /** + * @brief Get GPU temperature. + * @param data On success is filled with the value, in °mC (milliCelsius). + * @return Success. + */ + virtual bool getTemperature(int *data) const = 0; + + /** + * @brief Get GPU current clock (sclk). + * @param data On success is filled with the value, in MHz. + * @return Success. + */ + virtual bool getCoreClock(unsigned *data) const = 0; + + /** + * @brief Get GPU maximum clock. + * @param data On success is filled with the value, in KHz. + * @return Success. + */ + virtual bool getMaxCoreClock(unsigned *data) const = 0; + + /** + * @brief Get how busy the GPU is. + * Sample the GPU status register N times and check how many of these samples have the GPU busy + * @param data On success is filled with the value, as percentage of time (o%=idle, 100%=full). + * @param time How much time to consider, in μS (microSeconds). + * @warning This function blocks the process for the whole time indicated in 'time'. + * @param frequency How frequently to check if the GPU is busy during the time, in Hz. + * @note A frequency > 100 Hz is suggested (A low sampling frequency reduces precision). + * @return Success. + */ + bool getGpuUsage(float *data, unsigned time, unsigned frequency) const; + + /** + * @brief Get VRAM memory current clock (mclk). + * @param data On success is filled with the value, in MHz. + * @return Success. + */ + virtual bool getMemoryClock(unsigned *data) const = 0; + + /** + * @brief Get VRAM memory current usage. + * @param data On success is filled with the value, in bytes. + * @return Success. + */ + virtual bool getVramUsage(unsigned long *data) const = 0; + + /** + * @brief Get VRAM memory total size. + * @param data On success is filled with the value, in bytes. + * @return Success. + */ + virtual bool getVramSize(unsigned long *data) const = 0; + + /** + * @brief Get the name of driver + * @return Driver name on success, empty on failure + */ + QString getDriverName() const; + +}; + + + +/** + * @brief The radeonIoctlHandler class implements ioctlHandler for the radeon driver. + * @note Define NO _IOCTL if libdrm headers can't be installed (all ioctl functions will fail). + */ +class radeonIoctlHandler : public ioctlHandler { +protected: + bool getValue(void *data, unsigned dataSize, unsigned command) const override; + bool readRegistry(unsigned *data) const override; + +public: + /** + * @brief Open the communication with the device and initialize the ioctl handler. + * @note You can check if it worked out with isValid(). + * @param cardIndex Index of the card to be opened (for example 'card0' --> 0). + * @note You can find the list of available cards by running 'ls /dev/dri/ | grep card'. + */ + radeonIoctlHandler(unsigned cardIndex); + bool isValid() const override; + bool getCoreClock(unsigned *data) const override; + bool getMaxCoreClock(unsigned *data) const override; + bool getMemoryClock(unsigned *data) const override; + bool getTemperature(int *data) const override; + bool getVramSize(unsigned long *data) const override; + bool getVramUsage(unsigned long *data) const override; +}; + + + +/** + * @brief The amdgpuIoctlHandler class implements ioctlHandler for the amdgpu driver. + * @note Define NO _IOCTL if libdrm headers can't be installed (all ioctl functions will fail). + * @note Define NO_AMDGPU_IOCTL if only libdrm amdgpu headers are not available (amdgpu ioctl functions will fail). + */ +class amdgpuIoctlHandler : public ioctlHandler { +protected: + bool getValue(void *data, unsigned dataSize, unsigned command) const override; + bool readRegistry(unsigned *data) const override; + +public: + /** + * @brief Open the communication with the device and initialize the ioctl handler. + * @note You can check if it worked out with isValid(). + * @param cardIndex Index of the card to be opened (for example 'card0' --> 0). + * @note You can find the list of available cards by running 'ls /dev/dri/ | grep card'. + */ + amdgpuIoctlHandler(unsigned cardIndex); + bool isValid() const override; + bool getCoreClock(unsigned *data) const override; + bool getMaxCoreClock(unsigned *data) const override; + bool getMemoryClock(unsigned *data) const override; + bool getTemperature(int *data) const override; + bool getVramSize(unsigned long *data) const override; + bool getVramUsage(unsigned long *data) const override; +}; + +#endif diff -Nru radeon-profile-0.1.10~yakkety/ioctl_radeon.cpp radeon-profile-0.1.17~yakkety/ioctl_radeon.cpp --- radeon-profile-0.1.10~yakkety/ioctl_radeon.cpp 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/ioctl_radeon.cpp 2017-01-25 18:00:54.000000000 +0000 @@ -0,0 +1,116 @@ +#include "ioctlHandler.hpp" + +#ifndef NO_IOCTL // Include libdrm headers only if NO_IOCTL is not defined +# include // radeon ioctl codes and structs +#endif + + +radeonIoctlHandler::radeonIoctlHandler(unsigned cardIndex) : ioctlHandler(cardIndex){} + +bool radeonIoctlHandler::getValue(void *data, unsigned dataSize, unsigned command) const { + // https://cgit.freedesktop.org/mesa/drm/tree/include/drm/radeon_drm.h#n993 + // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/drm/radeon_drm.h#n993 + // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/radeon/radeon_kms.c#n203 + +#ifdef DRM_IOCTL_RADEON_INFO + struct drm_radeon_info buffer; + CLEAN(buffer); + buffer.request = command; + buffer.value = (uint64_t)data; + bool success = !ioctl(fd, DRM_IOCTL_RADEON_INFO, &buffer); + if(Q_UNLIKELY(!success)) + DESCRIBE_ERROR("ioctl"); + return success; +#else + return false; + Q_UNUSED(data); + Q_UNUSED(command); +#endif + + Q_UNUSED(dataSize); +} + + +bool radeonIoctlHandler::isValid() const { + if(fd < 0){ + qDebug() << "Ioctl: file descriptor not available"; + return false; + } + +#ifdef DRM_IOCTL_RADEON_INFO + if(ioctl(fd, DRM_IOCTL_RADEON_INFO) && (errno == EACCES)){ + qDebug() << "Ioctl: drm render node not available and no root access"; + return false; + } +#else + return false; +#endif + + return true; +} + + +bool radeonIoctlHandler::getTemperature(int *data) const { +#ifdef RADEON_INFO_CURRENT_GPU_TEMP // Linux >= 4.1 + return getValue(data, sizeof(*data), RADEON_INFO_CURRENT_GPU_TEMP); +#else + return false; + Q_UNUSED(data); +#endif +} + + +bool radeonIoctlHandler::getCoreClock(unsigned *data) const { +#ifdef RADEON_INFO_CURRENT_GPU_SCLK // Linux >= 4.1 + return getValue(data, sizeof(*data), RADEON_INFO_CURRENT_GPU_SCLK); +#else + return false; + Q_UNUSED(data); +#endif +} + + +bool radeonIoctlHandler::getMaxCoreClock(unsigned *data) const { +#ifdef RADEON_INFO_MAX_SCLK + return getValue(data, sizeof(*data), RADEON_INFO_MAX_SCLK); +#else + return false; + Q_UNUSED(data); +#endif +} + + +bool radeonIoctlHandler::getMemoryClock(unsigned *data) const { +#ifdef RADEON_INFO_CURRENT_GPU_MCLK // Linux >= 4.1 + return getValue(data, sizeof(*data), RADEON_INFO_CURRENT_GPU_MCLK); +#else + return false; + Q_UNUSED(data); +#endif +} + + +bool radeonIoctlHandler::getVramUsage(unsigned long *data) const { +#ifdef RADEON_INFO_VRAM_USAGE + return getValue(data, sizeof(*data), RADEON_INFO_VRAM_USAGE); +#else + return false; + Q_UNUSED(data); +#endif +} + + +bool radeonIoctlHandler::getVramSize(unsigned long *data) const { + return false; + Q_UNUSED(data); +} + + +bool radeonIoctlHandler::readRegistry(unsigned *data) const { +#ifdef RADEON_INFO_READ_REG // Linux >= 4.1 + return getValue(data, sizeof(*data), RADEON_INFO_READ_REG); +#else + return false; + Q_UNUSED(data); +#endif +} diff -Nru radeon-profile-0.1.10~yakkety/main.cpp radeon-profile-0.1.17~yakkety/main.cpp --- radeon-profile-0.1.10~yakkety/main.cpp 2016-06-28 14:42:31.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/main.cpp 2017-01-25 18:00:11.000000000 +0000 @@ -5,12 +5,19 @@ int main(int argc, char *argv[]) { QApplication a(argc, argv); + QTranslator translator; + QLocale locale; - QTranslator * translator = new QTranslator(); - if(translator->load(QLocale(), "strings", ".", "/usr/share/radeon-profile") || translator->load(QLocale(), "strings", ".")) - a.installTranslator(translator); - else - qWarning() << "Failed loading translation"; + if (locale.language() != QLocale::Language::English) { + + if (translator.load(locale, "strings", ".") + || translator.load(locale, "strings", ".", QApplication::applicationDirPath()) + || translator.load(locale, "strings", ".", "/usr/share/radeon-profile")) + + a.installTranslator(&translator); + else + qWarning() << "Translation not found."; + } radeon_profile w(a.arguments()); diff -Nru radeon-profile-0.1.10~yakkety/radeon_ioctl.c radeon-profile-0.1.17~yakkety/radeon_ioctl.c --- radeon-profile-0.1.10~yakkety/radeon_ioctl.c 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/radeon_ioctl.c 2017-01-25 18:00:54.000000000 +0000 @@ -0,0 +1,197 @@ +#include "radeon_ioctl.h" + + +#ifdef NO_IOCTL + + +int openCardFD(const char * card){(void)card; return -1;} +void closeCardFD(int fd){(void)fd;} +int radeonTemperature(int fd, int *data){(void)fd;(void)data; return -1;} +int radeonCoreClock(int fd, unsigned *data){(void)fd;(void)data; return -1;} +int radeonMemoryClock(int fd, unsigned *data){(void)fd;(void)data; return -1;} +int radeonMaxCoreClock(int fd, unsigned *data){(void)fd;(void)data; return -1;} +int radeonVramUsage(int fd, unsigned long *data){(void)fd;(void)data; return -1;} +int radeonGttUsage(int fd, unsigned long *data){(void)fd;(void)data; return -1;} +int radeonReadRegistry(int fd, unsigned *data){(void)fd;(void)data; return -1;} +int radeonGpuUsage(int fd, float *data, unsigned time, unsigned frequency){(void)fd;(void)data;(void)time;(void)frequency; return -1;} +int amdgpuVramSize(int fd, unsigned long *data){(void)fd;(void)data; return -1;} +int amdgpuVramUsage(int fd, unsigned long *data){(void)fd;(void)data; return -1;} +int amdgpuGttUsage(int fd, unsigned long *data){(void)fd;(void)data; return -1;} +int amdgpuReadRegistry(int fd, unsigned *data){(void)fd;(void)data; return -1;} +int amdgpuGpuUsage(int fd, float *data, unsigned time, unsigned frequency){(void)fd;(void)data;(void)time;(void)frequency; return -1;} + + +#else + + +#include +#include +#include +#include +#include +#include +#include +#include + +#define CLEAN(object) memset(&(object), 0, sizeof(object)) +#define PATH_SIZE 20 + +void errorDebug(const char * title){ +#ifdef QT_NO_DEBUG_OUTPUT + (void)title; +#else + perror(title); +#endif +} + +int openCardFD(const char * card){ + int fd; + char path[PATH_SIZE] = "/dev/dri/"; + + strncat(path, card, PATH_SIZE-strlen(path)-1); + fd= open(path,O_RDONLY); + + if(fd < 0) + errorDebug("open"); + + return fd; +} + +void closeCardFD(int fd){ + if(close(fd)) + errorDebug("close"); +} + +int gpuUsage(int fd, float *data, unsigned time, unsigned frequency, int(*accessRegistry)(int fd, unsigned *data)){ +#define REGISTRY_ADDRESS 0x8010 // http://support.amd.com/TechDocs/46142.pdf#page=246 +#define REGISTRY_MASK 1<<31 +#define ONE_SECOND 1000000 + const unsigned int sleep = ONE_SECOND/frequency; + unsigned int remaining, activeCount = 0, totalCount = 0, buffer; + int error; + for(remaining = time; (remaining > 0) && (remaining <= time); remaining -= (sleep - usleep(sleep)), totalCount++){ + buffer = REGISTRY_ADDRESS; + error = accessRegistry(fd, &buffer); + + if(error) + return error; + + if(REGISTRY_MASK & buffer) + activeCount++; + } + + if(totalCount == 0) + return -1; + + *data = (100.0f * activeCount) / totalCount; + +#ifndef QT_NO_DEBUG_OUTPUT + printf("%u active moments out of %u (%3.2f%%) in %umS (Sampling at %uHz)\n", activeCount, totalCount, *data, time/1000, frequency); +#endif + + return 0; +} + +/******************** RADEON ********************/ +#include // http://lxr.free-electrons.com/source/include/uapi/drm/radeon_drm.h#L993 + +int radeonGetValue(int fd, void *data, uint32_t command){ + int error; + struct drm_radeon_info buffer; + CLEAN(buffer); + buffer.request = command; + buffer.value = (uint64_t)data; + + error = ioctl(fd, DRM_IOCTL_RADEON_INFO, &buffer); + if(error) + errorDebug("ioctl radeon"); + + return error; +} + +int radeonTemperature(int fd, int *data){ + return radeonGetValue(fd, data, RADEON_INFO_CURRENT_GPU_TEMP); // http://lxr.free-electrons.com/source/drivers/gpu/drm/radeon/radeon_kms.c#L555 +} + +int radeonCoreClock(int fd, unsigned *data){ + return radeonGetValue(fd, data, RADEON_INFO_CURRENT_GPU_SCLK); // http://lxr.free-electrons.com/source/drivers/gpu/drm/radeon/radeon_kms.c#L562 +} + +int radeonMaxCoreClock(int fd, unsigned *data){ + return radeonGetValue(fd, data, RADEON_INFO_MAX_SCLK); // http://lxr.free-electrons.com/source/drivers/gpu/drm/radeon/radeon_kms.c#L511 +} + +int radeonMemoryClock(int fd, unsigned *data){ + return radeonGetValue(fd, data, RADEON_INFO_CURRENT_GPU_MCLK); // http://lxr.free-electrons.com/source/drivers/gpu/drm/radeon/radeon_kms.c#L569 +} + +int radeonVramUsage(int fd, unsigned long *data){ + return radeonGetValue(fd, data, RADEON_INFO_VRAM_USAGE); // http://lxr.free-electrons.com/source/drivers/gpu/drm/radeon/radeon_kms.c#L529 +} + +int radeonGttUsage(int fd, unsigned long *data){ + return radeonGetValue(fd, data, RADEON_INFO_GTT_USAGE); // http://lxr.free-electrons.com/source/drivers/gpu/drm/radeon/radeon_kms.c#L534 +} + +int radeonReadRegistry(int fd, unsigned *data){ + return radeonGetValue(fd, data, RADEON_INFO_READ_REG); // http://lxr.free-electrons.com/source/drivers/gpu/drm/radeon/radeon_kms.c#L576 +} + +int radeonGpuUsage(int fd, float *data, unsigned time, unsigned frequency){ + return gpuUsage(fd, data, time, frequency, radeonReadRegistry); +} + + +/******************** AMDGPU ********************/ +#include // http://lxr.free-electrons.com/source/include/uapi/drm/amdgpu_drm.h#L441 + +int amdgpuVramSize(int fd, unsigned long *data){ + int error; + struct drm_amdgpu_info_vram_gtt info; + struct drm_amdgpu_info buffer; + CLEAN(buffer); + buffer.query = AMDGPU_INFO_VRAM_GTT; // http://lxr.free-electrons.com/source/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c#L404 + buffer.return_pointer = (uint64_t)&info; + buffer.return_size = sizeof(info); + + error = ioctl(fd, DRM_IOCTL_AMDGPU_INFO, &buffer); + *data = info.vram_size; + + if(error) + errorDebug("ioctl amdgpu"); + + return error; +} + +int amdgpuGetValue(int fd, void *data, uint32_t command){ + int error; + struct drm_amdgpu_info buffer; + CLEAN(buffer); + buffer.query = command; + buffer.return_pointer = (uint64_t)data; + buffer.return_size = sizeof(unsigned long); + + error = ioctl(fd, DRM_IOCTL_AMDGPU_INFO, &buffer); + if(error) + errorDebug("ioctl amdgpu"); + + return error; +} + +int amdgpuVramUsage(int fd, unsigned long *data){ + return amdgpuGetValue(fd, data, AMDGPU_INFO_VRAM_USAGE); // http://lxr.free-electrons.com/source/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c#L381 +} + +int amdgpuGttUsage(int fd, unsigned long *data){ + return amdgpuGetValue(fd, data, AMDGPU_INFO_GTT_USAGE); // http://lxr.free-electrons.com/source/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c#L387 +} + +int amdgpuReadRegistry(int fd, unsigned *data){ + return amdgpuGetValue(fd, data, AMDGPU_INFO_READ_MMR_REG); // http://lxr.free-electrons.com/source/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c#L416 +} + +int amdgpuGpuUsage(int fd, float *data, unsigned time, unsigned frequency){ + return gpuUsage(fd, data, time, frequency, amdgpuReadRegistry); +} + +#endif diff -Nru radeon-profile-0.1.10~yakkety/radeon_ioctl.cpp radeon-profile-0.1.17~yakkety/radeon_ioctl.cpp --- radeon-profile-0.1.10~yakkety/radeon_ioctl.cpp 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/radeon_ioctl.cpp 2017-01-25 18:00:54.000000000 +0000 @@ -0,0 +1,353 @@ +// Define NO _IOCTL if libdrm headers can't be installed (all ioctl functions will return failure) +// Define NO_AMDGPU_IOCTL if libdrm headers are installed but amdgpu is not available (Linux < 4.2) + +#ifndef NO_IOCTL // Check if libdrm headers are available only if NO_IOCTL is not defined ... +# ifdef __has_include // ... and the compiler supports the __has_include macro (clang or gcc>=5.0) +# if !__has_include() +# error radeon_drm.h is not available! Install libdrm headers or compile with the flag -DNO_IOCTL +# endif // radeon_drm.h +# ifndef NO_AMDGPU_IOCTL // Search the amdgpu drm header only if NO_AMDGPU_IOCTL is not defined +# if !__has_include() +# error amdgpu_drm.h is not available! Install libdrm headers or compile with the flag -DNO_AMDGPU_IOCTL +# endif // amdgpu_drm.h +# endif // NO_AMDGPU_IOCTL +# endif // __has_include +#endif // NO_IOCTL + + +#include "radeon_ioctl.h" +#include +#include +#include // memset(), strerror() +#include // snprintf() +#include // errno +#include // close(), usleep() +#include // open() +#include // ioctl() + +#ifndef NO_IOCTL // Include libdrm headers only if NO_IOCTL is not defined +# include // radeon ioctl codes and structs +# ifndef NO_AMDGPU_IOCTL +# include // amdgpu ioctl codes and structs +# endif +#endif + + +#define DESCRIBE_ERROR(title) qWarning() << (title) << ':' << strerror(errno) +#define CLEAN(object) memset(&(object), 0, sizeof(object)) + + +ioctlHandler::ioctlCodes::ioctlCodes(){ + request = UNAVAILABLE; + temperature = UNAVAILABLE; + coreClock = UNAVAILABLE; + maxCoreClock = UNAVAILABLE; + memoryClock = UNAVAILABLE; + vramUsage = UNAVAILABLE; + vramSize = UNAVAILABLE; + registry = UNAVAILABLE; +} + +int ioctlHandler::openPath(const char *prefix, unsigned index){ +#define PATH_SIZE 20 + char path[PATH_SIZE]; + snprintf(path, PATH_SIZE, "%s%u", prefix, index); + qDebug() << "Opening" << path << "for ioctls"; + + int res = open(path, O_RDONLY); + if(res < 0) // Open failed + DESCRIBE_ERROR(path); + + return res; +} + +ioctlHandler::ioctlHandler(unsigned card){ + codes = ioctlCodes(); + +#ifdef NO_IOCTL + qWarning() << "radeon profile was compiled with NO_IOCTL, ioctls won't work"; + fd = -1; + return; +#endif // NO_IOCTL + + + /* Open file descriptor to card device + * Information ioctls can be accessed in two ways: + * The kernel generates for the card with index N the files /dev/dri/card and /dev/dri/renderD<128+N> + * Both can be opened without root access + * Executing ioctls on /dev/dri/card requires either root access or being DRM Master + * /dev/dri/renderD<128+N> does not require these permissions, but legacy kernels (Linux < 3.15) do not support it + * For more details: + * https://en.wikipedia.org/wiki/Direct_Rendering_Manager#DRM-Master_and_DRM-Auth + * https://en.wikipedia.org/wiki/Direct_Rendering_Manager#Render_nodes + * https://www.x.org/wiki/Events/XDC2013/XDC2013DavidHerrmannDRMSecurity/slides.pdf#page=15 + */ + fd = openPath("/dev/dri/renderD", 128+card); // Try /dev/dri/renderD<128+N> + if(fd < 0){ // /dev/dri/renderD<128+N> not available + fd = openPath("/dev/dri/card", card); // Try /dev/dri/card + if(fd < 0) // /dev/dri/card not available + return; // Initialization failed + } + + // Initialize ioctl codes + QString driver = getDriverName(); + qDebug() << "Initializing ioctl codes for driver " << driver; + +#ifdef __RADEON_DRM_H__ + if(driver=="radeon"){ + // https://cgit.freedesktop.org/mesa/drm/tree/include/drm/radeon_drm.h#n993 + // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/drm/radeon_drm.h#n993 + // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/radeon/radeon_kms.c#n203 + codes.request = DRM_IOCTL_RADEON_INFO; +#ifdef RADEON_INFO_CURRENT_GPU_TEMP // Available only in Linux 4.1 and above + codes.temperature = RADEON_INFO_CURRENT_GPU_TEMP; + codes.coreClock = RADEON_INFO_CURRENT_GPU_SCLK; + codes.memoryClock = RADEON_INFO_CURRENT_GPU_MCLK; + codes.registry = RADEON_INFO_READ_REG; +#endif // RADEON_INFO_CURRENT_GPU_TEMP + codes.maxCoreClock = RADEON_INFO_MAX_SCLK; + codes.vramUsage = RADEON_INFO_VRAM_USAGE; + } +#endif // __RADEON_DRM_H__ + +#ifdef __AMDGPU_DRM_H__ + if (driver == "amdgpu") { + // https://cgit.freedesktop.org/mesa/drm/tree/include/drm/amdgpu_drm.h#n437 + // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/drm/amdgpu_drm.h#n471 + // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c#n212 + codes.request = DRM_IOCTL_AMDGPU_INFO; +# ifdef AMDGPU_INFO_VCE_CLOCK_TABLE // Available only in Linux 4.10 and above + codes.coreClock = AMDGPU_INFO_VCE_CLOCK_TABLE; + codes.memoryClock = AMDGPU_INFO_VCE_CLOCK_TABLE; +# endif // AMDGPU_INFO_VCE_CLOCK_TABLE + codes.maxCoreClock = AMDGPU_INFO_DEV_INFO; + codes.vramUsage = AMDGPU_INFO_VRAM_USAGE; + codes.vramSize = AMDGPU_INFO_VRAM_GTT; + codes.registry = AMDGPU_INFO_READ_MMR_REG; + } +#endif // __AMDGPU_DRM_H__ +} + + +QString ioctlHandler::getDriverName(){ + if(fd < 0) + return ""; + +#define NAME_SIZE 10 + char driver[NAME_SIZE] = ""; + +#ifdef _DRM_H_ + drm_version_t v; + CLEAN(v); + v.name = driver; + v.name_len = NAME_SIZE; + if(ioctl(fd, DRM_IOCTL_VERSION, &v)){ + DESCRIBE_ERROR("ioctl version"); + return ""; + } +#endif // _DRM_H_ + + return QString(driver); +} + + +bool ioctlHandler::isValid(){ + if(fd < 0){ + qDebug() << "Ioctl: file descriptor not available"; + return false; + } + + if(codes.request == UNAVAILABLE){ + qDebug() << "Ioctl: request code not available"; + return false; + } + + if(ioctl(fd, codes.request) && (errno == EACCES)){ + qDebug() << "Ioctl: drm render node not available and no root access"; + return false; + } + + return true; +} + + +ioctlHandler::~ioctlHandler(){ + if((fd >= 0) && close(fd)) + DESCRIBE_ERROR("fd close"); +} + + +bool ioctlHandler::getGpuUsage(float *data, unsigned time, unsigned frequency){ + /* Sample the GPU status register N times and check how many of these samples have the GPU busy + * Register documentation: + * http://support.amd.com/TechDocs/46142.pdf#page=246 (address 0x8010, 31st bit) + */ +#define REGISTRY_ADDRESS 0x8010 +#define REGISTRY_MASK 1<<31 +#define ONE_SECOND 1000000 + const unsigned int sleep = ONE_SECOND/frequency; + unsigned int remaining, activeCount = 0, totalCount = 0, buffer; + for(remaining = time; (remaining > 0) && (remaining <= time); // Cycle until the time has finished + remaining -= (sleep - usleep(sleep)), totalCount++){ // On each cycle sleep and subtract the slept time from the remaining + buffer = REGISTRY_ADDRESS; + bool success = readRegistry(&buffer); + + if(Q_UNLIKELY(!success)) // Read failed + return false; + + if(REGISTRY_MASK & buffer) // Check if the activity bit is 1 + activeCount++; + } + + if(Q_UNLIKELY(totalCount == 0)) + return false; + + *data = (100.0f * activeCount) / totalCount; + + // qDebug() << activeCount << "active moments out of" << totalCount << "(" << *data << "%) in" << time/1000 << "mS (Sampling at" << frequency << "Hz)"; + return true; +} + + +bool ioctlHandler::getValue(void *data, unsigned dataSize, unsigned command){ + switch(codes.request){ +#ifdef __RADEON_DRM_H__ + case DRM_IOCTL_RADEON_INFO:{ // Radeon driver + struct drm_radeon_info buffer; + CLEAN(buffer); + buffer.request = command; + buffer.value = (uint64_t)data; + bool success = !ioctl(fd, codes.request, &buffer); + if(Q_UNLIKELY(!success)) + DESCRIBE_ERROR("ioctl"); + return success; + } +#endif // __RADEON_DRM_H__ + +#ifdef __AMDGPU_DRM_H__ + case DRM_IOCTL_AMDGPU_INFO:{ // Amdgpu driver + struct drm_amdgpu_info buffer; + CLEAN(buffer); + buffer.query = command; + buffer.return_pointer = (uint64_t)data; + buffer.return_size = dataSize; + bool success = !ioctl(fd, codes.request, &buffer); + if(Q_UNLIKELY(!success)) + DESCRIBE_ERROR("ioctl"); + return success; + } +#else + Q_UNUSED(data) + Q_UNUSED(command) + Q_UNUSED(dataSize) +#endif // __AMDGPU_DRM_H__ + + default: // Unknown driver or not initialized + qWarning("ioctlHandler not initialized correctly"); + return false; + } +} + + +bool ioctlHandler::getTemperature(int *data){ + return (codes.temperature != UNAVAILABLE) && getValue(data, sizeof(*data), codes.temperature); +} + + +bool ioctlHandler::getCoreClock(unsigned *data){ + switch(codes.coreClock){ +#ifdef AMDGPU_INFO_VCE_CLOCK_TABLE + case AMDGPU_INFO_VCE_CLOCK_TABLE:{ + struct drm_amdgpu_info_vce_clock_table table; + CLEAN(table); + bool success = getValue(&table, sizeof(table), codes.coreClock); + if(success && table.num_valid_entries > 0) + *data = table.entries[0].sclk; + return success; + } +#endif // AMDGPU_INFO_VCE_CLOCK_TABLE + + case UNAVAILABLE: + return false; + + default: + return getValue(data, sizeof(*data), codes.coreClock); + } +} + + +bool ioctlHandler::getMaxCoreClock(unsigned *data){ + switch (codes.maxCoreClock) { +#ifdef __AMDGPU_DRM_H__ + case AMDGPU_INFO_DEV_INFO:{ + struct drm_amdgpu_info_device info; + CLEAN(info); + bool success = getValue(&info, sizeof(info), codes.maxCoreClock); + if(success) + *data = info.max_engine_clock; + return success; + } +#endif // __AMDGPU_DRM_H__ + + case UNAVAILABLE: + return false; + + default: + return getValue(data, sizeof(*data), codes.maxCoreClock); + } +} + + +bool ioctlHandler::getMemoryClock(unsigned *data){ + switch(codes.memoryClock){ +#ifdef AMDGPU_INFO_VCE_CLOCK_TABLE + case AMDGPU_INFO_VCE_CLOCK_TABLE:{ + struct drm_amdgpu_info_vce_clock_table table; + CLEAN(table); + bool success = getValue(&table, sizeof(table), codes.memoryClock); + if(success && table.num_valid_entries > 0) + *data = table.entries[0].mclk; + return success; + } +#endif // AMDGPU_INFO_VCE_CLOCK_TABLE + + case UNAVAILABLE: + return false; + + default: + return getValue(data, sizeof(*data), codes.memoryClock); + } +} + + +bool ioctlHandler::getVramUsage(unsigned long *data){ + return (codes.vramUsage != UNAVAILABLE) && getValue(data, sizeof(*data), codes.vramUsage); +} + + +bool ioctlHandler::readRegistry(unsigned *data){ + return (codes.registry != UNAVAILABLE) && getValue(data, sizeof(*data), codes.registry); +} + + +bool ioctlHandler::getVramSize(unsigned long *data){ + switch(codes.vramSize){ +#ifdef __AMDGPU_DRM_H__ + case AMDGPU_INFO_VRAM_GTT:{ + struct drm_amdgpu_info_vram_gtt info; + CLEAN(info); + bool success = getValue(&info, sizeof(info), codes.vramSize); + if(success) + *data = info.vram_size; + return success; + } +#endif + + case UNAVAILABLE: + return false; + + default: + return getValue(data, sizeof(*data), codes.vramSize); + } +} + diff -Nru radeon-profile-0.1.10~yakkety/radeon_ioctl.h radeon-profile-0.1.17~yakkety/radeon_ioctl.h --- radeon-profile-0.1.10~yakkety/radeon_ioctl.h 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/radeon_ioctl.h 2017-01-25 18:00:54.000000000 +0000 @@ -0,0 +1,145 @@ +#ifndef RADEON_IOCTL_H +#define RADEON_IOCTL_H + + +#include + +/** + * @brief The ioctlHandler class is an interface to the kernel IOCTL system that allows to retrieve informations from the driver. + */ +class ioctlHandler +{ +private: + /** + * @brief File descriptor for the card device, used by all IOCTLs. + */ + int fd; + + /** + * @brief The ioctlCodes struct contains all query codes needed to execute the ioctls. + */ + struct ioctlCodes{ +#define UNAVAILABLE 0 + unsigned request, /**< Identifies the driver to query (radeon/amdgpu). */ + temperature, /**< Temperature ioctl request. */ + coreClock, /**< SCLK ioctl request. */ + maxCoreClock, /**< Max SCLK ioctl request. */ + memoryClock, /**< MCLK ioctl request. */ + vramUsage, /**< VRAM usage ioctl request. */ + vramSize, /**< VRAM total size ioctl request. */ + registry; /**< Registry read ioctl request .*/ + + /** @brief Create an empty struct (all codes initialized to UNAVAILABLE). */ + ioctlCodes(); + } codes; /**< Contains available query codes. */ + + + /** + * @brief Execute an ioctl call to the driver. + * @param data Points to the memory area to store input/output data. + * @param dataSize Size of the memory area. + * @param command Driver request identifier. + * @return Success. + */ + bool getValue(void *data, unsigned dataSize, unsigned command); + + /** + * @brief Read the content of a GPU register. + * @param data When called must contain the registry address. On success is filled with the content of the register. + * @return Success. + */ + bool readRegistry(unsigned *data); + + /** + * @brief Open a file descriptor to a file in the path $prefix$index + * @param prefix Text prefix of the file to open (for example '/dev/dri/card' or '/dev/dri/renderD') + * @param index Index to append to the prefix + * @return The file descriptor + */ + int openPath(const char *prefix, unsigned index); + + +public: + /** + * @brief Open the communication with the device and initialize the ioctl handler. + * @note You can check if it worked out with isValid(). + * @param card Index of the card to be opened (for example 'card0' --> 0). + * @note You can find the list of available cards by running 'ls /dev/dri/ | grep card'. + */ + ioctlHandler(unsigned card); + + /** + * @brief Close the communication with the device. + */ + ~ioctlHandler(); + + /** + * @brief Check if the ioctlHandler has been initialized correctly. + * @return Validity. + */ + bool isValid(); + + /** + * @brief Get GPU temperature. + * @param data On success is filled with the value, in °mC (milliCelsius). + * @return Success. + */ + bool getTemperature(int *data); + + /** + * @brief Get GPU current clock (sclk). + * @param data On success is filled with the value, in MHz. + * @return Success. + */ + bool getCoreClock(unsigned *data); + + /** + * @brief Get GPU maximum clock. + * @param data On success is filled with the value, in KHz. + * @return Success. + */ + bool getMaxCoreClock(unsigned *data); + + /** + * @brief Get how busy the GPU is. + * @param data On success is filled with the value, as percentage of time (o%=idle, 100%=full). + * @param time How much time to consider, in μS (microSeconds). + * @warning This function blocks the process for the whole time indicated in 'time'. + * @param frequency How frequently to check if the GPU is busy during the time, in Hz. + * @note A frequency > 100 Hz is suggested (A low sampling frequency reduces precision). + * @return Success. + */ + bool getGpuUsage(float *data, unsigned time, unsigned frequency); + + /** + * @brief Get VRAM memory current clock (mclk). + * @param data On success is filled with the value, in MHz. + * @return Success. + */ + bool getMemoryClock(unsigned *data); + + /** + * @brief Get VRAM memory current usage. + * @param data On success is filled with the value, in bytes. + * @return Success. + */ + bool getVramUsage(unsigned long *data); + + /** + * @brief Get VRAM memory total size. + * @param data On success is filled with the value, in bytes. + * @return Success. + */ + bool getVramSize(unsigned long *data); + + /** + * @brief Get the name of driver + * @return Driver name on success, empty on failure + */ + QString getDriverName(); + +}; + + + +#endif diff -Nru radeon-profile-0.1.10~yakkety/radeon_profile.cpp radeon-profile-0.1.17~yakkety/radeon_profile.cpp --- radeon-profile-0.1.10~yakkety/radeon_profile.cpp 2016-06-28 14:42:31.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/radeon_profile.cpp 2017-01-25 18:00:54.000000000 +0000 @@ -26,15 +26,19 @@ #include #include - +unsigned int radeon_profile::minFanStepsSpeed = 10; radeon_profile::radeon_profile(QStringList a,QWidget *parent) : QMainWindow(parent), ui(new Ui::radeon_profile) { + rangeX = 180; + ticksCounter = 0; + statsTickCounter = 0; + savedState = nullptr; + ui->setupUi(this); - timer = new QTimer(); - execsRunning = new QList(); + timer = new QTimer(this); // checks if running as root if (globalStuff::grabSystemInfo("whoami")[0] == "root") { @@ -61,15 +65,11 @@ //figure out parameters QString params = a.join(" "); - if (params.contains("--driver xorg")) { - device.driverByParam(gpu::XORG); - ui->combo_gpus->addItems(device.initialize(true)); - } - else if (params.contains("--driver fglrx")) { - device.driverByParam(gpu::FGLRX); - ui->combo_gpus->addItems(device.initialize(true)); - } - else // driver object detects cards in pc and fill the list in ui // + if (params.contains("--driver xorg")) + ui->combo_gpus->addItems(device.initialize(gpu::XORG)); + else if (params.contains("--driver fglrx")) + ui->combo_gpus->addItems(device.initialize(gpu::FGLRX)); + else ui->combo_gpus->addItems(device.initialize()); ui->configGroups->setTabEnabled(2,device.daemonConnected()); @@ -78,23 +78,24 @@ if(ui->cb_enableOverclock->isChecked() && ui->cb_overclockAtLaunch->isChecked()) ui->btn_applyOverclock->click(); - connectSignals(); - // timer init timer->setInterval(ui->spin_timerInterval->value()*1000); // fill tables with data at the start // refreshGpuData(); ui->list_glxinfo->addItems(device.getGLXInfo(ui->combo_gpus->currentText())); - ui->list_connectors->addTopLevelItems(device.getCardConnectors()); - ui->list_connectors->expandToDepth(2); - ui->list_modInfo->addTopLevelItems(device.getModuleInfo()); + fillConnectors(); + fillModInfo(); refreshUI(); timer->start(); + timerEvent(); + addRuntimeWidgets(); + connectSignals(); showWindow(); + qDebug() << "Initialization completed"; } radeon_profile::~radeon_profile() @@ -122,7 +123,7 @@ refreshBtn->show(); connect(refreshBtn,SIGNAL(clicked()),this,SLOT(refreshBtnClicked())); - ui->label_version->setText(format_version); + ui->label_version->setText(tr("version %n", NULL, appVersion)); // version label QLabel *l = new QLabel("v. " +QString().setNum(appVersion),this); @@ -136,16 +137,15 @@ // button on exec pages QPushButton *btnBackProfiles = new QPushButton(); - btnBackProfiles->setText(label_backToProfiles); + btnBackProfiles->setText(tr("Back to profiles")); ui->tabs_execOutputs->setCornerWidget(btnBackProfiles); btnBackProfiles->show(); connect(btnBackProfiles,SIGNAL(clicked()),this,SLOT(btnBackToProfilesClicked())); // set pwm buttons in group - QButtonGroup *pwmGroup = new QButtonGroup(); - pwmGroup->addButton(ui->btn_pwmAuto); - pwmGroup->addButton(ui->btn_pwmFixed); - pwmGroup->addButton(ui->btn_pwmProfile); + pwmGroup.addButton(ui->btn_pwmAuto); + pwmGroup.addButton(ui->btn_pwmFixed); + pwmGroup.addButton(ui->btn_pwmProfile); } // based on driverFeatures structure returned by gpu class, adjust ui elements @@ -163,6 +163,8 @@ dpmMenu->setEnabled(false); ui->combo_pLevel->setEnabled(false); ui->combo_pProfile->setEnabled(false); + ui->cb_eventsTracking->setEnabled(false); + ui->cb_eventsTracking->setChecked(false); } ui->cb_showFreqGraph->setEnabled(features.coreClockAvailable); @@ -178,36 +180,49 @@ if (!features.coreClockAvailable && !features.temperatureAvailable && !features.coreVoltAvailable) ui->mainTabs->setTabEnabled(1,false); - if (features.pwmAvailable && (globalStuff::globalConfig.rootMode || device.daemonConnected())) { + if (!features.coreClockAvailable && !features.memClockAvailable) { + ui->l_cClk->setVisible(false); + ui->l_mClk->setVisible(false); + } + + if (!features.coreVoltAvailable && !features.memVoltAvailable) { + ui->l_cVolt->setVisible(false); + ui->l_mVolt->setVisible(false); + } + + if (features.pwmAvailable && features.canChangeProfile) { qDebug() << "Fan control is available , configuring the fan control tab"; - ui->fanSpeedSlider->setMaximum(device.features.pwmMaxSpeed); - loadFanProfiles(); on_fanSpeedSlider_valueChanged(ui->fanSpeedSlider->value()); + ui->l_fanProfileUnsavedIndicator->setVisible(false); + + setupFanProfilesMenu(); + + if (ui->cb_saveFanMode->isChecked()) { + switch (ui->fanModesTabs->currentIndex()) { + case 1: + ui->btn_pwmFixed->click(); + break; + case 2: + device.getTemperature(); + ui->btn_pwmProfile->click(); + break; + } + } } else { qDebug() << "Fan control is not available"; - ui->mainTabs->setTabEnabled(2,false); + ui->mainTabs->setTabEnabled(3,false); ui->l_fanSpeed->setVisible(false); } - if (features.pm == globalStuff::DPM) { - ui->combo_pProfile->addItems(QStringList() << dpm_battery << dpm_balanced << dpm_performance); - ui->combo_pLevel->addItems(QStringList() << dpm_auto << dpm_low << dpm_high); - - ui->combo_pProfile->setCurrentIndex(ui->combo_pLevel->findText(device.currentPowerLevel)); - ui->combo_pLevel->setCurrentIndex(ui->combo_pProfile->findText(device.currentPowerLevel)); - + if (Q_LIKELY(features.pm == globalStuff::DPM)) { + ui->combo_pProfile->addItems(globalStuff::createDPMCombo()); + ui->combo_pLevel->addItems(globalStuff::createPowerLevelCombo()); } else { ui->combo_pLevel->setEnabled(false); - ui->combo_pProfile->addItems(QStringList() << profile_auto << profile_default << profile_high << profile_mid << profile_low); + ui->combo_pProfile->addItems(globalStuff::createProfileCombo()); } - // ui->mainTabs->setTabEnabled(2,features.overClockAvailable); - // Overclock is still not tested (it will be fully available only with Linux 4.7/4.8), disable it in release mode -#ifdef QT_DEBUG // TO BE REMOVED AFTER TESTING - ui->mainTabs->setTabEnabled(2,true); -#else - ui->mainTabs->setTabEnabled(2,false); -#endif + ui->mainTabs->setTabEnabled(2,features.overClockAvailable); } void radeon_profile::refreshGpuData() { @@ -218,6 +233,9 @@ if (device.features.pwmAvailable) device.getPwmSpeed(); + if (Q_LIKELY(execsRunning.count() == 0)) + return; + updateExecLogs(); } @@ -244,30 +262,30 @@ ui->list_currentGPUData->clear(); if (device.gpuClocksData.powerLevel != -1) - addChild(ui->list_currentGPUData, label_currentPowerLevel, device.gpuClocksDataString.powerLevel); + addChild(ui->list_currentGPUData, tr("Power level"), device.gpuClocksDataString.powerLevel); if (device.gpuClocksData.coreClk != -1) - addChild(ui->list_currentGPUData, label_currentGPUClock, device.gpuClocksDataString.coreClk); - if (device.gpuClocksData.coreClk != -1) - addChild(ui->list_currentGPUData, label_currentMemClock, device.gpuClocksDataString.memClk); + addChild(ui->list_currentGPUData, tr("GPU clock"), device.gpuClocksDataString.coreClk); + if (device.gpuClocksData.memClk != -1) + addChild(ui->list_currentGPUData, tr("Memory clock"), device.gpuClocksDataString.memClk); if (device.gpuClocksData.uvdCClk != -1) - addChild(ui->list_currentGPUData, label_uvdVideoCoreClock, device.gpuClocksDataString.uvdCClk); + addChild(ui->list_currentGPUData, tr("UVD core clock (cclk)"), device.gpuClocksDataString.uvdCClk); if (device.gpuClocksData.uvdDClk != -1) - addChild(ui->list_currentGPUData, label_uvdDecoderClock, device.gpuClocksDataString.uvdDClk); + addChild(ui->list_currentGPUData, tr("UVD decoder clock (dclk)"), device.gpuClocksDataString.uvdDClk); if (device.gpuClocksData.coreVolt != -1) - addChild(ui->list_currentGPUData, label_vddc, device.gpuClocksDataString.memVolt); + addChild(ui->list_currentGPUData, tr("GPU voltage (vddc)"), device.gpuClocksDataString.coreVolt); if (device.gpuClocksData.memVolt != -1) - addChild(ui->list_currentGPUData, label_vddci, device.gpuClocksDataString.coreVolt); + addChild(ui->list_currentGPUData, tr("I/O voltage (vddci)"), device.gpuClocksDataString.memVolt); if (ui->list_currentGPUData->topLevelItemCount() == 0) - addChild(ui->list_currentGPUData, label_errorReadingData, label_howToReadData); + addChild(ui->list_currentGPUData, tr("Can't read data"), tr("You need debugfs mounted and either root rights or the daemon running")); - addChild(ui->list_currentGPUData, label_currentGPUTemperature, device.gpuTemeperatureDataString.current); + addChild(ui->list_currentGPUData, tr("GPU temperature"), device.gpuTemeperatureDataString.current); } } void radeon_profile::updateExecLogs() { - for (int i = 0; i < execsRunning->count(); i++) { - if (execsRunning->at(i)->getExecState() == QProcess::Running && execsRunning->at(i)->logEnabled) { + for (int i = 0; i < execsRunning.count(); i++) { + if (execsRunning.at(i)->getExecState() == QProcess::Running && execsRunning.at(i)->logEnabled) { QString logData = QDateTime::currentDateTime().toString(logDateFormat) +";" + device.gpuClocksDataString.powerLevel + ";" + device.gpuClocksDataString.coreClk + ";"+ device.gpuClocksDataString.memClk + ";"+ @@ -276,7 +294,7 @@ device.gpuClocksDataString.coreVolt + ";"+ device.gpuClocksDataString.memVolt + ";"+ device.gpuTemeperatureDataString.current; - execsRunning->at(i)->appendToLog(logData); + execsRunning.at(i)->appendToLog(logData); } } } @@ -284,20 +302,25 @@ // === Main timer loop === // void radeon_profile::timerEvent() { if (!refreshWhenHidden->isChecked() && this->isHidden()) { + // even if in tray, keep the fan control active (if enabled) - device.getTemperature(); - adjustFanSpeed(); + if (device.features.pwmAvailable && ui->btn_pwmProfile->isChecked()) { + device.getTemperature(); + adjustFanSpeed(); + } return; } - if (ui->cb_gpuData->isChecked()) { + if (Q_LIKELY(ui->cb_gpuData->isChecked())) { refreshGpuData(); ui->combo_pProfile->setCurrentIndex(ui->combo_pProfile->findText(device.currentPowerProfile)); if (device.features.pm == globalStuff::DPM) ui->combo_pLevel->setCurrentIndex(ui->combo_pLevel->findText(device.currentPowerLevel)); - adjustFanSpeed(); + if (device.features.pwmAvailable && ui->btn_pwmProfile->isChecked()) + adjustFanSpeed(); + // lets say coreClk is essential to get stats (it is disabled in ui anyway when features.clocksAvailable is false) if (ui->cb_stats->isChecked() && device.gpuClocksData.coreClk != -1) { @@ -310,57 +333,62 @@ refreshUI(); } - if (ui->cb_graphs->isChecked()) + if (Q_LIKELY(ui->cb_graphs->isChecked())) refreshGraphs(); if (ui->cb_glxInfo->isChecked()) { ui->list_glxinfo->clear(); ui->list_glxinfo->addItems(device.getGLXInfo(ui->combo_gpus->currentText())); } - if (ui->cb_connectors->isChecked()) { - ui->list_connectors->clear(); - ui->list_connectors->addTopLevelItems(device.getCardConnectors()); - ui->list_connectors->expandToDepth(2); - } - if (ui->cb_modParams->isChecked()) { - ui->list_modInfo->clear(); - ui->list_modInfo->addTopLevelItems(device.getModuleInfo()); - } + + if (ui->cb_connectors->isChecked()) + fillConnectors(); + + if (ui->cb_modParams->isChecked()) + fillModInfo(); refreshTooltip(); + + if (ui->cb_eventsTracking->isChecked()) + checkEvents(); } -void radeon_profile::adjustFanSpeed(const bool force) -{ - // If 'force' is true skip all checks. - if (force || - // Otherwise check if PWM is available and enabled by the user and if the temperature has changed - (device.features.pwmAvailable && ui->btn_pwmProfile->isChecked() && - device.gpuTemeperatureData.current != device.gpuTemeperatureData.currentBefore)) { - - float speed; - if (fanSteps.contains(device.gpuTemeperatureData.current)) // Exact match - speed = fanSteps.value(device.gpuTemeperatureData.current); - else { - // find bounds of current temperature - const QMap::const_iterator high = fanSteps.upperBound(device.gpuTemeperatureData.current), - low = high - 1; - if(high == fanSteps.constBegin()) // Before the first step - speed = high.value(); - else if(low == fanSteps.constEnd()) // After the last step - speed = low.value(); - else // In the middle - // calculate two point stright line equation based on boundaries of current temperature - // y = mx + b = (y2-y1)/(x2-x1)*(x-x1)+y1 - speed=(float)(high.value()-low.value())/(high.key()-low.key())*(device.gpuTemeperatureData.current-low.key())+low.value(); +void radeon_profile::adjustFanSpeed() { + if (device.gpuTemeperatureData.current != device.gpuTemeperatureData.currentBefore) { + if (currentFanProfile.contains(device.gpuTemeperatureData.current)) { // Exact match + device.setPwmValue(currentFanProfile.value(device.gpuTemeperatureData.current)); + return; + } + + // find bounds of current temperature + QMap::const_iterator high = currentFanProfile.upperBound(device.gpuTemeperatureData.current); + QMap::const_iterator low = (currentFanProfile.size() > 1 ? high - 1 : high); + + int hSpeed = high.value(), + lSpeed = low.value(); + + if (high == currentFanProfile.constBegin()) { + device.setPwmValue(hSpeed); + return; + } + + if (low == currentFanProfile.constEnd()) { + device.setPwmValue(lSpeed); + return; } - qDebug() << device.gpuTemeperatureDataString.current << " -->" << speed << "%"; - if(speed >= 0 && speed <= 100) - device.setPwmValue(device.features.pwmMaxSpeed * speed / 100); + // calculate two point stright line equation based on boundaries of current temperature + // y = mx + b = (y2-y1)/(x2-x1)*(x-x1)+y1 + int hTemperature = high.key(), + lTemperature = low.key(); + + float speed = (float)(hSpeed - lSpeed) / (float)(hTemperature - lTemperature) * (device.gpuTemeperatureData.current - lTemperature) + lSpeed; + + device.setPwmValue((speed < minFanStepsSpeed) ? minFanStepsSpeed : speed); } } + void radeon_profile::refreshGraphs() { // count the tick and move graph to right ticksCounter++; @@ -416,6 +444,7 @@ else { // This power level does not exist, create it pmStats.insert(pmLevelName, 1); ui->list_stats->addTopLevelItem(new QTreeWidgetItem(QStringList() << pmLevelName)); + ui->list_stats->header()->resizeSections(QHeaderView::ResizeToContents); } } @@ -427,10 +456,11 @@ void radeon_profile::refreshTooltip() { - QString tooltipdata = radeon_profile::windowTitle() + "\nCurrent profile: "+ device.currentPowerProfile + " " + device.currentPowerLevel +"\n"; - for (short i = 0; i < ui->list_currentGPUData->topLevelItemCount(); i++) { + QString tooltipdata = radeon_profile::windowTitle() + "\n" + tr("Current profile: ")+ device.currentPowerProfile + " " + device.currentPowerLevel +"\n"; + + for (short i = 0; i < ui->list_currentGPUData->topLevelItemCount(); i++) tooltipdata += ui->list_currentGPUData->topLevelItem(i)->text(0) + ": " + ui->list_currentGPUData->topLevelItem(i)->text(1) + '\n'; - } + tooltipdata.remove(tooltipdata.length() - 1, 1); //remove empty line at bootom trayIcon->setToolTip(tooltipdata); } @@ -444,51 +474,17 @@ device.reconfigureDaemon(); } -bool radeon_profile::fanStepIsValid(const int temperature, const int fanSpeed){ - return temperature >= minFanStepsTemp && - temperature <= maxFanStepsTemp && - fanSpeed >= minFanStepsSpeed && - fanSpeed <= maxFanStepsSpeed; +bool radeon_profile::askConfirmation(const QString title, const QString question){ + return QMessageBox::Yes == + QMessageBox::question(this, title, question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); } -bool radeon_profile::addFanStep(const int temperature, - const int fanSpeed, - const bool alsoToList, - const bool alsoToGraph, - const bool alsoAdjustSpeed){ - - if (!fanStepIsValid(temperature, fanSpeed)) { - qWarning() << "Invalid value, can't be inserted into the fan step list:" << temperature << fanSpeed; - return false; - } - - qDebug() << "Adding step to fanSteps" << temperature << fanSpeed; - fanSteps.insert(temperature,fanSpeed); - - if (alsoToList){ - qDebug() << "Adding step to list_fanSteps"; - const QString temperatureString = QString::number(temperature), - speedString = QString::number(fanSpeed); - const QList existing = ui->list_fanSteps->findItems(temperatureString,Qt::MatchExactly); - - if(existing.isEmpty()){ // The element does not exist - ui->list_fanSteps->addTopLevelItem(new QTreeWidgetItem(QStringList() << temperatureString << speedString)); - ui->list_fanSteps->sortItems(0, Qt::AscendingOrder); - } else // The element exists already, overwrite it - existing.first()->setText(1,speedString); - } - - if (alsoToGraph){ - qDebug() << "Adding step to plotFanProfile"; - ui->plotFanProfile->graph(0)->removeData(temperature); - ui->plotFanProfile->graph(0)->addData(temperature, fanSpeed); - ui->plotFanProfile->replot(); - } - - if (alsoAdjustSpeed){ - qDebug() << "Adjusting fan speed"; - adjustFanSpeed(true); - } +void radeon_profile::showWindow() { + if (ui->cb_minimizeTray->isChecked() && ui->cb_startMinimized->isChecked()) + return; - return true; + if (ui->cb_startMinimized->isChecked()) + this->showMinimized(); + else + this->showNormal(); } diff -Nru radeon-profile-0.1.10~yakkety/radeon_profile.h radeon-profile-0.1.17~yakkety/radeon_profile.h --- radeon-profile-0.1.10~yakkety/radeon_profile.h 2016-06-28 14:42:31.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/radeon_profile.h 2017-01-25 18:00:54.000000000 +0000 @@ -4,6 +4,7 @@ #include "gpu.h" #include "daemonComm.h" #include "execbin.h" +#include "rpevent.h" #include #include @@ -15,6 +16,8 @@ #include #include #include +#include +#include #define startClocksScaleL 50 #define startClocksScaleH 150 @@ -24,9 +27,10 @@ #define minFanStepsTemp 0 #define maxFanStepsTemp 99 -#define minFanStepsSpeed 20 #define maxFanStepsSpeed 100 +#define appVersion 20161221 + namespace Ui { class radeon_profile; } @@ -35,7 +39,7 @@ { Q_OBJECT - // names in this enum equals indexes in Qtreewidged in ui for selecting clors + // names in this enum equals indexes in Qtreewidget in ui for selecting colors enum graphColors { TEMP_BG = 0, CLOCKS_BG, @@ -58,7 +62,6 @@ LOG_FILE_DATE_APPEND }; - public: explicit radeon_profile(QStringList, QWidget *parent = 0); ~radeon_profile(); @@ -66,8 +69,11 @@ QSystemTrayIcon *trayIcon; QAction *closeApp, *dpmSetBattery, *dpmSetBalanced, *dpmSetPerformance,*changeProfile, *refreshWhenHidden; - QMenu *dpmMenu, *trayMenu, *optionsMenu, *forcePowerMenu; + QMenu *dpmMenu, *trayMenu, *optionsMenu, *forcePowerMenu, *fanProfilesMenu; QTimer *timer; + static unsigned int minFanStepsSpeed; + + typedef QMap fanProfileSteps; private slots: void timerEvent(); @@ -134,15 +140,40 @@ void on_cb_enableOverclock_toggled(bool enable); void on_btn_applyOverclock_clicked(); void on_slider_overclock_valueChanged(int value); - void addChild(QTreeWidget * parent, const QString &leftColumn, const QString &rightColumn); + void on_btn_activateFanProfile_clicked(); + void on_btn_removeFanProfile_clicked(); + void on_btn_saveFanProfile_clicked(); + void on_btn_saveAsFanProfile_clicked(); + void fanProfileMenuActionClicked(QAction *a); + void on_btn_export_clicked(); + void on_cb_zeroPercentFanSpeed_clicked(bool checked); + void on_combo_fanProfiles_currentIndexChanged(const QString &arg1); + void on_btn_addEvent_clicked(); + void on_list_events_itemChanged(QTreeWidgetItem *item, int column); + void on_btn_eventsInfo_clicked(); + void on_btn_modifyEvent_clicked(); + void on_btn_removeEvent_clicked(); + void on_btn_revokeEvent_clicked(); + void on_list_events_itemDoubleClicked(QTreeWidgetItem *item, int column); private: + struct currentStateInfo { + globalStuff::powerProfiles profile; + globalStuff::forcePowerLevels powerLevel; + short fanIndex; + QString fanProfileName; + }; + gpu device; static const QString settingsPath; - QList *execsRunning; - QMap fanSteps; + QList execsRunning; + fanProfileSteps currentFanProfile; + QMap fanProfiles; + QMap events; QMap pmStats; - unsigned int rangeX = 180, ticksCounter = 0, statsTickCounter = 0; + unsigned int rangeX, ticksCounter, statsTickCounter; + QButtonGroup pwmGroup; + currentStateInfo *savedState; Ui::radeon_profile *ui; void setupGraphs(); @@ -164,17 +195,31 @@ void updateExecLogs(); void addRuntimeWidgets(); void loadFanProfiles(); - void saveFanProfiles(); int askNumber(const int value, const int min, const int max, const QString label); - void makeFanProfileGraph(); + void makeFanProfileListaAndGraph(const fanProfileSteps &profile); + void makeFanProfilePlot(); void refreshUI(); void connectSignals(); - - /** - * @brief adjustFanSpeed Sets the PWM fan speed indicated for the actual temperature on the fan profile. - * @param force Adjust the fan speed even if the temperature has not changed - */ - void adjustFanSpeed(bool force = false); + void setCurrentFanProfile(const QString &profileName, const fanProfileSteps &profile); + void adjustFanSpeed(); + fanProfileSteps stepsListToMap(); + void addChild(QTreeWidget * parent, const QString &leftColumn, const QString &rightColumn); + void setupFanProfilesMenu(const bool rebuildMode = false); + int findCurrentFanProfileMenuIndex(); + void setupMinFanSpeedSetting(unsigned int speed); + void markFanProfileUnsaved(bool unsaved); + void checkEvents(); + void activateEvent(const RPEvent &rpe); + void saveRpevents(QXmlStreamWriter &xml); + void loadRpevent(const QXmlStreamReader &xml); + void revokeEvent(); + void hideEventControls(bool hide); + void saveExecProfiles(QXmlStreamWriter &xml); + void loadExecProfile(const QXmlStreamReader &xml); + void saveFanProfiles(QXmlStreamWriter &xml); + void loadFanProfile(QXmlStreamReader &xml); + void createDefaultFanProfile(); + void loadExecProfiles(); /** * @brief configureDaemonAutoRefresh Reconfigures the daemon with indicated auto-refresh settings. @@ -194,19 +239,19 @@ * @param fanSpeed * @return If the step is valid. */ - bool fanStepIsValid(int temperature, int fanSpeed); + bool isFanStepValid(unsigned int temperature, unsigned int fanSpeed); /** * @brief addFanStep Adds a single fan step to the custom curve steps. * If another step with the same temperature exists already it is overwritten. * @param temperature * @param fanSpeed - * @param alsoToList Adds the step also to the ui->list_fanSteps list. - * @param alsoToGraph Adds the step also to the fan steps graph (does NOT replot). - * @param alsoAdjustSpeed Updates the fan speed after adding the step. - * @return If the operation was successful. */ - bool addFanStep (int temperature, int fanSpeed, bool alsoToList = true, bool alsoToGraph = true, bool alsoAdjustSpeed = true); + void addFanStep (int temperature, int fanSpeed); + + void fillConnectors(); + void fillModInfo(); + bool askConfirmation(const QString title, const QString question); }; #endif // RADEON_PROFILE_H diff -Nru radeon-profile-0.1.10~yakkety/radeon-profile.pro radeon-profile-0.1.17~yakkety/radeon-profile.pro --- radeon-profile-0.1.10~yakkety/radeon-profile.pro 2016-06-28 14:53:06.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/radeon-profile.pro 2017-01-25 23:10:02.000000000 +0000 @@ -11,11 +11,22 @@ TARGET = radeon-profile TEMPLATE = app +QMAKE_CXXFLAGS += -std=c++0x + # https://forum.qt.io/topic/10178/solved-qdebug-and-debug-release/2 # http://doc.qt.io/qt-5/qtglobal.html#QtMsgType-enum # qDebug will work only when compiled for Debug # QtWarning, QtCritical and QtFatal will still work on Release -CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG_OUTPUT +CONFIG(release, debug|release){ + message('Building for release') + DEFINES += QT_NO_DEBUG_OUTPUT NO_IOCTL +} else { + message('Building for debug') + QMAKE_CXXFLAGS += -Wall -Wextra -Wpedantic +} + +### Flag for Ubuntu trusty +#QMAKE_CXXFLAGS += -std=c++11 SOURCES += main.cpp\ radeon_profile.cpp \ @@ -28,7 +39,13 @@ settings.cpp \ daemonComm.cpp \ execTab.cpp \ - execbin.cpp + execbin.cpp \ + dialog_rpevent.cpp \ + eventsTab.cpp \ + fanControlTab.cpp \ + ioctlHandler.cpp \ + ioctl_radeon.cpp \ + ioctl_amdgpu.cpp HEADERS += radeon_profile.h \ qcustomplot.h \ @@ -37,9 +54,13 @@ dfglrx.h \ globalStuff.h \ daemonComm.h \ - execbin.h + execbin.h \ + dialog_rpevent.h \ + rpevent.h \ + ioctlHandler.hpp -FORMS += radeon_profile.ui +FORMS += radeon_profile.ui \ + dialog_rpevent.ui RESOURCES += \ radeon-resource.qrc @@ -57,8 +78,11 @@ # When the translations are ready it is necessary to run "lrelease" in this folder (QtCreator: Tools > External > Linguist > Release) # This produces compiled translation files (strings.*.qm), that need to be packaged together with the runnable # These can be placed in "/usr/share/radeon-profile/" or in the same folder of the binary (useful for development) -TRANSLATIONS += strings.hr.ts -TRANSLATIONS += strings.it.ts - -DISTFILES += strings.hr.ts -DISTFILES += strings.it.ts +TRANSLATIONS += translations/strings.it.ts \ + translations/strings.pl.ts \ + translations/strings.hr.ts + +DISTFILES += \ + translations/strings.it.ts \ + translations/strings.pl.ts \ + translations/strings.hr.ts diff -Nru radeon-profile-0.1.10~yakkety/radeon_profile.ui radeon-profile-0.1.17~yakkety/radeon_profile.ui --- radeon-profile-0.1.10~yakkety/radeon_profile.ui 2016-06-28 14:42:31.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/radeon_profile.ui 2017-01-25 18:00:11.000000000 +0000 @@ -157,230 +157,210 @@ Power level - - - - 530 - 0 - 70 - 50 - - - - - 40 - 40 - - - - - 90 - 50 - - - - - Monospace - 20 - - - - Fan speed - - - 999% - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 410 - 0 - 100 - 50 - - - - - 40 - 40 - - - - - 120 - 50 - - - - - Monospace - 20 - - - - GPU temperature - - - 99.9°C - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 260 - 0 - 60 - 25 - - - - - 40 - 20 - - - - - 70 - 25 - - - - - Monospace - 10 - - - - GPU clock - - - 9999MHz - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - + 260 - 25 - 60 - 25 - - - - - 40 - 20 - - - - - 70 - 25 - - - - - Monospace - 10 - - - - Memory clock - - - 9999MHz - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 340 0 - 50 - 25 + 561 + 51 - - - 40 - 20 - - - - - 80 - 25 - - - - - Monospace - 10 - - - - GPU voltage - - - 1 - - - 9999mV - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 340 - 25 - 50 - 25 - - - - - 40 - 20 - - - - - 60 - 25 - - - - - Monospace - 10 - - - - I/O voltage - - - 9999mV - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + + + 20 + + + 2 + + + + + + Monospace + 20 + + + + 999% + + + true + + + + + + + + 40 + 20 + + + + + 60 + 25 + + + + + Monospace + 10 + + + + I/O voltage + + + 9999mV + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 40 + 20 + + + + + 70 + 25 + + + + + Monospace + 10 + + + + Memory clock + + + 9999MHz + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 40 + 20 + + + + + 80 + 25 + + + + + Monospace + 10 + + + + GPU voltage + + + 1 + + + 9999mV + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 40 + 40 + + + + + 120 + 50 + + + + + Monospace + 20 + + + + GPU temperature + + + 99.9°C + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 40 + 20 + + + + + 70 + 25 + + + + + Monospace + 10 + + + + GPU clock + + + 9999MHz + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + @@ -399,7 +379,7 @@ QTabWidget::South - 3 + 0 @@ -413,16 +393,16 @@ QLayout::SetDefaultConstraint - 3 + 4 - 3 + 4 - 3 + 4 - 3 + 4 @@ -892,16 +872,16 @@ - 5 + 4 - 5 + 4 - 5 + 4 - 5 + 4 4 @@ -1028,6 +1008,13 @@ + + + + Export + + + @@ -1135,6 +1122,18 @@ Overclock + + 4 + + + 4 + + + 4 + + + 4 + @@ -1323,6 +1322,18 @@ Fan Control + + 4 + + + 4 + + + 4 + + + 4 + @@ -1418,6 +1429,12 @@ + + + 0 + 0 + + 0 @@ -1426,7 +1443,7 @@ - 190 + 230 70 161 27 @@ -1441,84 +1458,314 @@ 10 20 - 561 + 581 41 - + Monospace - 8 + 10 - 20% + 10% - 51 + 10 - 255 + 100 + + + 20 + + + Qt::Horizontal + + + false + + + QSlider::TicksBothSides + + + 5 + + + + + + + + Monospace + 10 + + + + 20% + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 3 + + + + + + 241 + 101 + + + + + 261 + 101 + + + + + + 0 + 30 + 171 + 22 + + + + + + + 180 + 30 + 81 + 21 + + + + Activate + + + + + + 0 + 0 + 91 + 21 + + + + Current profile: + + + + + + 80 + 0 + 181 + 21 + + + + + 75 + true + false + + + + + + + Qt::AlignCenter + + + + + + 0 + 57 + 111 + 21 + + + + Save - - 80 + + + + + 0 + 80 + 111 + 21 + - - Qt::Horizontal + + Save as - - - - - - Monospace - 8 - + + + + 140 + 80 + 121 + 21 + - 20% + Remove profile - - - + + + + 150 + 50 + 111 + 31 + + + + + + + + + 170 + 0 + 0 + + + + + + + + + 170 + 0 + 0 + + + + + + + + + 164 + 166 + 168 + + + + + + - Monospace 8 + 75 + true - / 100% + Unsaved + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - QLayout::SetDefaultConstraint + + + + + + + 0 + 0 + - - - + + + 300 + 0 + + + + + + + + + + + 0 + 0 + + + + + 101 + 21 + + + + Add step + + + + + + + + 0 + 0 + + + - 211 - 16777215 + 101 + 21 + + Remove step + + + + + 2 @@ -1534,82 +1781,177 @@ - - - - - - - 101 - 27 - - - - - 101 - 27 - - - - Add step - - - - - - - - 101 - 27 - - - - - 101 - 27 - - - - Remove step - - - - - - - - - - 300 - 0 - - - - + + + Events + + + + 4 + + + 4 + + + 4 + + + 4 + + + + + + + Enable event tracking + + + + + + + Qt::Horizontal + + + + 40 + 30 + + + + + + + + Current active event: + + + + + + + + 75 + true + + + + + + + + + + + Revoke current event + + + + + + + + + QAbstractItemView::NoEditTriggers + + + false + + + QAbstractItemView::SingleSelection + + + 20 + + + false + + + false + + + + Enabled + + + + + Event name + + + + + + + + + + Add + + + + + + + Modify + + + + + + + Remove + + + + + + + Qt::Horizontal + + + + 40 + 30 + + + + + + + + Info + + + + + + + Exec - 2 + 4 - 2 + 4 - 2 + 4 - 2 + 4 @@ -2871,16 +3213,16 @@ - 3 + 4 - 3 + 4 - 3 + 4 - 3 + 4 @@ -2888,7 +3230,7 @@ QTabWidget::West - 2 + 0 @@ -3146,7 +3488,7 @@ 210 - 120 + 170 91 24 @@ -3166,7 +3508,7 @@ 10 - 120 + 170 181 21 @@ -3179,7 +3521,7 @@ 10 - 142 + 192 291 21 @@ -3191,6 +3533,32 @@ true + + + + 10 + 110 + 301 + 20 + + + + Save selected fan control mode + + + + + + 10 + 130 + 291 + 16 + + + + Enable 0% fan speed + + @@ -3342,7 +3710,7 @@ 10 40 - 141 + 211 27 @@ -3358,11 +3726,23 @@ - + About + + 4 + + + 4 + + + 4 + + + 4 + diff -Nru radeon-profile-0.1.10~yakkety/rpevent.h radeon-profile-0.1.17~yakkety/rpevent.h --- radeon-profile-0.1.10~yakkety/rpevent.h 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/rpevent.h 2017-01-25 18:00:11.000000000 +0000 @@ -0,0 +1,45 @@ +#ifndef EVENT_H +#define EVENT_H + +#include "globalStuff.h" + +enum rpeventType { + TEMPEREATURE, BIANRY +}; + +struct checkInfoStruct { + unsigned short checkTemperature; +}; + +class RPEvent { +public: + + RPEvent() { } + + bool enabled; + QString name, activationBinary, fanProfileNameChange; + globalStuff::powerProfiles dpmProfileChange; + globalStuff::forcePowerLevels powerLevelChange; + unsigned short fixedFanSpeedChange, activationTemperature, fanComboIndex; + rpeventType type; + + bool isActivationConditonFulfilled(const checkInfoStruct &check) { + switch (type) { + case rpeventType::TEMPEREATURE: + return activationTemperature < check.checkTemperature; + break; + case rpeventType::BIANRY: + return !globalStuff::grabSystemInfo("pidof \""+activationBinary+"\"")[0].isEmpty(); + break; + } + + return false; + } + + template + T getEnumFromCombo(const unsigned int comboIndex) { + return static_cast(comboIndex - 1); + } +}; + +#endif // EVENT_H diff -Nru radeon-profile-0.1.10~yakkety/settings.cpp radeon-profile-0.1.17~yakkety/settings.cpp --- radeon-profile-0.1.10~yakkety/settings.cpp 2016-06-28 14:42:31.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/settings.cpp 2017-01-25 18:00:11.000000000 +0000 @@ -12,8 +12,7 @@ #include const QString radeon_profile::settingsPath = QDir::homePath() + "/.radeon-profile-settings"; -const QString execProfilesPath = QDir::homePath() + "/.radeon-profile-execProfiles"; -const QString fanStepsPath = QDir::homePath() + "/.radeon-profile-fanSteps"; +const QString auxStuffPath = QDir::homePath() + "/.radeon-profile-auxstuff"; // init of static struct with setting exposed to global scope globalStuff::globalCfgStruct globalStuff::globalConfig; @@ -40,6 +39,10 @@ settings.setValue("graphRange",ui->timeSlider->value()); settings.setValue("daemonAutoRefresh",ui->cb_daemonAutoRefresh->isChecked()); settings.setValue("fanSpeedSlider",ui->fanSpeedSlider->value()); + settings.setValue("saveSelectedFanMode",ui->cb_saveFanMode->isChecked()); + settings.setValue("fanMode",ui->fanModesTabs->currentIndex()); + settings.setValue("fanProfileName",ui->l_currentFanProfile->text()); + settings.setValue("enableZeroPercentFanSpeed", ui->cb_zeroPercentFanSpeed->isChecked()); settings.setValue("overclockEnabled", ui->cb_enableOverclock->isChecked()); settings.setValue("overclockAtLaunch", ui->cb_overclockAtLaunch->isChecked()); @@ -63,24 +66,89 @@ settings.setValue("showVoltsGraphOnStart",ui->cb_showVoltsGraph->isChecked()); settings.setValue("execDbcAction",ui->cb_execDbcAction->currentIndex()); settings.setValue("appendSysEnv",ui->cb_execSysEnv->isChecked()); + settings.setValue("eventsTracking", ui->cb_eventsTracking->isChecked()); - // save profiles from Exec tab - QFile ef(execProfilesPath); - if (ef.open(QIODevice::WriteOnly)) { - for (int i = 0; i < ui->list_execProfiles->topLevelItemCount(); i++) { - QString profile = ui->list_execProfiles->topLevelItem(i)->text(PROFILE_NAME) + "###" + - ui->list_execProfiles->topLevelItem(i)->text(BINARY) + "###" + - ui->list_execProfiles->topLevelItem(i)->text(BINARY_PARAMS) + "###" + - ui->list_execProfiles->topLevelItem(i)->text(ENV_SETTINGS) + "###" + - ui->list_execProfiles->topLevelItem(i)->text(LOG_FILE) + "###" + - ui->list_execProfiles->topLevelItem(i)->text(LOG_FILE_DATE_APPEND) + "\n"; - ef.write(profile.toLatin1()); + QString xmlString; + QXmlStreamWriter xml(&xmlString); + xml.setAutoFormatting(true); + xml.writeStartDocument(); + xml.writeStartElement("auxStuff"); + + saveRpevents(xml); + saveExecProfiles(xml); + saveFanProfiles(xml); + + xml.writeEndElement(); + xml.writeEndDocument(); + + QFile f(auxStuffPath); + if (f.open(QIODevice::WriteOnly)) { + f.write(xmlString.toLatin1()); + f.close(); + } +} + +void radeon_profile::saveRpevents(QXmlStreamWriter &xml) { + xml.writeStartElement("RPEvents"); + + for (RPEvent rpe : events) { + xml.writeStartElement("rpevent"); + xml.writeAttribute("name", rpe.name); + xml.writeAttribute("enabled", QString::number(rpe.enabled)); + xml.writeAttribute("tiggerType", QString::number(rpe.type)); + xml.writeAttribute("activationBinary", rpe.activationBinary); + xml.writeAttribute("activationTemperature", QString::number(rpe.activationTemperature)); + xml.writeAttribute("dpmProfileChange", QString::number(rpe.dpmProfileChange)); + xml.writeAttribute("powerLevelChange", QString::number(rpe.powerLevelChange)); + xml.writeAttribute("fixedFanSpeedChange", QString::number(rpe.fixedFanSpeedChange)); + xml.writeAttribute("fanProfileNameChange",rpe.fanProfileNameChange); + xml.writeAttribute("fanComboIndex", QString::number(rpe.fanComboIndex)); + xml.writeEndElement(); + } + + xml.writeEndElement(); +} + +void radeon_profile::saveExecProfiles(QXmlStreamWriter &xml) { + xml.writeStartElement("ExecProfiles"); + + for (int i = 0; i < ui->list_execProfiles->topLevelItemCount(); ++i) { + xml.writeStartElement("execProfile"); + xml.writeAttribute("name", ui->list_execProfiles->topLevelItem(i)->text(PROFILE_NAME)); + xml.writeAttribute("binary", ui->list_execProfiles->topLevelItem(i)->text(BINARY)); + xml.writeAttribute("binaryParams",ui->list_execProfiles->topLevelItem(i)->text(BINARY_PARAMS) ); + xml.writeAttribute("envSettings", ui->list_execProfiles->topLevelItem(i)->text(ENV_SETTINGS)); + xml.writeAttribute("logFile", ui->list_execProfiles->topLevelItem(i)->text(LOG_FILE)); + xml.writeAttribute("logFileDateAppend", ui->list_execProfiles->topLevelItem(i)->text(LOG_FILE_DATE_APPEND)); + xml.writeEndElement(); + } + + xml.writeEndElement(); +} + +void radeon_profile::saveFanProfiles(QXmlStreamWriter &xml) { + xml.writeStartElement("FanProfiles"); + + for (QString k : fanProfiles.keys()) { + xml.writeStartElement("fanProfile"); + xml.writeAttribute("name", k); + + fanProfileSteps fps = fanProfiles.value(k); + + for (auto ks : fps.keys()) { + xml.writeStartElement("step"); + xml.writeAttribute("temperature", QString::number(ks)); + xml.writeAttribute("speed", QString::number(fps.value(ks))); + xml.writeEndElement(); } - ef.close(); + xml.writeEndElement(); } + xml.writeEndElement(); } + + void radeon_profile::loadConfig() { QSettings settings(radeon_profile::settingsPath,QSettings::IniFormat); @@ -98,7 +166,12 @@ ui->cb_alternateRow->setChecked(settings.value("aleternateRowColors",true).toBool()); ui->cb_daemonAutoRefresh->setChecked(settings.value("daemonAutoRefresh",true).toBool()); ui->cb_execDbcAction->setCurrentIndex(settings.value("execDbcAction",0).toInt()); - ui->fanSpeedSlider->setValue(settings.value("fanSpeedSlider",80).toInt()); + ui->fanSpeedSlider->setValue(settings.value("fanSpeedSlider",20).toInt()); + ui->cb_saveFanMode->setChecked(settings.value("saveSelectedFanMode",false).toBool()); + ui->l_currentFanProfile->setText(settings.value("fanProfileName","default").toString()); + ui->cb_zeroPercentFanSpeed->setChecked(settings.value("enableZeroPercentFanSpeed",false).toBool()); + if (ui->cb_saveFanMode->isChecked()) + ui->fanModesTabs->setCurrentIndex(settings.value("fanMode",0).toInt()); optionsMenu->actions().at(0)->setChecked(settings.value("showLegend",true).toBool()); optionsMenu->actions().at(1)->setChecked(settings.value("graphOffset",true).toBool()); @@ -123,6 +196,7 @@ ui->cb_showFreqGraph->setChecked(settings.value("showFreqGraphOnStart",true).toBool()); ui->cb_showVoltsGraph->setChecked(settings.value("showVoltsGraphOnStart",false).toBool()); ui->cb_execSysEnv->setChecked(settings.value("appendSysEnv",true).toBool()); + ui->cb_eventsTracking->setChecked(settings.value("eventsTracking", false).toBool()); ui->cb_enableOverclock->setChecked(settings.value("overclockEnabled",false).toBool()); ui->cb_overclockAtLaunch->setChecked(settings.value("overclockAtLaunch",false).toBool()); @@ -156,6 +230,9 @@ else ui->mainTabs->setTabEnabled(1,false); + if (ui->cb_zeroPercentFanSpeed->isChecked()) + setupMinFanSpeedSetting(0); + ui->list_currentGPUData->setAlternatingRowColors(ui->cb_alternateRow->isChecked()); ui->list_glxinfo->setAlternatingRowColors(ui->cb_alternateRow->isChecked()); ui->list_modInfo->setAlternatingRowColors(ui->cb_alternateRow->isChecked()); @@ -171,71 +248,149 @@ on_cb_showFreqGraph_clicked(ui->cb_showFreqGraph->isChecked()); on_cb_showVoltsGraph_clicked(ui->cb_showVoltsGraph->isChecked()); + hideEventControls(true); + globalStuff::globalConfig.interval = ui->spin_timerInterval->value(); globalStuff::globalConfig.daemonAutoRefresh = ui->cb_daemonAutoRefresh->isChecked(); globalStuff::globalConfig.graphOffset = ((optionsMenu->actions().at(1)->isChecked()) ? 20 : 0); - QFile ef(execProfilesPath); - if (ef.open(QIODevice::ReadOnly)) { - QStringList profiles = QString(ef.readAll()).split('\n'); - for (int i=0;i list_execProfiles->addTopLevelItem(new QTreeWidgetItem(QStringList() << profiles[i].split("###"))); + QFile f(auxStuffPath); + if (f.open(QIODevice::ReadOnly)) { + QXmlStreamReader xml(&f); + while (!xml.atEnd()) { + + if (xml.readNextStartElement()) { + if (xml.name().toString() == "rpevent") { + loadRpevent(xml); + continue; + } + + if (xml.name().toString() == "execProfile") { + loadExecProfile(xml); + continue; + } + + if (xml.name().toString() == "fanProfile") { + loadFanProfile(xml); + continue; + } + } } + f.close(); + } + + // legacy load + loadExecProfiles(); + + // legacy load + loadFanProfiles(); + + // create default if empty + if (ui->combo_fanProfiles->count() == 0) + createDefaultFanProfile(); + + makeFanProfileListaAndGraph(fanProfiles.value(ui->combo_fanProfiles->currentText())); +} + +void radeon_profile::loadRpevent(const QXmlStreamReader &xml) { + RPEvent rpe; + rpe.name = xml.attributes().value("name").toString(); + rpe.enabled = (xml.attributes().value("enabled") == "1"); + rpe.type = static_cast(xml.attributes().value("tiggerType").toString().toInt()); + rpe.activationBinary = xml.attributes().value("activationBinary").toString(); + rpe.activationTemperature = xml.attributes().value("activationTemperature").toString().toInt(); + rpe.dpmProfileChange = static_cast(xml.attributes().value("dpmProfileChange").toString().toInt()); + rpe.powerLevelChange = static_cast(xml.attributes().value("powerLevelChange").toString().toInt()); + rpe.fixedFanSpeedChange = xml.attributes().value("fixedFanSpeedChange").toString().toInt(); + rpe.fanProfileNameChange = xml.attributes().value("fanProfileNameChange").toString(); + rpe.fanComboIndex = xml.attributes().value("fanComboIndex").toString().toInt(); + + events.insert(rpe.name, rpe); + + QTreeWidgetItem *item = new QTreeWidgetItem(); + item->setText(1, rpe.name); + item->setCheckState(0,(rpe.enabled) ? Qt::Checked : Qt::Unchecked); + ui->list_events->addTopLevelItem(item); +} + +void radeon_profile::loadExecProfile(const QXmlStreamReader &xml) { + QTreeWidgetItem *item = new QTreeWidgetItem(); + + item->setText(PROFILE_NAME, xml.attributes().value("name").toString()); + item->setText(BINARY,xml.attributes().value("binary").toString()); + item->setText(BINARY_PARAMS, xml.attributes().value("binaryParams").toString()); + item->setText(ENV_SETTINGS, xml.attributes().value("envSettings").toString()); + item->setText(LOG_FILE, xml.attributes().value("logFile").toString()); + item->setText(LOG_FILE_DATE_APPEND, xml.attributes().value("logFileDateAppend").toString()); + + ui->list_execProfiles->addTopLevelItem(item); +} + +void radeon_profile::loadFanProfile(QXmlStreamReader &xml) { + QString fpName = xml.attributes().value("name").toString(); + + fanProfileSteps fps; + while (xml.readNext()) { + if (xml.name().toString() == "step") + fps.insert(xml.attributes().value("temperature").toString().toInt(), + xml.attributes().value("speed").toString().toInt()); + + if (xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == "fanProfile") { + fanProfiles.insert(fpName, fps); + ui->combo_fanProfiles->addItem(fpName); + return; + } } } +// legacy load fan profiles void radeon_profile::loadFanProfiles() { - QFile fsPath(fanStepsPath); - if (fsPath.open(QIODevice::ReadOnly)) { - QString profile = QString(fsPath.readAll()); - - QStringList steps = profile.split("|",QString::SkipEmptyParts); - - if (steps.count() > 1) { - for (int i = 1; i < steps.count(); ++i) { - QStringList pair = steps[i].split("#"); - addFanStep(pair[0].toInt(),pair[1].toInt(), true, true, false); - } + QFile fsPath(QDir::homePath() + "/.radeon-profile-fanSteps"); - fsPath.close(); - } - } else { - //default profile if no file found - addFanStep(0,20,true, true, false); - addFanStep(65,100,true, true, false); - addFanStep(90,100, true, true, false); + if (fsPath.open(QIODevice::ReadOnly) && ui->combo_fanProfiles->count() == 0) { + QStringList profiles = QString(fsPath.readAll()).trimmed().split('\n',QString::SkipEmptyParts); - } + for (QString profileLine : profiles) { + QStringList profileData = profileLine.split("|",QString::SkipEmptyParts); -} + fanProfileSteps p; -void radeon_profile::makeFanProfileGraph() { - ui->plotFanProfile->graph(0)->clearData(); + for (int i = 1; i < profileData.count(); ++i) { + QStringList pair = profileData[i].split("#"); + p.insert(pair[0].toInt(),pair[1].toInt()); + } - for (int temperature : fanSteps.keys()) - ui->plotFanProfile->graph(0)->addData(temperature, fanSteps.value(temperature)); - ui->plotFanProfile->replot(); + ui->combo_fanProfiles->addItem(profileData[0]); + fanProfiles.insert(profileData[0], p); + } + // remove old file + fsPath.remove(); + fsPath.close(); + } } -void radeon_profile::saveFanProfiles() { - QFile fsPath(fanStepsPath); - if (fsPath.open(QIODevice::WriteOnly)) { - QString profile = "default|"; - for (int temperature : fanSteps.keys()) - profile.append(QString::number(temperature)+ "#" + QString::number(fanSteps.value(temperature)) + "|"); +// legacy load +void radeon_profile::loadExecProfiles() +{ + QFile ef(QDir::homePath() + "/.radeon-profile-execProfiles"); + if (ef.open(QIODevice::ReadOnly) && ui->list_execProfiles->topLevelItemCount() == 0) { + QStringList profiles = QString(ef.readAll()).split('\n'); - fsPath.write(profile.toLatin1()); - fsPath.close(); + for (int i=0;i < profiles.count(); i++) { + if (!profiles[i].isEmpty()) + ui->list_execProfiles->addTopLevelItem(new QTreeWidgetItem(QStringList() << profiles[i].split("###"))); + } + // remove old file + ef.remove(); + ef.close(); } } -void radeon_profile::showWindow() { - if (ui->cb_startMinimized->isChecked()) - this->showMinimized(); - else - this->showNormal(); +void radeon_profile::setupMinFanSpeedSetting(unsigned int speed) { + minFanStepsSpeed = speed; + ui->l_minFanSpeed->setText(QString::number(minFanStepsSpeed)+"%"); + ui->fanSpeedSlider->setMinimum(minFanStepsSpeed); } diff -Nru radeon-profile-0.1.10~yakkety/strings.hr.ts radeon-profile-0.1.17~yakkety/strings.hr.ts --- radeon-profile-0.1.10~yakkety/strings.hr.ts 2016-06-28 14:52:24.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/strings.hr.ts 1970-01-01 00:00:00.000000000 +0000 @@ -1,1177 +0,0 @@ - - - - - QObject - - - Resolution - Razlučivost - - - - Minimum resolution - Najmanja razlučivost - - - - Maximum resolution - Najveća razlučivost - - - - Power level - Razina energije - - - - GPU clock - GPU frekvencija - - - - Memory clock - Frekvencija memorije - - - - UVD core clock (cclk) - UVD frekvencija jezgre (cclk) - - - - UVD decoder clock (dclk) - UVD frekvencija dekôdera (dclk) - - - - GPU voltage (vddc) - GPU napon (vddc) - - - - I/O voltage (vddci) - I/O napon (vddci) - - - - GPU temperature - GPU temperatura - - - - No info - Nema informacija - - - - Back to profiles - Natrag na profile - - - - Can't read data - Nemoguće čitanje podataka - - - - You need debugfs mounted and either root rights or the daemon running - Trebate imati debugfs montiran i ili korijenske ovlasti ili pokrenut pozadinski program - - - - Error - Greška - - - - Profile name can't be empty! - Naziv profila ne može biti prazan! - - - - No binary is selected! - Nema odabrane binarne datoteke! - - - - Binary not found in /usr/bin: - Binarna datoteka nije pronađena u /usr/bin: - - - - Enter value - Upiši vrijednost - - - - Enter valid value for - Upiši valjanu vrijednost za - - - - Question - Pitanje - - - - Remove - Ukloni - - - - Remove this item? - Ukloni ovu stavku? - - - - Select binary - Odaberi binarnu datoteku - - - - Select log file - Odaberi datoteku zapisa - - - - Can't run something that not exists! - Ne mogu pokrenti nešto što ne postoji! - - - - Run - Pokreni - - - - Run: " - Pokreni: " - - - - "? - "? - - - - Unknown - Nepoznato - - - - Virtual size - Virtualna dimenzija - - - - Outputs - Izlazi - - - - Active - Aktivno - - - - Hz vertical, - Hz okomito, - - - - KHz horizontal, - KHz vodoravno, - - - - MHz dot clock - MHz frekvenicja točke - - - - Yes - Da - - - - No - Ne - - - - Refresh rate - Frekvencija osvježavanja - - - - Offset - Pomak - - - - Brightness (software) - Svjetlina (softver) - - - - Size - Dimenzija - - - - Supported modes - Podržani načini - - - - Properties - Svojstva - - - - Serial number - Serijski broj - - - - Not available - Nedostupno - - - - Connected with - Povezano s - - - - Temperature - Temperatura - - - - Fan speed - Brzina ventilatora - - - - Disconnected - Nije povezano - - - - Time (s) - Vrijeme (s) - - - - Temperature (°C) - Temperature (°C) - Temperatura (°C) - - - - Clock (MHz) - Frekvencija (MHz) - - - - Voltage (mV) - Napon (mV) - - - - DPM - DPM - - - - Change standard profile - Promijeni standardni profil - - - - Quit - Zatvori - - - - Keep refreshing when hidden - Nastavi osvježavati dok je skriveno - - - - Battery - Baterija - - - - Balanced - Uravnoteženo - - - - Performance - Performanse - - - - Reset min/max temperature - Vrati zadanu min/maks temperaturu - - - - Reset graphs vertical scale - Vrati zadane grafikone okomite promjene veličine - - - - Show legend - Prikaži legendu - - - - Graph offset on right - Pomak grafikona ulijevo - - - - Auto - Automatski - - - - Low - Nisko - - - - High - Visoko - - - - Force power level - Profil energije - - - - Copy to clipboard - Kopiraj u međuspremnik - - - - Reset statistics - Vrati zadanu statistiku - - - - GPU data is disabled - GPU podaci su onemogućeni - - - - Fan control information - Informacije upravljanja ventilatorom - - - - Don't overheat your card! Be careful! Don't use this if you don't know what you're doing! - -Hovewer, looks like card won't apply too low values due its internal protection. - -Closing application will restore fan control to Auto. If application crashes, last fan value will remain, so you have been warned! - Nemojte pregrijati svoju grafičku karticu! Budite oprezni! Ne koristite ovo ako ne znate što radite! - -Ipak, izgleda da grafička kartica neće primijeniti premale vrijednosti zbog njene unutrašnje zaštite. - -Zatvaranje aplikacije će vratiti automatsko upravljanje ventilatorom. Ako se aplikacija sruši, zadnja vrijednost ventilatora će preostati, stoga ste upozoreni! - - - - Speed [%] (20-100) - Brzina [%] (20-100) - - - - Select new power profile - Odaberi novi profil energije - - - - Profile selection - Odabir profila - - - - This step already exists. To edit it double click it - Ovaj korak već postoji. Kako bi ga uredili dvostruko kliknite - - - - You can't delete the first and the last item - Ne možete obrisati prvu i zadnju stavku - - - - You can't edit the first and the last item - Ne možete urediti prvu i zadnju stavku - - - - An error occurred, overclock failed - Dogodila se greška, overklokiranje neuspjelo - - - - Process state: running - Stanje procesa: pokrenuto - - - - version %n - inačica %n - - - - Process is still running. Close tab? - Proces je još uvijek pokrenut. Zatvori karticu? - - - - Process state: not running - Stanje procesa: nije pokrenuto - - - - Save output to file - Spremi izlaz u datoteku - - - - Command - Naredba - - - - Output - Izlaz - - - - Save - Spremi - - - - %n mm - %n mm - - - - %n mm - %n mm - - - - (%n inches) - (%n inča) - - - - - %n mm x - %n mm x - - - - %n connected, - %n povezana, - - - - %n active - %n aktivna - - - - Virtual screen n°%n - Virtual screen n°%n - Virtualni zalon n°%n - - - - radeon_profile - - - - Radeon Profile - Radeon profil - - - - GPU temperature - GPU temperatura - - - - GPU clock - GPU frekvencija - - - - Fan speed - Brzina ventilatora - - - - GPU - GPU - - - - Memory clock - Frekvencija memorije - - - - GPU voltage - GPU napon - - - - I/O voltage - I/O napon - - - - GPU Summary - GPU sažetak - - - - - Property - Svojstva - - - - - Value - Vrijednosti - - - - Profiles - Profili - - - - Change profile - Promijeni profil - - - - DPM - DPM - - - - - Auto - Automatski - - - - Battery - Baterija - - - - Balanced - Uravnoteženo - - - - Performance - Performanse - - - - Low - Nisko - - - - High - Visoko - - - - GLX info - GLX informacije - - - - - Connectors - Priključci - - - - Connector - Priključak - - - - Status - Stanje - - - - Module info - Informacije modula - - - - Option - Mogućnosti - - - - Description - Opis - - - - Stats - Statistika - - - - - Power level - Razine energije - - - - Selected GPU - Odabrani GPU - - - - Power profile - Profil energije - - - - 999% - 999% - - - - 99.9°C - 99.9°C - - - - - 9999MHz - 9999MHz - - - - - 9999mV - 9999mV - - - - Time - Vrijeme - - - - - - Graphs - Grafikoni - - - - Reset min max temps and graphs scale - Vrati na početno min/maks promjene temperatura i grafikona - - - - Options - Mogućnosti - - - - Clocks graph - Grafikon frekvencije - - - - Volts graph - Grafikon napona - - - - Temperature graph - Grafikon temperature - - - - 1h - 1h - - - - 30s - 30s - - - - temps label - Temperatura - - - - Fan Control - Upravljanje ventilatorom - - - - Fixed - Nepromjenjivo - - - - Custom curve - Prilagođena krivulja - - - - Info - Informacije - - - - - Apply - Primijeni - - - - Overclock - Overklokiranje - - - - Be careful! Overclock can harm your GPU, use it only if you know what you are doing! - Be careful! Overclock can harm your GPU, use it at your own risk! - Budite oprezni! Overklokiranje može oštetiti vaš GPU, koristite samo ako znate što radite! - - - - Enable overclock - Omogući overklokiranje - - - - Apply at launch - Apply on startup - Primijeni pri pokretanju - - - - - 20% - 20% - - - - / 100% - / 100% - - - - Temperature - Temperatura - - - - Fan Speed [%] - Brzina ventilatora [%] - - - - Add step - Dodaj korak - - - - Remove step - Ukloni korak - - - - Exec - Binarna datoteka - - - - Warning! Unrecommended root mode! - Upozorenje! Nepreporučen korijenski način! - - - - Name - Naziv - - - - Binary - Binarna datoteka - - - - Params - Parametri - - - - Setting - Postavke - - - - Log file - Datoteka zapisa - - - - Append date-time - Dodaj datum i vrijeme - - - - Add - Dodaj - - - - Modify - Promijeni - - - - Remove - Ukloni - - - - View output - Prikaz izlaza - - - - - Run - Pokretanje - - - - Name: - Naziv: - - - - Binary: - Binarna datoteka: - - - - - ... - ... - - - - Binary parameters: - Parametri binarne datoteke: - - - - Log file: (leave empty if don't want it) - Datoteka zapisa: (ostavite prazno ako vam nije potrebno) - - - - Append date and time - Dodaj datum i vrijeme - - - - Variables: - Varijable: - - - - Values: - Vrijednosti: - - - - Summary: - Sažetak: - - - - Be careful, remember to save one space between variables. - Budite oprezni, ostavljajte samo jedan razmak između varijabli. - - - - Tune variables manually - Prilagodi varijable ručno - - - - Proceed with caution now. - Sada nastavite s oprezom. - - - - Cancel - Odustani - - - - OK - U redu - - - - Configuration - Podešavanje - - - - Main - Općenito - - - - Start minimized - Pokreni smanjeno - - - - Minimize to tray - Smanji u traku sustava - - - - On close hide to tray - Pri zatvaranju sakrij u traku sustava - - - - Save window geometry - Spremi geometriju prozora - - - - Alternate row colors on lists - Dvobojne boje redaka na popisu - - - - Refresh interval [s] - Razdoblje osvježavanja [s] - - - - Update: - Osvježavaj: - - - - GPU data, power profile, temperature - GPU podatke, profile, temperature - - - - Power levels statistics - Statistiku profila energije - - - - GLX Info - GLX informacije - - - - Module parameters - Parametre modula - - - - Edit - Uređivanje - - - - Double click action on exec item - Dvostruki klik na izvršne datoteke za - - - - Explicit append system env to exec command - Izričito dodaj env sustava exec naredbi - - - - Line thickness: - Debljina linije: - - - - Color - Boja - - - - Temperature background - Pozadinska temperatura - - - - Clocks background - Pozadina frekvencije - - - - Voltage background - Pozadina napona - - - - Temperature line - Linija temperature - - - - GPU clock line - Linija GPU frekvencije - - - - Mem clock line - Linija frekvencije memorije - - - - UVD video core line - Linija UVD video jezgre - - - - UVD decoder clock line - Linija UVD frekvencije dekôdera - - - - Core voltage line - Linija GPU napona - - - - Mem voltage line - Linija napona memorije - - - - Daemon - Pozadinski program - - - - Good option to check. Causes that daemon gets data from system automaticly with interval when GUI is on instead of waiting for request to read this data. Interval is the same as GUI. - Vrlo korisna mogućnost za odabir. Omogućava pozadinskom programu automatsko dobivanje podataka iz sustava u razdobljima kada GUI čeka zahtjeve za čitanje ovog podatka. Razdoblje je isto kao i u GUI-u. - - - - Refresh data without request - Osvježi podatke bez zahtjeva - - - - Apply new configuration and send it to daemon. - Primijeni nove postavke i pošalji ih u pozadinski program. - - - - Reconfigure daemon - Ponovno podesi pozadinski program - - - - About - O programu - - - - <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile"><span style=" text-decoration: underline; color:#2980b9;">Go to GitHub repository</span></a></p></body></html> - <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile"><span style=" text-decoration: underline; color:#2980b9;">Posjetite GitHub repozitorij</span></a></p></body></html> - - - - External resources: - Vanjski izvori: - - - - <html><head/><body><p><a href="http://www.qcustomplot.com/"><span style=" text-decoration: underline; color:#2980b9;">QCustomPlot library</span></a></p></body></html> - <html><head/><body><p><a href="http://www.qcustomplot.com/"><span style=" text-decoration: underline; color:#2980b9;">QCustomPlot grafikoni</span></a></p></body></html> - - - - <html><head/><body><p><a href="http://proicons.deviantart.com/art/Graphics-Cards-Icons-H1-Pack-161178339"><span style=" text-decoration: underline; color:#2980b9;">Icon</span></a></p></body></html> - <html><head/><body><p><a href="http://proicons.deviantart.com/art/Graphics-Cards-Icons-H1-Pack-161178339"><span style=" text-decoration: underline; color:#2980b9;">Ikona</span></a></p></body></html> - - - - <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile-daemon"><span style=" text-decoration: underline; color:#2980b9;">Radeon profile daemon</span></a></p></body></html> - <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile-daemon"><span style=" text-decoration: underline; color:#2980b9;">Radeon profil pozadinski program</span></a></p></body></html> - - - - Contributors: - Doprinositelji: - - - - <html><head/><body><p><a href="https://github.com/marazmista"><span style=" text-decoration: underline; color:#2980b9;">Marazmista</span></a></p></body></html> - <html><head/><body><p><a href="https://github.com/marazmista"><span style=" text-decoration: underline; color:#2980b9;">Marazmista GitHub</span></a></p></body></html> - - - - <html><head/><body><p><a href="https://github.com/Danysan1"><span style=" text-decoration: underline; color:#2980b9;">Danysan1</span></a></p></body></html> - <html><head/><body><p><a href="https://github.com/Danysan1"><span style=" text-decoration: underline; color:#2980b9;">Danysan1 GitHub</span></a></p></body></html> - - - - <html><head/><body><p><a href="https://github.com/V10lator"><span style=" text-decoration: underline; color:#2980b9;">V10lator</span></a></p></body></html> - <html><head/><body><p><a href="https://github.com/V10lator"><span style=" text-decoration: underline; color:#2980b9;">V10lator GitHub</span></a></p></body></html> - - - - <html><head/><body><p><a href="https://github.com/pontostroy"><span style=" text-decoration: underline; color:#2980b9;">Pontostroy</span></a></p></body></html> - <html><head/><body><p><a href="https://github.com/pontostroy"><span style=" text-decoration: underline; color:#2980b9;">Pontostroy GitHub</span></a></p></body></html> - - - diff -Nru radeon-profile-0.1.10~yakkety/strings.it.ts radeon-profile-0.1.17~yakkety/strings.it.ts --- radeon-profile-0.1.10~yakkety/strings.it.ts 2016-06-28 14:52:24.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/strings.it.ts 1970-01-01 00:00:00.000000000 +0000 @@ -1,1178 +0,0 @@ - - - - - QObject - - - Resolution - Risoluzione - - - - Minimum resolution - Risoluzione minima - - - - Maximum resolution - Risoluzione massima - - - - Power level - Livello di potenza - - - - GPU clock - Clock della GPU - - - - Memory clock - Clock della memoria - - - - UVD core clock (cclk) - Clock del UVD (cclk) - - - - UVD decoder clock (dclk) - Clock del decoder UVD (dclk) - - - - GPU voltage (vddc) - Voltaggio GPU (vddc) - - - - I/O voltage (vddci) - Voltaggio dell'I/O - - - - GPU temperature - Temperatura della GPU - - - - No info - Nessuna info - - - - Back to profiles - Ritorna ai profili - - - - Can't read data - Impossibile leggere i dati - - - - You need debugfs mounted and either root rights or the daemon running - È necessario che debugfs sia montato e che il demone sia attivo (o che il programma venga eseguito come root) - - - - Error - Errore - - - - Profile name can't be empty! - Il nome del profilo non può essere vuoto! - - - - No binary is selected! - Nessun eseguibile selezionato! - - - - Binary not found in /usr/bin: - Eseguibile non trovato in /usr/bin: - - - - Enter value - Inserisci valore - - - - Enter valid value for - Inserisci un valore valido per - - - - Question - - - - - Remove - Rimuovi - - - - Remove this item? - Rimuovere questo elemento? - - - - Select binary - Seleziona un eseguibile - - - - Select log file - Seleziona un file di log - - - - Can't run something that not exists! - Non posso eseguire qualcosa che non esiste! - - - - Run - Esegui - - - - Run: " - Eseguire " - - - - "? - - - - - Unknown - Sconosciuto - - - - Virtual size - Dimensione virtuale - - - - Outputs - Connessioni - - - - Active - Attivo - - - - Hz vertical, - Hz verticale, - - - - KHz horizontal, - KHz orizzontale, - - - - MHz dot clock - MHz dot clock - - - - Yes - Si - - - - No - No - - - - Refresh rate - Frequenza di aggiornamento - - - - Offset - - - - - Brightness (software) - Luminosità (software) - - - - Size - Dimensione - - - - Supported modes - Modalità supportate - - - - Properties - Proprietà - - - - Serial number - Numero di serie - - - - Not available - Non disponibile - - - - Connected with - Connesso con - - - - Temperature - Temperatura - - - - Fan speed - Velocità della ventola - - - - Disconnected - Disconnesso - - - - Time (s) - Tempo (s) - - - - Temperature (°C) - Temperature (°C) - Temperatura (°C) - - - - Clock (MHz) - - - - - Voltage (mV) - Voltaggio (mV) - - - - DPM - - - - - Change standard profile - Cambia profilo standard - - - - Quit - Esci - - - - Keep refreshing when hidden - Continua a aggiornare quando nascosto - - - - Battery - Batteria - - - - Balanced - Bilanciato - - - - Performance - - - - - Reset min/max temperature - Resetta temperatura min/max - - - - Reset graphs vertical scale - Resetta scala verticale dei grafici - - - - Show legend - Mostra la legenda - - - - Graph offset on right - Offset del grafico a destra - - - - Auto - - - - - Low - Basso - - - - High - Alto - - - - Force power level - Forza il livello di potenza - - - - Copy to clipboard - Copia negli appunti - - - - Reset statistics - Resetta le statistiche - - - - GPU data is disabled - Dati della GPU disabilitati - - - - Fan control information - Informazioni sul controllo della ventola - - - - Don't overheat your card! Be careful! Don't use this if you don't know what you're doing! - -Hovewer, looks like card won't apply too low values due its internal protection. - -Closing application will restore fan control to Auto. If application crashes, last fan value will remain, so you have been warned! - Non surriscaldare la tua scheda grafica! Usa questo sistema solo se sai quello che stai facendo! - -Il sistema di protezione della scheda grafica non accetta valori troppo bassi. - -Prima di chiudersi, l'applicazione reimposterà il controllo della ventola su Auto. Se l'applicazione va in crash, l'ultimo valore usato rimarrà attivo. Sei stato avvertito! - - - - Speed [%] (20-100) - Velocità [%] (20-100) - - - - Select new power profile - Seleziona un nuovo profilo di potenza - - - - Profile selection - Selezione del profilo - - - - This step already exists. To edit it double click it - Questo elemento è gia presente. Per modificarlo fai doppio click - - - - You can't delete the first and the last item - Non puoi cancellare il primo e l'ultimo elemento - - - - You can't edit the first and the last item - Non puoi modificare il primo e l'ultimo elemento - - - - An error occurred, overclock failed - Si è verificato un errore, overclock fallito - - - - Process state: running - Processo in esecuzione - - - - version %n - versione %n - - - - Process is still running. Close tab? - Il processo è ancora attivo. Chiudere comunque? - - - - Process state: not running - Processo terminato - - - - Save output to file - Salva output in un file - - - - Command - Comando - - - - Output - - - - - Save - Salva - - - - %n mm - - - - - %n mm - - - - - (%n inches) - (%n pollici) - - - - - %n mm x - - - - - %n connected, - %n connessi, - - - - %n active - %n attivi - - - - Virtual screen n°%n - Virtual screen n°%n - Per un qualche motivo non viene tradotto correttamente a runtime, investigare - Schermo virtuale n°%n - - - - radeon_profile - - - - Radeon Profile - - - - - GPU temperature - Temperatura della GPU - - - - GPU clock - Clock della GPU - - - - Fan speed - Velocità della ventola - - - - GPU - - - - - Memory clock - Clock della memoria - - - - GPU voltage - Voltaggio della GPU - - - - I/O voltage - Voltaggio dell'I/O - - - - GPU Summary - Sommario - - - - - Property - Proprietà - - - - - Value - Valore - - - - Profiles - Profili - - - - Change profile - Cambia profilo - - - - DPM - - - - - - Auto - - - - - Battery - Batteria - - - - Balanced - Bilanciato - - - - Performance - - - - - Low - Basso - - - - High - Alto - - - - GLX info - Informazioni GLX - - - - - Connectors - Connettori - - - - Connector - Componente - - - - Status - Stato - - - - Module info - Informazioni del modulo - - - - Option - Opzione - - - - Description - Descrizione - - - - Stats - Statistiche - - - - - Power level - Livello di potenza - - - - Selected GPU - GPU selezionata - - - - Power profile - Profilo di potenza - - - - 999% - - - - - 99.9°C - - - - - - 9999MHz - - - - - - 9999mV - - - - - Time - Tempo - - - - - - Graphs - Grafici - - - - Reset min max temps and graphs scale - Resetta la scala del grafico - - - - Options - Opzioni - - - - Clocks graph - Grafico dei clock - - - - Volts graph - Grafico dei voltaggi - - - - Temperature graph - Grafico delle temperature - - - - 1h - - - - - 30s - - - - - temps label - Temperature - - - - Fan Control - Controllo ventola - - - - Fixed - Fisso - - - - Custom curve - Curva personalizzata - - - - Info - Informazioni - - - - - Apply - Applica - - - - Overclock - - - - - Be careful! Overclock can harm your GPU, use it only if you know what you are doing! - Be careful! Overclock can harm your GPU, use it at your own risk! - Stai attento! L'overclock può danneggiare la tua GPU, usalo solo se sai quello che stai facendo! - - - - Enable overclock - Abilita overclock - - - - Apply at launch - Apply on startup - Applica all'avvio - - - - - 20% - - - - - / 100% - - - - - Temperature - Temperatura - - - - Fan Speed [%] - Velocità ventola [%] - - - - Add step - Aggiungi punto - - - - Remove step - Rimuovi punto - - - - Exec - Eseguibili - - - - Warning! Unrecommended root mode! - ATTENZIONE! L'esecuzione di comandi in modalità root è sconsigliata! - - - - Name - Nome - - - - Binary - Comando - - - - Params - Parametri - - - - Setting - Opzioni - - - - Log file - File di log - - - - Append date-time - Aggiungi data e ora - - - - Add - Aggiungi - - - - Modify - Modifica - - - - Remove - Rimuovi - - - - View output - Vedi output - - - - - Run - Esegui - - - - Name: - Nome: - - - - Binary: - Comando: - - - - - ... - ... - - - - Binary parameters: - Parametri: - - - - Log file: (leave empty if don't want it) - File di log (lascia vuoto se non ti interessa) - - - - Append date and time - Aggiungi data e ora - - - - Variables: - Variabili: - - - - Values: - Valori: - - - - Summary: - Sommario: - - - - Be careful, remember to save one space between variables. - Procedi con cautela, ricorda di aggiungere uno spazio fra le variabili. - - - - Tune variables manually - Modifica le variabili manualmente - - - - Proceed with caution now. - Procedi con cautela. - - - - Cancel - Annulla - - - - OK - - - - - Configuration - Impostazioni - - - - Main - Generali - - - - Start minimized - Avvia minimizzato - - - - Minimize to tray - Minimizza nella barra delle applicazioni - - - - On close hide to tray - Minimizza invece di chiudere - - - - Save window geometry - Salva la geometria della finestra - - - - Alternate row colors on lists - Alterna i colori delle righe nelle liste - - - - Refresh interval [s] - Intervallo di refresh [s] - - - - Update: - Aggiornamento: - - - - GPU data, power profile, temperature - Dati GPU, profili, temperatura - - - - Power levels statistics - Statistiche sul livello di potenza - - - - GLX Info - Informazioni GLX - - - - Module parameters - Parametri dei moduli - - - - Edit - Modifica - - - - Double click action on exec item - Doppio click su un eseguibile - - - - Explicit append system env to exec command - Comando esplicito di aggiunta di data e ora - - - - Line thickness: - Spessore della linea: - - - - Color - Colore - - - - Temperature background - Sfondo temperature - - - - Clocks background - Sfondo clock - - - - Voltage background - Sfondo voltaggi - - - - Temperature line - Temperatura GPU - - - - GPU clock line - Clock della GPU - - - - Mem clock line - Clock della memoria - - - - UVD video core line - UVD video core - - - - UVD decoder clock line - Decoder UVD - - - - Core voltage line - Voltaggio della GPU - - - - Mem voltage line - Voltaggio della memoria - - - - Daemon - Background - - - - Good option to check. Causes that daemon gets data from system automaticly with interval when GUI is on instead of waiting for request to read this data. Interval is the same as GUI. - Il servizio in background aggiornerà i dati automaticamente quando la GUI è attiva (consigliato). - - - - Refresh data without request - Aggiorna dati automaticamente - - - - Apply new configuration and send it to daemon. - Applica le opzioni e riconfigura il servizio in background. - - - - Reconfigure daemon - Riconfigura il demone - - - - About - Dettagli - - - - <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile"><span style=" text-decoration: underline; color:#2980b9;">Go to GitHub repository</span></a></p></body></html> - <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile"><span style=" text-decoration: underline; color:#2980b9;">Vai alla repository su GitHub</span></a></p></body></html> - - - - External resources: - Risorse esterne: - - - - <html><head/><body><p><a href="http://www.qcustomplot.com/"><span style=" text-decoration: underline; color:#2980b9;">QCustomPlot library</span></a></p></body></html> - <html><head/><body><p><a href="http://www.qcustomplot.com/"><span style=" text-decoration: underline; color:#2980b9;">QCustomPlot</span></a></p></body></html> - - - - <html><head/><body><p><a href="http://proicons.deviantart.com/art/Graphics-Cards-Icons-H1-Pack-161178339"><span style=" text-decoration: underline; color:#2980b9;">Icon</span></a></p></body></html> - <html><head/><body><p><a href="http://proicons.deviantart.com/art/Graphics-Cards-Icons-H1-Pack-161178339"><span style=" text-decoration: underline; color:#2980b9;">Icona</span></a></p></body></html> - - - - <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile-daemon"><span style=" text-decoration: underline; color:#2980b9;">Radeon profile daemon</span></a></p></body></html> - - - - - Contributors: - Contributori: - - - - <html><head/><body><p><a href="https://github.com/marazmista"><span style=" text-decoration: underline; color:#2980b9;">Marazmista</span></a></p></body></html> - - - - - <html><head/><body><p><a href="https://github.com/Danysan1"><span style=" text-decoration: underline; color:#2980b9;">Danysan1</span></a></p></body></html> - - - - - <html><head/><body><p><a href="https://github.com/V10lator"><span style=" text-decoration: underline; color:#2980b9;">V10lator</span></a></p></body></html> - - - - - <html><head/><body><p><a href="https://github.com/pontostroy"><span style=" text-decoration: underline; color:#2980b9;">Pontostroy</span></a></p></body></html> - - - - diff -Nru radeon-profile-0.1.10~yakkety/translations/strings.hr.ts radeon-profile-0.1.17~yakkety/translations/strings.hr.ts --- radeon-profile-0.1.10~yakkety/translations/strings.hr.ts 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/translations/strings.hr.ts 2017-01-25 22:13:42.000000000 +0000 @@ -0,0 +1,1702 @@ + + + + + Dialog_RPEvent + + + Event definition + Definicija događaja + + + + Save + Spremi + + + + Cancel + Odustani + + + + Event trigger + Pokretač događaja + + + + Event name + Naziv događaja + + + + Temperature + Temperatura + + + + Binary + Binarna datoteka + + + + Modify: + Prilagodi: + + + + Set power level: + Postavi razinu energije: + + + + + + No change + Bez promjene + + + + Set fan: + Postavi ventilator: + + + + Set DPM to: + Postavi DPM na: + + + + % + % + + + + Activate above this temperature: + Aktiviraj iznad ove temperature: + + + + Binary (executing this binary will trigger event): + Binarna datoteka (pokretanje ove binarne datoteke će pokrenuti događaj): + + + + ... + ... + + + + Enabled + Omogućeno + + + + Set Profile to: + Postavi profil na: + + + + Auto + Automatski + + + + Fixed speed + Nepromjenjiva brzina + + + + Selected trigger type is Binary, so the binary field cannot be empty. + Odabrani pokretač događaja je binarna datoteka, stoga polje binarne datoteke ne može biti prazno. + + + + Select binary + Odaberi binarnu datoteku + + + + QObject + + + + Resolution + Razlučivost + + + + Minimum resolution + Najmanja razlučivost + + + + Maximum resolution + Najveća razlučivost + + + Power level + Razina energije + + + GPU clock + GPU frekvencija + + + Memory clock + Frekvencija memorije + + + UVD core clock (cclk) + UVD frekvencija jezgre (cclk) + + + UVD decoder clock (dclk) + UVD frekvencija dekôdera (dclk) + + + GPU voltage (vddc) + GPU napon (vddc) + + + I/O voltage (vddci) + I/O napon (vddci) + + + GPU temperature + GPU temperatura + + + + No info + Nema informacija + + + Back to profiles + Natrag na profile + + + Can't read data + Nemoguće čitanje podataka + + + You need debugfs mounted and either root rights or the daemon running + Trebate imati debugfs montiran i ili korijenske ovlasti ili pokrenut pozadinski program + + + Error + Greška + + + Profile name can't be empty! + Naziv profila ne može biti prazan! + + + No binary is selected! + Nema odabrane binarne datoteke! + + + Binary not found in /usr/bin: + Binarna datoteka nije pronađena u /usr/bin: + + + Enter value + Upiši vrijednost + + + Enter valid value for + Upiši valjanu vrijednost za + + + Question + Pitanje + + + Remove + Ukloni + + + Remove this item? + Ukloni ovu stavku? + + + Select binary + Odaberi binarnu datoteku + + + Select log file + Odaberi datoteku zapisa + + + Can't run something that not exists! + Ne mogu pokrenti nešto što ne postoji! + + + Run + Pokreni + + + Run: " + Pokreni: " + + + "? + "? + + + + Unknown + Nepoznato + + + + Virtual size + Virtualna dimenzija + + + + Outputs + Izlazi + + + + + Active + Aktivno + + + + Hz vertical, + Hz okomito, + + + + KHz horizontal, + KHz vodoravno, + + + + MHz dot clock + MHz frekvenicja točke + + + + Yes + Da + + + + No + Ne + + + + Refresh rate + Frekvencija osvježavanja + + + + Offset + Pomak + + + + Brightness (software) + Svjetlina (softver) + + + + Size + Dimenzija + + + + Supported modes + Podržani načini + + + + Properties + Svojstva + + + + Serial number + Serijski broj + + + + Not available + Nedostupno + + + + Connected with + Povezano s + + + Temperature + Temperatura + + + Fan speed + Brzina ventilatora + + + + Disconnected + Nije povezano + + + Time (s) + Vrijeme (s) + + + Temperature (°C) + Temperature (°C) + Temperatura (°C) + + + Clock (MHz) + Frekvencija (MHz) + + + Voltage (mV) + Napon (mV) + + + DPM + DPM + + + Change standard profile + Promijeni standardni profil + + + Quit + Zatvori + + + Keep refreshing when hidden + Nastavi osvježavati dok je skriveno + + + Battery + Baterija + + + Balanced + Uravnoteženo + + + Performance + Performanse + + + Reset min/max temperature + Vrati zadanu min/maks temperaturu + + + Reset graphs vertical scale + Vrati zadane grafikone okomite promjene veličine + + + Show legend + Prikaži legendu + + + Graph offset on right + Pomak grafikona ulijevo + + + Auto + Automatski + + + Low + Nisko + + + High + Visoko + + + Force power level + Profil energije + + + Copy to clipboard + Kopiraj u međuspremnik + + + Reset statistics + Vrati zadanu statistiku + + + GPU data is disabled + GPU podaci su onemogućeni + + + Fan control information + Informacije upravljanja ventilatorom + + + Don't overheat your card! Be careful! Don't use this if you don't know what you're doing! + +Hovewer, looks like card won't apply too low values due its internal protection. + +Closing application will restore fan control to Auto. If application crashes, last fan value will remain, so you have been warned! + Nemojte pregrijati svoju grafičku karticu! Budite oprezni! Ne koristite ovo ako ne znate što radite! + +Ipak, izgleda da grafička kartica neće primijeniti premale vrijednosti zbog njene unutrašnje zaštite. + +Zatvaranje aplikacije će vratiti automatsko upravljanje ventilatorom. Ako se aplikacija sruši, zadnja vrijednost ventilatora će preostati, stoga ste upozoreni! + + + Speed [%] (20-100) + Brzina [%] (20-100) + + + Select new power profile + Odaberi novi profil energije + + + Profile selection + Odabir profila + + + This step already exists. To edit it double click it + Ovaj korak već postoji. Kako bi ga uredili dvostruko kliknite + + + You can't delete the first and the last item + Ne možete obrisati prvu i zadnju stavku + + + You can't edit the first and the last item + Ne možete urediti prvu i zadnju stavku + + + An error occurred, overclock failed + Dogodila se greška, overklokiranje neuspjelo + + + Process state: running + Stanje procesa: pokrenuto + + + version %n + inačica %n + + + Process is still running. Close tab? + Proces je još uvijek pokrenut. Zatvori karticu? + + + Process state: not running + Stanje procesa: nije pokrenuto + + + Save output to file + Spremi izlaz u datoteku + + + Command + Naredba + + + Output + Izlaz + + + Save + Spremi + + + + %n mm + %n mm + + + + %n mm + %n mm + + + + (%n inches) + (%n inča) + + + + + %n mm x + %n mm x + + + + %n connected, + %n povezana, + + + + %n active + %n aktivna + + + + Virtual screen n°%n + Virtual screen n°%n + Virtualni zalon n°%n + + + + execBin + + + Save output to file + Spremi izlaz u datoteku + + + + Command + Naredba + + + + Output + Izlaz + + + + Process state: running + Stanje procesa: pokrenuto + + + + Process state: not running + Stanje procesa: nije pokrenuto + + + + Save + Spremi + + + + radeon_profile + + + + Radeon Profile + Radeon profil + + + + + GPU temperature + GPU temperatura + + + + + + GPU clock + GPU frekvencija + + + + + + Time (s) + Vrijeme (s) + + + + Temperature (°C) + Temperatura (°C) + + + + Clock (MHz) + Frekvencija (MHz) + + + + Voltage (mV) + Napon (mV) + + + + Fan speed + Brzina ventilatora + + + + + Quit + Zatvori + + + + Change standard profile + Promijeni standardni profil + + + + Keep refreshing when hidden + Nastavi osvježavati dok je skriveno + + + + Reset min/max temperature + Vrati zadanu min/maks temperaturu + + + + Reset graphs vertical scale + Vrati zadane grafikone okomite promjene veličine + + + + Show legend + Prikaži legendu + + + + Graph offset on right + Pomak grafikona ulijevo + + + + Force power level + Profil energije + + + + + Copy to clipboard + Kopiraj u međuspremnik + + + + Reset statistics + Vrati zadanu statistiku + + + + + Fixed + Nepromjenjivo + + + + GPU + GPU + + + + + + Memory clock + Frekvencija memorije + + + + GPU voltage + GPU napon + + + + I/O voltage + I/O napon + + + + GPU Summary + GPU sažetak + + + + + Property + Svojstva + + + + + Value + Vrijednosti + + + + Profiles + Profili + + + + Change profile + Promijeni profil + + + + + DPM + DPM + + + + + + + Auto + Automatski + + + + + Battery + Baterija + + + + + Balanced + Uravnoteženo + + + + + Performance + Performanse + + + + + Low + Nisko + + + + + High + Visoko + + + + GLX info + GLX informacije + + + + + Connectors + Priključci + + + + Connector + Priključak + + + + Status + Stanje + + + + Module info + Informacije modula + + + + Option + Mogućnosti + + + + Description + Opis + + + + Stats + Statistika + + + + + + Power level + Razine energije + + + + Selected GPU + Odabrani GPU + + + + Power profile + Profil energije + + + + 999% + 999% + + + + 99.9°C + 99.9°C + + + + + 9999MHz + 9999MHz + + + + + 9999mV + 9999mV + + + + Time + Vrijeme + + + + + + Graphs + Grafikoni + + + + Reset min max temps and graphs scale + Vrati na početno min/maks promjene temperatura i grafikona + + + + Options + Mogućnosti + + + + Clocks graph + Grafikon frekvencije + + + + Volts graph + Grafikon napona + + + + Temperature graph + Grafikon temperature + + + + 1h + 1h + + + + 30s + 30s + + + + temps label + Temperatura + + + + Fan Control + Upravljanje ventilatorom + + + + Fixed + Nepromjenjivo + + + + Custom curve + Prilagođena krivulja + + + + + Info + Informacije + + + + + Apply + Primijeni + + + + Overclock + Overklokiranje + + + + Be careful! Overclock can harm your GPU, use it only if you know what you are doing! + Be careful! Overclock can harm your GPU, use it at your own risk! + Budite oprezni! Overklokiranje može oštetiti vaš GPU, koristite samo ako znate što radite! + + + + Enable overclock + Omogući overklokiranje + + + + Apply at launch + Apply on startup + Primijeni pri pokretanju + + + + 20% + 20% + + + / 100% + / 100% + + + + + + + Temperature + Temperatura + + + + Fan Speed [%] + Brzina ventilatora [%] + + + + Add step + Dodaj korak + + + + Remove step + Ukloni korak + + + + Exec + Binarna datoteka + + + + Warning! Unrecommended root mode! + Upozorenje! Nepreporučen korijenski način! + + + + Name + Naziv + + + + Binary + Binarna datoteka + + + + Params + Parametri + + + + Setting + Postavke + + + + Log file + Datoteka zapisa + + + + Append date-time + Dodaj datum i vrijeme + + + + + Add + Dodaj + + + + Export + Izvezi + + + + 10% + 10% + + + + Activate + Aktiviraj + + + + Current profile: + Trenutni profil: + + + + Save + Spremi + + + + Save as + Spremi kao + + + + Remove profile + Ukloni profil + + + + Unsaved + Nespremljeno + + + + Events + Događaji + + + + Enable event tracking + Omogući praćenje događaja + + + + Current active event: + Trenutni aktivni događaj: + + + + Revoke current event + Opozovi trenutni događaj + + + + Enabled + Omogućeno + + + + Event name + Naziv događaja + + + + + Modify + Promijeni + + + + + + Remove + Ukloni + + + + View output + Prikaz izlaza + + + + + + Run + Pokretanje + + + + Name: + Naziv: + + + + Binary: + Binarna datoteka: + + + + + ... + ... + + + + Binary parameters: + Parametri binarne datoteke: + + + + Log file: (leave empty if don't want it) + Datoteka zapisa: (ostavite prazno ako vam nije potrebno) + + + + Append date and time + Dodaj datum i vrijeme + + + + Variables: + Varijable: + + + + Values: + Vrijednosti: + + + + Summary: + Sažetak: + + + + Be careful, remember to save one space between variables. + Budite oprezni, ostavljajte samo jedan razmak između varijabli. + + + + Tune variables manually + Prilagodi varijable ručno + + + + Proceed with caution now. + Sada nastavite s oprezom. + + + + Cancel + Odustani + + + + OK + U redu + + + + Configuration + Podešavanje + + + + Main + Općenito + + + + Start minimized + Pokreni smanjeno + + + + Minimize to tray + Smanji u traku sustava + + + + On close hide to tray + Pri zatvaranju sakrij u traku sustava + + + + Save window geometry + Spremi geometriju prozora + + + + Alternate row colors on lists + Dvobojne boje redaka na popisu + + + + Refresh interval [s] + Razdoblje osvježavanja [s] + + + + Update: + Osvježavaj: + + + + GPU data, power profile, temperature + GPU podatke, profile, temperature + + + + Power levels statistics + Statistiku profila energije + + + + GLX Info + GLX informacije + + + + Module parameters + Parametre modula + + + + Edit + Uređivanje + + + + Double click action on exec item + Dvostruki klik na izvršne datoteke za + + + + Explicit append system env to exec command + Izričito dodaj env sustava exec naredbi + + + + Save selected fan control mode + Spremi odabrani način upravljanja ventilatorom + + + + Enable 0% fan speed + Omogući 0% brzinu ventilatora + + + + Line thickness: + Debljina linije: + + + + Color + Boja + + + + Temperature background + Pozadinska temperatura + + + + Clocks background + Pozadina frekvencije + + + + Voltage background + Pozadina napona + + + + Temperature line + Linija temperature + + + + GPU clock line + Linija GPU frekvencije + + + + Mem clock line + Linija frekvencije memorije + + + + UVD video core line + Linija UVD video jezgre + + + + UVD decoder clock line + Linija UVD frekvencije dekôdera + + + + Core voltage line + Linija GPU napona + + + + Mem voltage line + Linija napona memorije + + + + Daemon + Pozadinski program + + + + Good option to check. Causes that daemon gets data from system automaticly with interval when GUI is on instead of waiting for request to read this data. Interval is the same as GUI. + Vrlo korisna mogućnost za odabir. Omogućava pozadinskom programu automatsko dobivanje podataka iz sustava u razdobljima kada GUI čeka zahtjeve za čitanje ovog podatka. Razdoblje je isto kao i u GUI-u. + + + + Refresh data without request + Osvježi podatke bez zahtjeva + + + + Apply new configuration and send it to daemon. + Primijeni nove postavke i pošalji ih u pozadinski program. + + + + Reconfigure daemon + Ponovno podesi pozadinski program + + + + About + O programu + + + + <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile"><span style=" text-decoration: underline; color:#2980b9;">Go to GitHub repository</span></a></p></body></html> + <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile"><span style=" text-decoration: underline; color:#2980b9;">Posjetite GitHub repozitorij</span></a></p></body></html> + + + + External resources: + Vanjski izvori: + + + + <html><head/><body><p><a href="http://www.qcustomplot.com/"><span style=" text-decoration: underline; color:#2980b9;">QCustomPlot library</span></a></p></body></html> + <html><head/><body><p><a href="http://www.qcustomplot.com/"><span style=" text-decoration: underline; color:#2980b9;">QCustomPlot grafikoni</span></a></p></body></html> + + + + <html><head/><body><p><a href="http://proicons.deviantart.com/art/Graphics-Cards-Icons-H1-Pack-161178339"><span style=" text-decoration: underline; color:#2980b9;">Icon</span></a></p></body></html> + <html><head/><body><p><a href="http://proicons.deviantart.com/art/Graphics-Cards-Icons-H1-Pack-161178339"><span style=" text-decoration: underline; color:#2980b9;">Ikona</span></a></p></body></html> + + + + <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile-daemon"><span style=" text-decoration: underline; color:#2980b9;">Radeon profile daemon</span></a></p></body></html> + <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile-daemon"><span style=" text-decoration: underline; color:#2980b9;">Radeon profil pozadinski program</span></a></p></body></html> + + + + Contributors: + Doprinositelji: + + + + <html><head/><body><p><a href="https://github.com/marazmista"><span style=" text-decoration: underline; color:#2980b9;">Marazmista</span></a></p></body></html> + <html><head/><body><p><a href="https://github.com/marazmista"><span style=" text-decoration: underline; color:#2980b9;">Marazmista GitHub</span></a></p></body></html> + + + + <html><head/><body><p><a href="https://github.com/Danysan1"><span style=" text-decoration: underline; color:#2980b9;">Danysan1</span></a></p></body></html> + <html><head/><body><p><a href="https://github.com/Danysan1"><span style=" text-decoration: underline; color:#2980b9;">Danysan1 GitHub</span></a></p></body></html> + + + + <html><head/><body><p><a href="https://github.com/V10lator"><span style=" text-decoration: underline; color:#2980b9;">V10lator</span></a></p></body></html> + <html><head/><body><p><a href="https://github.com/V10lator"><span style=" text-decoration: underline; color:#2980b9;">V10lator GitHub</span></a></p></body></html> + + + + <html><head/><body><p><a href="https://github.com/pontostroy"><span style=" text-decoration: underline; color:#2980b9;">Pontostroy</span></a></p></body></html> + <html><head/><body><p><a href="https://github.com/pontostroy"><span style=" text-decoration: underline; color:#2980b9;">Pontostroy GitHub</span></a></p></body></html> + + + + Events info + Informacije događaja + + + + Here you can define events. Each event has a defined condition, and when this condition is fulfilled, event is activated. + +After activation, defined power profile, power level and fan profile are applied. When one of events is activated, tracking is suspended. + +When active event condition is no longer true, event is revoked and power profile, power level and fan profile are restored to state before event was activated. + Ovdje možete definirati događaje. Svaki događaj ima definirano stanje i kada je to stanje ispunjeno, događaj je aktiviran. + +Nakon aktivacije, definirani profil energije, razina energije i profil ventilatora su primijenjeni. Kada je jedan od događaja aktiviran, praćenje se obustavlja. + +Kada aktivno stanje događaja više nije istinito, događaj je opozvan i profil energije, razina energije i profil ventilatora su vraćeni na stanje prije aktivacije profila. + + + + Cannot remove event that is currently active. + Nemoguće je ukloniti događaj koji je trenutno aktivan. + + + + Do you want to remove event: + Želite li ukloniti događaj: + + + + + + + + + + + + Error + Greška + + + + Profile name can't be empty! + Naziv profila ne može biti prazan! + + + + No binary is selected! + Nema odabrane binarne datoteke! + + + + Binary not found in /usr/bin: + Binarna datoteka nije pronađena u /usr/bin: + + + + Enter value + Upiši vrijednost + + + + Enter valid value for + Upiši valjanu vrijednost za + + + + + Question + Pitanje + + + + + Remove this item? + Ukloni ovu stavku? + + + + Select binary + Odaberi binarnu datoteku + + + + Select log file + Odaberi datoteku zapisa + + + + Can't run something that not exists! + Ne mogu pokrenti nešto što ne postoji! + + + + Run: " + Pokreni: " + + + + This option may cause overheat of your card and it is your responsibility if this happens. Do you want to enable it? + Ova mogućnost može uzrokovati pregrijavanje vaše grafičke kartice i vi ste odgovorni ako se to dogodi. Želite li ovo omogućiti? + + + + Cannot remove default profile. + Nemoguće je ukloniti zadani profil. + + + + Remove profile: + Ukloni profil: + + + + Fan profile name: + Naziv profila ventilatora: + + + + Profile name musn't contain '|' character. + Naziv profila mora sadržavati '|' znak. + + + + Cannot add another profile with the same name that already exists. + Nemoguće je dodati profil s već postojećim nazivom. + + + + Cannot activate unsaved profile. Do you want to save it? + Nemoguće je aktivirati nespremljeni profil. Želite li ga spremiti? + + + + Fan control information + Informacije upravljanja ventilatorom + + + + Don't overheat your card! Be careful! Don't use this if you don't know what you're doing! + +Hovewer, looks like card won't apply too low values due its internal protection. + +Closing application will restore fan control to Auto. If application crashes, last fan value will remain, so you have been warned! + Nemojte pregrijati svoju grafičku karticu! Budite oprezni! Ne koristite ovo ako ne znate što radite! + +Ipak, izgleda da grafička kartica neće primijeniti premale vrijednosti zbog njene unutrašnje zaštite. + +Zatvaranje aplikacije će vratiti automatsko upravljanje ventilatorom. Ako se aplikacija sruši, zadnja vrijednost ventilatora će preostati, stoga ste upozoreni! + + + + This step already exists. Double click on it, to change its value + Ovaj korak već postoji. Kako bi ga uredili dvostruko kliknite + + + + + Speed [%] + Brzina [%] + + + + You can't delete the first and the last item + Ne možete obrisati prvu i zadnju stavku + + + + You can't edit the last item + Ne možete urediti zadnju stavku + + + + You can't edit temperature of the first item + Ne možete urediti temperaturu prve stavke + + + + version %n + inačica %n + + + + Back to profiles + Natrag na profile + + + + + UVD core clock (cclk) + UVD frekvencija jezgre (cclk) + + + + + UVD decoder clock (dclk) + UVD frekvencija dekôdera (dclk) + + + + + GPU voltage (vddc) + GPU napon (vddc) + + + + + I/O voltage (vddci) + I/O napon (vddci) + + + + Can't read data + Nemoguće čitanje podataka + + + + You need debugfs mounted and either root rights or the daemon running + Trebate imati debugfs montiran i ili korijenske ovlasti ili pokrenut pozadinski program + + + + Current profile: + Trenutni profil: + + + + is still running, exit anyway? + je još uvijek pokrenut, svejedno izađi? + + + + GPU data is disabled + GPU podaci su onemogućeni + + + + Select new power profile + Odaberi novi profil energije + + + + Profile selection + Odabir profila + + + + Process is still running. Close tab? + Proces je još uvijek pokrenut. Zatvori karticu? + + + + An error occurred, overclock failed + Dogodila se greška, overklokiranje neuspjelo + + + + Export destination directory + Odredišni direktorij izvoza + + + diff -Nru radeon-profile-0.1.10~yakkety/translations/strings.it.ts radeon-profile-0.1.17~yakkety/translations/strings.it.ts --- radeon-profile-0.1.10~yakkety/translations/strings.it.ts 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/translations/strings.it.ts 2017-01-25 20:59:26.000000000 +0000 @@ -0,0 +1,1688 @@ + + + + + Dialog_RPEvent + + + Event definition + + + + + Save + Salva + + + + Cancel + Annulla + + + + Event trigger + + + + + Event name + + + + + Temperature + Temperatura + + + + Binary + Comando + + + + Modify: + + + + + Set power level: + + + + + + + No change + + + + + Set fan: + + + + + Set DPM to: + + + + + % + + + + + Activate above this temperature: + + + + + Binary (executing this binary will trigger event): + + + + + ... + ... + + + + Enabled + + + + + Set Profile to: + + + + + Auto + + + + + Fixed speed + + + + + Selected trigger type is Binary, so the binary field cannot be empty. + + + + + Select binary + Seleziona un eseguibile + + + + QObject + + + + Resolution + Risoluzione + + + + Minimum resolution + Risoluzione minima + + + + Maximum resolution + Risoluzione massima + + + Power level + Livello di potenza + + + GPU clock + Clock della GPU + + + Memory clock + Clock della memoria + + + UVD core clock (cclk) + Clock del UVD (cclk) + + + UVD decoder clock (dclk) + Clock del decoder UVD (dclk) + + + GPU voltage (vddc) + Voltaggio GPU (vddc) + + + I/O voltage (vddci) + Voltaggio dell'I/O + + + GPU temperature + Temperatura della GPU + + + + No info + Nessuna info + + + Back to profiles + Ritorna ai profili + + + Can't read data + Impossibile leggere i dati + + + You need debugfs mounted and either root rights or the daemon running + È necessario che debugfs sia montato e che il demone sia attivo (o che il programma venga eseguito come root) + + + Error + Errore + + + Profile name can't be empty! + Il nome del profilo non può essere vuoto! + + + No binary is selected! + Nessun eseguibile selezionato! + + + Binary not found in /usr/bin: + Eseguibile non trovato in /usr/bin: + + + Enter value + Inserisci valore + + + Enter valid value for + Inserisci un valore valido per + + + Remove + Rimuovi + + + Remove this item? + Rimuovere questo elemento? + + + Select binary + Seleziona un eseguibile + + + Select log file + Seleziona un file di log + + + Can't run something that not exists! + Non posso eseguire qualcosa che non esiste! + + + Run + Esegui + + + Run: " + Eseguire " + + + + Unknown + Sconosciuto + + + + Virtual size + Dimensione virtuale + + + + Outputs + Connessioni + + + + + Active + Attivo + + + + Hz vertical, + Hz verticale, + + + + KHz horizontal, + KHz orizzontale, + + + + MHz dot clock + MHz dot clock + + + + Yes + Si + + + + Virtual screen n°%n + + + + + No + No + + + + Refresh rate + Frequenza di aggiornamento + + + + Offset + + + + + Brightness (software) + Luminosità (software) + + + + Size + Dimensione + + + + Supported modes + Modalità supportate + + + + Properties + Proprietà + + + + Serial number + Numero di serie + + + + Not available + Non disponibile + + + + Connected with + Connesso con + + + Temperature + Temperatura + + + Fan speed + Velocità della ventola + + + + Disconnected + Disconnesso + + + Time (s) + Tempo (s) + + + Temperature (°C) + Temperatura (°C) + + + Voltage (mV) + Voltaggio (mV) + + + Change standard profile + Cambia profilo standard + + + Quit + Esci + + + Keep refreshing when hidden + Continua a aggiornare quando nascosto + + + Battery + Batteria + + + Balanced + Bilanciato + + + Reset min/max temperature + Resetta temperatura min/max + + + Reset graphs vertical scale + Resetta scala verticale dei grafici + + + Show legend + Mostra la legenda + + + Graph offset on right + Offset del grafico a destra + + + Low + Basso + + + High + Alto + + + Force power level + Forza il livello di potenza + + + Copy to clipboard + Copia negli appunti + + + Reset statistics + Resetta le statistiche + + + GPU data is disabled + Dati della GPU disabilitati + + + Fan control information + Informazioni sul controllo della ventola + + + Don't overheat your card! Be careful! Don't use this if you don't know what you're doing! + +Hovewer, looks like card won't apply too low values due its internal protection. + +Closing application will restore fan control to Auto. If application crashes, last fan value will remain, so you have been warned! + Non surriscaldare la tua scheda grafica! Usa questo sistema solo se sai quello che stai facendo! + +Il sistema di protezione della scheda grafica non accetta valori troppo bassi. + +Prima di chiudersi, l'applicazione reimposterà il controllo della ventola su Auto. Se l'applicazione va in crash, l'ultimo valore usato rimarrà attivo. Sei stato avvertito! + + + Speed [%] (20-100) + Velocità [%] (20-100) + + + Select new power profile + Seleziona un nuovo profilo di potenza + + + Profile selection + Selezione del profilo + + + This step already exists. To edit it double click it + Questo elemento è gia presente. Per modificarlo fai doppio click + + + You can't delete the first and the last item + Non puoi cancellare il primo e l'ultimo elemento + + + You can't edit the first and the last item + Non puoi modificare il primo e l'ultimo elemento + + + An error occurred, overclock failed + Si è verificato un errore, overclock fallito + + + Process state: running + Processo in esecuzione + + + version %n + versione %n + + + Process is still running. Close tab? + Il processo è ancora attivo. Chiudere comunque? + + + Process state: not running + Processo terminato + + + Save output to file + Salva output in un file + + + Command + Comando + + + Save + Salva + + + + %n mm + + + + + %n mm + + + + + (%n inches) + (%n pollici) + + + + + %n mm x + + + + + %n connected, + %n connesso, + + + + %n active + %n attivo + + + Virtual screen n°%n + Per un qualche motivo non viene tradotto correttamente a runtime, investigare + + Schermo virtuale n°%n + Schermo virtuale n°%n + + + + + execBin + + + Save output to file + Salva output in un file + + + + Command + Comando + + + + Output + + + + + Process state: running + Processo in esecuzione + + + + Process state: not running + Processo terminato + + + + Save + Salva + + + + radeon_profile + + + + Radeon Profile + + + + + + GPU temperature + Temperatura della GPU + + + + + + GPU clock + Clock della GPU + + + + + + Time (s) + Tempo (s) + + + Temperature (°C) + Temperatura (°C) + + + + Clock (MHz) + + + + + Voltage (mV) + Voltaggio (mV) + + + + Fan speed + Velocità della ventola + + + + + I/O voltage (vddci) + Voltaggio dell'I/O + + + + Temperature (°C) + + + + + + Quit + Esci + + + + Change standard profile + Cambia profilo standard + + + + Keep refreshing when hidden + Continua a aggiornare quando nascosto + + + + Reset min/max temperature + Resetta temperatura min/max + + + + Reset graphs vertical scale + Resetta scala verticale dei grafici + + + + Show legend + Mostra la legenda + + + + Graph offset on right + Offset del grafico a destra + + + + Force power level + Forza il livello di potenza + + + + + Copy to clipboard + Copia negli appunti + + + + Reset statistics + Resetta le statistiche + + + + + Fixed + Fisso + + + + GPU + + + + + + + Memory clock + Clock della memoria + + + + GPU voltage + Voltaggio della GPU + + + + I/O voltage + Voltaggio dell'I/O + + + + GPU Summary + Sommario + + + + + Property + Proprietà + + + + + Value + Valore + + + + Profiles + Profili + + + + Change profile + Cambia profilo + + + + + DPM + + + + + + + + Auto + + + + + + Battery + Batteria + + + + + Balanced + Bilanciato + + + + + Performance + + + + + + Low + Basso + + + + + High + Alto + + + + GLX info + Informazioni GLX + + + + + Connectors + Connettori + + + + Connector + Componente + + + + Status + Stato + + + + Module info + Informazioni del modulo + + + + Option + Opzione + + + + Description + Descrizione + + + + Stats + Statistiche + + + + + + Power level + Livello di potenza + + + + Selected GPU + GPU selezionata + + + + Power profile + Profilo di potenza + + + + 999% + + + + + 99.9°C + + + + + + 9999MHz + + + + + + 9999mV + + + + + Time + Tempo + + + + + + Graphs + Grafici + + + + Reset min max temps and graphs scale + Resetta la scala del grafico + + + + Options + Opzioni + + + + Clocks graph + Grafico dei clock + + + + Volts graph + Grafico dei voltaggi + + + + Temperature graph + Grafico delle temperature + + + + 1h + + + + + 30s + + + + + temps label + Temperature + + + + Fan Control + Controllo ventola + + + + Fixed + Fisso + + + + Custom curve + Curva personalizzata + + + + + Info + Informazioni + + + + + Apply + Applica + + + + Overclock + + + + + Be careful! Overclock can harm your GPU, use it only if you know what you are doing! + Be careful! Overclock can harm your GPU, use it at your own risk! + Stai attento! L'overclock può danneggiare la tua GPU, usalo solo se sai quello che stai facendo! + + + + Enable overclock + Abilita overclock + + + + Apply at launch + Apply on startup + Applica all'avvio + + + + 20% + + + + + + + + Temperature + Temperatura + + + + Fan Speed [%] + Velocità ventola [%] + + + + Add step + Aggiungi punto + + + + Export + Esporta + + + + 10% + + + + + Activate + Attiva + + + + Current profile: + Profilo attuale: + + + + Save + Salva + + + + Save as + Salva come + + + + Remove profile + Rimuovi profilo + + + + Remove step + Rimuovi punto + + + + Exec + Eseguibili + + + + Warning! Unrecommended root mode! + ATTENZIONE! L'esecuzione di comandi in modalità root è sconsigliata! + + + + Name + Nome + + + + Binary + Comando + + + + Params + Parametri + + + + Setting + Opzioni + + + + Log file + File di log + + + + Append date-time + Aggiungi data e ora + + + + + Add + Aggiungi + + + + Unsaved + + + + + Events + + + + + Enable event tracking + + + + + Current active event: + + + + + Revoke current event + + + + + Enabled + + + + + Event name + + + + + + Modify + Modifica + + + + + + Remove + Rimuovi + + + + View output + Vedi output + + + + + + Run + Esegui + + + + Name: + Nome: + + + + Binary: + Comando: + + + + + ... + ... + + + + Binary parameters: + Parametri: + + + + Log file: (leave empty if don't want it) + File di log (lascia vuoto se non ti interessa) + + + + Append date and time + Aggiungi data e ora + + + + Variables: + Variabili: + + + + Values: + Valori: + + + + Summary: + Sommario: + + + + Be careful, remember to save one space between variables. + Procedi con cautela, ricorda di aggiungere uno spazio fra le variabili. + + + + Tune variables manually + Modifica le variabili manualmente + + + + Proceed with caution now. + Procedi con cautela. + + + + Cancel + Annulla + + + + OK + + + + + Configuration + Impostazioni + + + + Main + Generali + + + + Start minimized + Avvia minimizzato + + + + Minimize to tray + Minimizza nella barra delle applicazioni + + + + On close hide to tray + Minimizza invece di chiudere + + + + Save window geometry + Salva la geometria della finestra + + + + Alternate row colors on lists + Alterna i colori delle righe nelle liste + + + + Refresh interval [s] + Intervallo di refresh [s] + + + + Update: + Aggiornamento: + + + + GPU data, power profile, temperature + Dati GPU, profili, temperatura + + + + Power levels statistics + Statistiche sul livello di potenza + + + + GLX Info + Informazioni GLX + + + + Module parameters + Parametri dei moduli + + + + Edit + Modifica + + + + Double click action on exec item + Doppio click su un eseguibile + + + + Explicit append system env to exec command + Comando esplicito di aggiunta di data e ora + + + + Save selected fan control mode + Salva il profilo della ventola selezionato + + + + Enable 0% fan speed + Abilita modalità ventola 0% + + + + Line thickness: + Spessore della linea: + + + + Color + Colore + + + + Temperature background + Sfondo temperature + + + + Clocks background + Sfondo clock + + + + Voltage background + Sfondo voltaggi + + + + Temperature line + Temperatura GPU + + + + GPU clock line + Clock della GPU + + + + Mem clock line + Clock della memoria + + + + UVD video core line + UVD video core + + + + UVD decoder clock line + Decoder UVD + + + + Core voltage line + Voltaggio della GPU + + + + Mem voltage line + Voltaggio della memoria + + + + Daemon + Background + + + + Good option to check. Causes that daemon gets data from system automaticly with interval when GUI is on instead of waiting for request to read this data. Interval is the same as GUI. + Il servizio in background aggiornerà i dati automaticamente quando la GUI è attiva (consigliato). + + + + Refresh data without request + Aggiorna dati automaticamente + + + + Apply new configuration and send it to daemon. + Applica le opzioni e riconfigura il servizio in background. + + + + Reconfigure daemon + Riconfigura il demone + + + + About + Dettagli + + + + <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile"><span style=" text-decoration: underline; color:#2980b9;">Go to GitHub repository</span></a></p></body></html> + <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile"><span style=" text-decoration: underline; color:#2980b9;">Vai alla repository su GitHub</span></a></p></body></html> + + + + External resources: + Risorse esterne: + + + + <html><head/><body><p><a href="http://www.qcustomplot.com/"><span style=" text-decoration: underline; color:#2980b9;">QCustomPlot library</span></a></p></body></html> + <html><head/><body><p><a href="http://www.qcustomplot.com/"><span style=" text-decoration: underline; color:#2980b9;">QCustomPlot</span></a></p></body></html> + + + + <html><head/><body><p><a href="http://proicons.deviantart.com/art/Graphics-Cards-Icons-H1-Pack-161178339"><span style=" text-decoration: underline; color:#2980b9;">Icon</span></a></p></body></html> + <html><head/><body><p><a href="http://proicons.deviantart.com/art/Graphics-Cards-Icons-H1-Pack-161178339"><span style=" text-decoration: underline; color:#2980b9;">Icona</span></a></p></body></html> + + + + <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile-daemon"><span style=" text-decoration: underline; color:#2980b9;">Radeon profile daemon</span></a></p></body></html> + + + + + Contributors: + Contributori: + + + + <html><head/><body><p><a href="https://github.com/marazmista"><span style=" text-decoration: underline; color:#2980b9;">Marazmista</span></a></p></body></html> + + + + + <html><head/><body><p><a href="https://github.com/Danysan1"><span style=" text-decoration: underline; color:#2980b9;">Danysan1</span></a></p></body></html> + + + + + <html><head/><body><p><a href="https://github.com/V10lator"><span style=" text-decoration: underline; color:#2980b9;">V10lator</span></a></p></body></html> + + + + + <html><head/><body><p><a href="https://github.com/pontostroy"><span style=" text-decoration: underline; color:#2980b9;">Pontostroy</span></a></p></body></html> + + + + + + + + + + + + + Error + Errore + + + + Profile name can't be empty! + Il nome del profilo non può essere vuoto! + + + + No binary is selected! + Nessun eseguibile selezionato! + + + + Binary not found in /usr/bin: + Eseguibile non trovato in /usr/bin: + + + + Enter value + Inserisci valore + + + + Enter valid value for + Inserisci un valore valido per + + + + + Question + Domanda + + + + + Remove this item? + Rimuovere questo elemento? + + + + Select binary + Seleziona un eseguibile + + + + Select log file + Seleziona un file di log + + + + Can't run something that not exists! + Non posso eseguire qualcosa che non esiste! + + + + Run: " + Eseguire " + + + + version %n + versione %n + + + + Back to profiles + Ritorna ai profili + + + + + UVD core clock (cclk) + Clock del UVD (cclk) + + + + + UVD decoder clock (dclk) + Clock del decoder UVD (dclk) + + + + + GPU voltage (vddc) + Voltaggio GPU (vddc) + + + + Can't read data + Impossibile leggere i dati + + + + You need debugfs mounted and either root rights or the daemon running + È necessario che debugfs sia montato e che il demone sia attivo (o che il programma venga eseguito come root) + + + + Current profile: + + + + + is still running, exit anyway? + è ancora in esecuzione, uscire comunque? + + + + GPU data is disabled + Dati della GPU disabilitati + + + + Select new power profile + Seleziona un nuovo profilo di potenza + + + + Profile selection + Selezione del profilo + + + + Process is still running. Close tab? + Il processo è ancora attivo. Chiudere comunque? + + + + Cannot activate unsaved profile. Do you want to save it? + + + + + Fan control information + Informazioni sul controllo della ventola + + + + Don't overheat your card! Be careful! Don't use this if you don't know what you're doing! + +Hovewer, looks like card won't apply too low values due its internal protection. + +Closing application will restore fan control to Auto. If application crashes, last fan value will remain, so you have been warned! + Non surriscaldare la tua scheda grafica! Usa questo sistema solo se sai quello che stai facendo! + +Il sistema di protezione della scheda grafica non accetta valori troppo bassi. + +Prima di chiudersi, l'applicazione reimposterà il controllo della ventola su Auto. Se l'applicazione va in crash, l'ultimo valore usato rimarrà attivo. Sei stato avvertito! + + + + This step already exists. Double click on it, to change its value + Questa temperatura esiste già. Doppio click per modificarla + + + + + Speed [%] + Velocità [%] + + + + You can't edit the last item + Non puoi modificare l'ultimo elemento + + + + You can't edit temperature of the first item + Non puoi modificare la temperatura del primo elemento + + + Speed [%] (10-100) + Velocità [%] (10-100) + + + + Export destination directory + Cartella di destinazione + + + + This option may cause overheat of your card and it is your responsibility if this happens. Do you want to enable it? + Questa opzione può causare un sirriscaldamento della scheda video, ti assumi la responsabilità se questo succede. Vuoi abilitarla? + + + Speed [%] (20-100) + Velocità [%] (20-100) + + + + You can't delete the first and the last item + Non puoi cancellare il primo e l'ultimo elemento + + + You can't edit the first and the last item + Non puoi modificare il primo e l'ultimo elemento + + + + An error occurred, overclock failed + Si è verificato un errore, overclock fallito + + + + Cannot remove default profile. + Non puoi rimuovere il profilo di default. + + + + Remove profile: + + + + + Fan profile name: + Nome del profilo: + + + + Profile name musn't contain '|' character. + Il nome del profilo non può contenere il carattere '|'. + + + + Cannot add another profile with the same name that already exists. + Esiste già un profilo con questo nome. + + + + Events info + + + + + Here you can define events. Each event has a defined condition, and when this condition is fulfilled, event is activated. + +After activation, defined power profile, power level and fan profile are applied. When one of events is activated, tracking is suspended. + +When active event condition is no longer true, event is revoked and power profile, power level and fan profile are restored to state before event was activated. + + + + + Cannot remove event that is currently active. + + + + + Do you want to remove event: + + + + diff -Nru radeon-profile-0.1.10~yakkety/translations/strings.pl.ts radeon-profile-0.1.17~yakkety/translations/strings.pl.ts --- radeon-profile-0.1.10~yakkety/translations/strings.pl.ts 1970-01-01 00:00:00.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/translations/strings.pl.ts 2017-01-25 20:59:26.000000000 +0000 @@ -0,0 +1,1708 @@ + + + + + Dialog_RPEvent + + + Event definition + Defiincja zdarzenia + + + + Save + Zapisz + + + + Cancel + Anuluj + + + + Event trigger + Wyzwalacz zdarzenia + + + + Event name + Nazwa zdarzenia + + + + Temperature + Temperatura + + + + Binary + Plik wykonywalny + + + + Modify: + Zmodyfikuj: + + + + Set power level: + Poziom: + + + + + + No change + Bez zmian + + + + Set fan: + Wiatrak: + + + + Set DPM to: + Profil DPM: + + + + % + % + + + + Activate above this temperature: + Aktywuj powyżej tej temperatury: + + + + Binary (executing this binary will trigger event): + Plik wykonywalny (uruchomienie włączy zdarzenie): + + + + ... + ... + + + + Enabled + Włączony + + + + Set Profile to: + Profil: + + + + Auto + Auto + + + + Fixed speed + Stała prędkość + + + + Selected trigger type is Binary, so the binary field cannot be empty. + Wybrany wyzwalacz zdarzenia to plik wykonywaly, więc musisz go wskazać. + + + + Select binary + Wskaż plik wykonywalny + + + + QObject + + + Unknown + Nieznany + + + + Virtual screen n°%n + + + + + + Resolution + Rozdzielczość + + + + Minimum resolution + Minimalna rozdzielczość + + + + Maximum resolution + Maksymalna rozdzielczość + + + + Virtual size + Rozmiar wirtualny + + + + + %n mm x + + + + + %n mm + + + + + Outputs + Wyjścia + + + + Disconnected + Nie podłączony + + + + + Active + Aktywny + + + + No + +Nie + + + + Yes + Tak + + + + Refresh rate + Odświeżanie + + + + Offset + Przesunięcie + + + + Brightness (software) + Jasność (programowa) + + + + Size + +Rozmiar + + + + %n mm + + + + + (%n inches) + (%n cali) + + + + Supported modes + Obsługiwane tryby + + + + Hz vertical, + Hz pionowo, + + + + KHz horizontal, + KHz poziomo, + + + + MHz dot clock + MHz dot zegar + + + + Properties + Właściwości + + + + Connected with + Połączony z: + + + + Not available + Nie dostępny + + + + Serial number + Numer seryjny + + + + %n connected, + %n podłaczony, + + + + %n active + %n aktywny + + + + No info + Brak informacji + + + + dXorg + + No info + Brak informacji + + + + execBin + + Executable + Plik wykonywalny + + + Enviroinment + Zmienne środowiskowe + + + + Output + Wyjście + + + Process not started + Proces nie uruchomiony + + + + Save output to file + Zapisz wyjscie do pliku + + + + Command + Polecenie + + + + Process state: running + Proces: uruchomiony + + + + Process state: not running + Proces: nie uruchomiony + + + Process running + Process state: running + Proces uruchomiony + + + Process terminated + Process not running + Porces zakończony + + + + Save + Zapisz + + + + export_graphs + + Export graphs + Eksportuj wykresy + + + Output format + Format + + + Graphs to export + Wykres + + + Temperature + Temperatura + + + Frequency + Częstotliwości + + + Voltage + Volts + Napięcia + + + Output directory + Ścieżka eksportu + + + Change + Zmień + + + + gpu + + Unknown + Nieznany + + + Virtual screen %n + Virtual screen n°%n + + Ekran %n + Ekran %n + + + + + Resolution + Rozdzielczość + + + Minimum resolution + Minimalna rozdzielczość + + + Maximum resolution + Maksymalna rozdzielczość + + + Virtual size + Rozmiar wirtualny + + + Outputs + Wyjścia + + + Disconnected + Nie podłączony + + + Active + Aktywny + + + No + +Nie + + + Yes + Tak + + + Refresh rate + Odświeżanie + + + Offset + Przesunięcie + + + Brightness (software) + Jasność (programowa) + + + Size + +Rozmiar + + + inches) + cali) + + + Driver: + Sterownik: + + + OpenGL info + Informacje OpenGL + + + Vulkan info + Informacje Vulkan + + + OpenCL info + Informacje OpenCL + + + Supported modes + Obsługiwane tryby + + + Hz vertical, + Hz pionowo + + + KHz horizontal, + KHz poziomo, + + + MHz dot clock + MHz dot zegar + + + Properties + Właściwości + + + Connected with + Połączony z: + + + Not available + Nie dostępny + + + Serial number + Numer seryjny + + + %n connected, + + %n podłaczony, + %n podłaczony, + + + + + %n active + + %n aktywny + %n aktywny + + + + + + radeon_profile + + + + Radeon Profile + + + + + + GPU temperature + Temperatura GPU + + + + + + GPU clock + Zegar GPU + + + + Fan speed + Prędkość wentylatora + + + + GPU + + + + + + + Memory clock + Zegar pamięci + + + + GPU voltage + Napięcie rdzenia GPU (vddc) + + + + I/O voltage + Napięcie I/O (vddci) + + + + GPU Summary + Podsumowanie + + + + + Property + Właściwość + + + + + Value + Wartość + + + + Profiles + Profil + + + + Change profile + Zmień profil + + + + + DPM + + + + + + + + Auto + + + + + + Battery + Oszczędny + + + + + Balanced + Zbalansowany + + + + + Performance + Wydajny + + + + + Low + Min + + + + + High + Max + + + + GLX info + Informacje GLX + + + + + Connectors + Wyświetlacze + + + + Connector + Wyświetlacz + + + + Status + + + + + Module info + Informacje o module + + + + Option + Opcja + + + + Description + Opis + + + + Stats + Statystyki + + + + + + Power level + Poziom + + + + Selected GPU + Wybrane GPU + + + + Power profile + Profil GPU + + + + 999% + + + + + 99.9°C + + + + + + 9999MHz + + + + + + 9999mV + + + + + Time + Czas + + + + + + Graphs + Wykresy + + + + Reset min max temps and graphs scale + Resetuj skrajne temperatur i skalę wykresu + + + + Options + Opcje + + + + Clocks graph + Częstotliwości + + + + Volts graph + Napięcia + + + + Temperature graph + Temperatura + + + + 1h + + + + + 30s + + + + + Fan Control + Wentylator + + + + Fixed + Stała wartość + + + + Custom curve + Krzywa + + + + + Info + Info + + + + + Apply + Zastosuj + + + Memory + Pamięć + + + + Export + Eksportuj + + + + Overclock + Podkręcanie + + + + Be careful! Overclock can harm your GPU, use it only if you know what you are doing! + Be careful! Overclock can harm your GPU, use it at your own risk! + Bądź ostrożny! Podkręcanie może trwale uszkodzić elementy komputera. + + + + Enable overclock + Włącz podkręcanie + + + + 20% + + + + + + + + Temperature + Temperatura + + + + Fan Speed [%] + Wiatrak [%] + + + + Add step + Dodaj + + + + temps label + + + + + Apply at launch + Zastosuj przy uruchomieniu + + + + 10% + 10% + + + + Activate + Aktywuj + + + + Current profile: + Aktywny profil: + + + + Save + Zapisz + + + + Save as + Zapisz jako + + + + Remove profile + Usuń profil + + + + Unsaved + Niezapisany + + + + Remove step + Usuń + + + + Events + Zdarzenia + + + + Enable event tracking + Włącz śledzenie zdarzeń + + + + Current active event: + Aktywne zdarzenie: + + + + Revoke current event + Wyłącz aktywowane zdarzenie + + + + Enabled + Włączony + + + + Event name + Nazwa zdarzenia + + + + Exec + Exec + + + + Warning! Unrecommended root mode! + Uwaga! Aplikacja uruchomiona w niezalecanym trybie roota + + + + Name + Nazwa + + + + Binary + Plik wykonywalny + + + + Params + Parametry + + + + Setting + Ustawienia + + + + Log file + Plik logu + + + + Append date-time + Dopisz datę i godzinę + + + + + Add + Dodaj + + + + + Modify + Modyfikuj + + + + + + Remove + Usuń + + + + View output + Pokaż wyjście + + + + + + Run + Uruchom + + + + Name: + Nazwa: + + + + Binary: + Plik wykonywalny: + + + + + ... + ... + + + + Binary parameters: + Parametry: + + + + Log file: (leave empty if don't want it) + Plik logu (zostaw puste jeśli nie chcesz logu) + + + + Append date and time + Dopisz datę i czas + + + + Variables: + Zmienne: + + + + Values: + Wartości: + + + Apply at application launch + Zastosuj przy starcie aplikacji + + + + Summary: + Podsumowanie: + + + + Be careful, remember to save one space between variables. + Pamiętaj o spacji oddzielającej parametry. + + + + Tune variables manually + Ręcznie modyfikuj parametry + + + + Proceed with caution now. + Teraz ostrożnie, skup się. + + + + Cancel + Anuluj + + + + OK + + + + + Configuration + Konfiguracja + + + + Main + Główne + + + + Start minimized + Uruchom zminimalizowany + + + + Minimize to tray + Minimalizuj do traya + + + + On close hide to tray + Przy zamykaniu schowaj do traya + + + + Save window geometry + Zapisz wymiary okna + + + + Alternate row colors on lists + Wiersze parzyste oznacz innym kolorem + + + + Refresh interval [s] + Częstotliwość odświeżania [s] + + + + Update: + Odświeżaj: + + + + GPU data, power profile, temperature + Dane GPU, profil i temperatura + + + + Power levels statistics + Statystyki + + + + GLX Info + Informacje GLX + + + + Module parameters + Parametry modułu + + + + Edit + Edytuj + + + + Double click action on exec item + Dwukrotne klinięcie w tabeli exec + + + + Explicit append system env to exec command + Dolącz systemowe zmienne środowiskowe do polecenia + + + Always show gpu selector + Pokaż listę GPU + + + Show profile and power level selector + Pokaż listę profili GPU + + + + Line thickness: + Grubość linii: + + + + Color + Kolor + + + + Temperature background + Tło wykresu temperatury + + + + Clocks background + Tło wykresu częstotliowści + + + + Voltage background + Tło wykresu napięć + + + + Temperature line + Linia temperatury + + + + GPU clock line + Linia zegara GPU + + + + Mem clock line + Linia zegara pamięci + + + + UVD video core line + Linia zegara UVD + + + + UVD decoder clock line + Linia zegara dekodera UVD + + + + Core voltage line + Linia rdzenia GPU + + + + Mem voltage line + Linia napięcia pamięci + + + + Daemon + Daemon + + + + Good option to check. Causes that daemon gets data from system automaticly with interval when GUI is on instead of waiting for request to read this data. Interval is the same as GUI. + Lepiej zaznacz. Powoduje, że daemon sam odświeża dane bez czekania na polecenie odświeżenia od interfejsu + + + + Refresh data without request + Odśwież dane bez żądania + + + + Apply new configuration and send it to daemon. + Zastosuj i wyślij konfigurację daemona + + + + Reconfigure daemon + Zastosuj konfigurację daemona + + + + About + O aplikacji + + + + <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile"><span style=" text-decoration: underline; color:#2980b9;">Go to GitHub repository</span></a></p></body></html> + <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile"><span style=" text-decoration: underline; color:#2980b9;">GitHub repo</span></a></p></body></html> + + + + External resources: + Zewnętrzne: + + + + <html><head/><body><p><a href="http://www.qcustomplot.com/"><span style=" text-decoration: underline; color:#2980b9;">QCustomPlot library</span></a></p></body></html> + <html><head/><body><p><a href="http://www.qcustomplot.com/"><span style=" text-decoration: underline; color:#2980b9;">Biblioteka QCustomPlot</span></a></p></body></html> + + + + <html><head/><body><p><a href="http://proicons.deviantart.com/art/Graphics-Cards-Icons-H1-Pack-161178339"><span style=" text-decoration: underline; color:#2980b9;">Icon</span></a></p></body></html> + <html><head/><body><p><a href="http://proicons.deviantart.com/art/Graphics-Cards-Icons-H1-Pack-161178339"><span style=" text-decoration: underline; color:#2980b9;">Ikona</span></a></p></body></html> + + + + <html><head/><body><p><a href="https://github.com/marazmista/radeon-profile-daemon"><span style=" text-decoration: underline; color:#2980b9;">Radeon profile daemon</span></a></p></body></html> + + + + + Save selected fan control mode + Zapisz ustawienia kontroli wentylatora + + + + Enable 0% fan speed + Pozwól na prędkość wiatraka równą 0% + + + + Contributors: + Współtwórcy + + + + <html><head/><body><p><a href="https://github.com/marazmista"><span style=" text-decoration: underline; color:#2980b9;">Marazmista</span></a></p></body></html> + + + + + <html><head/><body><p><a href="https://github.com/Danysan1"><span style=" text-decoration: underline; color:#2980b9;">Danysan1</span></a></p></body></html> + + + + + <html><head/><body><p><a href="https://github.com/V10lator"><span style=" text-decoration: underline; color:#2980b9;">V10lator</span></a></p></body></html> + + + + + <html><head/><body><p><a href="https://github.com/pontostroy"><span style=" text-decoration: underline; color:#2980b9;">Pontostroy</span></a></p></body></html> + + + + + + + Time (s) + Czas (s) + + + Temperature (°C) + Temperatura (°C) + + + + Clock (MHz) + Zegar (MHz) + + + + Voltage (mV) + Napięcie (mV) + + + Show + Pokaż + + + + + I/O voltage (vddci) + Napięcie I/O (vddci) + + + + Temperature (°C) + Temperatura (°C) + + + + + Quit + Zamknij + + + + Change standard profile + Zmień standardowy profil + + + + Keep refreshing when hidden + Odświeżaj kiedy okno schowane + + + + Reset min/max temperature + Resetuj temperatury min/max + + + + Reset graphs vertical scale + Zresetuj pionową skalę wykresu + + + + Show legend + Pokaż legendę + + + + Graph offset on right + Odstęp od prawej krawędzi wykresu + + + + Force power level + Wymuś stan + + + + + Copy to clipboard + Kopiuj do schowka + + + + Reset statistics + Resetuj statystyki + + + + + Fixed + Stała + + + + version %n + wersja %n + + + + Back to profiles + Powrót do profili + + + + + UVD core clock (cclk) + Zegar rdzenia UVD (cclk) + + + + + UVD decoder clock (dclk) + Zegar dekodera UVD (dclk) + + + + + GPU voltage (vddc) + Napięcie rdzenia GPU (vddc) + + + + Current profile: + + + + Your driver or your GPU does not support overclocking + Sterownik nie obsuguje podkręcania + + + + You need debugfs mounted and either root rights or the daemon running + Debugfs musi być zamontowany oraz uruchomiony daemon lub radeon-profile w trybie roota + + + Maximum GPU clock + Maksymalny zegar GPU + + + Minimum GPU clock + Minimalny zegar GPU + + + UVD core clock + Zegar UVD + + + UVD decoder clock + Zegar dekodera UVD + + + + Can't read data + Nie można odczytać danych + + + + + + + + + + + + Error + Błąd + + + + Profile name can't be empty! + Nazwa profilu nie może być pusta! + + + + No binary is selected! + Nie wskazano pliku wykonywalnego! + + + + Binary not found in /usr/bin: + Nie znaleziono pliku wykonywalnego w /usr/bin: + + + + Enter value + Wprowadź wartość + + + + Enter valid value for + Wprowadź poprawną wartość dla: + + + + + Remove this item? + Usunąć pozycję? + + + + + Question + Pytanie + + + + Select binary + Wskaż plik wykonywalny + + + + Select log file + Wskaż plik logu + + + + Can't run something that not exists! + Nie można uruchomić nieistniejącego pliku! + + + The selected binary does not exist! + Wskazany plik wykonywalny nie istnieje! + + + The selected file is not executable! + Wskazany plik nie jest wykonywalny! + + + + Run: " + Uruchomić " + + + + is still running, exit anyway? + jest uruchomiony. Zamknąć mimo to? + + + + GPU data is disabled + Informacje GPU wyłączone + + + Stats disabled + Statystyki wyłączone + + + + Select new power profile + Wskaż nowy profil + + + + Profile selection + Wybór profilu + + + + Process is still running. Close tab? + Proces jest uruchomiony. Zamknąć zakładkę? + + + + This step already exists. Double click on it, to change its value + Ta wartość już istnieje. Kliknij dwukrotnie aby edytować. + + + + + Speed [%] + Prędkość [%] + + + + You can't edit the last item + Edycja ostatniej pozycji zablokowana + + + + You can't edit temperature of the first item + Edycja temperatury pierwszej pozycji zablokowana + + + Speed [%] (10-100) + Prędkość [%] + + + + An error occurred, overclock failed + Wystąpił błąd, podkręcanie nie powiodło się. + + + + Cannot remove default profile. + Nie można usunąć profilu 'defalut' + + + + Remove profile: + Usunąć profil: + + + + Fan profile name: + Nazwa profilu: + + + + Profile name musn't contain '|' character. + Nazwa profilu nie może zawierać znaku '|' + + + + Cannot add another profile with the same name that already exists. + Nie można dodać kolejnego profilu o tej samej nazwie. + + + + Cannot activate unsaved profile. Do you want to save it? + Profil nie jest zapisany. Czy chcesz zapisać? + + + + Export destination directory + Katalog do eksportu + + + + This option may cause overheat of your card and it is your responsibility if this happens. Do you want to enable it? + Włączenie tej opcji może spowodować, że karta zostanie uszkodzona przez zbyt wysoką temperaturę. Robisz to na własną odpowiedzialność. Czy włączyć tę opcję? + + + Process running + Proces uruchomiony + + + + Fan control information + Informacje o wentylatorze + + + + Don't overheat your card! Be careful! Don't use this if you don't know what you're doing! + +Hovewer, looks like card won't apply too low values due its internal protection. + +Closing application will restore fan control to Auto. If application crashes, last fan value will remain, so you have been warned! + Bądź ostrożny, nie przegrzej swojej karty! Używaj wtedy gdy wiesz co robisz. + +Warto jednak zaznaczyć, że karta ma własne zabezpieczenia, które nie pozwolą na ustawienie zbyt niskiej prędkości jeśli nie jest to możliwe. + +Zamykając aplikację, wiatrak ustawiany jest z powrotem na Auto. Jeśli program zostanie nieoczekiwanie zamknięty (np. z powodu błędu) ustawienie to nie zostanie przywrócone więc warto mieć na nie oko. + + + This step already exists. To edit it double click it + Taka wartość już instnieje. Kliknij dwa razy żeby poprawić. + + + Speed [%] (20-100) + Prędkość [%] (10-100) + + + + You can't delete the first and the last item + Nie można usunąć pierwszej i ostatniej wartości + + + You can't edit the first and the last item + Nie można edytować pierwszej i ostatniej wartości + + + An error occurred, GPU overclock failed + Wystąpił błąd, podkręcanie nie powiodło się. + + + An error occurred, memory overclock failed + Wystąpił błąd, podkręcanie pamięci nie powiodło się. + + + + Events info + Informacje o zdarzeniach + + + + Here you can define events. Each event has a defined condition, and when this condition is fulfilled, event is activated. + +After activation, defined power profile, power level and fan profile are applied. When one of events is activated, tracking is suspended. + +When active event condition is no longer true, event is revoked and power profile, power level and fan profile are restored to state before event was activated. + Tutaj możesz zdefiniować zdarzenia. Każde z nich ma zdefiniowany warunek i kiedy ten warunek zostanie spełniony, zdarzenie zostaje aktywowane. + +Po aktywacji, zdefiniowany profil i poziom zarządzania energią oraz profil wiatraka zostają przestawione. Kiedy jedno ze zdarzeń jest aktywne, sprawdzanie pozostałych jest wstrzymane. + +Kiedy warunek włączenia aktywnego zdarzenie nie jest prawdziwy, zostaje ono wyłaczone a profil i poziom zarządzania energią oraz profil wiartaka zostają przywrócone do poprzedniego stanu. + + + + Cannot remove event that is currently active. + Nie można usunąć zdarzenie, które jest włączone. + + + + Do you want to remove event: + Czy chcesz usunąć zdarzenie: + + + diff -Nru radeon-profile-0.1.10~yakkety/uiElements.cpp radeon-profile-0.1.17~yakkety/uiElements.cpp --- radeon-profile-0.1.10~yakkety/uiElements.cpp 2016-06-28 14:42:31.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/uiElements.cpp 2017-01-25 18:00:11.000000000 +0000 @@ -14,12 +14,12 @@ ui->plotClocks->yAxis->setRange(startClocksScaleL,startClocksScaleH); ui->plotVolts->yAxis->setRange(startVoltsScaleL,startVoltsScaleH); - ui->plotTemp->xAxis->setLabel(label_timeAxis); - ui->plotTemp->yAxis->setLabel(label_temperatureAxis); - ui->plotClocks->xAxis->setLabel(label_timeAxis); - ui->plotClocks->yAxis->setLabel(label_clockAxis); - ui->plotVolts->xAxis->setLabel(label_timeAxis); - ui->plotVolts->yAxis->setLabel(label_voltageAxis); + ui->plotTemp->xAxis->setLabel(tr("Time (s)")); + ui->plotTemp->yAxis->setLabel(tr("Temperature (°C)")); + ui->plotClocks->xAxis->setLabel(tr("Time (s)")); + ui->plotClocks->yAxis->setLabel(tr("Clock (MHz)")); + ui->plotVolts->xAxis->setLabel(tr("Time (s)")); + ui->plotVolts->yAxis->setLabel(tr("Voltage (mV)")); ui->plotTemp->xAxis->setTickLabels(false); ui->plotClocks->xAxis->setTickLabels(false); ui->plotVolts->xAxis->setTickLabels(false); @@ -35,21 +35,21 @@ ui->plotFanProfile->addGraph(); ui->plotFanProfile->yAxis->setRange(0,100); ui->plotFanProfile->xAxis->setRange(0,110); - ui->plotFanProfile->xAxis->setLabel(label_temperature); - ui->plotFanProfile->yAxis->setLabel(label_fanSpeed); + ui->plotFanProfile->xAxis->setLabel(tr("Temperature")); + ui->plotFanProfile->yAxis->setLabel(tr("Fan speed")); setupGraphsStyle(); // legend clocks // - ui->plotClocks->graph(0)->setName(label_currentGPUClock); - ui->plotClocks->graph(1)->setName(label_currentMemClock); - ui->plotClocks->graph(2)->setName(label_uvdVideoCoreClock); - ui->plotClocks->graph(3)->setName(label_uvdDecoderClock); + ui->plotClocks->graph(0)->setName(tr("GPU clock")); + ui->plotClocks->graph(1)->setName(tr("Memory clock")); + ui->plotClocks->graph(2)->setName(tr("UVD core clock (cclk)")); + ui->plotClocks->graph(3)->setName(tr("UVD decoder clock (dclk)")); ui->plotClocks->axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignTop|Qt::AlignLeft); ui->plotClocks->legend->setVisible(true); - ui->plotVolts->graph(0)->setName(label_vddc); - ui->plotVolts->graph(1)->setName(label_vddci); + ui->plotVolts->graph(0)->setName(tr("GPU voltage (vddc)")); + ui->plotVolts->graph(1)->setName(tr("I/O voltage (vddci)")); ui->plotVolts->axisRect()->insetLayout()->setInsetAlignment(0,Qt::AlignTop|Qt::AlignLeft); ui->plotVolts->legend->setVisible(true); @@ -86,37 +86,37 @@ } void radeon_profile::setupTrayIcon() { - trayMenu = new QMenu(); + trayMenu = new QMenu(this); setWindowState(Qt::WindowMinimized); //close // - closeApp = new QAction(this); - closeApp->setText(label_quit); + closeApp = new QAction(trayMenu); + closeApp->setText(tr("Quit")); connect(closeApp,SIGNAL(triggered()),this,SLOT(closeFromTray())); // standard profiles - changeProfile = new QAction(this); - changeProfile->setText(label_changeProfile); + changeProfile = new QAction(trayMenu); + changeProfile->setText(tr("Change standard profile")); connect(changeProfile,SIGNAL(triggered()),this,SLOT(on_chProfile_clicked())); // refresh when hidden - refreshWhenHidden = new QAction(this); + refreshWhenHidden = new QAction(trayMenu); refreshWhenHidden->setCheckable(true); refreshWhenHidden->setChecked(true); - refreshWhenHidden->setText(label_refreshWhenHidden); + refreshWhenHidden->setText(tr("Keep refreshing when hidden")); // dpm menu // dpmMenu = new QMenu(this); - dpmMenu->setTitle(label_dpm); + dpmMenu->setTitle(tr("DPM")); - dpmSetBattery = new QAction(this); - dpmSetBalanced = new QAction(this); - dpmSetPerformance = new QAction(this); + dpmSetBattery = new QAction(dpmMenu); + dpmSetBalanced = new QAction(dpmMenu); + dpmSetPerformance = new QAction(dpmMenu); - dpmSetBattery->setText(label_battery); + dpmSetBattery->setText(tr("Battery")); dpmSetBattery->setIcon(QIcon(":/icon/symbols/arrow1.png")); - dpmSetBalanced->setText(label_performance); + dpmSetBalanced->setText(tr("Balanced")); dpmSetBalanced->setIcon(QIcon(":/icon/symbols/arrow2.png")); - dpmSetPerformance->setText(label_performance); + dpmSetPerformance->setText(tr("Performance")); dpmSetPerformance->setIcon(QIcon(":/icon/symbols/arrow3.png")); connect(dpmSetBattery,SIGNAL(triggered()),this,SLOT(on_btn_dpmBattery_clicked())); @@ -150,19 +150,19 @@ optionsMenu = new QMenu(this); ui->btn_options->setMenu(optionsMenu); - QAction *resetMinMax = new QAction(this); - resetMinMax->setText(label_resetMinMax); + QAction *resetMinMax = new QAction(optionsMenu); + resetMinMax->setText(tr("Reset min/max temperature")); - QAction *resetGraphs = new QAction(this); - resetGraphs->setText(label_resetGraphs); + QAction *resetGraphs = new QAction(optionsMenu); + resetGraphs->setText(tr("Reset graphs vertical scale")); - QAction *showLegend = new QAction(this); - showLegend->setText(label_showLegend); + QAction *showLegend = new QAction(optionsMenu); + showLegend->setText(tr("Show legend")); showLegend->setCheckable(true); showLegend->setChecked(true); - QAction *graphOffset = new QAction(this); - graphOffset->setText(label_graphOffset); + QAction *graphOffset = new QAction(optionsMenu); + graphOffset->setText(tr("Graph offset on right")); graphOffset->setCheckable(true); graphOffset->setChecked(true); @@ -181,16 +181,16 @@ void radeon_profile::setupForcePowerLevelMenu() { forcePowerMenu = new QMenu(this); - QAction *forceAuto = new QAction(this); - forceAuto->setText(label_auto); + QAction *forceAuto = new QAction(forcePowerMenu); + forceAuto->setText(tr("Auto")); - QAction *forceLow = new QAction(this); - forceLow->setText(label_low); + QAction *forceLow = new QAction(forcePowerMenu); + forceLow->setText(tr("Low")); - QAction *forceHigh = new QAction(this); - forceHigh->setText(label_high); + QAction *forceHigh = new QAction(forcePowerMenu); + forceHigh->setText(tr("High")); - forcePowerMenu->setTitle(label_forcePowerLevel); + forcePowerMenu->setTitle(tr("Force power level")); forcePowerMenu->addAction(forceAuto); forcePowerMenu->addSeparator(); forcePowerMenu->addAction(forceLow); @@ -203,22 +203,70 @@ void radeon_profile::setupContextMenus() { QAction *copyToClipboard = new QAction(this); - copyToClipboard->setText(label_copyToClipboard); + copyToClipboard->setText(tr("Copy to clipboard")); ui->list_glxinfo->setContextMenuPolicy(Qt::ActionsContextMenu); ui->list_glxinfo->addAction(copyToClipboard); connect(copyToClipboard, SIGNAL(triggered()),this,SLOT(copyGlxInfoToClipboard())); QAction * copyConnectors = new QAction(this); - copyConnectors->setText(label_copyToClipboard); + copyConnectors->setText(tr("Copy to clipboard")); ui->list_connectors->setContextMenuPolicy(Qt::ActionsContextMenu); ui->list_connectors->addAction(copyConnectors); connect(copyConnectors, SIGNAL(triggered()), this, SLOT(copyConnectorsToClipboard())); QAction *reset = new QAction(this); - reset->setText(label_resetStatistics); + reset->setText(tr("Reset statistics")); ui->list_stats->setContextMenuPolicy(Qt::ActionsContextMenu); ui->list_stats->addAction(reset); connect(reset,SIGNAL(triggered()),this,SLOT(resetStats())); } -//======== +void radeon_profile::setupFanProfilesMenu(const bool rebuildMode) { + if (rebuildMode) + delete fanProfilesMenu; + + fanProfilesMenu = new QMenu(this); + connect(fanProfilesMenu, SIGNAL(triggered(QAction*)), this, SLOT(fanProfileMenuActionClicked(QAction*))); + QActionGroup *ag = new QActionGroup(fanProfilesMenu); + + QAction *fanAuto = new QAction(fanProfilesMenu); + fanAuto->setText(tr("Auto")); + fanAuto->setCheckable(true); + fanAuto->setChecked(true); + fanAuto->setActionGroup(ag); + connect(fanAuto, SIGNAL(triggered()), this, SLOT(on_btn_pwmAuto_clicked())); + + QAction *fanFixed = new QAction(fanProfilesMenu); + fanFixed->setText(tr("Fixed ") + ui->labelFixedSpeed->text()); + fanFixed->setCheckable(true); + fanFixed->setActionGroup(ag); + connect(fanFixed, SIGNAL(triggered()), this, SLOT(on_btn_pwmFixed_clicked())); + + fanProfilesMenu->addAction(fanAuto); + fanProfilesMenu->addAction(fanFixed); + + fanProfilesMenu->addSeparator(); + + for (QString p : fanProfiles.keys()) { + QAction *a = new QAction(fanProfilesMenu); + a->setText(p); + a->setCheckable(true); + a->setActionGroup(ag); + fanProfilesMenu->addAction(a); + } + + ui->l_fanSpeed->setMenu(fanProfilesMenu); +} + +void radeon_profile::fillConnectors(){ + ui->list_connectors->clear(); + ui->list_connectors->addTopLevelItems(device.getCardConnectors()); + ui->list_connectors->expandToDepth(2); + ui->list_connectors->header()->resizeSections(QHeaderView::ResizeToContents); +} + +void radeon_profile::fillModInfo(){ + ui->list_modInfo->clear(); + ui->list_modInfo->addTopLevelItems(device.getModuleInfo()); + ui->list_modInfo->header()->resizeSections(QHeaderView::ResizeToContents); +} diff -Nru radeon-profile-0.1.10~yakkety/uiEvents.cpp radeon-profile-0.1.17~yakkety/uiEvents.cpp --- radeon-profile-0.1.10~yakkety/uiEvents.cpp 2016-06-28 14:42:31.000000000 +0000 +++ radeon-profile-0.1.17~yakkety/uiEvents.cpp 2017-01-25 18:00:11.000000000 +0000 @@ -10,6 +10,8 @@ #include #include #include +#include +#include bool closeFromTrayMenu; @@ -53,10 +55,13 @@ void radeon_profile::on_btn_pwmFixedApply_clicked() { device.setPwmValue(ui->fanSpeedSlider->value()); + fanProfilesMenu->actions()[1]->setText(tr("Fixed ") + ui->labelFixedSpeed->text()); } void radeon_profile::on_btn_pwmFixed_clicked() { + ui->btn_pwmFixed->setChecked(true); + fanProfilesMenu->actions()[1]->setChecked(true); ui->fanModesTabs->setCurrentIndex(1); device.setPwmManualControl(true); @@ -65,30 +70,25 @@ void radeon_profile::on_btn_pwmAuto_clicked() { + ui->btn_pwmAuto->setChecked(true); + fanProfilesMenu->actions()[0]->setChecked(true); device.setPwmManualControl(false); ui->fanModesTabs->setCurrentIndex(0); } void radeon_profile::on_btn_pwmProfile_clicked() { + ui->btn_pwmProfile->setChecked(true); ui->fanModesTabs->setCurrentIndex(2); device.setPwmManualControl(true); - - adjustFanSpeed(true); + setCurrentFanProfile(ui->l_currentFanProfile->text(), fanProfiles.value(ui->l_currentFanProfile->text())); } void radeon_profile::changeProfileFromCombo() { - int index = ui->combo_pProfile->currentIndex(); - - globalStuff::powerProfiles newPP = (globalStuff::powerProfiles)index; - - if (device.features.pm == globalStuff::DPM) - device.setPowerProfile(newPP); - else { - index = index + 3; // frist three in enum is dpm so we need to increase - device.setPowerProfile(newPP); - } + device.setPowerProfile(static_cast((device.features.pm == globalStuff::DPM) ? + ui->combo_pProfile->currentIndex() : + ui->combo_pProfile->currentIndex() + 3)); // frist three in enum is dpm so we need to increase } void radeon_profile::changePowerLevelFromCombo() { @@ -154,15 +154,12 @@ void radeon_profile::changeEvent(QEvent *event) { - if(event->type() == QEvent::WindowStateChange && ui->cb_minimizeTray->isChecked()) { - if(isMinimized()) + if (event->type() == QEvent::WindowStateChange && ui->cb_minimizeTray->isChecked()) { + if (isMinimized()) this->hide(); - event->ignore(); - } - if (event->type() == QEvent::Close && ui->cb_closeTray) { - this->hide(); - event->ignore(); + event->accept(); + return; } } @@ -191,18 +188,28 @@ if (ui->cb_closeTray->isChecked() && !closeFromTrayMenu) { this->hide(); e->ignore(); - } else { - - timer->stop(); - saveConfig(); + return; + } - if (device.features.pwmAvailable) { - device.setPwmManualControl(false); - saveFanProfiles(); + //Check if a process is still running + for(execBin * process : execsRunning) { + if(process->getExecState() == QProcess::Running + && ! askConfirmation(tr("Quit"), process->name + tr(" is still running, exit anyway?"))) { + e->ignore(); + return; } - QCoreApplication::processEvents(QEventLoop::AllEvents, 50); // Wait for the daemon to disable pwm - QApplication::quit(); } + + timer->stop(); + delete timer; + + saveConfig(); + + if (device.features.pwmAvailable) + device.setPwmManualControl(false); + + QCoreApplication::processEvents(QEventLoop::AllEvents, 50); // Wait for the daemon to disable pwm + QApplication::quit(); } void radeon_profile::closeFromTray() { @@ -212,6 +219,7 @@ void radeon_profile::on_spin_lineThick_valueChanged(int arg1) { + Q_UNUSED(arg1) setupGraphsStyle(); } @@ -238,7 +246,7 @@ if (!checked) { ui->list_currentGPUData->clear(); - ui->list_currentGPUData->addTopLevelItem(new QTreeWidgetItem(QStringList() << label_dataDisabled)); + ui->list_currentGPUData->addTopLevelItem(new QTreeWidgetItem(QStringList() << tr("GPU data is disabled"))); } } @@ -246,16 +254,14 @@ ui->list_glxinfo->clear(); ui->list_glxinfo->addItems(device.getGLXInfo(ui->combo_gpus->currentText())); - ui->list_connectors->clear(); - ui->list_connectors->addTopLevelItems(device.getCardConnectors()); - ui->list_connectors->expandToDepth(2); + fillConnectors(); - ui->list_modInfo->clear(); - ui->list_modInfo->addTopLevelItems(device.getModuleInfo()); + fillModInfo(); } void radeon_profile::on_graphColorsList_itemDoubleClicked(QTreeWidgetItem *item, int column) { + Q_UNUSED(column) QColor c = QColorDialog::getColor(item->backgroundColor(1)); if (c.isValid()) { item->setBackgroundColor(1,c); @@ -315,10 +321,8 @@ void radeon_profile::on_chProfile_clicked() { bool ok; - QStringList profiles; - profiles << profile_auto << profile_default << profile_high << profile_mid << profile_low; - QString selection = QInputDialog::getItem(this, label_selectProfile, label_profileSelection, profiles,0,false,&ok); + QString selection = QInputDialog::getItem(this, tr("Select new power profile"), tr("Profile selection"), globalStuff::createProfileCombo(), 0, false, &ok); if (ok) { if (selection == profile_default) @@ -341,93 +345,19 @@ void radeon_profile::on_tabs_execOutputs_tabCloseRequested(int index) { - if (execsRunning->at(index)->getExecState() == QProcess::Running) { - if (QMessageBox::question(this,"", label_processStillRunning, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::No) + if (execsRunning.at(index)->getExecState() == QProcess::Running) { + if (QMessageBox::question(this,"", tr("Process is still running. Close tab?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::No) return; } ui->tabs_execOutputs->removeTab(index); - execsRunning->removeAt(index); + execsRunning.removeAt(index); if (ui->tabs_execOutputs->count() == 0) btnBackToProfilesClicked(); } -void radeon_profile::on_btn_fanInfo_clicked() -{ - QMessageBox::information(this,label_fanControlInfo, label_fanControlWarning); -} - -void radeon_profile::on_btn_addFanStep_clicked() -{ - const int temperature = askNumber(0, minFanStepsTemp, maxFanStepsTemp, label_temperature); - if (temperature == -1) // User clicked Cancel - return; - - if (fanSteps.contains(temperature)) // A step with this temperature already exists - QMessageBox::warning(this, label_error, label_howToEdit); - else { // This step does not exist, proceed - const int fanSpeed = askNumber(0, minFanStepsSpeed, maxFanStepsSpeed, label_fanSpeedRange); - if (fanSpeed == -1) // User clicked Cancel - return; - - addFanStep(temperature,fanSpeed); - - } -} - -void radeon_profile::on_btn_removeFanStep_clicked() -{ - QTreeWidgetItem *current = ui->list_fanSteps->currentItem(); - - if (ui->list_fanSteps->indexOfTopLevelItem(current) == 0 || ui->list_fanSteps->indexOfTopLevelItem(current) == ui->list_fanSteps->topLevelItemCount()-1) { - // The selected item is the first or the last, it can't be deleted - QMessageBox::warning(this, label_error, label_cantDeleteThisItem); - return; - } - - // The selected item can be removed, remove it - int temperature = current->text(0).toInt(); - - fanSteps.remove(temperature); - adjustFanSpeed(true); - - // Remove the step from the list and from the graph - delete current; - ui->plotFanProfile->graph(0)->removeData(temperature); - ui->plotFanProfile->replot(); -} - - -void radeon_profile::on_list_fanSteps_itemDoubleClicked(QTreeWidgetItem *item, int column) -{ - if (ui->list_fanSteps->indexOfTopLevelItem(item) == 0 || ui->list_fanSteps->indexOfTopLevelItem(item) == ui->list_fanSteps->topLevelItemCount()-1) { - // The selected item is the first or the last, it can't be edited - QMessageBox::warning(this, label_error, label_cantEditThisItem); - return; - } - - const int oldTemp = item->text(0).toInt(), oldSpeed = item->text(1).toInt(); - int newTemp, newSpeed; - - if(column == 0){ // The user wants to change the temperature - newTemp = askNumber(oldTemp, minFanStepsTemp, maxFanStepsTemp, label_temperature); - if(newTemp != -1){ - newSpeed = oldSpeed; - fanSteps.remove(oldTemp); - delete item; - ui->plotFanProfile->graph(0)->removeData(oldTemp); - addFanStep(newTemp,newSpeed); - } - } else { // The user wants to change the speed - newTemp = oldTemp; - newSpeed = askNumber(oldSpeed, minFanStepsSpeed, maxFanStepsSpeed, label_fanSpeedRange); - // addFanStep() will check the validity of newSpeed and overwrite the current step - addFanStep(newTemp,newSpeed); - } -} - int radeon_profile::askNumber(const int value, const int min, const int max, const QString label) { bool ok; int number = QInputDialog::getInt(this,"",label,value,min,max,1, &ok); @@ -438,13 +368,6 @@ return number; } -void radeon_profile::on_fanSpeedSlider_valueChanged(int value) -{ - ui->labelFixedSpeed->setText(QString().setNum(((float)value / device.features.pwmMaxSpeed) * 100,'f',0)); -} - -//======== - void radeon_profile::on_cb_enableOverclock_toggled(const bool enable){ ui->slider_overclock->setEnabled(enable); ui->btn_applyOverclock->setEnabled(enable); @@ -460,9 +383,26 @@ void radeon_profile::on_btn_applyOverclock_clicked(){ if( ! device.overclock(ui->slider_overclock->value())) - QMessageBox::warning(this, label_error, label_overclockFailed); + QMessageBox::warning(this, tr("Error"), tr("An error occurred, overclock failed")); } void radeon_profile::on_slider_overclock_valueChanged(const int value){ ui->label_overclockPercentage->setText(QString::number(value)); } + +void radeon_profile::on_btn_export_clicked(){ + QString folder = QFileDialog::getExistingDirectory(this, tr("Export destination directory")); + + if (!folder.isEmpty()) { + qDebug() << "Exporting graphs into " << folder; + + if (ui->cb_showTempsGraph->isChecked()) + ui->plotTemp->savePng(folder + "/temperature.png"); + + if (ui->cb_showFreqGraph->isChecked()) + ui->plotClocks->savePng(folder + "/clocks.png"); + + if (ui->cb_showVoltsGraph->isChecked()) + ui->plotVolts->savePng(folder + "/voltages.png"); + } +}