Generate clickable links to resource inspector in RDTreeWidget

This commit is contained in:
baldurk
2017-11-17 16:30:56 +00:00
parent 1776b4e6c0
commit 200f0799a4
16 changed files with 611 additions and 171 deletions
+8 -1
View File
@@ -626,7 +626,7 @@ void CaptureContext::AddMessages(const rdcarray<DebugMessage> &msgs)
QString CaptureContext::GetResourceName(ResourceId id)
{
if(id == ResourceId())
return tr("{No Resource}");
return tr("No Resource");
if(m_CustomNames.contains(id))
return m_CustomNames[id];
@@ -672,9 +672,16 @@ void CaptureContext::SetResourceCustomName(ResourceId id, const QString &name)
m_CustomNames[id] = name;
}
m_CustomNameCachedID++;
RefreshUIStatus({}, true, true);
}
int CaptureContext::ResourceNameCacheID()
{
return m_CustomNameCachedID;
}
void *CaptureContext::FillWindowingData(uintptr_t widget)
{
#if defined(WIN32)
+2
View File
@@ -120,6 +120,7 @@ public:
bool IsAutogeneratedName(ResourceId id) override;
bool HasResourceCustomName(ResourceId id) override;
void SetResourceCustomName(ResourceId id, const QString &name) override;
int ResourceNameCacheID() override;
TextureDescription *GetTexture(ResourceId id) override { return m_Textures[id]; }
const rdcarray<TextureDescription> &GetTextures() override { return m_TextureList; }
BufferDescription *GetBuffer(ResourceId id) override { return m_Buffers[id]; }
@@ -283,6 +284,7 @@ private:
rdcarray<ResourceDescription> m_ResourceList;
QMap<ResourceId, QString> m_CustomNames;
int m_CustomNameCachedID = 1;
const SDFile *m_StructuredFile;
SDFile m_DummySDFile;
@@ -131,3 +131,16 @@ QString ConfigFilePath(const QString &filename)
return QDir::cleanPath(dir.absoluteFilePath(filename));
}
ICaptureContext *getCaptureContext(QWidget *widget)
{
void *ctxptr = NULL;
while(widget && !ctxptr)
{
ctxptr = widget->property("ICaptureContext").value<void *>();
widget = widget->parentWidget();
}
return (ICaptureContext *)ctxptr;
}
+28
View File
@@ -1107,6 +1107,20 @@ name fetched from the capture.
)");
virtual void SetResourceCustomName(ResourceId id, const QString &name) = 0;
DOCUMENT(R"(Returns an index that can be used to cache the results of resource naming.
In some cases (e.g. formatting in widgets) there might be high frequency fetches to names without an
easy way to force a refresh on a rename. Instead, the index here can be cached and compared each
time to see if any names have changed.
The index starts at 1, so initialising an internal cache to 0 will cause the first check to be
considered out of date
:return: An incrementing index that can be used as a quick check if any names have changed.
:rtype: int
)");
virtual int ResourceNameCacheID() = 0;
DOCUMENT(R"(Retrieve the information about a particular texture.
:param ~renderdoc.ResourceId id: The ID of the texture to query about.
@@ -1594,3 +1608,17 @@ protected:
};
DECLARE_REFLECTION_STRUCT(ICaptureContext);
DOCUMENT(R"(Attempt to retrieve the capture context for a particular widget.
This will search up the widget heirarchy to find if a capture context is associated with this widget
or any of its parents. Mostly useful from within widget code where a capture context can't be
explicitly passed in.
This may return ``None`` if no capture context can be found.
:param QWidget widget: The widget to search from.
:return: The capture context associated with this widget, if one unambiguously exists.
:rtype: CaptureContext
)");
ICaptureContext *getCaptureContext(QWidget *widget);
+8 -6
View File
@@ -55,7 +55,9 @@ std::string DoStringise(const uint32_t &el)
template <>
std::string DoStringise(const ResourceId &el)
{
return QString::number((const uint64_t &)el).toStdString();
uint64_t num;
memcpy(&num, &el, sizeof(num));
return lit("resourceid::%1").arg(num).toStdString();
}
#include "renderdoc_tostr.inl"
@@ -359,8 +361,8 @@ void CombineUsageEvents(ICaptureContext &ctx, const rdcarray<EventUsage> &usage,
callback(start, end, us);
}
void addStructuredObjects(ICaptureContext &ctx, RDTreeWidgetItem *parent,
const StructuredObjectList &objs, bool parentIsArray)
void addStructuredObjects(RDTreeWidgetItem *parent, const StructuredObjectList &objs,
bool parentIsArray)
{
for(const SDObject *obj : objs)
{
@@ -388,7 +390,7 @@ void addStructuredObjects(ICaptureContext &ctx, RDTreeWidgetItem *parent,
static_assert(sizeof(id) == sizeof(obj->data.basic.u), "ResourceId is no longer uint64_t!");
memcpy(&id, &obj->data.basic.u, sizeof(id));
param = ctx.GetResourceName(id);
param = id;
}
else if(obj->type.flags & SDTypeFlags::NullString)
{
@@ -405,11 +407,11 @@ void addStructuredObjects(ICaptureContext &ctx, RDTreeWidgetItem *parent,
case SDBasic::Chunk:
case SDBasic::Struct:
param = QFormatStr("%1()").arg(obj->type.name);
addStructuredObjects(ctx, item, obj->data.children, false);
addStructuredObjects(item, obj->data.children, false);
break;
case SDBasic::Array:
param = QFormatStr("%1[]").arg(obj->type.name);
addStructuredObjects(ctx, item, obj->data.children, true);
addStructuredObjects(item, obj->data.children, true);
break;
case SDBasic::Null: param = lit("NULL"); break;
case SDBasic::Buffer: param = lit("(%1 bytes)").arg(obj->type.byteSize); break;
+2 -2
View File
@@ -104,8 +104,8 @@ void CombineUsageEvents(
class RDTreeWidgetItem;
void addStructuredObjects(ICaptureContext &ctx, RDTreeWidgetItem *parent,
const StructuredObjectList &objs, bool parentIsArray);
void addStructuredObjects(RDTreeWidgetItem *parent, const StructuredObjectList &objs,
bool parentIsArray);
struct Formatter
{
+433 -8
View File
@@ -23,6 +23,7 @@
******************************************************************************/
#include "RDTreeWidget.h"
#include <QAbstractTextDocumentLayout>
#include <QApplication>
#include <QClipboard>
#include <QColor>
@@ -32,8 +33,115 @@
#include <QPainter>
#include <QPen>
#include <QStack>
#include <QTextBlock>
#include <QTextCursor>
#include <QTextDocument>
#include <QToolTip>
#include "Code/Interface/QRDInterface.h"
#include "Code/Resources.h"
// this is used often, so cache it
QRegularExpression &ResourceIdRegexp()
{
static QRegularExpression re(lit("(resourceid::)([0-9]*)"));
return re;
}
struct ResourceIdLinkedText
{
QVector<QVariant> fragments;
// cached formatted document. We use cacheId to check if it needs to be updated
QTextDocument doc;
int cacheId = 0;
// a plain-text version of the document, suitable for e.g. copy-paste
QString text;
void cacheDocument(QWidget *widget)
{
ICaptureContext *ctxptr = getCaptureContext(widget);
if(!ctxptr)
return;
ICaptureContext &ctx = *(ICaptureContext *)ctxptr;
int refCache = ctx.ResourceNameCacheID();
if(cacheId == refCache)
return;
cacheId = refCache;
// use a table to ensure images don't screw up the baseline for text. DON'T JUDGE ME.
QString html = lit("<table><tr>");
int i = 0;
QVector<int> fragmentIndexFromBlockIndex;
// there's an empty block at the start.
fragmentIndexFromBlockIndex.push_back(-1);
for(const QVariant &v : fragments)
{
if(v.userType() == qMetaTypeId<ResourceId>())
{
html += lit("<td><b>%1</b></td><td><img src=':/link.png'></td>")
.arg(ctx.GetResourceName(v.value<ResourceId>()));
// these generate two blocks (one for each cell)
fragmentIndexFromBlockIndex.push_back(i);
fragmentIndexFromBlockIndex.push_back(i);
}
else
{
html += lit("<td>%1</td>").arg(v.toString());
// this only generates one block
fragmentIndexFromBlockIndex.push_back(i);
}
i++;
}
// there's another empty block at the end
fragmentIndexFromBlockIndex.push_back(-1);
html += lit("</tr></table>");
doc.setDocumentMargin(0);
doc.setHtml(html);
if(doc.blockCount() != fragmentIndexFromBlockIndex.count())
{
qCritical() << "Block count is not what's expected!" << doc.blockCount()
<< fragmentIndexFromBlockIndex.count();
for(i = 0; i < doc.blockCount(); i++)
doc.findBlockByNumber(i).setUserState(-1);
return;
}
for(i = 0; i < doc.blockCount(); i++)
doc.findBlockByNumber(i).setUserState(fragmentIndexFromBlockIndex[i]);
text = doc.toPlainText();
// "Embedded objects, such as images, are represented by a Unicode value U+FFFC (OBJECT
// REPLACEMENT CHARACTER)."
text.remove(QChar(0xfffc));
text = text.trimmed();
}
};
// using QSharedPointer here since the lifetime management of these objects would get quite
// complicated, and there is no obvious QObject parent to assign to. The alternative would be to
// have the RDTreeWidgetItem track pointers in and out of the QVariant text
typedef QSharedPointer<ResourceIdLinkedText> ResourceIdLinkedTextPtr;
Q_DECLARE_METATYPE(ResourceIdLinkedTextPtr);
class RDTreeWidgetModel : public QAbstractItemModel
{
@@ -165,13 +273,12 @@ public:
RDTreeWidgetItem *item = itemForIndex(index);
// invisible root element has no data
if(!item->m_parent)
if(!item->m_parent || index.column() >= item->m_text.count())
return QVariant();
if(role == Qt::DisplayRole)
{
if(index.column() < item->m_text.count())
return item->m_text[index.column()];
return item->m_text[index.column()];
}
else if(role == Qt::DecorationRole)
{
@@ -183,8 +290,7 @@ public:
return widget->m_normalHoverIcon;
}
if(index.column() < item->m_icons.count())
return item->m_icons[index.column()];
return item->m_icons[index.column()];
}
else if(role == Qt::BackgroundRole)
{
@@ -311,12 +417,63 @@ RDTreeWidgetItem::RDTreeWidgetItem(const QVariantList &values)
for(const QVariant &v : values)
m_text.push_back(v);
m_icons.resize(m_text.size());
for(int i = 0; i < m_text.count(); i++)
checkForResourceId(i);
}
RDTreeWidgetItem::RDTreeWidgetItem(const std::initializer_list<QVariant> &values)
{
m_text = values;
m_icons.resize(m_text.size());
for(int i = 0; i < m_text.count(); i++)
checkForResourceId(i);
}
void RDTreeWidgetItem::checkForResourceId(int col)
{
QRegularExpression &re = ResourceIdRegexp();
QVariant &v = m_text[col];
if(v.userType() == qMetaTypeId<ResourceId>() || re.match(v.toString()).hasMatch())
{
QString text;
if(v.userType() == qMetaTypeId<ResourceId>())
text = ToQStr(v.value<ResourceId>());
else
text = v.toString();
ResourceIdLinkedTextPtr linkedText(new ResourceIdLinkedText);
// use regexp to split up into fragments of text and resourceid. The resourceid is then
// formatted on the fly in ResourceIdLinkedText::cacheDocument
QRegularExpressionMatch match = re.match(text);
while(match.hasMatch())
{
qulonglong idnum = match.captured(2).toULongLong();
ResourceId id;
memcpy(&id, &idnum, sizeof(id));
// push any text that preceeded the ResourceId.
if(match.capturedStart(1) > 0)
linkedText->fragments.push_back(text.left(match.capturedStart(1)));
text.remove(0, match.capturedEnd(2));
linkedText->fragments.push_back(id);
match = re.match(text);
}
if(!text.isEmpty())
linkedText->fragments.push_back(text);
linkedText->doc.setHtml(text);
v = QVariant::fromValue(linkedText);
}
}
RDTreeWidgetItem::~RDTreeWidgetItem()
@@ -424,6 +581,10 @@ void RDTreeWidgetItem::setWidget(RDTreeWidget *widget)
if(widget == m_widget)
return;
QWidget *parent = widget;
while(parent)
parent = parent->parentWidget();
// if the widget is different, we need to recurse to children
m_widget = widget;
for(RDTreeWidgetItem *item : m_children)
@@ -525,11 +686,236 @@ RDTreeWidgetItemIterator &RDTreeWidgetItemIterator::operator++()
return *this;
}
RDTreeWidgetDelegate::RDTreeWidgetDelegate(RDTreeWidget *parent)
: m_widget(parent), ForwardingDelegate(parent)
{
}
RDTreeWidgetDelegate::~RDTreeWidgetDelegate()
{
}
void RDTreeWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
RDTreeWidgetModel *model = m_widget->m_model;
if(model == index.model())
{
RDTreeWidgetItem *item = model->itemForIndex(index);
if(item->m_text[index.column()].userType() == qMetaTypeId<ResourceIdLinkedTextPtr>())
{
{
// draw the item without text, so we get the proper background/selection/etc.
QStyleOptionViewItem opt = option;
opt.text.clear();
ForwardingDelegate::paint(painter, opt, index);
}
ResourceIdLinkedTextPtr linkedText =
item->m_text[index.column()].value<ResourceIdLinkedTextPtr>();
painter->save();
painter->translate(option.rect.left(), option.rect.top());
linkedText->cacheDocument(m_widget);
linkedText->doc.setTextWidth(option.rect.width());
linkedText->doc.drawContents(painter);
if(option.state & QStyle::State_MouseOver)
{
painter->setPen(QPen(option.palette.brush(QPalette::WindowText), 1.0));
QAbstractTextDocumentLayout *layout = linkedText->doc.documentLayout();
QPoint p = m_widget->viewport()->mapFromGlobal(QCursor::pos());
p -= option.rect.topLeft();
int pos = layout->hitTest(p, Qt::FuzzyHit);
if(pos >= 0)
{
QTextBlock block = linkedText->doc.findBlock(pos);
int frag = block.userState();
if(frag >= 0)
{
QVariant v = linkedText->fragments[frag];
if(v.userType() == qMetaTypeId<ResourceId>() && v.value<ResourceId>() != ResourceId())
{
layout->blockBoundingRect(block);
QRectF rect = layout->blockBoundingRect(block);
if(block.previous().userState() == frag)
{
rect = rect.united(layout->blockBoundingRect(block.previous()));
}
if(block.next().userState() == frag)
{
rect = rect.united(layout->blockBoundingRect(block.next()));
}
rect.translate(0.0, -2.0);
painter->drawLine(rect.bottomLeft(), rect.bottomRight());
}
}
}
}
painter->restore();
return;
}
}
else
{
qCritical() << "Unexpected model being passed to RDTreeWidgetDelegate!";
}
return ForwardingDelegate::paint(painter, option, index);
}
QSize RDTreeWidgetDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if(index.isValid())
{
RDTreeWidgetModel *model = m_widget->m_model;
if(model == index.model())
{
RDTreeWidgetItem *item = model->itemForIndex(index);
if(item->m_text[index.column()].userType() == qMetaTypeId<ResourceIdLinkedTextPtr>())
{
ResourceIdLinkedTextPtr linkedText =
item->m_text[index.column()].value<ResourceIdLinkedTextPtr>();
linkedText->cacheDocument(m_widget);
return QSize(linkedText->doc.idealWidth(), option.fontMetrics.height());
}
}
else
{
qCritical() << "Unexpected model being passed to RDTreeWidgetDelegate!";
}
}
return ForwardingDelegate::sizeHint(option, index);
}
bool RDTreeWidgetDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &index)
{
if(event->type() == QEvent::MouseButtonRelease && index.isValid())
{
RDTreeWidgetModel *rdmodel = m_widget->m_model;
if(rdmodel == model)
{
RDTreeWidgetItem *item = rdmodel->itemForIndex(index);
if(item->m_text[index.column()].userType() == qMetaTypeId<ResourceIdLinkedTextPtr>())
{
ResourceIdLinkedTextPtr linkedText =
item->m_text[index.column()].value<ResourceIdLinkedTextPtr>();
linkedText->cacheDocument(m_widget);
QAbstractTextDocumentLayout *layout = linkedText->doc.documentLayout();
QPoint p = ((QMouseEvent *)event)->pos();
p -= option.rect.topLeft();
int pos = layout->hitTest(p, Qt::FuzzyHit);
if(pos >= 0)
{
QTextBlock block = linkedText->doc.findBlock(pos);
int frag = block.userState();
if(frag >= 0)
{
QVariant v = linkedText->fragments[frag];
if(v.userType() == qMetaTypeId<ResourceId>() && v.value<ResourceId>() != ResourceId())
{
ICaptureContext *ctxptr = getCaptureContext(m_widget);
if(ctxptr)
{
ICaptureContext &ctx = *(ICaptureContext *)ctxptr;
if(!ctx.HasResourceInspector())
ctx.ShowResourceInspector();
ctx.GetResourceInspector()->Inspect(v.value<ResourceId>());
ctx.RaiseDockWindow(ctx.GetResourceInspector()->Widget());
}
}
}
}
return true;
}
}
else
{
qCritical() << "Unexpected model being passed to RDTreeWidgetDelegate!";
}
}
return ForwardingDelegate::editorEvent(event, model, option, index);
}
bool RDTreeWidgetDelegate::linkHover(QMouseEvent *e, const QModelIndex &index)
{
if(index.isValid())
{
RDTreeWidgetItem *item = m_widget->m_model->itemForIndex(index);
if(item->m_text[index.column()].userType() == qMetaTypeId<ResourceIdLinkedTextPtr>())
{
ResourceIdLinkedTextPtr linkedText =
item->m_text[index.column()].value<ResourceIdLinkedTextPtr>();
linkedText->cacheDocument(m_widget);
QAbstractTextDocumentLayout *layout = linkedText->doc.documentLayout();
QPoint p = e->pos();
p -= m_widget->visualRect(index).topLeft();
int pos = layout->hitTest(p, Qt::FuzzyHit);
if(pos >= 0)
{
QTextBlock block = linkedText->doc.findBlock(pos);
int frag = block.userState();
if(frag >= 0)
{
QVariant v = linkedText->fragments[frag];
if(v.userType() == qMetaTypeId<ResourceId>() && v.value<ResourceId>() != ResourceId())
{
return true;
}
}
}
}
}
return false;
}
RDTreeWidget::RDTreeWidget(QWidget *parent) : RDTreeView(parent)
{
// we'll call this ourselves in drawBranches()
RDTreeView::enableBranchRectFill(false);
m_delegate = new RDTreeWidgetDelegate(this);
RDTreeView::setItemDelegate(m_delegate);
header()->setSectionsMovable(false);
m_root = new RDTreeWidgetItem;
@@ -610,6 +996,17 @@ void RDTreeWidget::setColumnAlignment(int column, Qt::Alignment align)
m_alignments[column] = align;
}
void RDTreeWidget::setItemDelegate(QAbstractItemDelegate *delegate)
{
m_userDelegate = delegate;
m_delegate->setForwardDelegate(m_userDelegate);
}
QAbstractItemDelegate *RDTreeWidget::itemDelegate() const
{
return m_userDelegate;
}
void RDTreeWidget::setColumns(const QStringList &columns)
{
m_headers = columns;
@@ -710,9 +1107,18 @@ void RDTreeWidget::mouseMoveEvent(QMouseEvent *e)
RDTreeWidgetItem *newHover = m_model->itemForIndex(m_currentHoverIndex);
if(m_currentHoverIndex.column() == m_hoverColumn && m_hoverHandCursor)
{
setCursor(QCursor(Qt::PointingHandCursor));
}
else if(m_delegate->linkHover(e, m_currentHoverIndex))
{
m_model->itemChanged(m_model->itemForIndex(m_currentHoverIndex), {Qt::DecorationRole});
setCursor(QCursor(Qt::PointingHandCursor));
}
else
{
unsetCursor();
}
if(oldHover == newHover)
return;
@@ -810,7 +1216,17 @@ void RDTreeWidget::keyPressEvent(QKeyEvent *e)
RDTreeWidgetItem *item = m_model->itemForIndex(idx);
for(int i = 0; i < qMin(colCount, item->m_text.count()); i++)
widths[i] = qMax(widths[i], item->m_text[i].toString().count());
{
QString text = item->m_text[i].toString();
if(item->m_text[i].userType() == qMetaTypeId<ResourceIdLinkedTextPtr>())
{
ResourceIdLinkedTextPtr linkedText = item->m_text[i].value<ResourceIdLinkedTextPtr>();
linkedText->cacheDocument(this);
text = linkedText->text;
}
widths[i] = qMax(widths[i], text.count());
}
}
// only align up to 50 characters so one really long item doesn't mess up the whole thing
@@ -825,7 +1241,16 @@ void RDTreeWidget::keyPressEvent(QKeyEvent *e)
for(int i = 0; i < qMin(colCount, item->m_text.count()); i++)
{
QString format = i == 0 ? QFormatStr("%1") : QFormatStr(" %1");
clipData += format.arg(item->m_text[i].toString(), -widths[i]);
QString text = item->m_text[i].toString();
if(item->m_text[i].userType() == qMetaTypeId<ResourceIdLinkedTextPtr>())
{
ResourceIdLinkedTextPtr linkedText = item->m_text[i].value<ResourceIdLinkedTextPtr>();
linkedText->cacheDocument(this);
text = linkedText->text;
}
clipData += format.arg(text, -widths[i]);
}
clipData += lit("\n");
@@ -1003,4 +1428,4 @@ void RDTreeWidget::endAddChild(RDTreeWidgetItem *item)
// work is all done in beginAddChild
if(!m_queueUpdates)
m_model->endAddChild(item);
}
}
@@ -103,6 +103,7 @@ public:
}
m_text[column] = value;
checkForResourceId(column);
dataChanged(column, Qt::DisplayRole);
}
inline void setToolTip(const QString &value)
@@ -122,8 +123,11 @@ public:
}
private:
void checkForResourceId(int column);
friend class RDTreeWidget;
friend class RDTreeWidgetModel;
friend class RDTreeWidgetDelegate;
void setWidget(RDTreeWidget *widget);
RDTreeWidget *m_widget = NULL;
@@ -190,6 +194,26 @@ private:
RDTreeWidgetItem *m_Current;
};
class RDTreeWidgetDelegate : public ForwardingDelegate
{
Q_OBJECT
public:
explicit RDTreeWidgetDelegate(RDTreeWidget *parent);
~RDTreeWidgetDelegate();
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
const QModelIndex &index) override;
bool linkHover(QMouseEvent *e, const QModelIndex &index);
private:
RDTreeWidget *m_widget;
};
class RDTreeWidget : public RDTreeView
{
Q_OBJECT
@@ -225,6 +249,9 @@ public:
void endUpdate();
void setColumnAlignment(int column, Qt::Alignment align);
void setItemDelegate(QAbstractItemDelegate *delegate);
QAbstractItemDelegate *itemDelegate() const;
void setColumns(const QStringList &columns);
QString headerText(int column) const { return m_headers[column]; }
void setHeaderText(int column, const QString &text);
@@ -275,12 +302,16 @@ private:
friend class RDTreeWidgetModel;
friend class RDTreeWidgetItem;
friend class RDTreeWidgetDelegate;
// invisible root item, used to simplify recursion by even top-level items having a parent
RDTreeWidgetItem *m_root;
RDTreeWidgetModel *m_model;
QAbstractItemDelegate *m_userDelegate = NULL;
RDTreeWidgetDelegate *m_delegate;
bool m_clearing = false;
QStringList m_headers;
+1 -1
View File
@@ -146,7 +146,7 @@ void APIInspector::fillAPIView()
root->setText(1, chunk->name);
addStructuredObjects(m_Ctx, root, chunk->data.children, false);
addStructuredObjects(root, chunk->data.children, false);
}
else
{
+2
View File
@@ -59,6 +59,8 @@ MainWindow::MainWindow(ICaptureContext &ctx) : QMainWindow(NULL), ui(new Ui::Mai
{
ui->setupUi(this);
setProperty("ICaptureContext", QVariant::fromValue((void *)&ctx));
#if !defined(Q_OS_WIN32)
// process injection is not supported on non-Windows, so remove the menu item rather than disable
// it without a clear way to communicate that it is never supported
@@ -606,12 +606,10 @@ void D3D11PipelineStateViewer::addResourceRow(const D3D11ViewTag &view,
uint32_t w = 1, h = 1, d = 1;
uint32_t a = 1;
QString format = tr("Unknown");
QString name = m_Ctx.GetResourceName(r.Resource);
QString typeName = tr("Unknown");
if(!filledSlot)
{
name = tr("Empty");
format = lit("-");
typeName = lit("-");
w = h = d = a = 0;
@@ -689,6 +687,11 @@ void D3D11PipelineStateViewer::addResourceRow(const D3D11ViewTag &view,
viewDetails = true;
}
QVariant name = r.Resource;
if(viewDetails)
name = tr("%1 viewed by %2").arg(ToQStr(r.Resource)).arg(ToQStr(r.Object));
RDTreeWidgetItem *node =
new RDTreeWidgetItem({slotname, name, typeName, w, h, d, a, format, QString()});
@@ -924,8 +927,6 @@ void D3D11PipelineStateViewer::setShaderState(const D3D11Pipe::Shader &stage, QL
if(shaderInput && !shaderInput->name.empty())
slotname += lit(": ") + shaderInput->name;
QString sampName = m_Ctx.GetResourceName(s.Samp);
QString borderColor = QFormatStr("%1, %2, %3, %4")
.arg(s.BorderColor[0])
.arg(s.BorderColor[1])
@@ -974,7 +975,7 @@ void D3D11PipelineStateViewer::setShaderState(const D3D11Pipe::Shader &stage, QL
filter = QFormatStr(" (%1)").arg(ToQStr(s.Filter.func));
RDTreeWidgetItem *node = new RDTreeWidgetItem(
{slotname, sampName, addressing, filter,
{slotname, s.Samp, addressing, filter,
QFormatStr("%1 - %2")
.arg(s.MinLOD == -FLT_MAX ? lit("0") : QString::number(s.MinLOD))
.arg(s.MaxLOD == FLT_MAX ? lit("FLT_MAX") : QString::number(s.MaxLOD)),
@@ -1025,17 +1026,10 @@ void D3D11PipelineStateViewer::setShaderState(const D3D11Pipe::Shader &stage, QL
if(showNode(usedSlot, filledSlot))
{
QString name = m_Ctx.GetResourceName(b.Buffer);
ulong length = 1;
ulong length = 0;
int numvars = shaderCBuf ? shaderCBuf->variables.count() : 0;
uint32_t bytesize = shaderCBuf ? shaderCBuf->byteSize : 0;
if(!filledSlot)
{
name = tr("Empty");
length = 0;
}
BufferDescription *buf = m_Ctx.GetBuffer(b.Buffer);
if(buf)
@@ -1058,7 +1052,8 @@ void D3D11PipelineStateViewer::setShaderState(const D3D11Pipe::Shader &stage, QL
QString vecrange = QFormatStr("%1 - %2").arg(b.VecOffset).arg(b.VecOffset + b.VecCount);
RDTreeWidgetItem *node = new RDTreeWidgetItem({slotname, name, vecrange, sizestr, QString()});
RDTreeWidgetItem *node =
new RDTreeWidgetItem({slotname, b.Buffer, vecrange, sizestr, QString()});
node->setTag(QVariant::fromValue(i));
@@ -1293,20 +1288,16 @@ void D3D11PipelineStateViewer::setState()
{
if(ibufferUsed || ui->showDisabled->isChecked())
{
QString name = m_Ctx.GetResourceName(state.m_IA.ibuffer.Buffer);
uint64_t length = 1;
if(!ibufferUsed)
length = 0;
uint64_t length = 0;
BufferDescription *buf = m_Ctx.GetBuffer(state.m_IA.ibuffer.Buffer);
if(buf)
length = buf->length;
RDTreeWidgetItem *node =
new RDTreeWidgetItem({tr("Index"), name, draw ? draw->indexByteWidth : 0,
state.m_IA.ibuffer.Offset, (qulonglong)length, QString()});
RDTreeWidgetItem *node = new RDTreeWidgetItem(
{tr("Index"), state.m_IA.ibuffer.Buffer, draw ? draw->indexByteWidth : 0,
state.m_IA.ibuffer.Offset, (qulonglong)length, QString()});
node->setTag(QVariant::fromValue(
D3D11VBIBTag(state.m_IA.ibuffer.Buffer, draw ? draw->indexOffset : 0)));
@@ -1350,14 +1341,7 @@ void D3D11PipelineStateViewer::setState()
if(showNode(usedSlot, filledSlot))
{
QString name = m_Ctx.GetResourceName(v.Buffer);
qulonglong length = 1;
if(!filledSlot)
{
name = tr("Empty");
length = 0;
}
qulonglong length = 0;
BufferDescription *buf = m_Ctx.GetBuffer(v.Buffer);
if(buf)
@@ -1366,7 +1350,7 @@ void D3D11PipelineStateViewer::setState()
RDTreeWidgetItem *node = NULL;
if(filledSlot)
node = new RDTreeWidgetItem({i, name, v.Stride, v.Offset, length, QString()});
node = new RDTreeWidgetItem({i, v.Buffer, v.Stride, v.Offset, length, QString()});
else
node =
new RDTreeWidgetItem({i, tr("No Buffer Set"), lit("-"), lit("-"), lit("-"), QString()});
@@ -1447,20 +1431,13 @@ void D3D11PipelineStateViewer::setState()
if(showNode(usedSlot, filledSlot))
{
QString name = m_Ctx.GetResourceName(s.Buffer);
qulonglong length = 0;
if(!filledSlot)
{
name = tr("Empty");
}
BufferDescription *buf = m_Ctx.GetBuffer(s.Buffer);
if(buf && length == 0)
if(buf)
length = buf->length;
RDTreeWidgetItem *node = new RDTreeWidgetItem({i, name, length, s.Offset, QString()});
RDTreeWidgetItem *node = new RDTreeWidgetItem({i, s.Buffer, length, s.Offset, QString()});
node->setTag(QVariant::fromValue(s.Buffer));
@@ -683,12 +683,10 @@ void D3D12PipelineStateViewer::addResourceRow(const D3D12ViewTag &view,
uint32_t w = 1, h = 1, d = 1;
uint32_t a = 1;
QString format = tr("Unknown");
QString name = m_Ctx.GetResourceName(r.Resource);
QString typeName = tr("Unknown");
if(!filledSlot)
{
name = tr("Empty");
format = lit("-");
typeName = lit("-");
w = h = d = a = 0;
@@ -760,7 +758,7 @@ void D3D12PipelineStateViewer::addResourceRow(const D3D12ViewTag &view,
}
RDTreeWidgetItem *node = new RDTreeWidgetItem(
{rootel, view.space, regname, name, typeName, w, h, d, a, format, QString()});
{rootel, view.space, regname, r.Resource, typeName, w, h, d, a, format, QString()});
node->setTag(QVariant::fromValue(view));
@@ -1140,7 +1138,6 @@ void D3D12PipelineStateViewer::setShaderState(const D3D12Pipe::Shader &stage, QL
if(showNode(usedSlot, filledSlot))
{
QString name = m_Ctx.GetResourceName(b.Buffer);
ulong length = b.ByteSize;
uint64_t offset = b.Offset;
int numvars = shaderCBuf ? shaderCBuf->variables.count() : 0;
@@ -1149,9 +1146,6 @@ void D3D12PipelineStateViewer::setShaderState(const D3D12Pipe::Shader &stage, QL
if(b.Immediate && !b.RootValues.empty())
bytesize = uint32_t(b.RootValues.count() * 4);
if(!filledSlot)
name = tr("Empty");
QString regname = QString::number(reg);
if(shaderCBuf && !shaderCBuf->name.empty())
@@ -1168,7 +1162,7 @@ void D3D12PipelineStateViewer::setShaderState(const D3D12Pipe::Shader &stage, QL
filledSlot = false;
RDTreeWidgetItem *node = new RDTreeWidgetItem(
{rootel, (qulonglong)space, regname, name, (qulonglong)offset, sizestr, QString()});
{rootel, (qulonglong)space, regname, b.Buffer, (qulonglong)offset, sizestr, QString()});
node->setTag(tag);
@@ -1292,11 +1286,7 @@ void D3D12PipelineStateViewer::setState()
{
if(ibufferUsed || ui->showDisabled->isChecked())
{
QString name = m_Ctx.GetResourceName(state.m_IA.ibuffer.Buffer);
uint64_t length = 1;
if(!ibufferUsed)
length = 0;
uint64_t length = 0;
BufferDescription *buf = m_Ctx.GetBuffer(state.m_IA.ibuffer.Buffer);
@@ -1304,7 +1294,7 @@ void D3D12PipelineStateViewer::setState()
length = buf->length;
RDTreeWidgetItem *node = new RDTreeWidgetItem(
{tr("Index"), name, draw ? draw->indexByteWidth : 0,
{tr("Index"), state.m_IA.ibuffer.Buffer, draw ? draw->indexByteWidth : 0,
(qulonglong)state.m_IA.ibuffer.Offset, (qulonglong)length, QString()});
node->setTag(QVariant::fromValue(
@@ -1349,14 +1339,7 @@ void D3D12PipelineStateViewer::setState()
if(showNode(usedSlot, filledSlot))
{
QString name = m_Ctx.GetResourceName(v.Buffer);
qulonglong length = 1;
if(!filledSlot)
{
name = tr("Empty");
length = 0;
}
qulonglong length = 0;
BufferDescription *buf = m_Ctx.GetBuffer(v.Buffer);
if(buf)
@@ -1365,7 +1348,7 @@ void D3D12PipelineStateViewer::setState()
RDTreeWidgetItem *node = NULL;
if(filledSlot)
node = new RDTreeWidgetItem({i, name, v.Stride, (qulonglong)v.Offset, length, QString()});
node = new RDTreeWidgetItem({i, v.Buffer, v.Stride, (qulonglong)v.Offset, length, QString()});
else
node =
new RDTreeWidgetItem({i, tr("No Buffer Set"), lit("-"), lit("-"), lit("-"), QString()});
@@ -1413,21 +1396,15 @@ void D3D12PipelineStateViewer::setState()
if(showNode(usedSlot, filledSlot))
{
QString name = m_Ctx.GetResourceName(s.Buffer);
qulonglong length = 0;
if(!filledSlot)
{
name = tr("Empty");
}
BufferDescription *buf = m_Ctx.GetBuffer(s.Buffer);
if(buf && length == 0)
if(buf)
length = buf->length;
RDTreeWidgetItem *node =
new RDTreeWidgetItem({i, name, length, (qulonglong)s.Offset, QString()});
new RDTreeWidgetItem({i, s.Buffer, length, (qulonglong)s.Offset, QString()});
node->setTag(QVariant::fromValue(s.Buffer));
@@ -652,12 +652,10 @@ void GLPipelineStateViewer::setShaderState(const GLPipe::Shader &stage, QLabel *
uint32_t w = 1, h = 1, d = 1;
uint32_t a = 1;
QString format = lit("Unknown");
QString name = m_Ctx.GetResourceName(r.Resource);
QString typeName = lit("Unknown");
if(!filledSlot)
{
name = tr("Empty");
format = lit("-");
typeName = lit("-");
w = h = d = a = 0;
@@ -695,7 +693,7 @@ void GLPipelineStateViewer::setShaderState(const GLPipe::Shader &stage, QLabel *
}
RDTreeWidgetItem *node =
new RDTreeWidgetItem({slotname, name, typeName, w, h, d, a, format, QString()});
new RDTreeWidgetItem({slotname, r.Resource, typeName, w, h, d, a, format, QString()});
node->setTag(QVariant::fromValue(r.Resource));
@@ -829,7 +827,6 @@ void GLPipelineStateViewer::setShaderState(const GLPipe::Shader &stage, QLabel *
if(b)
{
slotname = QFormatStr("%1: %2").arg(bindPoint).arg(shaderCBuf.name);
name = m_Ctx.GetResourceName(b->Resource);
offset = b->Offset;
length = b->Size;
@@ -852,7 +849,8 @@ void GLPipelineStateViewer::setShaderState(const GLPipe::Shader &stage, QLabel *
byterange = QFormatStr("%1 - %2").arg(offset).arg(offset + length);
}
RDTreeWidgetItem *node = new RDTreeWidgetItem({slotname, name, byterange, sizestr, QString()});
RDTreeWidgetItem *node =
new RDTreeWidgetItem({slotname, b->Resource, byterange, sizestr, QString()});
node->setTag(QVariant::fromValue(i));
@@ -927,7 +925,6 @@ void GLPipelineStateViewer::setShaderState(const GLPipe::Shader &stage, QLabel *
: readWriteType == GLReadWriteType::SSBO ? tr("SSBO") : tr("Unknown");
QString slotname = QFormatStr("%1: %2").arg(bindPoint).arg(res.name);
QString name = m_Ctx.GetResourceName(id);
QString dimensions;
QString format = lit("-");
QString access = tr("Read/Write");
@@ -990,13 +987,12 @@ void GLPipelineStateViewer::setShaderState(const GLPipe::Shader &stage, QLabel *
if(!filledSlot)
{
name = tr("Empty");
dimensions = lit("-");
access = lit("-");
}
RDTreeWidgetItem *node =
new RDTreeWidgetItem({binding, slotname, name, dimensions, format, access, QString()});
new RDTreeWidgetItem({binding, slotname, id, dimensions, format, access, QString()});
node->setTag(tag);
@@ -1192,7 +1188,6 @@ void GLPipelineStateViewer::setState()
{
if(ibufferUsed || showDisabled)
{
QString name = m_Ctx.GetResourceName(state.m_VtxIn.ibuffer);
uint64_t length = 1;
if(!ibufferUsed)
@@ -1201,13 +1196,11 @@ void GLPipelineStateViewer::setState()
BufferDescription *buf = m_Ctx.GetBuffer(state.m_VtxIn.ibuffer);
if(buf)
{
length = buf->length;
}
RDTreeWidgetItem *node =
new RDTreeWidgetItem({tr("Element"), name, draw ? draw->indexByteWidth : 0, 0, 0,
(qulonglong)length, QString()});
RDTreeWidgetItem *node = new RDTreeWidgetItem({tr("Element"), state.m_VtxIn.ibuffer,
draw ? draw->indexByteWidth : 0, 0, 0,
(qulonglong)length, QString()});
node->setTag(
QVariant::fromValue(GLVBIBTag(state.m_VtxIn.ibuffer, draw ? draw->indexOffset : 0)));
@@ -1251,22 +1244,15 @@ void GLPipelineStateViewer::setState()
if(showNode(usedSlot, filledSlot))
{
QString name = m_Ctx.GetResourceName(v.Buffer);
uint64_t length = 1;
uint64_t length = 0;
uint64_t offset = v.Offset;
if(!filledSlot)
{
name = tr("Empty");
length = 0;
}
BufferDescription *buf = m_Ctx.GetBuffer(v.Buffer);
if(buf)
length = buf->length;
RDTreeWidgetItem *node = new RDTreeWidgetItem(
{i, name, v.Stride, (qulonglong)offset, v.Divisor, (qulonglong)length, QString()});
{i, v.Buffer, v.Stride, (qulonglong)offset, v.Divisor, (qulonglong)length, QString()});
node->setTag(QVariant::fromValue(GLVBIBTag(v.Buffer, v.Offset)));
@@ -1311,19 +1297,16 @@ void GLPipelineStateViewer::setState()
if(showNode(usedSlot, filledSlot))
{
QString name = m_Ctx.GetResourceName(state.m_Feedback.BufferBinding[i]);
qulonglong length = state.m_Feedback.Size[i];
if(!filledSlot)
name = tr("Empty");
BufferDescription *buf = m_Ctx.GetBuffer(state.m_Feedback.BufferBinding[i]);
if(buf && length == 0)
if(buf)
length = buf->length;
RDTreeWidgetItem *node = new RDTreeWidgetItem(
{i, name, length, (qulonglong)state.m_Feedback.Offset[i], QString()});
RDTreeWidgetItem *node =
new RDTreeWidgetItem({i, state.m_Feedback.BufferBinding[i], length,
(qulonglong)state.m_Feedback.Offset[i], QString()});
node->setTag(QVariant::fromValue(state.m_Feedback.BufferBinding[i]));
@@ -1616,12 +1599,10 @@ void GLPipelineStateViewer::setState()
uint32_t w = 1, h = 1, d = 1;
uint32_t a = 1;
QString format = tr("Unknown");
QString name = m_Ctx.GetResourceName(p);
QString typeName = tr("Unknown");
if(p == ResourceId())
{
name = tr("Empty");
format = lit("-");
typeName = lit("-");
w = h = d = a = 0;
@@ -1637,19 +1618,6 @@ void GLPipelineStateViewer::setState()
format = tex->format.Name();
typeName = ToQStr(tex->resType);
if(m_Ctx.IsAutogeneratedName(p) && state.m_FS.ShaderDetails)
{
for(int s = 0; s < state.m_FS.ShaderDetails->OutputSig.count(); s++)
{
if(state.m_FS.ShaderDetails->OutputSig[s].regIndex == (uint32_t)db &&
(state.m_FS.ShaderDetails->OutputSig[s].systemValue == ShaderBuiltin::Undefined ||
state.m_FS.ShaderDetails->OutputSig[s].systemValue == ShaderBuiltin::ColorOutput))
{
name = QFormatStr("<%1>").arg(state.m_FS.ShaderDetails->OutputSig[s].varName);
}
}
}
if(tex->format.srgbCorrected && !state.m_FB.FramebufferSRGB)
format += lit(" (GL_FRAMEBUFFER_SRGB = 0)");
}
@@ -1664,8 +1632,23 @@ void GLPipelineStateViewer::setState()
.arg(ToQStr(r->Swizzle[3]));
}
QString slotname = QString::number(i);
if(state.m_FS.ShaderDetails)
{
for(int s = 0; s < state.m_FS.ShaderDetails->OutputSig.count(); s++)
{
if(state.m_FS.ShaderDetails->OutputSig[s].regIndex == (uint32_t)db &&
(state.m_FS.ShaderDetails->OutputSig[s].systemValue == ShaderBuiltin::Undefined ||
state.m_FS.ShaderDetails->OutputSig[s].systemValue == ShaderBuiltin::ColorOutput))
{
slotname += QFormatStr(": %1").arg(state.m_FS.ShaderDetails->OutputSig[s].varName);
}
}
}
RDTreeWidgetItem *node =
new RDTreeWidgetItem({i, name, typeName, w, h, d, a, format, QString()});
new RDTreeWidgetItem({i, p, typeName, w, h, d, a, format, QString()});
if(tex)
node->setTag(QVariant::fromValue(p));
@@ -1700,12 +1683,10 @@ void GLPipelineStateViewer::setState()
uint32_t w = 1, h = 1, d = 1;
uint32_t a = 1;
QString format = tr("Unknown");
QString name = m_Ctx.GetResourceName(ds);
QString typeName = tr("Unknown");
if(ds == ResourceId())
{
name = tr("Empty");
format = lit("-");
typeName = lit("-");
w = h = d = a = 0;
@@ -1736,7 +1717,7 @@ void GLPipelineStateViewer::setState()
}
RDTreeWidgetItem *node =
new RDTreeWidgetItem({slot, name, typeName, w, h, d, a, format, QString()});
new RDTreeWidgetItem({slot, ds, typeName, w, h, d, a, format, QString()});
if(tex)
node->setTag(QVariant::fromValue(ds));
@@ -653,7 +653,7 @@ QVariantList VulkanPipelineStateViewer::makeSampler(const QString &bindset, cons
bindset,
slotname,
descriptor.immutableSampler ? tr("Immutable Sampler") : tr("Sampler"),
m_Ctx.GetResourceName(descriptor.res),
descriptor.res,
addressing,
filter + lit(", ") + lod};
}
@@ -857,7 +857,6 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
uint32_t samples = 1;
uint64_t len = 0;
QString format = tr("Unknown");
QString name = m_Ctx.GetResourceName(descriptorBind->res);
TextureDim restype = TextureDim::Unknown;
QVariant tag;
@@ -906,7 +905,6 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
}
else
{
name = tr("Empty");
format = lit("-");
w = h = d = a = 0;
}
@@ -932,7 +930,8 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
range = QFormatStr("%1 - %2").arg(descriptorBind->offset).arg(descriptorLen);
node = new RDTreeWidgetItem({
QString(), bindset, slotname, ToQStr(bindType), name, tr("%1 bytes").arg(len), range,
QString(), bindset, slotname, ToQStr(bindType), descriptorBind->res,
tr("%1 bytes").arg(len), range,
});
node->setTag(tag);
@@ -1018,7 +1017,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
dim += QFormatStr(", %1x MSAA").arg(samples);
node = new RDTreeWidgetItem({
QString(), bindset, slotname, typeName, name, dim, format,
QString(), bindset, slotname, typeName, descriptorBind->res, dim, format,
});
node->setTag(tag);
@@ -1185,7 +1184,6 @@ void VulkanPipelineStateViewer::addConstantBlockRow(ShaderReflection *shaderDeta
slotname = QFormatStr("%1[%2]").arg(bind).arg(idx);
}
QString name = m_Ctx.GetResourceName(descriptorBind->res);
uint64_t length = 0;
int numvars = cblock != NULL ? cblock->variables.count() : 0;
uint64_t byteSize = cblock != NULL ? cblock->byteSize : 0;
@@ -1206,6 +1204,8 @@ void VulkanPipelineStateViewer::addConstantBlockRow(ShaderReflection *shaderDeta
QString sizestr;
QVariant name = descriptorBind->res;
// push constants or specialization constants
if(cblock != NULL && !cblock->bufferBacked)
{
@@ -1531,7 +1531,6 @@ void VulkanPipelineStateViewer::setState()
{
if(ibufferUsed || showDisabled)
{
QString name = m_Ctx.GetResourceName(state.IA.ibuffer.buf);
uint64_t length = 1;
if(!ibufferUsed)
@@ -1543,7 +1542,7 @@ void VulkanPipelineStateViewer::setState()
length = buf->length;
RDTreeWidgetItem *node = new RDTreeWidgetItem(
{tr("Index"), name, tr("Index"), (qulonglong)state.IA.ibuffer.offs,
{tr("Index"), state.IA.ibuffer.buf, tr("Index"), (qulonglong)state.IA.ibuffer.offs,
draw != NULL ? draw->indexByteWidth : 0, (qulonglong)length, QString()});
node->setTag(QVariant::fromValue(
@@ -1597,7 +1596,6 @@ void VulkanPipelineStateViewer::setState()
if(showNode(usedSlot, filledSlot))
{
QString name = tr("No Buffer");
QString rate = lit("-");
uint64_t length = 1;
uint64_t offset = 0;
@@ -1605,7 +1603,6 @@ void VulkanPipelineStateViewer::setState()
if(vbuff != NULL)
{
name = m_Ctx.GetResourceName(vbuff->buffer);
offset = vbuff->offset;
BufferDescription *buf = m_Ctx.GetBuffer(vbuff->buffer);
@@ -1620,14 +1617,14 @@ void VulkanPipelineStateViewer::setState()
}
else
{
name += tr(", No Binding");
rate += tr("No Binding");
}
RDTreeWidgetItem *node = NULL;
if(filledSlot)
node = new RDTreeWidgetItem(
{i, name, rate, (qulonglong)offset, stride, (qulonglong)length, QString()});
{i, vbuff->buffer, rate, (qulonglong)offset, stride, (qulonglong)length, QString()});
else
node = new RDTreeWidgetItem(
{i, tr("No Binding"), lit("-"), lit("-"), lit("-"), lit("-"), QString()});
@@ -1783,12 +1780,10 @@ void VulkanPipelineStateViewer::setState()
uint32_t w = 1, h = 1, d = 1;
uint32_t a = 1;
QString format = p.viewfmt.Name();
QString name = m_Ctx.GetResourceName(p.img);
QString typeName = tr("Unknown");
if(p.img == ResourceId())
{
name = tr("Empty");
format = lit("-");
typeName = lit("-");
w = h = d = a = 0;
@@ -1802,19 +1797,6 @@ void VulkanPipelineStateViewer::setState()
d = tex->depth;
a = tex->arraysize;
typeName = ToQStr(tex->resType);
if(m_Ctx.IsAutogeneratedName(p.img) && state.m_FS.ShaderDetails != NULL)
{
for(int s = 0; s < state.m_FS.ShaderDetails->OutputSig.count(); s++)
{
if(state.m_FS.ShaderDetails->OutputSig[s].regIndex == (uint32_t)colIdx &&
(state.m_FS.ShaderDetails->OutputSig[s].systemValue == ShaderBuiltin::Undefined ||
state.m_FS.ShaderDetails->OutputSig[s].systemValue == ShaderBuiltin::ColorOutput))
{
name = QFormatStr("<%1>").arg(state.m_FS.ShaderDetails->OutputSig[s].varName);
}
}
}
}
if(p.swizzle[0] != TextureSwizzle::Red || p.swizzle[1] != TextureSwizzle::Green ||
@@ -1836,8 +1818,21 @@ void VulkanPipelineStateViewer::setState()
else
slotname = lit("Depth");
if(state.m_FS.ShaderDetails != NULL)
{
for(int s = 0; s < state.m_FS.ShaderDetails->OutputSig.count(); s++)
{
if(state.m_FS.ShaderDetails->OutputSig[s].regIndex == (uint32_t)colIdx &&
(state.m_FS.ShaderDetails->OutputSig[s].systemValue == ShaderBuiltin::Undefined ||
state.m_FS.ShaderDetails->OutputSig[s].systemValue == ShaderBuiltin::ColorOutput))
{
slotname += QFormatStr(": %1").arg(state.m_FS.ShaderDetails->OutputSig[s].varName);
}
}
}
RDTreeWidgetItem *node =
new RDTreeWidgetItem({slotname, name, typeName, w, h, d, a, format, QString()});
new RDTreeWidgetItem({slotname, p.img, typeName, w, h, d, a, format, QString()});
if(tex)
node->setTag(QVariant::fromValue(p.img));
@@ -2486,7 +2481,6 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe::
int i = 0;
for(const VKPipe::VB &vb : vi.vbuffers)
{
QString name = m_Ctx.GetResourceName(vb.buffer);
uint64_t length = 0;
if(vb.buffer == ResourceId())
@@ -2500,7 +2494,7 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe::
length = buf->length;
}
rows.push_back({i, name, (qulonglong)vb.offset, (qulonglong)length});
rows.push_back({i, vb.buffer, (qulonglong)vb.offset, (qulonglong)length});
i++;
}
+1
View File
@@ -88,6 +88,7 @@ struct CaptureContextInvoker : ICaptureContext
{
return m_Ctx.HasResourceCustomName(id);
}
virtual int ResourceNameCacheID() override { return m_Ctx.ResourceNameCacheID(); }
virtual TextureDescription *GetTexture(ResourceId id) override { return m_Ctx.GetTexture(id); }
virtual const rdcarray<TextureDescription> &GetTextures() override { return m_Ctx.GetTextures(); }
virtual BufferDescription *GetBuffer(ResourceId id) override { return m_Ctx.GetBuffer(id); }
+3 -3
View File
@@ -207,7 +207,7 @@ void ResourceInspector::Inspect(ResourceId id)
for(ResourceId parent : desc->parentResources)
{
RDTreeWidgetItem *item = new RDTreeWidgetItem({tr("Parent"), m_Ctx.GetResourceName(parent)});
RDTreeWidgetItem *item = new RDTreeWidgetItem({tr("Parent"), parent});
item->setData(0, ResourceIdRole, QVariant::fromValue(parent));
item->setData(1, ResourceIdRole, QVariant::fromValue(parent));
ui->relatedResources->addTopLevelItem(item);
@@ -215,7 +215,7 @@ void ResourceInspector::Inspect(ResourceId id)
for(ResourceId derived : desc->derivedResources)
{
RDTreeWidgetItem *item = new RDTreeWidgetItem({tr("Derived"), m_Ctx.GetResourceName(derived)});
RDTreeWidgetItem *item = new RDTreeWidgetItem({tr("Derived"), derived});
item->setData(0, ResourceIdRole, QVariant::fromValue(derived));
item->setData(1, ResourceIdRole, QVariant::fromValue(derived));
ui->relatedResources->addTopLevelItem(item);
@@ -231,7 +231,7 @@ void ResourceInspector::Inspect(ResourceId id)
root->setText(0, chunkObj->name);
addStructuredObjects(m_Ctx, root, chunkObj->data.children, false);
addStructuredObjects(root, chunkObj->data.children, false);
}
else
{