diff --git a/qrenderdoc/Windows/ShaderMessageViewer.cpp b/qrenderdoc/Windows/ShaderMessageViewer.cpp
index f88384e43..a4b466d74 100644
--- a/qrenderdoc/Windows/ShaderMessageViewer.cpp
+++ b/qrenderdoc/Windows/ShaderMessageViewer.cpp
@@ -146,6 +146,21 @@ ShaderMessageViewer::ShaderMessageViewer(ICaptureContext &ctx, ShaderStageMask s
QObject::connect(ui->filterButton, &QToolButton::clicked, [this]() { refreshMessages(); });
QObject::connect(ui->filter, &RDLineEdit::returnPressed, [this]() { refreshMessages(); });
+ QMenu *menu = new QMenu(this);
+
+ QAction *action = new QAction(tr("Export to &Text"));
+ action->setIcon(Icons::save());
+ QObject::connect(action, &QAction::triggered, this, &ShaderMessageViewer::exportText);
+ menu->addAction(action);
+
+ action = new QAction(tr("Export to &CSV"));
+ action->setIcon(Icons::save());
+ QObject::connect(action, &QAction::triggered, this, &ShaderMessageViewer::exportCSV);
+ menu->addAction(action);
+
+ ui->exportButton->setMenu(menu);
+ QObject::connect(ui->exportButton, &QToolButton::clicked, this, &ShaderMessageViewer::exportText);
+
ui->vertex->setText(ToQStr(ShaderStage::Vertex, m_API));
ui->hull->setText(ToQStr(ShaderStage::Hull, m_API));
ui->domain->setText(ToQStr(ShaderStage::Domain, m_API));
@@ -513,6 +528,101 @@ void ShaderMessageViewer::OnEventChanged(uint32_t eventId)
}
}
+void ShaderMessageViewer::exportText()
+{
+ exportData(false);
+}
+
+void ShaderMessageViewer::exportCSV()
+{
+ exportData(true);
+}
+
+void ShaderMessageViewer::exportData(bool csv)
+{
+ QString filter;
+ QString title;
+ if(csv)
+ {
+ filter = tr("CSV Files (*.csv)");
+ title = tr("Export buffer to CSV");
+ }
+ else
+ {
+ filter = tr("Text Files (*.txt)");
+ title = tr("Export buffer to text");
+ }
+
+ QString filename =
+ RDDialog::getSaveFileName(this, title, QString(), tr("%1;;All files (*)").arg(filter));
+
+ if(filename.isEmpty())
+ return;
+
+ QFile *f = new QFile(filename);
+
+ QIODevice::OpenMode flags = QIODevice::WriteOnly | QFile::Truncate | QIODevice::Text;
+
+ if(!f->open(flags))
+ {
+ delete f;
+ RDDialog::critical(this, tr("Error exporting file"),
+ tr("Couldn't open file '%1' for writing").arg(filename));
+ return;
+ }
+
+ LambdaThread *exportThread = new LambdaThread([this, csv, f]() {
+ QTextStream s(f);
+
+ if(csv)
+ s << tr("Location,Message\n");
+
+ int base = 2;
+
+ if(m_OrigShaders[5] != ResourceId())
+ base = 1;
+
+ int locationWidth = 0;
+ for(int i = 0; i < ui->messages->topLevelItemCount(); i++)
+ {
+ RDTreeWidgetItem *node = ui->messages->topLevelItem(i);
+
+ locationWidth = qMax(locationWidth, node->text(base).length());
+ }
+
+ for(int i = 0; i < ui->messages->topLevelItemCount(); i++)
+ {
+ RDTreeWidgetItem *node = ui->messages->topLevelItem(i);
+
+ if(csv)
+ {
+ s << "\"" << node->text(base) << "\",\""
+ << node->text(base + 1).replace(QLatin1Char('"'), lit("\"\"")) << "\"\n";
+ }
+ else
+ {
+ s << QFormatStr("%1").arg(node->text(base), -locationWidth) << "\t" << node->text(base + 1)
+ << "\n";
+ }
+ }
+
+ f->close();
+
+ delete f;
+ });
+ exportThread->start();
+
+ // wait a short while before displaying the progress dialog (which won't show if we're already
+ // done by the time we reach it)
+ for(int i = 0; exportThread->isRunning() && i < 100; i++)
+ QThread::msleep(5);
+
+ ShowProgressDialog(this, tr("Exporting messages"),
+ [exportThread]() { return !exportThread->isRunning(); });
+
+ exportThread->deleteLater();
+}
+
void ShaderMessageViewer::refreshMessages()
{
ShaderStageMask mask = ShaderStageMask::Compute;
diff --git a/qrenderdoc/Windows/ShaderMessageViewer.h b/qrenderdoc/Windows/ShaderMessageViewer.h
index defd64cd1..7d51997a6 100644
--- a/qrenderdoc/Windows/ShaderMessageViewer.h
+++ b/qrenderdoc/Windows/ShaderMessageViewer.h
@@ -73,8 +73,12 @@ public:
void OnEventChanged(uint32_t eventId) override;
private slots:
+ void exportText();
+ void exportCSV();
+
private:
void refreshMessages();
+ void exportData(bool csv);
Ui::ShaderMessageViewer *ui;
ICaptureContext &m_Ctx;
diff --git a/qrenderdoc/Windows/ShaderMessageViewer.ui b/qrenderdoc/Windows/ShaderMessageViewer.ui
index 17f9b3b7d..4c07747e2 100644
--- a/qrenderdoc/Windows/ShaderMessageViewer.ui
+++ b/qrenderdoc/Windows/ShaderMessageViewer.ui
@@ -26,6 +26,59 @@
3
+ -
+
+
+ 5
+
+
+ 0
+
+
+ 2
+
+
+ 6
+
+
+ 2
+
+
-
+
+
+ Export
+
+
+
+ :/save.png:/save.png
+
+
+
+ Qt::ToolButtonTextBesideIcon
+
+
+ QToolButton::MenuButtonPopup
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
-
@@ -180,6 +233,12 @@
QAbstractItemView::NoEditTriggers
+
+ QAbstractItemView::ContiguousSelection
+
+
+ QAbstractItemView::SelectRows
+
false