Add flowchart custom widget to show select pipeline stages

This commit is contained in:
baldurk
2017-02-13 19:16:02 +00:00
parent 399a9f5a1e
commit 871a48d7fa
16 changed files with 643 additions and 99 deletions
+304
View File
@@ -0,0 +1,304 @@
/******************************************************************************
* 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 "PipelineFlowChart.h"
#include <QMouseEvent>
#include <QPainter>
PipelineFlowChart::PipelineFlowChart(QWidget *parent) : QFrame(parent)
{
setMouseTracking(true);
}
PipelineFlowChart::~PipelineFlowChart()
{
}
void PipelineFlowChart::setStages(const QStringList &abbrevs, const QStringList &names)
{
m_StageNames = names;
m_StageAbbrevs = abbrevs;
m_StageFlows.reserve(m_StageNames.count());
m_StagesEnabled.reserve(m_StageNames.count());
for(int i = 0; i < m_StageNames.count(); i++)
{
m_StageFlows.push_back(true);
m_StagesEnabled.push_back(true);
}
update();
}
void PipelineFlowChart::setStageName(int index, const QString &abbrev, const QString &name)
{
if(index >= 0 && index < m_StageNames.count())
{
m_StageAbbrevs[index] = abbrev;
m_StageNames[index] = name;
}
update();
}
void PipelineFlowChart::setIsolatedStage(int index)
{
if(index >= 0 && index < m_StageFlows.count())
m_StageFlows[index] = false;
}
void PipelineFlowChart::setSelectedStage(int idx)
{
if(idx >= 0 && idx < m_StageNames.length())
{
m_SelectedStage = idx;
update();
emit stageSelected(idx);
}
}
int PipelineFlowChart::selectedStage()
{
return m_SelectedStage;
}
void PipelineFlowChart::setStagesEnabled(const QList<bool> &enabled)
{
for(int i = 0; i < enabled.count() && i < m_StagesEnabled.count(); i++)
m_StagesEnabled[i] = enabled[i];
update();
}
bool PipelineFlowChart::stageEnabled(int index)
{
return index >= 0 && index < m_StagesEnabled.count() && m_StagesEnabled[index];
}
int PipelineFlowChart::numGaps()
{
if(!m_StageNames.isEmpty())
return m_StageNames.count() - 1;
return 1;
}
int PipelineFlowChart::numItems()
{
if(!m_StageNames.isEmpty())
return m_StageNames.count();
return 2;
}
QRectF PipelineFlowChart::totalAreaRect()
{
QRectF rect = this->rect();
qreal m = 6 + BoxBorderWidth;
return rect.marginsRemoved(QMarginsF(m, m, m, m));
}
qreal PipelineFlowChart::boxMargin()
{
qreal margin = qMax(totalAreaRect().width(), totalAreaRect().height()) * BoxMarginFraction;
margin = qMax(MinBoxMargin, margin);
return margin;
}
QRectF PipelineFlowChart::boxRect(int i)
{
QRectF totalRect = totalAreaRect();
qreal boxeswidth = totalRect.width() - numGaps() * boxMargin();
qreal boxdim = qMin(totalRect.height(), boxeswidth / numItems());
boxdim = qMax(MinBoxDimension, boxdim);
qreal oblongwidth = qMax(0.0, (boxeswidth - boxdim * numItems()) / numItems());
QSizeF boxSize(boxdim + oblongwidth, boxdim);
QRectF ret(totalRect.x() + i * (boxSize.width() + boxMargin()),
totalRect.y() + totalRect.height() / 2 - boxSize.height() / 2, boxSize.width(),
boxSize.height());
return ret;
}
void PipelineFlowChart::drawArrow(QPainter &p, const QPen &pen, float headsize, float y, float left,
float right)
{
p.setPen(pen);
p.drawPolygon(QPolygonF({QPointF(right, y), QPointF(right - headsize, y - headsize),
QPointF(right - headsize, y + headsize)}));
QPen linePen(pen);
linePen.setWidthF(BoxBorderWidth);
p.setPen(linePen);
p.drawLine(QPointF(left, y), QPointF(right, y));
}
void PipelineFlowChart::paintEvent(QPaintEvent *e)
{
if(m_StageNames.empty())
return;
QPainter p(this);
p.fillRect(rect(), Qt::transparent);
p.setRenderHint(QPainter::Antialiasing, true);
const QRectF totalRect = totalAreaRect();
const QRectF box0Rect = boxRect(0);
const qreal radius = qMin(MaxBoxCornerRadius, box0Rect.height() * BoxCornerRadiusFraction);
const qreal arrowY = totalRect.y() + totalRect.height() / 2;
QColor base = palette().color(QPalette::Base);
QColor baseText = palette().color(QPalette::Text);
QColor inactiveWin = palette().color(QPalette::Inactive, QPalette::Dark);
QColor inactiveWinText = palette().color(QPalette::Inactive, QPalette::WindowText);
QColor tooltip = palette().color(QPalette::ToolTipBase);
QColor tooltipText = palette().color(QPalette::ToolTipText);
QPen pen(baseText);
QPen selectedPen(Qt::red);
int num = numGaps();
for(int i = 0; i < num; i++)
{
if(!m_StageFlows[i] || !m_StageFlows[i + 1])
continue;
float right = totalRect.x() + (i + 1) * (box0Rect.width() + boxMargin());
float left = right - boxMargin();
p.setBrush(baseText);
drawArrow(p, pen, ArrowHeadSize, arrowY, left, right);
}
num = numItems();
for(int i = 0; i < num; i++)
{
QRectF boxrect = boxRect(i);
QBrush backBrush(base);
QPen textPen(baseText);
QPen outlinePen = pen;
if(!stageEnabled(i))
{
backBrush.setColor(inactiveWin);
textPen.setColor(inactiveWinText);
}
if(i == m_HoverStage)
{
backBrush.setColor(tooltip);
textPen.setColor(tooltipText);
}
if(i == m_SelectedStage)
{
outlinePen = selectedPen;
}
outlinePen.setWidthF(BoxBorderWidth);
p.setPen(outlinePen);
p.setBrush(backBrush);
p.drawRoundedRect(boxrect, radius, radius);
QTextOption opts(Qt::AlignCenter);
opts.setWrapMode(QTextOption::NoWrap);
QString s = m_StageNames[i];
QRectF reqBox = p.boundingRect(QRectF(0, 0, 1, 1), m_StageNames[i], opts);
if(reqBox.width() + BoxLabelMargin > (float)boxrect.width())
s = m_StageAbbrevs[i];
p.setPen(textPen);
p.drawText(boxrect, s, opts);
}
}
void PipelineFlowChart::mouseMoveEvent(QMouseEvent *e)
{
int old = m_HoverStage;
m_HoverStage = -1;
const int num = numItems();
for(int i = 0; i < num; i++)
{
if(boxRect(i).contains(e->pos()))
{
m_HoverStage = i;
break;
}
}
if(m_HoverStage != old)
update();
}
void PipelineFlowChart::mousePressEvent(QMouseEvent *e)
{
if(e->button() == Qt::LeftButton)
{
const int num = numItems();
for(int i = 0; i < numItems(); i++)
{
if(boxRect(i).contains(e->pos()))
{
setSelectedStage(i);
break;
}
}
}
}
void PipelineFlowChart::leaveEvent(QEvent *e)
{
m_HoverStage = -1;
update();
}
void PipelineFlowChart::focusOutEvent(QFocusEvent *event)
{
m_HoverStage = -1;
update();
}
+83
View File
@@ -0,0 +1,83 @@
/******************************************************************************
* 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 <QFrame>
class PipelineFlowChart : public QFrame
{
Q_OBJECT
public:
explicit PipelineFlowChart(QWidget *parent = 0);
~PipelineFlowChart();
void setStages(const QStringList &abbrevs, const QStringList &names);
void setStageName(int index, const QString &abbrev, const QString &name);
void setIsolatedStage(int index);
void setStagesEnabled(const QList<bool> &enabled);
void setSelectedStage(int idx);
int selectedStage();
signals:
void stageSelected(int idx);
private:
void paintEvent(QPaintEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void mousePressEvent(QMouseEvent *e) override;
void leaveEvent(QEvent *e) override;
void focusOutEvent(QFocusEvent *event) override;
QList<bool> m_StagesEnabled;
QList<bool> m_StageFlows;
QStringList m_StageAbbrevs;
QStringList m_StageNames;
int m_HoverStage = -1;
int m_SelectedStage = 0;
bool stageEnabled(int index);
const qreal BoxBorderWidth = 2.5;
const qreal MinBoxDimension = 25.0;
const qreal MaxBoxCornerRadius = 20.0;
const qreal BoxCornerRadiusFraction = 1.0 / 6.0;
const qreal ArrowHeadSize = 6.0;
const qreal MinBoxMargin = 4.0;
const qreal BoxLabelMargin = 8.0;
const qreal BoxMarginFraction = 0.02;
int numGaps();
int numItems();
QRectF totalAreaRect();
qreal boxMargin();
QRectF boxRect(int i);
void drawArrow(QPainter &p, const QPen &pen, float headsize, float y, float left, float right);
};
@@ -318,6 +318,21 @@ D3D11PipelineStateViewer::D3D11PipelineStateViewer(CaptureContext &ctx, Pipeline
// this is often changed just because we're changing some tab in the designer.
ui->stagesTabs->setCurrentIndex(0);
ui->stagesTabs->tabBar()->setVisible(false);
ui->pipeFlow->setStages(
{
"IA", "VS", "HS", "DS", "GS", "RS", "PS", "OM", "CS",
},
{
"Input Assembler", "Vertex Shader", "Hull Shader", "Domain Shader", "Geometry Shader",
"Rasterizer", "Pixel Shader", "Output Merger", "Compute Shader",
});
ui->pipeFlow->setIsolatedStage(8); // compute shader isolated
ui->pipeFlow->setStagesEnabled({true, true, true, true, true, true, true, true, true});
// reset everything back to defaults
clearState();
}
@@ -334,6 +349,8 @@ void D3D11PipelineStateViewer::OnLogfileLoaded()
void D3D11PipelineStateViewer::OnLogfileClosed()
{
ui->pipeFlow->setStagesEnabled({true, true, true, true, true, true, true, true, true});
clearState();
}
@@ -1628,37 +1645,21 @@ void D3D11PipelineStateViewer::setState()
ui->stencils->clearSelection();
ui->stencils->setUpdatesEnabled(true);
// highlight the appropriate stages in the flowchart
#if 0
if(draw == null)
// highlight the appropriate stages in the flowchart
if(draw == NULL)
{
pipeFlow.SetStagesEnabled(new bool[] { true, true, true, true, true, true, true, true, true });
ui->pipeFlow->setStagesEnabled({true, true, true, true, true, true, true, true, true});
}
else if((draw.flags & DrawcallFlags.Dispatch) != 0)
else if(draw->flags & eDraw_Dispatch)
{
pipeFlow.SetStagesEnabled(new bool[] { false, false, false, false, false, false, false, false, true });
ui->pipeFlow->setStagesEnabled({false, false, false, false, false, false, false, false, true});
}
else
{
pipeFlow.SetStagesEnabled(new bool[] {
true,
true,
state.HS.Shader != ResourceId(),
state.DS.Shader != ResourceId(),
state.GS.Shader != ResourceId(),
true,
state.PS.Shader != ResourceId(),
true,
false
});
// if(streamout only)
//{
// pipeFlow.Rasterizer = false;
// pipeFlow.OutputMerger = false;
//}
ui->pipeFlow->setStagesEnabled(
{true, true, state.m_HS.Shader != ResourceId(), state.m_DS.Shader != ResourceId(),
state.m_GS.Shader != ResourceId(), true, state.m_PS.Shader != ResourceId(), true, false});
}
#endif
}
QString D3D11PipelineStateViewer::formatMembers(int indent, const QString &nameprefix,
@@ -2088,6 +2089,11 @@ void D3D11PipelineStateViewer::on_iaBuffers_mouseMove(QMouseEvent *e)
}
}
void D3D11PipelineStateViewer::on_pipeFlow_stageSelected(int index)
{
ui->stagesTabs->setCurrentIndex(index);
}
void D3D11PipelineStateViewer::vertex_leave(QEvent *e)
{
ui->iaLayouts->model()->blockSignals(true);
@@ -61,6 +61,7 @@ private slots:
void on_iaBuffers_itemActivated(QTreeWidgetItem *item, int column);
void on_iaLayouts_mouseMove(QMouseEvent *event);
void on_iaBuffers_mouseMove(QMouseEvent *event);
void on_pipeFlow_stageSelected(int index);
// manual slots
void shaderView_clicked();
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>996</width>
<height>574</height>
<height>586</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@@ -143,6 +143,33 @@
</layout>
</widget>
</item>
<item>
<widget class="PipelineFlowChart" name="pipeFlow">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>60</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>75</height>
</size>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="stagesTabs">
<property name="currentIndex">
@@ -4977,6 +5004,12 @@ padding: 0px;</string>
<extends>QLabel</extends>
<header>Widgets/Extended/RDLabel.h</header>
</customwidget>
<customwidget>
<class>PipelineFlowChart</class>
<extends>QFrame</extends>
<header>Widgets/PipelineFlowChart.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../Resources/resources.qrc"/>
@@ -354,6 +354,21 @@ D3D12PipelineStateViewer::D3D12PipelineStateViewer(CaptureContext &ctx, Pipeline
// this is often changed just because we're changing some tab in the designer.
ui->stagesTabs->setCurrentIndex(0);
ui->stagesTabs->tabBar()->setVisible(false);
ui->pipeFlow->setStages(
{
"IA", "VS", "HS", "DS", "GS", "RS", "PS", "OM", "CS",
},
{
"Input Assembler", "Vertex Shader", "Hull Shader", "Domain Shader", "Geometry Shader",
"Rasterizer", "Pixel Shader", "Output Merger", "Compute Shader",
});
ui->pipeFlow->setIsolatedStage(8); // compute shader isolated
ui->pipeFlow->setStagesEnabled({true, true, true, true, true, true, true, true, true});
// reset everything back to defaults
clearState();
}
@@ -370,6 +385,8 @@ void D3D12PipelineStateViewer::OnLogfileLoaded()
void D3D12PipelineStateViewer::OnLogfileClosed()
{
ui->pipeFlow->setStagesEnabled({true, true, true, true, true, true, true, true, true});
clearState();
}
@@ -1611,37 +1628,21 @@ void D3D12PipelineStateViewer::setState()
ui->stencils->clearSelection();
ui->stencils->setUpdatesEnabled(true);
// highlight the appropriate stages in the flowchart
#if 0
if(draw == null)
// highlight the appropriate stages in the flowchart
if(draw == NULL)
{
pipeFlow.SetStagesEnabled(new bool[] { true, true, true, true, true, true, true, true, true });
ui->pipeFlow->setStagesEnabled({true, true, true, true, true, true, true, true, true});
}
else if((draw.flags & DrawcallFlags.Dispatch) != 0)
else if(draw->flags & eDraw_Dispatch)
{
pipeFlow.SetStagesEnabled(new bool[] { false, false, false, false, false, false, false, false, true });
ui->pipeFlow->setStagesEnabled({false, false, false, false, false, false, false, false, true});
}
else
{
pipeFlow.SetStagesEnabled(new bool[] {
true,
true,
state.HS.Shader != ResourceId(),
state.DS.Shader != ResourceId(),
state.GS.Shader != ResourceId(),
true,
state.PS.Shader != ResourceId(),
true,
false
});
// if(streamout only)
//{
// pipeFlow.Rasterizer = false;
// pipeFlow.OutputMerger = false;
//}
ui->pipeFlow->setStagesEnabled(
{true, true, state.m_HS.Shader != ResourceId(), state.m_DS.Shader != ResourceId(),
state.m_GS.Shader != ResourceId(), true, state.m_PS.Shader != ResourceId(), true, false});
}
#endif
}
QString D3D12PipelineStateViewer::formatMembers(int indent, const QString &nameprefix,
@@ -2134,6 +2135,11 @@ void D3D12PipelineStateViewer::vertex_leave(QEvent *e)
}
}
void D3D12PipelineStateViewer::on_pipeFlow_stageSelected(int index)
{
ui->stagesTabs->setCurrentIndex(index);
}
void D3D12PipelineStateViewer::shaderView_clicked()
{
QWidget *sender = qobject_cast<QWidget *>(QObject::sender());
@@ -61,6 +61,7 @@ private slots:
void on_iaBuffers_itemActivated(QTreeWidgetItem *item, int column);
void on_iaLayouts_mouseMove(QMouseEvent *event);
void on_iaBuffers_mouseMove(QMouseEvent *event);
void on_pipeFlow_stageSelected(int index);
// manual slots
void shaderView_clicked();
@@ -143,6 +143,28 @@
</layout>
</widget>
</item>
<item>
<widget class="PipelineFlowChart" name="pipeFlow">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>60</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>75</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="stagesTabs">
<property name="currentIndex">
@@ -5188,6 +5210,12 @@ padding: 0px;</string>
<extends>QLabel</extends>
<header>Widgets/Extended/RDLabel.h</header>
</customwidget>
<customwidget>
<class>PipelineFlowChart</class>
<extends>QFrame</extends>
<header>Widgets/PipelineFlowChart.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../Resources/resources.qrc"/>
@@ -324,6 +324,22 @@ GLPipelineStateViewer::GLPipelineStateViewer(CaptureContext &ctx, PipelineStateV
// this is often changed just because we're changing some tab in the designer.
ui->stagesTabs->setCurrentIndex(0);
ui->stagesTabs->tabBar()->setVisible(false);
ui->pipeFlow->setStages(
{
"VTX", "VS", "TCS", "TES", "GS", "RS", "FS", "FB", "CS",
},
{
"Vertex Input", "Vertex Shader", "Tess. Control Shader", "Tess. Eval. Shader",
"Geometry Shader", "Rasterizer", "Fragment Shader", "Framebuffer Output",
"Compute Shader",
});
ui->pipeFlow->setIsolatedStage(8); // compute shader isolated
ui->pipeFlow->setStagesEnabled({true, true, true, true, true, true, true, true, true});
// reset everything back to defaults
clearState();
}
@@ -340,6 +356,8 @@ void GLPipelineStateViewer::OnLogfileLoaded()
void GLPipelineStateViewer::OnLogfileClosed()
{
ui->pipeFlow->setStagesEnabled({true, true, true, true, true, true, true, true, true});
clearState();
}
@@ -1864,37 +1882,21 @@ void GLPipelineStateViewer::setState()
ui->stencils->clearSelection();
ui->stencils->setUpdatesEnabled(true);
// highlight the appropriate stages in the flowchart
#if 0
if(draw == null)
// highlight the appropriate stages in the flowchart
if(draw == NULL)
{
pipeFlow.SetStagesEnabled(new bool[] { true, true, true, true, true, true, true, true, true });
ui->pipeFlow->setStagesEnabled({true, true, true, true, true, true, true, true, true});
}
else if((draw.flags & DrawcallFlags.Dispatch) != 0)
else if(draw->flags & eDraw_Dispatch)
{
pipeFlow.SetStagesEnabled(new bool[] { false, false, false, false, false, false, false, false, true });
ui->pipeFlow->setStagesEnabled({false, false, false, false, false, false, false, false, true});
}
else
{
pipeFlow.SetStagesEnabled(new bool[] {
true,
true,
state.TCS.Shader != ResourceId(),
state.TES.Shader != ResourceId(),
state.GS.Shader != ResourceId(),
true,
state.FS.Shader != ResourceId(),
true,
false
});
// if(streamout only)
//{
// pipeFlow.Rasterizer = false;
// pipeFlow.OutputMerger = false;
//}
ui->pipeFlow->setStagesEnabled(
{true, true, state.m_TCS.Shader != ResourceId(), state.m_TES.Shader != ResourceId(),
state.m_GS.Shader != ResourceId(), true, state.m_FS.Shader != ResourceId(), true, false});
}
#endif
}
QString GLPipelineStateViewer::formatMembers(int indent, const QString &nameprefix,
@@ -2232,6 +2234,11 @@ void GLPipelineStateViewer::vertex_leave(QEvent *e)
}
}
void GLPipelineStateViewer::on_pipeFlow_stageSelected(int index)
{
ui->stagesTabs->setCurrentIndex(index);
}
void GLPipelineStateViewer::shaderView_clicked()
{
const GLPipelineState::ShaderStage *stage =
@@ -60,6 +60,7 @@ private slots:
void on_viBuffers_itemActivated(QTreeWidgetItem *item, int column);
void on_viAttrs_mouseMove(QMouseEvent *event);
void on_viBuffers_mouseMove(QMouseEvent *event);
void on_pipeFlow_stageSelected(int index);
// manual slots
void shaderView_clicked();
@@ -143,6 +143,28 @@
</layout>
</widget>
</item>
<item>
<widget class="PipelineFlowChart" name="pipeFlow">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>60</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>75</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="stagesTabs">
<property name="currentIndex">
@@ -5488,6 +5510,12 @@ padding: 0px;</string>
<extends>QLabel</extends>
<header>Widgets/Extended/RDLabel.h</header>
</customwidget>
<customwidget>
<class>PipelineFlowChart</class>
<extends>QFrame</extends>
<header>Widgets/PipelineFlowChart.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../Resources/resources.qrc"/>
@@ -288,6 +288,22 @@ VulkanPipelineStateViewer::VulkanPipelineStateViewer(CaptureContext &ctx,
// this is often changed just because we're changing some tab in the designer.
ui->stagesTabs->setCurrentIndex(0);
ui->stagesTabs->tabBar()->setVisible(false);
ui->pipeFlow->setStages(
{
"VTX", "VS", "TCS", "TES", "GS", "RS", "FS", "FB", "CS",
},
{
"Vertex Input", "Vertex Shader", "Tess. Control Shader", "Tess. Eval. Shader",
"Geometry Shader", "Rasterizer", "Fragment Shader", "Framebuffer Output",
"Compute Shader",
});
ui->pipeFlow->setIsolatedStage(8); // compute shader isolated
ui->pipeFlow->setStagesEnabled({true, true, true, true, true, true, true, true, true});
// reset everything back to defaults
clearState();
}
@@ -304,6 +320,8 @@ void VulkanPipelineStateViewer::OnLogfileLoaded()
void VulkanPipelineStateViewer::OnLogfileClosed()
{
ui->pipeFlow->setStagesEnabled({true, true, true, true, true, true, true, true, true});
clearState();
}
@@ -1955,37 +1973,21 @@ void VulkanPipelineStateViewer::setState()
ui->stencils->clearSelection();
ui->stencils->setUpdatesEnabled(true);
// highlight the appropriate stages in the flowchart
#if 0
if(draw == null)
// highlight the appropriate stages in the flowchart
if(draw == NULL)
{
pipeFlow.SetStagesEnabled(new bool[] { true, true, true, true, true, true, true, true, true });
ui->pipeFlow->setStagesEnabled({true, true, true, true, true, true, true, true, true});
}
else if((draw.flags & DrawcallFlags.Dispatch) != 0)
else if(draw->flags & eDraw_Dispatch)
{
pipeFlow.SetStagesEnabled(new bool[] { false, false, false, false, false, false, false, false, true });
ui->pipeFlow->setStagesEnabled({false, false, false, false, false, false, false, false, true});
}
else
{
pipeFlow.SetStagesEnabled(new bool[] {
true,
true,
state.TCS.Shader != ResourceId(),
state.TES.Shader != ResourceId(),
state.GS.Shader != ResourceId(),
true,
state.FS.Shader != ResourceId(),
true,
false
});
// if(streamout only)
//{
// pipeFlow.Rasterizer = false;
// pipeFlow.OutputMerger = false;
//}
ui->pipeFlow->setStagesEnabled(
{true, true, state.m_TCS.Shader != ResourceId(), state.m_TES.Shader != ResourceId(),
state.m_GS.Shader != ResourceId(), true, state.m_FS.Shader != ResourceId(), true, false});
}
#endif
}
QString VulkanPipelineStateViewer::formatMembers(int indent, const QString &nameprefix,
@@ -2334,6 +2336,11 @@ void VulkanPipelineStateViewer::vertex_leave(QEvent *e)
}
}
void VulkanPipelineStateViewer::on_pipeFlow_stageSelected(int index)
{
ui->stagesTabs->setCurrentIndex(index);
}
void VulkanPipelineStateViewer::shaderView_clicked()
{
const VulkanPipelineState::ShaderStage *stage =
@@ -67,6 +67,7 @@ private slots:
void on_viBuffers_itemActivated(QTreeWidgetItem *item, int column);
void on_viAttrs_mouseMove(QMouseEvent *event);
void on_viBuffers_mouseMove(QMouseEvent *event);
void on_pipeFlow_stageSelected(int index);
// manual slots
void shaderView_clicked();
@@ -143,6 +143,28 @@
</layout>
</widget>
</item>
<item>
<widget class="PipelineFlowChart" name="pipeFlow">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>60</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>75</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="stagesTabs">
<property name="currentIndex">
@@ -3738,6 +3760,12 @@ padding: 0px;</string>
<extends>QLabel</extends>
<header>Widgets/Extended/RDLabel.h</header>
</customwidget>
<customwidget>
<class>PipelineFlowChart</class>
<extends>QFrame</extends>
<header>Widgets/PipelineFlowChart.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../Resources/resources.qrc"/>
+4 -2
View File
@@ -145,7 +145,8 @@ SOURCES += Code/qrenderdoc.cpp \
Windows/Dialogs/SuggestRemoteDialog.cpp \
Windows/Dialogs/VirtualFileDialog.cpp \
Windows/Dialogs/RemoteManager.cpp \
Windows/PixelHistoryView.cpp
Windows/PixelHistoryView.cpp \
Widgets/PipelineFlowChart.cpp
HEADERS += Code/CaptureContext.h \
Code/qprocessinfo.h \
@@ -193,7 +194,8 @@ HEADERS += Code/CaptureContext.h \
Windows/Dialogs/SuggestRemoteDialog.h \
Windows/Dialogs/VirtualFileDialog.h \
Windows/Dialogs/RemoteManager.h \
Windows/PixelHistoryView.h
Windows/PixelHistoryView.h \
Widgets/PipelineFlowChart.h
FORMS += Windows/Dialogs/AboutDialog.ui \
Windows/MainWindow.ui \
+8
View File
@@ -661,6 +661,7 @@
<ClCompile Include="generated\moc_RemoteManager.cpp" />
<ClCompile Include="generated\moc_PipelineStateViewer.cpp" />
<ClCompile Include="generated\moc_QRDUtils.cpp" />
<ClCompile Include="generated\moc_PipelineFlowChart.cpp" />
<ClCompile Include="generated\moc_RangeHistogram.cpp" />
<ClCompile Include="generated\moc_RDDoubleSpinBox.cpp" />
<ClCompile Include="generated\moc_RDLabel.cpp" />
@@ -706,6 +707,7 @@
<ClCompile Include="Widgets\Extended\RDTableWidget.cpp" />
<ClCompile Include="Widgets\Extended\RDTreeView.cpp" />
<ClCompile Include="Widgets\Extended\RDTreeWidget.cpp" />
<ClCompile Include="Widgets\PipelineFlowChart.cpp" />
<ClCompile Include="Widgets\RangeHistogram.cpp" />
<ClCompile Include="Widgets\Extended\RDDoubleSpinBox.cpp" />
<ClCompile Include="Widgets\Extended\RDLabel.cpp" />
@@ -966,6 +968,12 @@
<Message>MOC %(Filename).h</Message>
<Outputs>generated\moc_%(Filename).cpp</Outputs>
</CustomBuild>
<CustomBuild Include="Widgets\PipelineFlowChart.h">
<AdditionalInputs>%(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs)</AdditionalInputs>
<Command>$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I$(ProjectDir) -I$(SolutionDir)\renderdoc\api\replay -I$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015 -I$(ProjectDir)3rdparty\qt\$(Platform)\include -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore %(Fullpath) -o $(ProjectDir)generated\moc_%(Filename).cpp</Command>
<Message>MOC %(Filename).h</Message>
<Outputs>generated\moc_%(Filename).cpp</Outputs>
</CustomBuild>
<CustomBuild Include="Widgets\RangeHistogram.h">
<AdditionalInputs>%(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs)</AdditionalInputs>
<Command>$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I$(ProjectDir) -I$(SolutionDir)\renderdoc\api\replay -I$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015 -I$(ProjectDir)3rdparty\qt\$(Platform)\include -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore %(Fullpath) -o $(ProjectDir)generated\moc_%(Filename).cpp</Command>