mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 09:00:44 +00:00
Add flowchart custom widget to show select pipeline stages
This commit is contained in:
@@ -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();
|
||||
}
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user