mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Add pixel history window
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
/******************************************************************************
|
||||
* 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 "RDTreeView.h"
|
||||
#include <QPainter>
|
||||
|
||||
RDTreeView::RDTreeView(QWidget *parent) : QTreeView(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void RDTreeView::drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const
|
||||
{
|
||||
if(m_DrawBranches)
|
||||
{
|
||||
QTreeView::drawBranches(painter, rect, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
// draw only the expand item, not the branches
|
||||
QRect primitive(0, rect.top(), indentation(), rect.height());
|
||||
|
||||
// if root isn't decorated, skip
|
||||
if(!rootIsDecorated() && !index.parent().isValid())
|
||||
return;
|
||||
|
||||
// if no children, nothing to render
|
||||
if(model()->rowCount(index) == 0)
|
||||
return;
|
||||
|
||||
QStyleOptionViewItem opt = viewOptions();
|
||||
|
||||
opt.rect = primitive;
|
||||
|
||||
// unfortunately QStyle::State_Children doesn't render ONLY the
|
||||
// open-toggle-button, but the vertical line upwards to a previous sibling.
|
||||
// For consistency, draw one downwards too.
|
||||
opt.state = QStyle::State_Children | QStyle::State_Sibling;
|
||||
if(isExpanded(index))
|
||||
opt.state |= QStyle::State_Open;
|
||||
|
||||
style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, painter, this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/******************************************************************************
|
||||
* 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 <QTreeView>
|
||||
|
||||
class RDTreeView : public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RDTreeView(QWidget *parent = 0);
|
||||
|
||||
void setDrawBranches(bool draw) { m_DrawBranches = draw; }
|
||||
private:
|
||||
void drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const override;
|
||||
|
||||
bool m_DrawBranches = true;
|
||||
};
|
||||
@@ -54,7 +54,15 @@ public:
|
||||
void OnSelectedEventChanged(uint32_t eventID) {}
|
||||
void OnEventChanged(uint32_t eventID);
|
||||
|
||||
void RT_FetchMeshData(IReplayRenderer *r);
|
||||
void ScrollToRow(int row, MeshDataStage stage = eMeshDataStage_VSIn)
|
||||
{
|
||||
if(stage == eMeshDataStage_VSOut)
|
||||
ScrollToRow(m_ModelVSOut, row);
|
||||
else if(stage == eMeshDataStage_GSOut)
|
||||
ScrollToRow(m_ModelGSOut, row);
|
||||
else
|
||||
ScrollToRow(m_ModelVSIn, row);
|
||||
}
|
||||
|
||||
private slots:
|
||||
// automatic slots
|
||||
@@ -94,6 +102,7 @@ private:
|
||||
IReplayOutput *m_Output;
|
||||
|
||||
void RT_UpdateAndDisplay(IReplayRenderer *);
|
||||
void RT_FetchMeshData(IReplayRenderer *r);
|
||||
|
||||
MeshDisplay m_Config;
|
||||
|
||||
|
||||
@@ -0,0 +1,724 @@
|
||||
/******************************************************************************
|
||||
* 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 "PixelHistoryView.h"
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
#include "3rdparty/toolwindowmanager/ToolWindowManager.h"
|
||||
#include "Windows/BufferViewer.h"
|
||||
#include "ui_PixelHistoryView.h"
|
||||
|
||||
struct EventTag
|
||||
{
|
||||
uint32_t eventID = 0;
|
||||
uint32_t primitive = ~0U;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(EventTag);
|
||||
|
||||
class PixelHistoryItemModel : public QAbstractItemModel
|
||||
{
|
||||
public:
|
||||
PixelHistoryItemModel(CaptureContext &ctx, ResourceId tex, const TextureDisplay &display,
|
||||
QObject *parent)
|
||||
: QAbstractItemModel(parent), m_Ctx(ctx)
|
||||
{
|
||||
m_Tex = m_Ctx.GetTexture(tex);
|
||||
m_Display = display;
|
||||
|
||||
FormatComponentType compType = m_Tex->format.compType;
|
||||
|
||||
if(compType == eCompType_None)
|
||||
compType = display.typeHint;
|
||||
|
||||
m_IsUint = (compType == eCompType_UInt);
|
||||
m_IsSint = (compType == eCompType_SInt);
|
||||
m_IsFloat = (!m_IsUint && !m_IsSint);
|
||||
|
||||
if(compType == eCompType_Depth)
|
||||
m_IsDepth = true;
|
||||
|
||||
if(m_Tex->format.special)
|
||||
{
|
||||
switch(m_Tex->format.specialFormat)
|
||||
{
|
||||
case eSpecial_D16S8:
|
||||
case eSpecial_D24S8:
|
||||
case eSpecial_D32S8:
|
||||
case eSpecial_S8: m_IsDepth = true; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setHistory(const rdctype::array<PixelModification> &history)
|
||||
{
|
||||
m_ModList.reserve(history.count);
|
||||
for(const PixelModification &h : history)
|
||||
m_ModList.push_back(h);
|
||||
|
||||
m_Loading = false;
|
||||
|
||||
emit beginResetModel();
|
||||
|
||||
setShowFailures(true);
|
||||
|
||||
emit endResetModel();
|
||||
}
|
||||
|
||||
void setShowFailures(bool show)
|
||||
{
|
||||
emit beginResetModel();
|
||||
|
||||
m_History.clear();
|
||||
m_History.reserve(m_ModList.count());
|
||||
for(const PixelModification &h : m_ModList)
|
||||
{
|
||||
if(!show && !h.passed())
|
||||
continue;
|
||||
|
||||
if(m_History.isEmpty() || m_History.back().back().eventID != h.eventID)
|
||||
m_History.push_back({h});
|
||||
else
|
||||
m_History.back().push_back(h);
|
||||
}
|
||||
|
||||
emit endResetModel();
|
||||
}
|
||||
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override
|
||||
{
|
||||
if(row < 0 || row >= rowCount(parent) || column < 0 || column >= columnCount())
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(row, column, makeTag(row, parent));
|
||||
}
|
||||
|
||||
QModelIndex parent(const QModelIndex &index) const override
|
||||
{
|
||||
if(m_Loading || isEvent(index))
|
||||
return QModelIndex();
|
||||
|
||||
int eventRow = getEventRow(index);
|
||||
|
||||
return createIndex(eventRow, 0, makeTag(eventRow, QModelIndex()));
|
||||
}
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override
|
||||
{
|
||||
if(m_Loading)
|
||||
return parent.isValid() ? 0 : 1;
|
||||
|
||||
if(!parent.isValid())
|
||||
return m_History.count();
|
||||
|
||||
if(isEvent(parent))
|
||||
{
|
||||
const QList<PixelModification> &mods = getMods(parent);
|
||||
const FetchDrawcall *draw = m_Ctx.GetDrawcall(mods.front().eventID);
|
||||
|
||||
if(draw->flags & eDraw_Clear)
|
||||
return 0;
|
||||
|
||||
return mods.count();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override { return 5; }
|
||||
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 && section == 0)
|
||||
return "Event";
|
||||
|
||||
// sizes for the colour previews
|
||||
if(orientation == Qt::Horizontal && role == Qt::SizeHintRole && (section == 2 || section == 4))
|
||||
return QSize(18, 0);
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
|
||||
{
|
||||
if(index.isValid())
|
||||
{
|
||||
int col = index.column();
|
||||
|
||||
// preview columns
|
||||
if(col == 2 || col == 4)
|
||||
{
|
||||
if(role == Qt::SizeHintRole)
|
||||
return QSize(16, 0);
|
||||
}
|
||||
|
||||
if(m_Loading)
|
||||
{
|
||||
if(role == Qt::DisplayRole && col == 0)
|
||||
return "Loading...";
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if(role == Qt::DisplayRole)
|
||||
{
|
||||
// main text
|
||||
if(col == 0)
|
||||
{
|
||||
if(isEvent(index))
|
||||
{
|
||||
const QList<PixelModification> &mods = getMods(index);
|
||||
const FetchDrawcall *drawcall = m_Ctx.GetDrawcall(mods.front().eventID);
|
||||
if(!drawcall)
|
||||
return QVariant();
|
||||
|
||||
QString ret = "";
|
||||
QList<const FetchDrawcall *> drawstack;
|
||||
const FetchDrawcall *parent = m_Ctx.GetDrawcall(drawcall->parent);
|
||||
while(parent)
|
||||
{
|
||||
drawstack.push_back(parent);
|
||||
parent = m_Ctx.GetDrawcall(parent->parent);
|
||||
}
|
||||
|
||||
if(!drawstack.isEmpty())
|
||||
{
|
||||
ret += "> " + ToQStr(drawstack.back()->name);
|
||||
|
||||
if(drawstack.count() > 3)
|
||||
ret += " ...";
|
||||
|
||||
ret += "\n";
|
||||
|
||||
if(drawstack.count() > 2)
|
||||
ret += "> " + ToQStr(drawstack[1]->name) + "\n";
|
||||
if(drawstack.count() > 1)
|
||||
ret += "> " + ToQStr(drawstack[0]->name) + "\n";
|
||||
|
||||
ret += "\n";
|
||||
}
|
||||
|
||||
bool passed = true;
|
||||
bool uavnowrite = false;
|
||||
|
||||
if(mods.front().uavWrite)
|
||||
{
|
||||
ret += tr("EID %1\n%2\nBound as UAV or copy - potential modification")
|
||||
.arg(mods.front().eventID)
|
||||
.arg(ToQStr(drawcall->name));
|
||||
|
||||
if(memcmp(mods[0].preMod.col.value_u, mods[0].postMod.col.value_u,
|
||||
sizeof(uint32_t) * 4) == 0)
|
||||
{
|
||||
ret += tr("\nNo change in tex value");
|
||||
uavnowrite = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
passed = false;
|
||||
for(const PixelModification &m : mods)
|
||||
passed |= m.passed();
|
||||
|
||||
QString failure = passed ? "" : failureString(mods[0]);
|
||||
|
||||
ret += tr("EID %1\n%2%3\n%4 Fragments touching pixel\n")
|
||||
.arg(mods.front().eventID)
|
||||
.arg(ToQStr(drawcall->name))
|
||||
.arg(failure)
|
||||
.arg(mods.count());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
const PixelModification &mod = getMod(index);
|
||||
|
||||
if(mod.uavWrite)
|
||||
{
|
||||
QString ret = tr("Potential UAV/Copy write");
|
||||
|
||||
if(mod.preMod.col.value_u[0] == mod.postMod.col.value_u[0] &&
|
||||
mod.preMod.col.value_u[1] == mod.postMod.col.value_u[1] &&
|
||||
mod.preMod.col.value_u[2] == mod.postMod.col.value_u[2] &&
|
||||
mod.preMod.col.value_u[3] == mod.postMod.col.value_u[3])
|
||||
{
|
||||
ret += tr("\nNo change in tex value");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
QString ret = tr("Primitive %1\n").arg(mod.primitiveID);
|
||||
|
||||
if(mod.shaderDiscarded)
|
||||
ret += failureString(mod);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// pre mod/shader out text
|
||||
if(col == 1)
|
||||
{
|
||||
if(isEvent(index))
|
||||
{
|
||||
return tr("Tex Before\n\n") + modString(getMods(index).first().preMod);
|
||||
}
|
||||
else
|
||||
{
|
||||
const PixelModification &mod = getMod(index);
|
||||
if(mod.unboundPS)
|
||||
return tr("No Pixel\nShader\nBound");
|
||||
if(mod.uavWrite)
|
||||
return tr("Tex Before\n\n") + modString(mod.preMod);
|
||||
return tr("Shader Out\n\n") + modString(mod.shaderOut);
|
||||
}
|
||||
}
|
||||
|
||||
// post mod text
|
||||
if(col == 3)
|
||||
{
|
||||
if(isEvent(index))
|
||||
return tr("Tex After\n\n") + modString(getMods(index).last().postMod);
|
||||
else
|
||||
return tr("Tex After\n\n") + modString(getMod(index).shaderOut);
|
||||
}
|
||||
}
|
||||
|
||||
if(role == Qt::BackgroundRole && (m_IsDepth || m_IsFloat))
|
||||
{
|
||||
// pre mod color
|
||||
if(col == 2)
|
||||
{
|
||||
if(isEvent(index))
|
||||
return backgroundBrush(getMods(index).first().preMod);
|
||||
else
|
||||
return backgroundBrush(getMod(index).shaderOut);
|
||||
}
|
||||
else if(col == 4)
|
||||
{
|
||||
if(isEvent(index))
|
||||
return backgroundBrush(getMods(index).last().postMod);
|
||||
else
|
||||
return backgroundBrush(getMod(index).postMod);
|
||||
}
|
||||
}
|
||||
|
||||
// text backgrounds marking pass/fail
|
||||
if(role == Qt::BackgroundRole && (col == 0 || col == 1 || col == 3))
|
||||
{
|
||||
// rest
|
||||
if(isEvent(index))
|
||||
{
|
||||
const QList<PixelModification> &mods = getMods(index);
|
||||
|
||||
bool passed = false;
|
||||
for(const PixelModification &m : mods)
|
||||
passed |= m.passed();
|
||||
|
||||
if(mods[0].uavWrite &&
|
||||
memcmp(mods[0].preMod.col.value_u, mods[0].postMod.col.value_u, sizeof(uint32_t) * 4) ==
|
||||
0)
|
||||
return QBrush(QColor::fromRgb(235, 235, 235));
|
||||
|
||||
return passed ? QBrush(QColor::fromRgb(235, 255, 235))
|
||||
: QBrush(QColor::fromRgb(255, 235, 235));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(getMod(index).shaderDiscarded)
|
||||
return QBrush(QColor::fromRgb(255, 235, 235));
|
||||
}
|
||||
}
|
||||
|
||||
if(role == Qt::UserRole)
|
||||
{
|
||||
EventTag tag;
|
||||
|
||||
if(isEvent(index))
|
||||
{
|
||||
tag.eventID = getMods(index).first().eventID;
|
||||
}
|
||||
else
|
||||
{
|
||||
const PixelModification &mod = getMod(index);
|
||||
|
||||
tag.eventID = mod.eventID;
|
||||
if(!mod.uavWrite)
|
||||
tag.primitive = mod.primitiveID;
|
||||
}
|
||||
|
||||
return QVariant::fromValue(tag);
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
private:
|
||||
CaptureContext &m_Ctx;
|
||||
|
||||
const FetchTexture *m_Tex;
|
||||
TextureDisplay m_Display;
|
||||
bool m_IsDepth = false, m_IsUint = false, m_IsSint = false, m_IsFloat = true;
|
||||
|
||||
bool m_Loading = true;
|
||||
QVector<QList<PixelModification>> m_History;
|
||||
QVector<PixelModification> m_ModList;
|
||||
|
||||
// mask for top bit of quintptr
|
||||
static const quintptr eventTagMask = 1ULL << (Q_PROCESSOR_WORDSIZE * 8 - 1);
|
||||
|
||||
// 1 byte on 32-bit, 2 bytes on 64-bit
|
||||
static const quintptr modRowBits = Q_PROCESSOR_WORDSIZE * 2;
|
||||
|
||||
// mask without top bit and however many bits we have for modification mask
|
||||
static const quintptr eventRowMask = UINTPTR_MAX >> (1 + modRowBits);
|
||||
|
||||
static const quintptr modRowMask = (1 << modRowBits) - 1;
|
||||
|
||||
inline bool isEvent(QModelIndex parent) const { return parent.internalId() & eventTagMask; }
|
||||
int getEventRow(QModelIndex index) const
|
||||
{
|
||||
if(isEvent(index))
|
||||
return index.row();
|
||||
else
|
||||
return (index.internalId() & ~eventTagMask) >> modRowBits;
|
||||
}
|
||||
|
||||
int getModRow(QModelIndex index) const { return int(index.internalId() & modRowMask); }
|
||||
const QList<PixelModification> &getMods(QModelIndex index) const
|
||||
{
|
||||
return m_History[index.row()];
|
||||
}
|
||||
|
||||
const PixelModification &getMod(QModelIndex index) const
|
||||
{
|
||||
return m_History[getEventRow(index)][getModRow(index)];
|
||||
}
|
||||
|
||||
quintptr makeTag(int row, QModelIndex parent) const
|
||||
{
|
||||
if(!parent.isValid())
|
||||
{
|
||||
// event
|
||||
return eventTagMask | row;
|
||||
}
|
||||
else
|
||||
{
|
||||
// modification
|
||||
if(row > modRowMask)
|
||||
qCritical() << "Packing failure - more than 255 modifications in one event";
|
||||
|
||||
return ((parent.internalId() & eventRowMask) << modRowBits) | (row & modRowMask);
|
||||
}
|
||||
}
|
||||
|
||||
QBrush backgroundBrush(const ModificationValue &val) const
|
||||
{
|
||||
float rangesize = (m_Display.rangemax - m_Display.rangemin);
|
||||
|
||||
float r = val.col.value_f[0];
|
||||
float g = val.col.value_f[1];
|
||||
float b = val.col.value_f[2];
|
||||
|
||||
if(!m_Display.Red)
|
||||
r = 0.0f;
|
||||
if(!m_Display.Green)
|
||||
g = 0.0f;
|
||||
if(!m_Display.Blue)
|
||||
b = 0.0f;
|
||||
|
||||
if(m_Display.Red && !m_Display.Green && !m_Display.Blue && !m_Display.Alpha)
|
||||
g = b = r;
|
||||
if(!m_Display.Red && m_Display.Green && !m_Display.Blue && !m_Display.Alpha)
|
||||
r = b = g;
|
||||
if(!m_Display.Red && !m_Display.Green && m_Display.Blue && !m_Display.Alpha)
|
||||
g = r = b;
|
||||
if(!m_Display.Red && !m_Display.Green && !m_Display.Blue && m_Display.Alpha)
|
||||
g = b = r = val.col.value_f[3];
|
||||
|
||||
r = qBound(0.0f, (r - m_Display.rangemin) / rangesize, 1.0f);
|
||||
g = qBound(0.0f, (g - m_Display.rangemin) / rangesize, 1.0f);
|
||||
b = qBound(0.0f, (b - m_Display.rangemin) / rangesize, 1.0f);
|
||||
|
||||
if(m_IsDepth)
|
||||
r = g = b = qBound(0.0f, (val.depth - m_Display.rangemin) / rangesize, 1.0f);
|
||||
|
||||
{
|
||||
r = (float)powf(r, 1.0f / 2.2f);
|
||||
g = (float)powf(g, 1.0f / 2.2f);
|
||||
b = (float)powf(b, 1.0f / 2.2f);
|
||||
}
|
||||
|
||||
return QBrush(QColor::fromRgb((int)(255.0f * r), (int)(255.0f * g), (int)(255.0f * b)));
|
||||
}
|
||||
|
||||
QString modString(const ModificationValue &val) const
|
||||
{
|
||||
QString s = "";
|
||||
|
||||
int numComps = (int)(m_Tex->format.compCount);
|
||||
|
||||
static const QString colourLetterPrefix[] = {"R: ", "G: ", "B: ", "A: "};
|
||||
|
||||
if(!m_IsDepth)
|
||||
{
|
||||
if(m_IsUint)
|
||||
{
|
||||
for(int i = 0; i < numComps; i++)
|
||||
s += colourLetterPrefix[i] + Formatter::Format(val.col.value_u[i]) + "\n";
|
||||
}
|
||||
else if(m_IsSint)
|
||||
{
|
||||
for(int i = 0; i < numComps; i++)
|
||||
s += colourLetterPrefix[i] + Formatter::Format(val.col.value_i[i]) + "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = 0; i < numComps; i++)
|
||||
s += colourLetterPrefix[i] + Formatter::Format(val.col.value_f[i]) + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if(val.depth >= 0.0f)
|
||||
s += "\nD: " + Formatter::Format(val.depth);
|
||||
else if(val.depth < -1.5f)
|
||||
s += "\nD: ?";
|
||||
else
|
||||
s += "\nD: -";
|
||||
|
||||
if(val.stencil >= 0)
|
||||
s += "\nS: 0x" + QString("%1").arg(val.stencil, 2, 16, QChar('0')).toUpper();
|
||||
else if(val.stencil == -2)
|
||||
s += "\nS: ?";
|
||||
else
|
||||
s += "\nS: -";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
QString failureString(const PixelModification &mod) const
|
||||
{
|
||||
QString s = "";
|
||||
|
||||
if(mod.sampleMasked)
|
||||
s += tr("\nMasked by SampleMask");
|
||||
if(mod.backfaceCulled)
|
||||
s += tr("\nBackface culled");
|
||||
if(mod.depthClipped)
|
||||
s += tr("\nDepth Clipped");
|
||||
if(mod.scissorClipped)
|
||||
s += tr("\nScissor Clipped");
|
||||
if(mod.shaderDiscarded)
|
||||
s += tr("\nShader executed a discard");
|
||||
if(mod.depthTestFailed)
|
||||
s += tr("\nDepth test failed");
|
||||
if(mod.stencilTestFailed)
|
||||
s += tr("\nStencil test failed");
|
||||
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
PixelHistoryView::PixelHistoryView(CaptureContext &ctx, ResourceId id, QPoint point,
|
||||
const TextureDisplay &display, QWidget *parent)
|
||||
: QFrame(parent), ui(new Ui::PixelHistoryView), m_Ctx(ctx)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_Pixel = point;
|
||||
m_Display = display;
|
||||
|
||||
FetchTexture *tex = m_Ctx.GetTexture(id);
|
||||
|
||||
QString title =
|
||||
tr("Pixel History on %1 for (%2, %3)").arg(ToQStr(tex->name)).arg(point.x()).arg(point.y());
|
||||
if(tex->msSamp > 1)
|
||||
title += tr(" @ Sample %1").arg(display.sampleIdx);
|
||||
setWindowTitle(title);
|
||||
|
||||
QString channelStr = "";
|
||||
if(display.Red)
|
||||
channelStr += "R";
|
||||
if(display.Green)
|
||||
channelStr += "G";
|
||||
if(display.Blue)
|
||||
channelStr += "B";
|
||||
|
||||
if(channelStr.length() > 1)
|
||||
channelStr += tr(" channels");
|
||||
else
|
||||
channelStr += tr(" channel");
|
||||
|
||||
if(!display.Red && !display.Green && !display.Blue && display.Alpha)
|
||||
channelStr = "Alpha";
|
||||
|
||||
QString text;
|
||||
text = tr("Preview colours displayed in visible range %1 - %2 with %3 visible.\n\n")
|
||||
.arg(Formatter::Format(display.rangemin))
|
||||
.arg(Formatter::Format(display.rangemax))
|
||||
.arg(channelStr);
|
||||
text +=
|
||||
"Double click to jump to an event.\n"
|
||||
"Right click to debug an event, or hide failed events.";
|
||||
|
||||
ui->label->setText(text);
|
||||
|
||||
ui->eventsHidden->setVisible(false);
|
||||
|
||||
m_Model = new PixelHistoryItemModel(ctx, id, display, this);
|
||||
ui->events->setModel(m_Model);
|
||||
|
||||
ui->events->setDrawBranches(false);
|
||||
|
||||
ui->events->header()->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
ui->events->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
|
||||
ui->events->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
|
||||
ui->events->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents);
|
||||
ui->events->header()->setSectionResizeMode(4, QHeaderView::ResizeToContents);
|
||||
}
|
||||
|
||||
PixelHistoryView::~PixelHistoryView()
|
||||
{
|
||||
ui->events->setModel(NULL);
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void PixelHistoryView::OnLogfileLoaded()
|
||||
{
|
||||
}
|
||||
|
||||
void PixelHistoryView::OnLogfileClosed()
|
||||
{
|
||||
ToolWindowManager::closeToolWindow(this);
|
||||
}
|
||||
|
||||
void PixelHistoryView::setHistory(const rdctype::array<PixelModification> &history)
|
||||
{
|
||||
m_Model->setHistory(history);
|
||||
}
|
||||
|
||||
void PixelHistoryView::startDebug(EventTag tag)
|
||||
{
|
||||
m_Ctx.SetEventID({this}, tag.eventID, tag.eventID);
|
||||
// TODO Shader debugging
|
||||
}
|
||||
|
||||
void PixelHistoryView::jumpToPrimitive(EventTag tag)
|
||||
{
|
||||
m_Ctx.SetEventID({this}, tag.eventID, tag.eventID);
|
||||
m_Ctx.showMeshPreview();
|
||||
|
||||
BufferViewer *viewer = m_Ctx.meshPreview();
|
||||
|
||||
const FetchDrawcall *draw = m_Ctx.CurDrawcall();
|
||||
|
||||
if(draw)
|
||||
{
|
||||
uint32_t vertIdx = Topology_VertexOffset(draw->topology, tag.primitive);
|
||||
|
||||
if(vertIdx != ~0U)
|
||||
viewer->ScrollToRow(vertIdx);
|
||||
}
|
||||
}
|
||||
|
||||
void PixelHistoryView::on_events_customContextMenuRequested(const QPoint &pos)
|
||||
{
|
||||
QModelIndex index = ui->events->indexAt(pos);
|
||||
|
||||
QMenu contextMenu(this);
|
||||
|
||||
QAction hideFailed(tr("&Show failed events"), this);
|
||||
hideFailed.setCheckable(true);
|
||||
hideFailed.setChecked(m_ShowFailures);
|
||||
|
||||
contextMenu.addAction(&hideFailed);
|
||||
|
||||
QObject::connect(&hideFailed, &QAction::toggled, [this](bool checked) {
|
||||
m_Model->setShowFailures(m_ShowFailures = checked);
|
||||
ui->eventsHidden->setVisible(!m_ShowFailures);
|
||||
});
|
||||
|
||||
if(!index.isValid())
|
||||
{
|
||||
RDDialog::show(&contextMenu, ui->events->viewport()->mapToGlobal(pos));
|
||||
return;
|
||||
}
|
||||
|
||||
EventTag tag = m_Model->data(index, Qt::UserRole).value<EventTag>();
|
||||
if(tag.eventID == 0)
|
||||
{
|
||||
RDDialog::show(&contextMenu, ui->events->viewport()->mapToGlobal(pos));
|
||||
return;
|
||||
}
|
||||
|
||||
QAction jumpAction(tr("&Go to primitive %1 at Event %2").arg(tag.primitive).arg(tag.eventID), this);
|
||||
|
||||
QString debugText;
|
||||
|
||||
if(tag.primitive == ~0U)
|
||||
{
|
||||
debugText =
|
||||
tr("&Debug Pixel (%1, %2) at Event %3").arg(m_Pixel.x()).arg(m_Pixel.y()).arg(tag.eventID);
|
||||
}
|
||||
else
|
||||
{
|
||||
debugText = tr("&Debug Pixel (%1, %2) primitive %3 at Event %4")
|
||||
.arg(m_Pixel.x())
|
||||
.arg(m_Pixel.y())
|
||||
.arg(tag.eventID)
|
||||
.arg(tag.primitive);
|
||||
|
||||
contextMenu.addAction(&jumpAction);
|
||||
}
|
||||
|
||||
QAction debugAction(debugText, this);
|
||||
|
||||
contextMenu.addAction(&debugAction);
|
||||
|
||||
QObject::connect(&jumpAction, &QAction::triggered, [this, tag]() { jumpToPrimitive(tag); });
|
||||
QObject::connect(&debugAction, &QAction::triggered, [this, tag]() { startDebug(tag); });
|
||||
|
||||
RDDialog::show(&contextMenu, ui->events->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void PixelHistoryView::on_events_doubleClicked(const QModelIndex &index)
|
||||
{
|
||||
EventTag tag = m_Model->data(index, Qt::UserRole).value<EventTag>();
|
||||
if(tag.eventID > 0)
|
||||
m_Ctx.SetEventID({this}, tag.eventID, tag.eventID);
|
||||
}
|
||||
|
||||
// TODO TimelineBar
|
||||
@@ -0,0 +1,69 @@
|
||||
/******************************************************************************
|
||||
* 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>
|
||||
#include "Code/CaptureContext.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class PixelHistoryView;
|
||||
}
|
||||
|
||||
class CaptureContext;
|
||||
class PixelHistoryItemModel;
|
||||
struct EventTag;
|
||||
|
||||
class PixelHistoryView : public QFrame, public ILogViewerForm
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PixelHistoryView(CaptureContext &ctx, ResourceId id, QPoint point,
|
||||
const TextureDisplay &display, QWidget *parent = 0);
|
||||
~PixelHistoryView();
|
||||
|
||||
void OnLogfileLoaded();
|
||||
void OnLogfileClosed();
|
||||
void OnSelectedEventChanged(uint32_t eventID) {}
|
||||
void OnEventChanged(uint32_t eventID) {}
|
||||
void setHistory(const rdctype::array<PixelModification> &history);
|
||||
|
||||
private slots:
|
||||
// automatic slots
|
||||
void on_events_customContextMenuRequested(const QPoint &pos);
|
||||
void on_events_doubleClicked(const QModelIndex &index);
|
||||
|
||||
private:
|
||||
Ui::PixelHistoryView *ui;
|
||||
CaptureContext &m_Ctx;
|
||||
|
||||
TextureDisplay m_Display;
|
||||
QPoint m_Pixel;
|
||||
PixelHistoryItemModel *m_Model;
|
||||
bool m_ShowFailures = true;
|
||||
void startDebug(EventTag tag);
|
||||
void jumpToPrimitive(EventTag tag);
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PixelHistoryView</class>
|
||||
<widget class="QFrame" name="PixelHistoryView">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>662</width>
|
||||
<height>569</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Pixel History</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>***code overwritten preview*** Preview colours displayed in visible range {min} - {max} with {red, blue, green} channels.
|
||||
|
||||
Right click to debug an event, hide failed events, or jump to the modification's primitive in the mesh view.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="eventsHidden">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: #f00;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Failed events are currently hidden</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="RDTreeView" name="events">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::PreventContextMenu</enum>
|
||||
</property>
|
||||
<attribute name="headerMinimumSectionSize">
|
||||
<number>16</number>
|
||||
</attribute>
|
||||
<attribute name="headerStretchLastSection">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>RDTreeView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>Widgets/Extended/RDTreeView.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "Widgets/TextureGoto.h"
|
||||
#include "BufferViewer.h"
|
||||
#include "MainWindow.h"
|
||||
#include "PixelHistoryView.h"
|
||||
#include "ui_TextureViewer.h"
|
||||
|
||||
float area(const QSizeF &s)
|
||||
@@ -3264,6 +3265,45 @@ void TextureViewer::on_saveTex_clicked()
|
||||
}
|
||||
}
|
||||
|
||||
void TextureViewer::on_pixelHistory_clicked()
|
||||
{
|
||||
FetchTexture *texptr = GetCurrentTexture();
|
||||
|
||||
if(!texptr || !m_Output)
|
||||
return;
|
||||
|
||||
int x = m_PickedPoint.x() >> (int)m_TexDisplay.mip;
|
||||
int y = m_PickedPoint.y() >> (int)m_TexDisplay.mip;
|
||||
|
||||
PixelHistoryView *hist =
|
||||
new PixelHistoryView(m_Ctx, texptr->ID, QPoint(x, y), m_TexDisplay, m_Ctx.mainWindow());
|
||||
|
||||
m_Ctx.setupDockWindow(hist);
|
||||
|
||||
ToolWindowManager *manager = ToolWindowManager::managerOf(this);
|
||||
|
||||
ToolWindowManager::AreaReference ref(ToolWindowManager::RightOf, manager->areaOf(this), 0.2f);
|
||||
manager->addToolWindow(hist, ref);
|
||||
|
||||
// add a short delay so that controls repainting after a new panel appears can get at the
|
||||
// render thread before we insert the long blocking pixel history task
|
||||
LambdaThread *thread = new LambdaThread([this, texptr, x, y, hist]() {
|
||||
QThread::msleep(150);
|
||||
m_Ctx.Renderer().AsyncInvoke([this, texptr, x, y, hist](IReplayRenderer *r) {
|
||||
rdctype::array<PixelModification> *history = new rdctype::array<PixelModification>();
|
||||
r->PixelHistory(texptr->ID, (uint32_t)x, (int32_t)y, m_TexDisplay.sliceFace, m_TexDisplay.mip,
|
||||
m_TexDisplay.sampleIdx, m_TexDisplay.typeHint, history);
|
||||
|
||||
GUIInvoke::call([hist, history] {
|
||||
hist->setHistory(*history);
|
||||
delete history;
|
||||
});
|
||||
});
|
||||
});
|
||||
thread->selfDelete(true);
|
||||
thread->start();
|
||||
}
|
||||
|
||||
void TextureViewer::on_texListShow_clicked()
|
||||
{
|
||||
if(ui->textureListFrame->isVisible())
|
||||
|
||||
@@ -159,6 +159,7 @@ private slots:
|
||||
void on_viewTexBuffer_clicked();
|
||||
void on_texListShow_clicked();
|
||||
void on_saveTex_clicked();
|
||||
void on_pixelHistory_clicked();
|
||||
|
||||
void on_cancelTextureListFilter_clicked();
|
||||
void on_textureListFilter_editTextChanged(const QString &text);
|
||||
|
||||
@@ -142,7 +142,8 @@ SOURCES += Code/qrenderdoc.cpp \
|
||||
Widgets/Extended/RDTableWidget.cpp \
|
||||
Windows/Dialogs/SuggestRemoteDialog.cpp \
|
||||
Windows/Dialogs/VirtualFileDialog.cpp \
|
||||
Windows/Dialogs/RemoteManager.cpp
|
||||
Windows/Dialogs/RemoteManager.cpp \
|
||||
Windows/PixelHistoryView.cpp
|
||||
|
||||
HEADERS += Code/CaptureContext.h \
|
||||
Code/qprocessinfo.h \
|
||||
@@ -187,7 +188,8 @@ HEADERS += Code/CaptureContext.h \
|
||||
Widgets/Extended/RDTableWidget.h \
|
||||
Windows/Dialogs/SuggestRemoteDialog.h \
|
||||
Windows/Dialogs/VirtualFileDialog.h \
|
||||
Windows/Dialogs/RemoteManager.h
|
||||
Windows/Dialogs/RemoteManager.h \
|
||||
Windows/PixelHistoryView.h
|
||||
|
||||
FORMS += Windows/Dialogs/AboutDialog.ui \
|
||||
Windows/MainWindow.ui \
|
||||
@@ -214,7 +216,8 @@ FORMS += Windows/Dialogs/AboutDialog.ui \
|
||||
Windows/Dialogs/OrderedListEditor.ui \
|
||||
Windows/Dialogs/SuggestRemoteDialog.ui \
|
||||
Windows/Dialogs/VirtualFileDialog.ui \
|
||||
Windows/Dialogs/RemoteManager.ui
|
||||
Windows/Dialogs/RemoteManager.ui \
|
||||
Windows/PixelHistoryView.ui
|
||||
|
||||
RESOURCES += Resources/resources.qrc
|
||||
|
||||
|
||||
@@ -669,6 +669,7 @@
|
||||
<ClCompile Include="generated\moc_RDListWidget.cpp" />
|
||||
<ClCompile Include="generated\moc_RDTableView.cpp" />
|
||||
<ClCompile Include="generated\moc_RDTableWidget.cpp" />
|
||||
<ClCompile Include="generated\moc_RDTreeView.cpp" />
|
||||
<ClCompile Include="generated\moc_RDTreeWidget.cpp" />
|
||||
<ClCompile Include="generated\moc_ResourcePreview.cpp" />
|
||||
<ClCompile Include="generated\moc_ScintillaDocument.cpp">
|
||||
@@ -685,6 +686,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="generated\moc_SettingsDialog.cpp" />
|
||||
<ClCompile Include="generated\moc_ShaderViewer.cpp" />
|
||||
<ClCompile Include="generated\moc_PixelHistoryView.cpp" />
|
||||
<ClCompile Include="generated\moc_StatisticsViewer.cpp" />
|
||||
<ClCompile Include="generated\moc_SuggestRemoteDialog.cpp" />
|
||||
<ClCompile Include="generated\moc_TextureGoto.cpp" />
|
||||
@@ -701,6 +703,7 @@
|
||||
<ClCompile Include="Widgets\Extended\RDListWidget.cpp" />
|
||||
<ClCompile Include="Widgets\Extended\RDTableView.cpp" />
|
||||
<ClCompile Include="Widgets\Extended\RDTableWidget.cpp" />
|
||||
<ClCompile Include="Widgets\Extended\RDTreeView.cpp" />
|
||||
<ClCompile Include="Widgets\Extended\RDTreeWidget.cpp" />
|
||||
<ClCompile Include="Widgets\RangeHistogram.cpp" />
|
||||
<ClCompile Include="Widgets\Extended\RDDoubleSpinBox.cpp" />
|
||||
@@ -737,6 +740,7 @@
|
||||
<ClCompile Include="Windows\PipelineState\PipelineStateViewer.cpp" />
|
||||
<ClCompile Include="Windows\PipelineState\VulkanPipelineStateViewer.cpp" />
|
||||
<ClCompile Include="Windows\ShaderViewer.cpp" />
|
||||
<ClCompile Include="Windows\PixelHistoryView.cpp" />
|
||||
<ClCompile Include="Windows\StatisticsViewer.cpp" />
|
||||
<ClCompile Include="Windows\TextureViewer.cpp" />
|
||||
<ClCompile Include="3rdparty\toolwindowmanager\ToolWindowManager.cpp">
|
||||
@@ -872,6 +876,7 @@
|
||||
<ClInclude Include="generated\ui_ResourcePreview.h" />
|
||||
<ClInclude Include="generated\ui_SettingsDialog.h" />
|
||||
<ClInclude Include="generated\ui_ShaderViewer.h" />
|
||||
<ClInclude Include="generated\ui_PixelHistoryView.h" />
|
||||
<ClInclude Include="generated\ui_StatisticsViewer.h" />
|
||||
<ClInclude Include="generated\ui_SuggestRemoteDialog.h" />
|
||||
<ClInclude Include="generated\ui_TextureSaveDialog.h" />
|
||||
@@ -947,6 +952,12 @@
|
||||
<Message>MOC %(Filename).h</Message>
|
||||
<Outputs>generated\moc_%(Filename).cpp</Outputs>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Widgets\Extended\RDTreeView.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\Extended\RDTreeWidget.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>
|
||||
@@ -1097,6 +1108,12 @@
|
||||
<Message>MOC %(Filename).h</Message>
|
||||
<Outputs>generated\moc_%(Filename).cpp</Outputs>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Windows\PixelHistoryView.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="Windows\ShaderViewer.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>
|
||||
@@ -1257,6 +1274,12 @@
|
||||
<Message>UIC %(Filename).ui</Message>
|
||||
<Outputs>generated\ui_%(Filename).h</Outputs>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Windows\PixelHistoryView.ui">
|
||||
<AdditionalInputs>%(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Command>$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe %(Fullpath) -o $(ProjectDir)generated\ui_%(Filename).h</Command>
|
||||
<Message>UIC %(Filename).ui</Message>
|
||||
<Outputs>generated\ui_%(Filename).h</Outputs>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Windows\ShaderViewer.ui">
|
||||
<AdditionalInputs>%(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Command>$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe %(Fullpath) -o $(ProjectDir)generated\ui_%(Filename).h</Command>
|
||||
|
||||
@@ -510,6 +510,18 @@
|
||||
<ClCompile Include="Windows\Dialogs\RemoteManager.cpp">
|
||||
<Filter>Windows\Dialogs</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="generated\moc_PixelHistoryView.cpp">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Windows\PixelHistoryView.cpp">
|
||||
<Filter>Windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="generated\moc_RDTreeView.cpp">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Widgets\Extended\RDTreeView.cpp">
|
||||
<Filter>Widgets\Extended</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="3rdparty\flowlayout\FlowLayout.h">
|
||||
@@ -782,6 +794,9 @@
|
||||
<ClInclude Include="generated\ui_RemoteManager.h">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="generated\ui_PixelHistoryView.h">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources\128.png">
|
||||
@@ -1195,5 +1210,14 @@
|
||||
<CustomBuild Include="Windows\Dialogs\RemoteManager.h">
|
||||
<Filter>Windows\Dialogs</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Windows\PixelHistoryView.ui">
|
||||
<Filter>Windows</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Windows\PixelHistoryView.h">
|
||||
<Filter>Windows</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Widgets\Extended\RDTreeView.h">
|
||||
<Filter>Widgets\Extended</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -515,4 +515,10 @@ struct PixelModification
|
||||
bool32 shaderDiscarded;
|
||||
bool32 depthTestFailed;
|
||||
bool32 stencilTestFailed;
|
||||
|
||||
bool passed() const
|
||||
{
|
||||
return !sampleMasked && !backfaceCulled && !depthClipped && !viewClipped && !scissorClipped &&
|
||||
!shaderDiscarded && !depthTestFailed && !stencilTestFailed;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user