mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Address review feedback.
This commit is contained in:
committed by
baldurk
parent
4d25394c0b
commit
8478bfbb52
@@ -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("<b>%1</b><hr>%2")).arg(item->text(0)).arg(d.toString()));
|
||||
QString(lit("<b>%1</b><hr>%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<Uuid> 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<CounterDescription> &counters) -> void {
|
||||
ui->counterTree->clear();
|
||||
ui->enabledCounters->clear();
|
||||
|
||||
QTreeWidgetItem *currentRoot = NULL;
|
||||
CounterFamily currentFamily = CounterFamily::Unknown;
|
||||
|
||||
std::unordered_map<std::string, QTreeWidgetItem *> categories;
|
||||
|
||||
for(const auto desc : counters)
|
||||
ctx.Replay().AsyncInvoke([this](IReplayController *controller) -> void {
|
||||
QVector<CounterDescription> 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<CounterDescription> 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<CounterDescription> &descriptions)
|
||||
{
|
||||
ui->counterTree->clear();
|
||||
ui->enabledCounters->clear();
|
||||
|
||||
QTreeWidgetItem *currentRoot = NULL;
|
||||
CounterFamily currentFamily = CounterFamily::Unknown;
|
||||
|
||||
std::unordered_map<std::string, QTreeWidgetItem *> 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<GPUCounter> 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<Uuid> 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));
|
||||
}
|
||||
}
|
||||
@@ -44,11 +44,20 @@ public:
|
||||
|
||||
QList<GPUCounter> GetSelectedCounters() const;
|
||||
|
||||
public slots:
|
||||
void Save();
|
||||
void Load();
|
||||
|
||||
private:
|
||||
void SetCounters(const QVector<CounterDescription> &descriptions);
|
||||
|
||||
Ui::PerformanceCounterSelection *ui;
|
||||
|
||||
ICaptureContext &m_Ctx;
|
||||
QMap<GPUCounter, QListWidgetItem *> m_SelectedCounters;
|
||||
QMap<GPUCounter, Uuid> m_CounterToUuid;
|
||||
QMap<Uuid, GPUCounter> m_UuidToCounter;
|
||||
|
||||
static const int CounterDescriptionRole;
|
||||
static const int CounterIdRole;
|
||||
};
|
||||
|
||||
@@ -48,15 +48,6 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="counterDescription">
|
||||
<property name="html">
|
||||
<string><!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></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
||||
@@ -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<GPUCounter> selectedCounters = pcs.GetSelectedCounters();
|
||||
|
||||
bool done = false;
|
||||
m_Ctx.Replay().AsyncInvoke([this, selectedCounters, &done](IReplayController *controller) -> void {
|
||||
rdctype::array<GPUCounter> counters;
|
||||
counters.create(selectedCounters.size());
|
||||
|
||||
QMap<GPUCounter, CounterDescription> counterDescriptions;
|
||||
|
||||
for(int i = 0; i < selectedCounters.size(); ++i)
|
||||
{
|
||||
const QList<GPUCounter> selectedCounters = pcs.GetSelectedCounters();
|
||||
|
||||
bool done = false;
|
||||
m_Ctx.Replay().AsyncInvoke([=, &done](IReplayController *controller) -> void {
|
||||
rdctype::array<GPUCounter> counters;
|
||||
counters.create(selectedCounters.size());
|
||||
|
||||
QMap<GPUCounter, CounterDescription> counterDescriptions;
|
||||
|
||||
for(int i = 0; i < selectedCounters.size(); ++i)
|
||||
{
|
||||
counters[i] = (GPUCounter)selectedCounters[i];
|
||||
counterDescriptions.insert(counters[i], controller->DescribeCounter(counters[i]));
|
||||
}
|
||||
|
||||
QMap<GPUCounter, int> 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<uint32_t, int> 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<GPUCounter, int> counterIndex;
|
||||
for(int i = 0; i < selectedCounters.size(); ++i)
|
||||
{
|
||||
counterIndex.insert((GPUCounter)selectedCounters[i], i);
|
||||
}
|
||||
|
||||
const rdctype::array<CounterResult> 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<uint32_t, int> 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()
|
||||
|
||||
@@ -50,4 +50,5 @@ public:
|
||||
private:
|
||||
Ui::PerformanceCounterViewer *ui;
|
||||
ICaptureContext &m_Ctx;
|
||||
void CaptureCounters();
|
||||
};
|
||||
|
||||
@@ -13,42 +13,42 @@
|
||||
<property name="windowTitle">
|
||||
<string>Performance Counter viewer</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolButton" name="captureCounters">
|
||||
<property name="text">
|
||||
@@ -59,7 +59,11 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="counterResults"/>
|
||||
<widget class="QTableWidget" name="counterResults">
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
Reference in New Issue
Block a user