summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Janes <mark.a.janes@intel.com>2017-03-03 11:01:12 -0800
committerMark Janes <mark.a.janes@intel.com>2017-06-19 14:04:50 -0700
commit2047f6ce05e5f28d9f47f8171b369d6434fdcfda (patch)
tree3b857551b4ca7488196bc75fe3b7838c0fa5ba40
parent518b608e11bf7443d4a261309b793c50fbae54ac (diff)
OpenFile: Provide warning when gpu clock rate can change
GPU power management generates fluctuations in metrics data. For stable metric analysis, the GPU clock rate should be pegged at the maximum. Provide a warning to the user when the clock is not pegged, and instructions on how to peg the clock.
-rw-r--r--retrace/daemon/CMakeLists.txt2
-rw-r--r--retrace/daemon/glframe_gpu_speed.hpp43
-rw-r--r--retrace/daemon/glframe_gpu_speed_linux.cpp65
-rw-r--r--retrace/daemon/glframe_retrace.cpp2
-rw-r--r--retrace/daemon/glframe_retrace_stub.cpp2
-rw-r--r--retrace/daemon/ui/glframe_retrace_model.cpp10
-rw-r--r--retrace/daemon/ui/glframe_retrace_model.hpp8
-rw-r--r--retrace/daemon/ui/qml/mainwin.qml5
8 files changed, 137 insertions, 0 deletions
diff --git a/retrace/daemon/CMakeLists.txt b/retrace/daemon/CMakeLists.txt
index 60a75edc..b2affde4 100644
--- a/retrace/daemon/CMakeLists.txt
+++ b/retrace/daemon/CMakeLists.txt
@@ -29,6 +29,7 @@ set (RETRACE_LINUX_SOURCE
glframe_os_linux.cpp
glframe_stderr.cpp
glframe_thread_linux.cpp
+ glframe_gpu_speed_linux.cpp
)
set (RETRACE_WIN_SOURCE
@@ -45,6 +46,7 @@ endif()
set (RETRACE_SOURCES
${RETRACE_OS_SOURCE}
+ glframe_gpu_speed.hpp
glframe_metrics.cpp
glframe_metrics.hpp
glframe_os.hpp
diff --git a/retrace/daemon/glframe_gpu_speed.hpp b/retrace/daemon/glframe_gpu_speed.hpp
new file mode 100644
index 00000000..7567aae7
--- /dev/null
+++ b/retrace/daemon/glframe_gpu_speed.hpp
@@ -0,0 +1,43 @@
+// Copyright (C) Intel Corp. 2017. All Rights Reserved.
+
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+
+// The above copyright notice and this permission notice (including the
+// next paragraph) shall be included in all copies or substantial
+// portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// **********************************************************************/
+// * Authors:
+// * Mark Janes <mark.a.janes@intel.com>
+// **********************************************************************/
+
+#ifndef _GLFRAME_GPU_SPEED_H_
+#define _GLFRAME_GPU_SPEED_H_
+
+
+namespace glretrace {
+class OnFrameRetrace;
+
+void check_gpu_speed(OnFrameRetrace *callback);
+
+#ifdef WIN32
+void check_gpu_speed(OnFrameRetrace *callback) {}
+#endif
+
+} // namespace glretrace
+
+#endif // _GLFRAME_GPU_SPEED_H_
diff --git a/retrace/daemon/glframe_gpu_speed_linux.cpp b/retrace/daemon/glframe_gpu_speed_linux.cpp
new file mode 100644
index 00000000..ac6989a5
--- /dev/null
+++ b/retrace/daemon/glframe_gpu_speed_linux.cpp
@@ -0,0 +1,65 @@
+// Copyright (C) Intel Corp. 2017. All Rights Reserved.
+
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+
+// The above copyright notice and this permission notice (including the
+// next paragraph) shall be included in all copies or substantial
+// portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// **********************************************************************/
+// * Authors:
+// * Mark Janes <mark.a.janes@intel.com>
+// **********************************************************************/
+
+#include "glframe_gpu_speed.hpp"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <vector>
+#include <sstream>
+
+#include "glframe_retrace_interface.hpp"
+
+using glretrace::check_gpu_speed;
+using glretrace::OnFrameRetrace;
+
+void
+glretrace::check_gpu_speed(OnFrameRetrace *callback) {
+ FILE * fh = fopen("/sys/class/drm/card0/gt_max_freq_mhz", "r");
+ std::vector<unsigned char> buf(100);
+ size_t bytes = fread(buf.data(), 1, 99, fh);
+ buf[bytes] = '\0';
+ const int max_rate = atoi(reinterpret_cast<char*>(buf.data()));
+ fclose(fh);
+ fh = fopen("/sys/class/drm/card0/gt_min_freq_mhz", "r");
+ bytes = fread(buf.data(), 1, 99, fh);
+ buf[bytes] = '\0';
+ const int min_rate = atoi(reinterpret_cast<char*>(buf.data()));
+ fclose(fh);
+
+ if (min_rate == max_rate)
+ return;
+
+ std::stringstream msg;
+ msg << "The target platform gpu clock rate is not fixed.\n" <<
+ "To stabilize metrics, execute as root:" <<
+ " `cat /sys/class/drm/card0/gt_max_freq_mhz > " <<
+ "/sys/class/drm/card0/gt_min_freq_mhz`";
+ callback->onError(msg.str());
+}
+
diff --git a/retrace/daemon/glframe_retrace.cpp b/retrace/daemon/glframe_retrace.cpp
index 1f0146af..8c1d54dc 100644
--- a/retrace/daemon/glframe_retrace.cpp
+++ b/retrace/daemon/glframe_retrace.cpp
@@ -49,6 +49,7 @@
#include "glstate.hpp"
#include "glstate_internal.hpp"
#include "trace_dump.hpp"
+#include "glframe_gpu_speed.hpp"
using glretrace::ExperimentId;
using glretrace::FrameRetrace;
@@ -107,6 +108,7 @@ FrameRetrace::openFile(const std::string &filename,
uint64_t fileSize,
uint32_t framenumber,
OnFrameRetrace *callback) {
+ check_gpu_speed(callback);
assemblyOutput.init();
retrace::debug = 0;
retracer.addCallbacks(glretrace::gl_callbacks);
diff --git a/retrace/daemon/glframe_retrace_stub.cpp b/retrace/daemon/glframe_retrace_stub.cpp
index b501aeb1..c18e359f 100644
--- a/retrace/daemon/glframe_retrace_stub.cpp
+++ b/retrace/daemon/glframe_retrace_stub.cpp
@@ -346,6 +346,8 @@ class RetraceOpenFileRequest: public IRetraceRequest {
status.percent_complete());
if (status.finished())
break;
+ } else if (response.has_error()) {
+ m_callback->onError(response.error().message());
} else {
assert(response.has_metricslist());
std::vector<MetricId> ids;
diff --git a/retrace/daemon/ui/glframe_retrace_model.cpp b/retrace/daemon/ui/glframe_retrace_model.cpp
index b7b429c8..74b7b0ff 100644
--- a/retrace/daemon/ui/glframe_retrace_model.cpp
+++ b/retrace/daemon/ui/glframe_retrace_model.cpp
@@ -479,6 +479,16 @@ FrameRetraceModel::onApi(SelectionId selectionCount,
void
FrameRetraceModel::onError(const std::string &message) {
GRLOG(ERR, message.c_str());
+
+ // split on newline, to provide additional context behind the "show
+ // details" button.
+ QString m(message.c_str());
+ QStringList m_l = m.split("\n");
+ m_general_error = m_l[0];
+ m_general_error_details = "";
+ if (m_l.size() > 1)
+ m_general_error_details = m_l[1];
+ emit onGeneralError();
}
void
diff --git a/retrace/daemon/ui/glframe_retrace_model.hpp b/retrace/daemon/ui/glframe_retrace_model.hpp
index 29170679..2f5fb7b5 100644
--- a/retrace/daemon/ui/glframe_retrace_model.hpp
+++ b/retrace/daemon/ui/glframe_retrace_model.hpp
@@ -115,6 +115,10 @@ class FrameRetraceModel : public QObject,
Q_PROPERTY(QString argvZero READ argvZero WRITE setArgvZero
NOTIFY onArgvZero)
Q_PROPERTY(glretrace::QMetricsModel* metricTab READ metricTab CONSTANT)
+ Q_PROPERTY(QString generalError READ generalError
+ NOTIFY onGeneralError)
+ Q_PROPERTY(QString generalErrorDetails READ generalErrorDetails
+ NOTIFY onGeneralError)
public:
FrameRetraceModel();
@@ -171,6 +175,8 @@ class FrameRetraceModel : public QObject,
QString argvZero() { return main_exe; }
void setArgvZero(const QString &a) { main_exe = a; emit onArgvZero(); }
QMetricsModel *metricTab() { return &m_metrics_table; }
+ QString generalError() { return m_general_error; }
+ QString generalErrorDetails() { return m_general_error_details; }
bool clearBeforeRender() const;
void setClearBeforeRender(bool v);
@@ -192,6 +198,7 @@ class FrameRetraceModel : public QObject,
void onApiCalls();
void onShaderCompileError();
void onArgvZero();
+ void onGeneralError();
// this signal transfers onMetricList to be handled in the UI
// thread. The handler generates QObjects which are passed to qml
@@ -227,6 +234,7 @@ class FrameRetraceModel : public QObject,
std::vector<MetricId> m_active_metrics;
float m_max_metric;
bool m_clear_before_render, m_stop_at_render, m_highlight_render;
+ QString m_general_error, m_general_error_details;
};
} // namespace glretrace
diff --git a/retrace/daemon/ui/qml/mainwin.qml b/retrace/daemon/ui/qml/mainwin.qml
index dcab4445..71feb160 100644
--- a/retrace/daemon/ui/qml/mainwin.qml
+++ b/retrace/daemon/ui/qml/mainwin.qml
@@ -27,6 +27,11 @@ ApplicationWindow {
progressBar.visible = false;
mainUI.visible = true;
}
+ onGeneralErrorChanged: {
+ fileError.text = frameRetrace.generalError;
+ fileError.detailedText = frameRetrace.generalErrorDetails;
+ fileError.visible = true;
+ }
}
MessageDialog {