Implement location tracking and goto for GS printfs

* We can't debug geometry shaders but we can scroll to them, as long as we have
  the primitive. We can't differentiate instances currently without passing that
  data through from the VS (and through tessellation, if it exists).
* This also disables the debug and goto buttons for printfs from shader stages
  that don't support those operations.
This commit is contained in:
baldurk
2022-07-11 13:02:23 +01:00
parent d39197a499
commit 7bdf26d329
8 changed files with 150 additions and 10 deletions
+65 -8
View File
@@ -34,8 +34,11 @@
#include "toolwindowmanager/ToolWindowManager.h"
#include "ui_ShaderMessageViewer.h"
ButtonDelegate::ButtonDelegate(const QIcon &icon, QWidget *parent)
: m_Icon(icon), QStyledItemDelegate(parent)
static const int debuggableRole = Qt::UserRole + 1;
static const int gotoableRole = Qt::UserRole + 2;
ButtonDelegate::ButtonDelegate(const QIcon &icon, int enableRole, QWidget *parent)
: m_Icon(icon), m_EnableRole(enableRole), QStyledItemDelegate(parent)
{
}
@@ -54,7 +57,9 @@ void ButtonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option
button.rect.setSize(sz);
button.icon = m_Icon;
button.iconSize = sz;
button.state = QStyle::State_Enabled;
if(m_EnableRole == 0 || index.data(m_EnableRole).toBool())
button.state = QStyle::State_Enabled;
if(m_ClickedIndex == index)
button.state |= QStyle::State_Sunken;
@@ -77,7 +82,8 @@ bool ButtonDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
{
if(event->type() == QEvent::MouseButtonPress)
{
m_ClickedIndex = index;
if(m_EnableRole == 0 || index.data(m_EnableRole).toBool())
m_ClickedIndex = index;
}
else if(event->type() == QEvent::MouseMove)
{
@@ -105,7 +111,7 @@ bool ButtonDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
}
else if(event->type() == QEvent::MouseButtonRelease)
{
if(m_ClickedIndex == index)
if(m_ClickedIndex == index && index != QModelIndex())
{
m_ClickedIndex = QModelIndex();
@@ -200,7 +206,7 @@ ShaderMessageViewer::ShaderMessageViewer(ICaptureContext &ctx, ShaderStageMask s
int sortColumn = 0;
m_debugDelegate = new ButtonDelegate(Icons::wrench(), this);
m_debugDelegate = new ButtonDelegate(Icons::wrench(), debuggableRole, this);
if(m_Action && (m_Action->flags & ActionFlags::Dispatch))
{
@@ -218,7 +224,7 @@ ShaderMessageViewer::ShaderMessageViewer(ICaptureContext &ctx, ShaderStageMask s
ui->messages->setColumns({lit("Debug"), lit("Go to"), tr("Location"), lit("Message")});
sortColumn = 2;
m_gotoDelegate = new ButtonDelegate(Icons::find(), this);
m_gotoDelegate = new ButtonDelegate(Icons::find(), gotoableRole, this);
ui->messages->setItemDelegateForColumn(0, m_debugDelegate);
ui->messages->setItemDelegateForColumn(1, m_gotoDelegate);
@@ -389,6 +395,9 @@ ShaderMessageViewer::ShaderMessageViewer(ICaptureContext &ctx, ShaderStageMask s
m_Ctx.ShowMeshPreview();
m_Ctx.GetMeshPreview()->SetCurrentInstance(msg.location.vertex.instance);
m_Ctx.GetMeshPreview()->SetCurrentView(msg.location.vertex.view);
m_Ctx.GetMeshPreview()->ShowMeshData(MeshDataStage::VSOut);
m_Ctx.GetMeshPreview()->ScrollToRow(msg.location.vertex.vertexIndex, MeshDataStage::VSOut);
m_Ctx.GetMeshPreview()->ShowMeshData(MeshDataStage::VSIn);
// TODO, not accurate for indices
m_Ctx.GetMeshPreview()->ScrollToRow(msg.location.vertex.vertexIndex, MeshDataStage::VSIn);
}
@@ -415,6 +424,17 @@ ShaderMessageViewer::ShaderMessageViewer(ICaptureContext &ctx, ShaderStageMask s
ShaderStage::Pixel, 0, 0);
m_Ctx.GetTextureViewer()->GotoLocation(msg.location.pixel.x, msg.location.pixel.y);
}
else if(msg.stage == ShaderStage::Geometry)
{
m_Ctx.ShowMeshPreview();
m_Ctx.GetMeshPreview()->SetCurrentView(msg.location.geometry.view);
m_Ctx.GetMeshPreview()->ShowMeshData(MeshDataStage::GSOut);
// TODO, instances not supported
m_Ctx.GetMeshPreview()->ScrollToRow(
RENDERDOC_VertexOffset(m_Ctx.CurPipelineState().GetPrimitiveTopology(),
msg.location.geometry.primitive),
MeshDataStage::GSOut);
}
else
{
qCritical() << "Can't go to a compute thread";
@@ -496,6 +516,15 @@ ShaderMessageViewer::ShaderMessageViewer(ICaptureContext &ctx, ShaderStageMask s
// column 2 is the thread column for compute
return am.location.compute.thread < bm.location.compute.thread;
}
else if(am.stage == ShaderStage::Geometry)
{
const ShaderGeometryMessageLocation &aloc = am.location.geometry;
const ShaderGeometryMessageLocation &bloc = bm.location.geometry;
if(aloc.view != bloc.view)
return aloc.view < bloc.view;
return am.location.geometry.primitive < bm.location.geometry.primitive;
}
else
{
// can't sort these, pretend they're all equal
@@ -735,6 +764,10 @@ void ShaderMessageViewer::refreshMessages()
QString filter = ui->filter->text().trimmed();
const ShaderReflection *vsrefl = m_Ctx.CurPipelineState().GetShaderReflection(ShaderStage::Vertex);
const ShaderReflection *psrefl = m_Ctx.CurPipelineState().GetShaderReflection(ShaderStage::Pixel);
const ShaderReflection *csrefl = m_Ctx.CurPipelineState().GetShaderReflection(ShaderStage::Compute);
for(int i = 0; i < m_Messages.count(); i++)
{
const ShaderMessage &msg = m_Messages[i];
@@ -745,9 +778,13 @@ void ShaderMessageViewer::refreshMessages()
QString text(msg.message);
const ShaderReflection *refl = NULL;
QString location;
if(msg.stage == ShaderStage::Vertex)
{
refl = vsrefl;
// only show the view if the draw has multiview enabled
if(m_Multiview)
{
@@ -771,6 +808,8 @@ void ShaderMessageViewer::refreshMessages()
}
else if(msg.stage == ShaderStage::Pixel)
{
refl = psrefl;
location = QFormatStr("%1 %2,%3")
.arg(IsD3D(m_API) ? lit("Pixel") : lit("Frag"))
.arg(msg.location.pixel.x)
@@ -794,11 +833,22 @@ void ShaderMessageViewer::refreshMessages()
}
else if(msg.stage == ShaderStage::Compute)
{
refl = csrefl;
}
else if(msg.stage == ShaderStage::Geometry)
{
location = lit("Geometry Prim %1").arg(msg.location.geometry.primitive);
// only show the view if the draw has multiview enabled
if(m_Multiview)
{
location += lit(", View %1").arg(msg.location.geometry.view);
}
}
else
{
// no location info for other stages
location = tr("Unknown shader");
location = tr("Unknown %1").arg(ToQStr(msg.stage, m_Ctx.APIProps().pipelineType));
}
// filter by text on location and messag
@@ -821,10 +871,17 @@ void ShaderMessageViewer::refreshMessages()
.arg(msg.location.compute.thread[2]),
text,
});
node->setData(0, debuggableRole, refl && refl->debugInfo.debuggable);
}
else
{
node = new RDTreeWidgetItem({QString(), QString(), location, text});
node->setData(0, debuggableRole, refl && refl->debugInfo.debuggable);
node->setData(1, gotoableRole, msg.stage == ShaderStage::Vertex ||
msg.stage == ShaderStage::Pixel ||
msg.stage == ShaderStage::Geometry);
}
if(node)