diff --git a/qrenderdoc/Code/CaptureContext.cpp b/qrenderdoc/Code/CaptureContext.cpp index 3cc040a35..2192684e4 100644 --- a/qrenderdoc/Code/CaptureContext.cpp +++ b/qrenderdoc/Code/CaptureContext.cpp @@ -35,6 +35,7 @@ #include #include "Windows/APIInspector.h" #include "Windows/BufferViewer.h" +#include "Windows/DebugMessageView.h" #include "Windows/Dialogs/CaptureDialog.h" #include "Windows/Dialogs/LiveCapture.h" #include "Windows/EventBrowser.h" @@ -518,6 +519,18 @@ CaptureDialog *CaptureContext::captureDialog() return m_CaptureDialog; } +DebugMessageView *CaptureContext::debugMessageView() +{ + if(m_DebugMessageView) + return m_DebugMessageView; + + m_DebugMessageView = new DebugMessageView(this, m_MainWindow); + m_DebugMessageView->setObjectName("debugMessageView"); + setupDockWindow(m_DebugMessageView); + + return m_DebugMessageView; +} + void CaptureContext::showEventBrowser() { m_MainWindow->showEventBrowser(); @@ -548,6 +561,11 @@ void CaptureContext::showCaptureDialog() m_MainWindow->showCaptureDialog(); } +void CaptureContext::showDebugMessageView() +{ + m_MainWindow->showDebugMessageView(); +} + QWidget *CaptureContext::createToolWindow(const QString &objectName) { if(objectName == "textureViewer") @@ -574,6 +592,10 @@ QWidget *CaptureContext::createToolWindow(const QString &objectName) { return captureDialog(); } + else if(objectName == "debugMessageView") + { + return debugMessageView(); + } return NULL; } @@ -592,6 +614,8 @@ void CaptureContext::windowClosed(QWidget *window) m_PipelineViewer = NULL; else if((QWidget *)m_MeshPreview == window) m_MeshPreview = NULL; + else if((QWidget *)m_DebugMessageView == window) + m_DebugMessageView = NULL; else qCritical() << "Unrecognised window being closed: " << window; } diff --git a/qrenderdoc/Code/CaptureContext.h b/qrenderdoc/Code/CaptureContext.h index f1678b575..4893d6456 100644 --- a/qrenderdoc/Code/CaptureContext.h +++ b/qrenderdoc/Code/CaptureContext.h @@ -62,6 +62,7 @@ class PipelineStateViewer; class BufferViewer; class TextureViewer; class CaptureDialog; +class DebugMessageView; class QProgressDialog; class CaptureContext @@ -138,6 +139,7 @@ public: BufferViewer *meshPreview(); PipelineStateViewer *pipelineViewer(); CaptureDialog *captureDialog(); + DebugMessageView *debugMessageView(); void setupDockWindow(QWidget *shad); bool hasEventBrowser() { return m_EventBrowser != NULL; } @@ -146,12 +148,14 @@ public: bool hasPipelineViewer() { return m_PipelineViewer != NULL; } bool hasMeshPreview() { return m_MeshPreview != NULL; } bool hasCaptureDialog() { return m_CaptureDialog != NULL; } + bool hasDebugMessageView() { return m_DebugMessageView != NULL; } void showEventBrowser(); void showAPIInspector(); void showTextureViewer(); void showMeshPreview(); void showPipelineViewer(); void showCaptureDialog(); + void showDebugMessageView(); QWidget *createToolWindow(const QString &objectName); void windowClosed(QWidget *window); @@ -224,4 +228,5 @@ private: BufferViewer *m_MeshPreview = NULL; PipelineStateViewer *m_PipelineViewer = NULL; CaptureDialog *m_CaptureDialog = NULL; + DebugMessageView *m_DebugMessageView = NULL; }; diff --git a/qrenderdoc/Code/QRDUtils.h b/qrenderdoc/Code/QRDUtils.h index f4d5c8fe6..8b8892cf8 100644 --- a/qrenderdoc/Code/QRDUtils.h +++ b/qrenderdoc/Code/QRDUtils.h @@ -310,6 +310,59 @@ struct ToStr return "Unknown"; } + static std::string Get(const DebugMessageSource &el) + { + switch(el) + { + case eDbgSource_API: return "API"; + case eDbgSource_RedundantAPIUse: return "Redundant API Use"; + case eDbgSource_IncorrectAPIUse: return "Incorrect API Use"; + case eDbgSource_GeneralPerformance: return "General Performance"; + case eDbgSource_GCNPerformance: return "GCN Performance"; + case eDbgSource_RuntimeWarning: return "Runtime Warning"; + case eDbgSoruce_UnsupportedConfiguration: return "Unsupported Configuration"; + default: break; + } + return "Unknown"; + } + + static std::string Get(const DebugMessageSeverity &el) + { + switch(el) + { + case eDbgSeverity_High: return "High"; + case eDbgSeverity_Medium: return "Medium"; + case eDbgSeverity_Low: return "Low"; + case eDbgSeverity_Info: return "Info"; + default: break; + } + return "Unknown"; + } + + static std::string Get(const DebugMessageCategory &el) + { + switch(el) + { + case eDbgCategory_Application_Defined: return "Application Defined"; + case eDbgCategory_Miscellaneous: return "Miscellaneous"; + case eDbgCategory_Initialization: return "Initialization"; + case eDbgCategory_Cleanup: return "Cleanup"; + case eDbgCategory_Compilation: return "Compilation"; + case eDbgCategory_State_Creation: return "State Creation"; + case eDbgCategory_State_Setting: return "State Setting"; + case eDbgCategory_State_Getting: return "State Getting"; + case eDbgCategory_Resource_Manipulation: return "Resource Manipulation"; + case eDbgCategory_Execution: return "Execution"; + case eDbgCategory_Shaders: return "Shaders"; + case eDbgCategory_Deprecated: return "Deprecated"; + case eDbgCategory_Undefined: return "Undefined"; + case eDbgCategory_Portability: return "Portability"; + case eDbgCategory_Performance: return "Performance"; + default: break; + } + return "Unknown"; + } + static std::string Get(const TextureSwizzle &el) { switch(el) diff --git a/qrenderdoc/Windows/DebugMessageView.cpp b/qrenderdoc/Windows/DebugMessageView.cpp new file mode 100644 index 000000000..bf7e58aa4 --- /dev/null +++ b/qrenderdoc/Windows/DebugMessageView.cpp @@ -0,0 +1,387 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2017 Baldur Karlsson + * + * 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 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 + * AUTHORS OR COPYRIGHT HOLDERS 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. + ******************************************************************************/ + +#include "DebugMessageView.h" +#include +#include +#include "ui_DebugMessageView.h" + +static const int EIDRole = Qt::UserRole + 1; + +class DebugMessageItemModel : public QAbstractItemModel +{ +public: + DebugMessageItemModel(CaptureContext *ctx, QObject *parent) : QAbstractItemModel(parent) + { + m_Ctx = ctx; + } + + void refresh() + { + emit beginResetModel(); + emit endResetModel(); + } + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override + { + if(row < 0 || row >= rowCount()) + return QModelIndex(); + + return createIndex(row, column); + } + + QModelIndex parent(const QModelIndex &index) const override { return QModelIndex(); } + int rowCount(const QModelIndex &parent = QModelIndex()) const override + { + return m_Ctx->DebugMessages.count(); + } + int columnCount(const QModelIndex &parent = QModelIndex()) const override { return 6; } + Qt::ItemFlags flags(const QModelIndex &index) const override + { + if(!index.isValid()) + return 0; + + return QAbstractItemModel::flags(index); + } + + QVariant headerData(int section, Qt::Orientation orientation, int role) const override + { + if(orientation == Qt::Horizontal && role == Qt::DisplayRole) + { + switch(section) + { + case 0: return "EID"; + case 1: return "Source"; + case 2: return "Severity"; + case 3: return "Category"; + case 4: return "ID"; + case 5: return "Description"; + default: break; + } + } + + return QVariant(); + } + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override + { + if(index.isValid() && role == Qt::DisplayRole) + { + int row = index.row(); + int col = index.column(); + + if(col >= 0 && col < columnCount() && row < rowCount()) + { + const DebugMessage &msg = m_Ctx->DebugMessages[row]; + + switch(col) + { + case 0: return msg.eventID; + case 1: return ToQStr(msg.source); + case 2: return ToQStr(msg.severity); + case 3: return ToQStr(msg.category); + case 4: return msg.messageID; + case 5: return ToQStr(msg.description); + default: break; + } + } + } + + if(index.isValid() && role == EIDRole && index.row() >= 0 && + index.row() < m_Ctx->DebugMessages.count()) + return m_Ctx->DebugMessages[index.row()].eventID; + + return QVariant(); + } + +private: + CaptureContext *m_Ctx; +}; + +class DebugMessageFilterModel : public QSortFilterProxyModel +{ +public: + DebugMessageFilterModel(CaptureContext *ctx, QObject *parent) : QSortFilterProxyModel(parent) + { + m_Ctx = ctx; + } + + typedef QPair, uint32_t> DebugMessageType; + static DebugMessageType makeType(const DebugMessage &msg) + { + return qMakePair(qMakePair(msg.source, msg.category), msg.messageID); + } + + QList m_HiddenSources; + QList m_HiddenCategories; + QList m_HiddenSeverities; + QList m_HiddenTypes; + + bool showHidden = false; + + void refresh() { invalidateFilter(); } + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override + { + if(role == Qt::FontRole && !isVisibleRow(mapToSource(index).row())) + { + QFont font; + font.setItalic(true); + return font; + } + + return QSortFilterProxyModel::data(index, role); + } + +protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override + { + if(showHidden) + return true; + + return isVisibleRow(sourceRow); + } + + bool isVisibleRow(int sourceRow) const + { + const DebugMessage &msg = m_Ctx->DebugMessages[sourceRow]; + + if(m_HiddenSources.contains(msg.source)) + return false; + + if(m_HiddenCategories.contains(msg.category)) + return false; + + if(m_HiddenSeverities.contains(msg.severity)) + return false; + + if(m_HiddenTypes.contains(makeType(msg))) + return false; + + return true; + } + + bool lessThan(const QModelIndex &left, const QModelIndex &right) const override + { + const DebugMessage &leftMsg = m_Ctx->DebugMessages[left.row()]; + const DebugMessage &rightMsg = m_Ctx->DebugMessages[right.row()]; + + if(leftMsg.eventID < rightMsg.eventID) + return true; + + if(leftMsg.source < rightMsg.source) + return true; + + if(leftMsg.severity < rightMsg.severity) + return true; + + if(leftMsg.category < rightMsg.category) + return true; + + if(leftMsg.messageID < rightMsg.messageID) + return true; + + return strcmp(leftMsg.description.c_str(), rightMsg.description.c_str()) < 0; + } + +private: + CaptureContext *m_Ctx; +}; + +DebugMessageView::DebugMessageView(CaptureContext *ctx, QWidget *parent) + : QFrame(parent), ui(new Ui::DebugMessageView) +{ + ui->setupUi(this); + + m_Ctx = ctx; + + m_ItemModel = new DebugMessageItemModel(m_Ctx, this); + m_FilterModel = new DebugMessageFilterModel(m_Ctx, this); + + m_FilterModel->setSourceModel(m_ItemModel); + ui->messages->setModel(m_FilterModel); + + ui->messages->setContextMenuPolicy(Qt::CustomContextMenu); + QObject::connect(ui->messages, &QWidget::customContextMenuRequested, this, + &DebugMessageView::messages_contextMenu); + + m_Ctx->AddLogViewer(this); + + m_ContextMenu = new QMenu(this); + + m_ShowHidden = new QAction(tr("Show hidden rows"), this); + m_ToggleSource = new QAction("", this); + m_ToggleSeverity = new QAction("", this); + m_ToggleCategory = new QAction("", this); + m_ToggleMessageType = new QAction("", this); + + m_ShowHidden->setCheckable(true); + + m_ContextMenu->addAction(m_ShowHidden); + m_ContextMenu->addSeparator(); + m_ContextMenu->addAction(m_ToggleSource); + m_ContextMenu->addAction(m_ToggleSeverity); + m_ContextMenu->addAction(m_ToggleCategory); + m_ContextMenu->addAction(m_ToggleMessageType); + + QObject::connect(m_ShowHidden, &QAction::triggered, this, &DebugMessageView::messages_toggled); + QObject::connect(m_ToggleSource, &QAction::triggered, this, &DebugMessageView::messages_toggled); + QObject::connect(m_ToggleSeverity, &QAction::triggered, this, &DebugMessageView::messages_toggled); + QObject::connect(m_ToggleCategory, &QAction::triggered, this, &DebugMessageView::messages_toggled); + QObject::connect(m_ToggleMessageType, &QAction::triggered, this, + &DebugMessageView::messages_toggled); + + RefreshMessageList(); +} + +DebugMessageView::~DebugMessageView() +{ + m_Ctx->windowClosed(this); + + m_Ctx->RemoveLogViewer(this); + delete ui; +} + +void DebugMessageView::OnLogfileClosed() +{ + m_FilterModel->showHidden = false; + RefreshMessageList(); +} + +void DebugMessageView::OnLogfileLoaded() +{ + m_FilterModel->showHidden = false; + RefreshMessageList(); +} + +void DebugMessageView::RefreshMessageList() +{ + m_ItemModel->refresh(); + + ui->messages->resizeColumnsToContents(); + + if(m_Ctx->UnreadMessageCount > 0) + setWindowTitle(tr("(%1) Errors and Warnings").arg(m_Ctx->UnreadMessageCount)); + else + setWindowTitle(tr("Errors and Warnings")); +} + +void DebugMessageView::on_messages_doubleClicked(const QModelIndex &index) +{ + QVariant var = m_ItemModel->data(index, EIDRole); + + if(var.isValid()) + { + uint32_t eid = var.toUInt(); + m_Ctx->SetEventID({}, eid, eid); + } +} + +void DebugMessageView::messages_toggled() +{ + QAction *action = qobject_cast(QObject::sender()); + + if(action == m_ShowHidden) + { + m_FilterModel->showHidden = !m_FilterModel->showHidden; + m_ShowHidden->setChecked(m_FilterModel->showHidden); + } + else if(action == m_ToggleSource) + { + if(m_FilterModel->m_HiddenSources.contains(m_ContextMessage.source)) + m_FilterModel->m_HiddenSources.removeOne(m_ContextMessage.source); + else + m_FilterModel->m_HiddenSources.push_back(m_ContextMessage.source); + } + else if(action == m_ToggleSeverity) + { + if(m_FilterModel->m_HiddenSeverities.contains(m_ContextMessage.severity)) + m_FilterModel->m_HiddenSeverities.removeOne(m_ContextMessage.severity); + else + m_FilterModel->m_HiddenSeverities.push_back(m_ContextMessage.severity); + } + else if(action == m_ToggleSeverity) + { + if(m_FilterModel->m_HiddenCategories.contains(m_ContextMessage.category)) + m_FilterModel->m_HiddenCategories.removeOne(m_ContextMessage.category); + else + m_FilterModel->m_HiddenCategories.push_back(m_ContextMessage.category); + } + else if(action == m_ToggleSeverity) + { + auto type = DebugMessageFilterModel::makeType(m_ContextMessage); + if(m_FilterModel->m_HiddenTypes.contains(type)) + m_FilterModel->m_HiddenTypes.removeOne(type); + else + m_FilterModel->m_HiddenTypes.push_back(type); + } + + m_FilterModel->refresh(); +} + +void DebugMessageView::messages_contextMenu(const QPoint &pos) +{ + if(!m_Ctx->LogLoaded()) + return; + + QModelIndex index = ui->messages->indexAt(pos); + + if(index.isValid()) + { + index = m_FilterModel->mapToSource(index); + + const DebugMessage &msg = m_Ctx->DebugMessages[index.row()]; + + QString hide = tr("Hide"); + QString show = tr("Show"); + + bool hidden = m_FilterModel->m_HiddenSources.contains(msg.source); + m_ToggleSource->setText(tr("%1 Source: %2").arg(hidden ? show : hide).arg(ToQStr(msg.source))); + + hidden = m_FilterModel->m_HiddenSeverities.contains(msg.severity); + m_ToggleSeverity->setText( + tr("%1 Severity: %2").arg(hidden ? show : hide).arg(ToQStr(msg.severity))); + + hidden = m_FilterModel->m_HiddenCategories.contains(msg.category); + m_ToggleCategory->setText( + tr("%1 Category: %2").arg(hidden ? show : hide).arg(ToQStr(msg.category))); + + hidden = m_FilterModel->m_HiddenTypes.contains(DebugMessageFilterModel::makeType(msg)); + m_ToggleMessageType->setText(tr("%1 Message Type").arg(hidden ? show : hide)); + + m_ContextMessage = msg; + + m_ContextMenu->exec(ui->messages->viewport()->mapToGlobal(pos)); + } +} + +void DebugMessageView::paintEvent(QPaintEvent *e) +{ + if(m_Ctx->UnreadMessageCount > 0) + { + m_Ctx->UnreadMessageCount = 0; + RefreshMessageList(); + } + + QFrame::paintEvent(e); +} diff --git a/qrenderdoc/Windows/DebugMessageView.h b/qrenderdoc/Windows/DebugMessageView.h new file mode 100644 index 000000000..243691d29 --- /dev/null +++ b/qrenderdoc/Windows/DebugMessageView.h @@ -0,0 +1,78 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2017 Baldur Karlsson + * + * 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 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 + * AUTHORS OR COPYRIGHT HOLDERS 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. + ******************************************************************************/ + +#pragma once + +#include +#include "Code/CaptureContext.h" + +namespace Ui +{ +class DebugMessageView; +} + +class QAction; +class QMenu; +class DebugMessageItemModel; +class DebugMessageFilterModel; + +class DebugMessageView : public QFrame, public ILogViewerForm +{ + Q_OBJECT + +public: + explicit DebugMessageView(CaptureContext *ctx, QWidget *parent = 0); + ~DebugMessageView(); + + void OnLogfileLoaded(); + void OnLogfileClosed(); + void OnSelectedEventChanged(uint32_t eventID) {} + void OnEventChanged(uint32_t eventID) {} + void RefreshMessageList(); + +private slots: + // automatic slots + void on_messages_doubleClicked(const QModelIndex &index); + + // manual slots + void messages_contextMenu(const QPoint &pos); + void messages_toggled(); + +private: + void paintEvent(QPaintEvent *e) override; + Ui::DebugMessageView *ui; + CaptureContext *m_Ctx; + + QVector m_Messages; + DebugMessageItemModel *m_ItemModel; + DebugMessageFilterModel *m_FilterModel; + + DebugMessage m_ContextMessage; + QMenu *m_ContextMenu; + QAction *m_ShowHidden; + QAction *m_ToggleSource; + QAction *m_ToggleSeverity; + QAction *m_ToggleCategory; + QAction *m_ToggleMessageType; +}; diff --git a/qrenderdoc/Windows/DebugMessageView.ui b/qrenderdoc/Windows/DebugMessageView.ui new file mode 100644 index 000000000..cbc72363e --- /dev/null +++ b/qrenderdoc/Windows/DebugMessageView.ui @@ -0,0 +1,49 @@ + + + DebugMessageView + + + + 0 + 0 + 400 + 300 + + + + + 2 + + + 2 + + + 2 + + + 2 + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + true + + + false + + + + + + + + diff --git a/qrenderdoc/Windows/MainWindow.cpp b/qrenderdoc/Windows/MainWindow.cpp index 2e5677b86..62a9201cc 100644 --- a/qrenderdoc/Windows/MainWindow.cpp +++ b/qrenderdoc/Windows/MainWindow.cpp @@ -32,12 +32,14 @@ #include "Code/QRDUtils.h" #include "PipelineState/PipelineStateViewer.h" #include "Resources/resource.h" +#include "Widgets/Extended/RDLabel.h" #include "Windows/Dialogs/AboutDialog.h" #include "Windows/Dialogs/CaptureDialog.h" #include "Windows/Dialogs/LiveCapture.h" #include "APIInspector.h" #include "BufferViewer.h" #include "ConstantBufferPreviewer.h" +#include "DebugMessageView.h" #include "EventBrowser.h" #include "TextureViewer.h" #include "ui_MainWindow.h" @@ -96,10 +98,10 @@ MainWindow::MainWindow(CaptureContext *ctx) : QMainWindow(NULL), ui(new Ui::Main QObject::connect(ui->action_Save_Layout_6, &QAction::triggered, this, &MainWindow::saveLayout_triggered); - statusIcon = new QLabel(this); + statusIcon = new RDLabel(this); ui->statusBar->addWidget(statusIcon); - statusText = new QLabel(this); + statusText = new RDLabel(this); ui->statusBar->addWidget(statusText); statusProgress = new QProgressBar(this); @@ -114,6 +116,9 @@ MainWindow::MainWindow(CaptureContext *ctx) : QMainWindow(NULL), ui(new Ui::Main statusIcon->setPixmap(QPixmap()); statusText->setText(""); + QObject::connect(statusIcon, &RDLabel::doubleClicked, this, &MainWindow::statusDoubleClicked); + QObject::connect(statusText, &RDLabel::doubleClicked, this, &MainWindow::statusDoubleClicked); + QObject::connect(&m_MessageTick, &QTimer::timeout, this, &MainWindow::messageCheck); m_MessageTick.setSingleShot(false); m_MessageTick.setInterval(500); @@ -883,6 +888,11 @@ void MainWindow::messageCheck() } } +void MainWindow::statusDoubleClicked() +{ + showDebugMessageView(); +} + void MainWindow::OnLogfileLoaded() { // TODO Remote @@ -1045,6 +1055,16 @@ void MainWindow::on_action_Inject_into_Process_triggered() ui->toolWindowManager->addToolWindow(capDialog, mainToolArea()); } +void MainWindow::on_action_Errors_and_Warnings_triggered() +{ + DebugMessageView *debugMessages = m_Ctx->debugMessageView(); + + if(ui->toolWindowManager->toolWindows().contains(debugMessages)) + ToolWindowManager::raiseToolWindow(debugMessages); + else + ui->toolWindowManager->addToolWindow(debugMessages, mainToolArea()); +} + void MainWindow::on_action_Resolve_Symbols_triggered() { m_Ctx->Renderer()->AsyncInvoke([this](IReplayRenderer *r) { r->InitResolver(); }); diff --git a/qrenderdoc/Windows/MainWindow.h b/qrenderdoc/Windows/MainWindow.h index da4993d1d..db9b6023e 100644 --- a/qrenderdoc/Windows/MainWindow.h +++ b/qrenderdoc/Windows/MainWindow.h @@ -35,7 +35,7 @@ namespace Ui class MainWindow; } -class QLabel; +class RDLabel; class QMimeData; class QProgressBar; class CaptureDialog; @@ -78,6 +78,7 @@ public: void showTextureViewer() { on_action_Texture_Viewer_triggered(); } void showPipelineViewer() { on_action_Pipeline_State_triggered(); } void showCaptureDialog() { on_action_Capture_Log_triggered(); } + void showDebugMessageView() { on_action_Errors_and_Warnings_triggered(); } private slots: // automatic slots void on_action_Exit_triggered(); @@ -91,6 +92,7 @@ private slots: void on_action_Texture_Viewer_triggered(); void on_action_Pipeline_State_triggered(); void on_action_Capture_Log_triggered(); + void on_action_Errors_and_Warnings_triggered(); void on_action_Inject_into_Process_triggered(); void on_action_Resolve_Symbols_triggered(); @@ -98,6 +100,7 @@ private slots: void saveLayout_triggered(); void loadLayout_triggered(); void messageCheck(); + void statusDoubleClicked(); private: void closeEvent(QCloseEvent *event) override; @@ -115,8 +118,8 @@ private: QList m_LiveCaptures; - QLabel *statusIcon; - QLabel *statusText; + RDLabel *statusIcon; + RDLabel *statusText; QProgressBar *statusProgress; QTimer m_MessageTick; diff --git a/qrenderdoc/qrenderdoc.pro b/qrenderdoc/qrenderdoc.pro index 8cad9129d..2c2bbc0c0 100644 --- a/qrenderdoc/qrenderdoc.pro +++ b/qrenderdoc/qrenderdoc.pro @@ -131,7 +131,8 @@ SOURCES += Code/qrenderdoc.cpp \ Widgets/BufferFormatSpecifier.cpp \ Code/FormatElement.cpp \ Windows/BufferViewer.cpp \ - Widgets/Extended/RDTableView.cpp + Widgets/Extended/RDTableView.cpp \ + Windows/DebugMessageView.cpp HEADERS += Code/CaptureContext.h \ Code/qprocessinfo.h \ @@ -167,7 +168,8 @@ HEADERS += Code/CaptureContext.h \ Windows/ConstantBufferPreviewer.h \ Widgets/BufferFormatSpecifier.h \ Windows/BufferViewer.h \ - Widgets/Extended/RDTableView.h + Widgets/Extended/RDTableView.h \ + Windows/DebugMessageView.h FORMS += Windows/Dialogs/AboutDialog.ui \ Windows/MainWindow.ui \ @@ -187,7 +189,8 @@ FORMS += Windows/Dialogs/AboutDialog.ui \ Windows/ConstantBufferPreviewer.ui \ Widgets/BufferFormatSpecifier.ui \ Windows/BufferViewer.ui \ - Windows/ShaderViewer.ui + Windows/ShaderViewer.ui \ + Windows/DebugMessageView.ui RESOURCES += resources.qrc diff --git a/qrenderdoc/qrenderdoc_local.vcxproj b/qrenderdoc/qrenderdoc_local.vcxproj index 5e7d81e58..5f107a3c1 100644 --- a/qrenderdoc/qrenderdoc_local.vcxproj +++ b/qrenderdoc/qrenderdoc_local.vcxproj @@ -499,6 +499,7 @@ + @@ -544,6 +545,7 @@ + @@ -650,6 +652,7 @@ + @@ -678,6 +681,7 @@ + @@ -705,6 +709,7 @@ + diff --git a/qrenderdoc/qrenderdoc_local.vcxproj.filters b/qrenderdoc/qrenderdoc_local.vcxproj.filters index c5572c5f9..3f329d070 100644 --- a/qrenderdoc/qrenderdoc_local.vcxproj.filters +++ b/qrenderdoc/qrenderdoc_local.vcxproj.filters @@ -466,6 +466,12 @@ Code + + Generated Files + + + Generated Files + @@ -825,6 +831,12 @@ Code + + Generated Files + + + Generated Files + @@ -1061,6 +1073,7 @@ Windows +