diff --git a/qrenderdoc/Windows/Dialogs/PerformanceCounterSelection.cpp b/qrenderdoc/Windows/Dialogs/PerformanceCounterSelection.cpp
index cc010f519..9a1bc5e94 100644
--- a/qrenderdoc/Windows/Dialogs/PerformanceCounterSelection.cpp
+++ b/qrenderdoc/Windows/Dialogs/PerformanceCounterSelection.cpp
@@ -62,223 +62,128 @@ CounterFamily GetCounterFamily(GPUCounter counter)
return CounterFamily::Generic;
}
-const char *ToString(CounterFamily family)
+QString ToString(CounterFamily family)
{
switch(family)
{
- case CounterFamily::AMD: return "AMD";
- case CounterFamily::Generic: return "Generic";
- case CounterFamily::Intel: return "Intel";
- case CounterFamily::NVIDIA: return "NVIDIA";
- case CounterFamily::Unknown: return "Unknown";
+ case CounterFamily::AMD: return lit("AMD");
+ case CounterFamily::Generic: return lit("Generic");
+ case CounterFamily::Intel: return lit("Intel");
+ case CounterFamily::NVIDIA: return lit("NVIDIA");
+ case CounterFamily::Unknown: return lit("Unknown");
}
- return nullptr;
+ return QString();
}
}
+const int PerformanceCounterSelection::CounterDescriptionRole = Qt::UserRole + 1;
+const int PerformanceCounterSelection::CounterIdRole = Qt::UserRole + 2;
+
PerformanceCounterSelection::PerformanceCounterSelection(ICaptureContext &ctx, QWidget *parent)
: QDialog(parent), ui(new Ui::PerformanceCounterSelection), m_Ctx(ctx)
{
ui->setupUi(this);
- connect(ui->counterTree, &QTreeWidget::itemEntered, [&](QTreeWidgetItem *item, int) -> void {
- const auto d = item->data(0, Qt::UserRole + 1);
+ connect(ui->counterTree, &QTreeWidget::itemEntered, [this](QTreeWidgetItem *item, int) -> void {
+ const QVariant d = item->data(0, CounterDescriptionRole);
if(d.isValid())
{
ui->counterDescription->setText(
- QString(QLatin1String("%1
%2")).arg(item->text(0)).arg(d.toString()));
+ QString(lit("%1
%2")).arg(item->text(0)).arg(d.toString()));
}
});
- connect(ui->save, &QPushButton::pressed, [&]() -> void {
- QString filename = RDDialog::getSaveFileName(this, tr("Save File"), QDir::homePath(),
- tr("Performance Counter Settings (*.json)"));
+ connect(ui->save, &QPushButton::pressed, this, &PerformanceCounterSelection::Save);
+ connect(ui->load, &QPushButton::pressed, this, &PerformanceCounterSelection::Load);
+ connect(ui->sampleCounters, &QPushButton::pressed, this, &PerformanceCounterSelection::accept);
- if(filename.isEmpty())
- return;
-
- QVariantList counterIds;
- for(auto v : m_SelectedCounters.keys())
- {
- const Uuid uuid = m_CounterToUuid[v];
- QVariantList e;
-
- for(const auto b : uuid.bytes)
- {
- e.append(b);
- }
-
- counterIds.append(QVariant{e});
- }
-
- QVariantMap doc;
- doc[QLatin1String{"counters"}] = counterIds;
-
- QFile f(filename);
- if(f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
- {
- SaveToJSON(doc, f, JSON_ID, JSON_VER);
- }
- else
- {
- RDDialog::critical(this, tr("Error saving config"),
- tr("Couldn't open path %1 for write.").arg(filename));
- }
- });
-
- connect(ui->load, &QPushButton::pressed, [&]() -> void {
- QString filename = RDDialog::getOpenFileName(this, tr("Load file"), QDir::homePath(),
- tr("Performance Counter Settings (*.json)"));
-
- if(filename.isEmpty())
- return;
-
- QVariantMap doc;
- QFile f(filename);
- if(f.open(QIODevice::ReadOnly | QIODevice::Text))
- {
- LoadFromJSON(doc, f, JSON_ID, JSON_VER);
-
- std::set selectedCounters;
-
- QVariantList counters = doc[QLatin1String{"counters"}].toList();
-
- for(const auto &counter : counters)
- {
- QVariantList bytes = counter.toList();
- Uuid uuid;
-
- /// TODO assert counter.size () == 4
-
- for(int i = 0; i < 4; ++i)
- {
- uuid.bytes[i] = bytes[i].toUInt();
- }
-
- selectedCounters.insert(uuid);
- }
-
- // We we walk over the complete tree, and toggle everything so it
- // matches the settings
- QTreeWidgetItemIterator it(ui->counterTree);
- while(*it)
- {
- const auto id = (*it)->data(0, Qt::UserRole + 2);
- if(id.isValid())
- {
- const GPUCounter counter = (GPUCounter)id.toUInt();
-
- if(!m_CounterToUuid.contains(counter))
- continue;
-
- (*it)->setCheckState(
- 0, (selectedCounters.find(m_CounterToUuid[counter]) != selectedCounters.end())
- ? Qt::Checked
- : Qt::Unchecked);
- }
-
- // The loop above will uncheck all unknown counters, and not crash if some counter is no
- // longer present, or unknown
-
- ++it;
- }
- }
- else
- {
- RDDialog::critical(this, tr("Error loading config"),
- tr("Couldn't open path %1 for reading.").arg(filename));
- }
-
- });
-
- connect(ui->counterTree, &QTreeWidget::itemChanged, [&](QTreeWidgetItem *item, int) -> void {
- const auto d = item->data(0, Qt::UserRole + 2);
+ connect(ui->counterTree, &QTreeWidget::itemChanged, [this](QTreeWidgetItem *item, int) -> void {
+ const QVariant d = item->data(0, CounterIdRole);
if(d.isValid())
{
if(item->checkState(0) == Qt::Checked)
{
// Add
- auto listItem = new QListWidgetItem(ui->enabledCounters);
+ QListWidgetItem *listItem = new QListWidgetItem(ui->enabledCounters);
listItem->setText(item->text(0));
m_SelectedCounters.insert((GPUCounter)d.toUInt(), listItem);
}
else
{
// Remove
- auto listItem = m_SelectedCounters.take((GPUCounter)d.toUInt());
+ QListWidgetItem *listItem = m_SelectedCounters.take((GPUCounter)d.toUInt());
delete listItem;
}
}
});
- connect(ui->sampleCounters, &QPushButton::pressed, [&]() -> void { this->accept(); });
-
ui->counterTree->setMouseTracking(true);
- auto showCounters = [&](const QVector &counters) -> void {
- ui->counterTree->clear();
- ui->enabledCounters->clear();
-
- QTreeWidgetItem *currentRoot = NULL;
- CounterFamily currentFamily = CounterFamily::Unknown;
-
- std::unordered_map categories;
-
- for(const auto desc : counters)
+ ctx.Replay().AsyncInvoke([this](IReplayController *controller) -> void {
+ QVector counterDescriptions;
+ for(const GPUCounter counter : controller->EnumerateCounters())
{
- m_CounterToUuid[desc.counterID] = desc.uuid;
- m_UuidToCounter[desc.uuid] = desc.counterID;
-
- const CounterFamily family = GetCounterFamily(desc.counterID);
- if(family != currentFamily)
- {
- currentRoot = new QTreeWidgetItem(ui->counterTree);
- currentRoot->setText(0, QLatin1String{ToString(family)});
-
- categories.clear();
-
- currentFamily = family;
- }
-
- QTreeWidgetItem *categoryItem = nullptr;
-
- const auto category = std::string{desc.category};
- auto categoryIterator = categories.find(category);
-
- if(categoryIterator == categories.end())
- {
- auto item = new QTreeWidgetItem{currentRoot};
- item->setText(0, desc.category);
- categories[category] = item;
- categoryItem = item;
- }
- else
- {
- categoryItem = categoryIterator->second;
- }
-
- auto counterItem = new QTreeWidgetItem{categoryItem};
- counterItem->setText(0, desc.name);
- counterItem->setData(0, Qt::UserRole + 1, desc.description);
- counterItem->setData(0, Qt::UserRole + 2, (uint32_t)desc.counterID);
- counterItem->setCheckState(0, Qt::Unchecked);
- }
- };
-
- ctx.Replay().AsyncInvoke([=](IReplayController *controller) -> void {
- QVector desc;
- for(const auto counter : controller->EnumerateCounters())
- {
- desc.append(controller->DescribeCounter(counter));
+ counterDescriptions.append(controller->DescribeCounter(counter));
}
- GUIInvoke::call([=]() -> void { showCounters(desc); });
+ GUIInvoke::call([counterDescriptions, this]() -> void { SetCounters(counterDescriptions); });
});
}
+void PerformanceCounterSelection::SetCounters(const QVector &descriptions)
+{
+ ui->counterTree->clear();
+ ui->enabledCounters->clear();
+
+ QTreeWidgetItem *currentRoot = NULL;
+ CounterFamily currentFamily = CounterFamily::Unknown;
+
+ std::unordered_map categories;
+
+ for(const CounterDescription &desc : descriptions)
+ {
+ m_CounterToUuid[desc.counterID] = desc.uuid;
+ m_UuidToCounter[desc.uuid] = desc.counterID;
+
+ const CounterFamily family = GetCounterFamily(desc.counterID);
+ if(family != currentFamily)
+ {
+ currentRoot = new QTreeWidgetItem(ui->counterTree);
+ currentRoot->setText(0, ToString(family));
+
+ categories.clear();
+
+ currentFamily = family;
+ }
+
+ QTreeWidgetItem *categoryItem = NULL;
+
+ const std::string category = desc.category;
+ auto categoryIterator = categories.find(category);
+
+ if(categoryIterator == categories.end())
+ {
+ QTreeWidgetItem *item = new QTreeWidgetItem(currentRoot);
+ item->setText(0, desc.category);
+ categories[category] = item;
+ categoryItem = item;
+ }
+ else
+ {
+ categoryItem = categoryIterator->second;
+ }
+
+ QTreeWidgetItem *counterItem = new QTreeWidgetItem(categoryItem);
+ counterItem->setText(0, desc.name);
+ counterItem->setData(0, CounterDescriptionRole, desc.description);
+ counterItem->setData(0, CounterIdRole, (uint32_t)desc.counterID);
+ counterItem->setCheckState(0, Qt::Unchecked);
+ }
+}
+
PerformanceCounterSelection::~PerformanceCounterSelection()
{
delete ui;
@@ -288,3 +193,105 @@ QList PerformanceCounterSelection::GetSelectedCounters() const
{
return m_SelectedCounters.keys();
}
+
+void PerformanceCounterSelection::Save()
+{
+ QString filename = RDDialog::getSaveFileName(this, tr("Save File"), QDir::homePath(),
+ tr("Performance Counter Settings (*.json)"));
+
+ if(filename.isEmpty())
+ return;
+
+ QVariantList counterIds;
+ for(const GPUCounter v : m_SelectedCounters.keys())
+ {
+ const Uuid uuid = m_CounterToUuid[v];
+ QVariantList e;
+
+ for(const byte b : uuid.bytes)
+ {
+ e.append(b);
+ }
+
+ counterIds.append(QVariant(e));
+ }
+
+ QVariantMap doc;
+ doc[lit("counters")] = counterIds;
+
+ QFile f(filename);
+ if(f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
+ {
+ SaveToJSON(doc, f, JSON_ID, JSON_VER);
+ }
+ else
+ {
+ RDDialog::critical(this, tr("Error saving config"),
+ tr("Couldn't open path %1 for write.").arg(filename));
+ }
+}
+
+void PerformanceCounterSelection::Load()
+{
+ QString filename = RDDialog::getOpenFileName(this, tr("Load file"), QDir::homePath(),
+ tr("Performance Counter Settings (*.json)"));
+
+ if(filename.isEmpty())
+ return;
+
+ QVariantMap doc;
+ QFile f(filename);
+ if(f.open(QIODevice::ReadOnly | QIODevice::Text))
+ {
+ LoadFromJSON(doc, f, JSON_ID, JSON_VER);
+
+ std::set selectedCounters;
+
+ QVariantList counters = doc[lit("counters")].toList();
+
+ for(const QVariant &counter : counters)
+ {
+ QVariantList bytes = counter.toList();
+ Uuid uuid;
+
+ /// TODO assert counter.size () == 4
+
+ for(int i = 0; i < 4; ++i)
+ {
+ uuid.bytes[i] = bytes[i].toUInt();
+ }
+
+ selectedCounters.insert(uuid);
+ }
+
+ // We we walk over the complete tree, and toggle everything so it
+ // matches the settings
+ QTreeWidgetItemIterator it(ui->counterTree);
+ while(*it)
+ {
+ const QVariant id = (*it)->data(0, Qt::UserRole + 2);
+ if(id.isValid())
+ {
+ const GPUCounter counter = (GPUCounter)id.toUInt();
+
+ if(!m_CounterToUuid.contains(counter))
+ continue;
+
+ (*it)->setCheckState(
+ 0, (selectedCounters.find(m_CounterToUuid[counter]) != selectedCounters.end())
+ ? Qt::Checked
+ : Qt::Unchecked);
+ }
+
+ // The loop above will uncheck all unknown counters, and not crash if some counter is no
+ // longer present, or unknown
+
+ ++it;
+ }
+ }
+ else
+ {
+ RDDialog::critical(this, tr("Error loading config"),
+ tr("Couldn't open path %1 for reading.").arg(filename));
+ }
+}
\ No newline at end of file
diff --git a/qrenderdoc/Windows/Dialogs/PerformanceCounterSelection.h b/qrenderdoc/Windows/Dialogs/PerformanceCounterSelection.h
index 5579ab563..347eca2d6 100644
--- a/qrenderdoc/Windows/Dialogs/PerformanceCounterSelection.h
+++ b/qrenderdoc/Windows/Dialogs/PerformanceCounterSelection.h
@@ -44,11 +44,20 @@ public:
QList GetSelectedCounters() const;
+public slots:
+ void Save();
+ void Load();
+
private:
+ void SetCounters(const QVector &descriptions);
+
Ui::PerformanceCounterSelection *ui;
ICaptureContext &m_Ctx;
QMap m_SelectedCounters;
QMap m_CounterToUuid;
QMap m_UuidToCounter;
+
+ static const int CounterDescriptionRole;
+ static const int CounterIdRole;
};
diff --git a/qrenderdoc/Windows/Dialogs/PerformanceCounterSelection.ui b/qrenderdoc/Windows/Dialogs/PerformanceCounterSelection.ui
index 50ebd8964..74cbcfd03 100644
--- a/qrenderdoc/Windows/Dialogs/PerformanceCounterSelection.ui
+++ b/qrenderdoc/Windows/Dialogs/PerformanceCounterSelection.ui
@@ -48,15 +48,6 @@
-
-
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
-<html><head><meta name="qrichtext" content="1" /><style type="text/css">
-p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:7.875pt; font-weight:400; font-style:normal;">
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Cache miss</span></p>
-<hr />
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Lorem ipsum something something about cache misses and why you don't want those to happen all the time. Not sure what to write here, given some people seem to like a high number here.</p></body></html>
-
-
diff --git a/qrenderdoc/Windows/PerformanceCounterViewer.cpp b/qrenderdoc/Windows/PerformanceCounterViewer.cpp
index 66244c0a1..555fee5ec 100644
--- a/qrenderdoc/Windows/PerformanceCounterViewer.cpp
+++ b/qrenderdoc/Windows/PerformanceCounterViewer.cpp
@@ -53,13 +53,13 @@ static QString FormatCounterResult(const CounterResult &result, const CounterDes
switch(description.unit)
{
- case CounterUnit::Bytes: returnValue += QLatin1String{" bytes"}; break;
+ case CounterUnit::Bytes: returnValue += lit(" bytes"); break;
- case CounterUnit::Cycles: returnValue += QLatin1String{" cycles"}; break;
+ case CounterUnit::Cycles: returnValue += lit(" cycles"); break;
- case CounterUnit::Percentage: returnValue += QLatin1String{" %"}; break;
+ case CounterUnit::Percentage: returnValue += lit(" %"); break;
- case CounterUnit::Seconds: returnValue += QLatin1String{" s"}; break;
+ case CounterUnit::Seconds: returnValue += lit(" s"); break;
case CounterUnit::Absolute:
case CounterUnit::Ratio: break;
@@ -75,74 +75,75 @@ PerformanceCounterViewer::PerformanceCounterViewer(ICaptureContext &ctx, QWidget
m_Ctx.AddLogViewer(this);
- connect(ui->captureCounters, &QToolButton::pressed, [=]() -> void {
- PerformanceCounterSelection pcs(m_Ctx, this);
- if(RDDialog::show(&pcs) == QDialog::Accepted)
+ connect(ui->captureCounters, &QToolButton::pressed, this,
+ &PerformanceCounterViewer::CaptureCounters);
+}
+
+void PerformanceCounterViewer::CaptureCounters()
+{
+ PerformanceCounterSelection pcs(m_Ctx, this);
+ if(RDDialog::show(&pcs) != QDialog::Accepted)
+ return;
+ const QList selectedCounters = pcs.GetSelectedCounters();
+
+ bool done = false;
+ m_Ctx.Replay().AsyncInvoke([this, selectedCounters, &done](IReplayController *controller) -> void {
+ rdctype::array counters;
+ counters.create(selectedCounters.size());
+
+ QMap counterDescriptions;
+
+ for(int i = 0; i < selectedCounters.size(); ++i)
{
- const QList selectedCounters = pcs.GetSelectedCounters();
-
- bool done = false;
- m_Ctx.Replay().AsyncInvoke([=, &done](IReplayController *controller) -> void {
- rdctype::array counters;
- counters.create(selectedCounters.size());
-
- QMap counterDescriptions;
-
- for(int i = 0; i < selectedCounters.size(); ++i)
- {
- counters[i] = (GPUCounter)selectedCounters[i];
- counterDescriptions.insert(counters[i], controller->DescribeCounter(counters[i]));
- }
-
- QMap counterIndex;
- for(int i = 0; i < selectedCounters.size(); ++i)
- {
- counterIndex.insert((GPUCounter)selectedCounters[i], i);
- }
-
- const auto results = controller->FetchCounters(counters);
-
- GUIInvoke::call([this, results, counterDescriptions, counterIndex]() -> void {
- ui->counterResults->clear();
-
- QStringList headers;
- headers << QLatin1String{"EID"};
- for(const auto &cd : counterDescriptions)
- {
- headers << cd.name;
- }
-
- QMap eventIdToRow;
- for(const auto &result : results)
- {
- if(eventIdToRow.contains(result.eventID))
- continue;
- eventIdToRow[result.eventID] = eventIdToRow.size();
- }
-
- ui->counterResults->setColumnCount(headers.size());
- ui->counterResults->setHorizontalHeaderLabels(headers);
- ui->counterResults->setRowCount(eventIdToRow.size());
- ui->counterResults->verticalHeader()->hide();
-
- for(int i = 0; i < (int)results.size(); ++i)
- {
- int row = eventIdToRow[results[i].eventID];
- ui->counterResults->setItem(row, 0,
- new QTableWidgetItem(QString::number(results[i].eventID)));
- ui->counterResults->setItem(row, counterIndex[results[i].counterID] + 1,
- new QTableWidgetItem(FormatCounterResult(
- results[i], counterDescriptions[results[i].counterID])));
- }
- });
-
- done = true;
- });
-
- ShowProgressDialog(this, QLatin1String("Capturing counters"),
- [&done]() -> bool { return done; });
+ counters[i] = (GPUCounter)selectedCounters[i];
+ counterDescriptions.insert(counters[i], controller->DescribeCounter(counters[i]));
}
+
+ QMap counterIndex;
+ for(int i = 0; i < selectedCounters.size(); ++i)
+ {
+ counterIndex.insert((GPUCounter)selectedCounters[i], i);
+ }
+
+ const rdctype::array results = controller->FetchCounters(counters);
+
+ GUIInvoke::call([this, results, counterDescriptions, counterIndex]() -> void {
+ ui->counterResults->clear();
+
+ QStringList headers;
+ headers << lit("EID");
+ for(const CounterDescription &cd : counterDescriptions)
+ {
+ headers << cd.name;
+ }
+
+ QMap eventIdToRow;
+ for(const CounterResult &result : results)
+ {
+ if(eventIdToRow.contains(result.eventID))
+ continue;
+ eventIdToRow[result.eventID] = eventIdToRow.size();
+ }
+
+ ui->counterResults->setColumnCount(headers.size());
+ ui->counterResults->setHorizontalHeaderLabels(headers);
+ ui->counterResults->setRowCount(eventIdToRow.size());
+
+ for(int i = 0; i < (int)results.size(); ++i)
+ {
+ int row = eventIdToRow[results[i].eventID];
+ ui->counterResults->setItem(row, 0,
+ new QTableWidgetItem(QString::number(results[i].eventID)));
+ ui->counterResults->setItem(row, counterIndex[results[i].counterID] + 1,
+ new QTableWidgetItem(FormatCounterResult(
+ results[i], counterDescriptions[results[i].counterID])));
+ }
+ });
+
+ done = true;
});
+
+ ShowProgressDialog(this, tr("Capturing counters"), [&done]() -> bool { return done; });
}
PerformanceCounterViewer::~PerformanceCounterViewer()
diff --git a/qrenderdoc/Windows/PerformanceCounterViewer.h b/qrenderdoc/Windows/PerformanceCounterViewer.h
index 6d4b85ad9..8b2c8aeff 100644
--- a/qrenderdoc/Windows/PerformanceCounterViewer.h
+++ b/qrenderdoc/Windows/PerformanceCounterViewer.h
@@ -50,4 +50,5 @@ public:
private:
Ui::PerformanceCounterViewer *ui;
ICaptureContext &m_Ctx;
+ void CaptureCounters();
};
diff --git a/qrenderdoc/Windows/PerformanceCounterViewer.ui b/qrenderdoc/Windows/PerformanceCounterViewer.ui
index 01afc89bb..4df628fea 100644
--- a/qrenderdoc/Windows/PerformanceCounterViewer.ui
+++ b/qrenderdoc/Windows/PerformanceCounterViewer.ui
@@ -13,42 +13,42 @@
Performance Counter viewer
-
- QFrame::StyledPanel
-
-
- QFrame::Raised
-
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
-
-
- 3
-
-
- QLayout::SetDefaultConstraint
-
-
- 6
-
-
- 6
-
+
+ 3
+
+
+ QLayout::SetDefaultConstraint
+
+
+ 6
+
+
+ 6
+
-
@@ -59,7 +59,11 @@
-
-
+
+
+ false
+
+