mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-11 17:20:56 +00:00
Add a compute debugging UI selector to the GL pipeline state view
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
#include <QScrollBar>
|
||||
#include <QXmlStreamWriter>
|
||||
#include "Code/Resources.h"
|
||||
#include "Widgets/ComputeDebugSelector.h"
|
||||
#include "Widgets/Extended/RDHeaderView.h"
|
||||
#include "flowlayout/FlowLayout.h"
|
||||
#include "toolwindowmanager/ToolWindowManager.h"
|
||||
@@ -86,6 +87,8 @@ GLPipelineStateViewer::GLPipelineStateViewer(ICaptureContext &ctx, PipelineState
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_ComputeDebugSelector = new ComputeDebugSelector(this);
|
||||
|
||||
const QIcon &action = Icons::action();
|
||||
const QIcon &action_hover = Icons::action_hover();
|
||||
|
||||
@@ -207,6 +210,9 @@ GLPipelineStateViewer::GLPipelineStateViewer(ICaptureContext &ctx, PipelineState
|
||||
QObject::connect(res, &RDTreeWidget::itemActivated, this,
|
||||
&GLPipelineStateViewer::resource_itemActivated);
|
||||
|
||||
QObject::connect(m_ComputeDebugSelector, &ComputeDebugSelector::beginDebug, this,
|
||||
&GLPipelineStateViewer::computeDebugSelector_beginDebug);
|
||||
|
||||
{
|
||||
QMenu *extensionsMenu = new QMenu(this);
|
||||
|
||||
@@ -1273,6 +1279,8 @@ void GLPipelineStateViewer::clearState()
|
||||
ui->depthBounds->setText(lit("0.0-1.0"));
|
||||
|
||||
ui->stencils->clear();
|
||||
|
||||
ui->computeDebugSelector->setEnabled(false);
|
||||
}
|
||||
|
||||
void GLPipelineStateViewer::setShaderState(const GLPipe::Shader &stage, RDLabel *pipeline,
|
||||
@@ -2591,6 +2599,57 @@ void GLPipelineStateViewer::setState()
|
||||
ui->stencils->clearSelection();
|
||||
ui->stencils->endUpdate();
|
||||
|
||||
// set up thread debugging inputs
|
||||
bool enableDebug = m_Ctx.APIProps().shaderDebugging && state.computeShader.reflection &&
|
||||
state.computeShader.reflection->debugInfo.debuggable && action &&
|
||||
(action->flags & ActionFlags::Dispatch);
|
||||
if(enableDebug)
|
||||
{
|
||||
// Validate dispatch/threadgroup dimensions
|
||||
enableDebug &= action->dispatchDimension[0] > 0;
|
||||
enableDebug &= action->dispatchDimension[1] > 0;
|
||||
enableDebug &= action->dispatchDimension[2] > 0;
|
||||
|
||||
const rdcfixedarray<uint32_t, 3> &threadDims =
|
||||
(action->dispatchThreadsDimension[0] == 0)
|
||||
? state.computeShader.reflection->dispatchThreadsDimension
|
||||
: action->dispatchThreadsDimension;
|
||||
enableDebug &= threadDims[0] > 0;
|
||||
enableDebug &= threadDims[1] > 0;
|
||||
enableDebug &= threadDims[2] > 0;
|
||||
}
|
||||
|
||||
if(enableDebug)
|
||||
{
|
||||
ui->computeDebugSelector->setEnabled(true);
|
||||
|
||||
// set maximums for CS debugging
|
||||
m_ComputeDebugSelector->SetThreadBounds(
|
||||
action->dispatchDimension, (action->dispatchThreadsDimension[0] == 0)
|
||||
? state.computeShader.reflection->dispatchThreadsDimension
|
||||
: action->dispatchThreadsDimension);
|
||||
|
||||
ui->computeDebugSelector->setToolTip(
|
||||
tr("Debug this compute shader by specifying group/thread ID or dispatch ID"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->computeDebugSelector->setEnabled(false);
|
||||
|
||||
if(!m_Ctx.APIProps().shaderDebugging)
|
||||
ui->computeDebugSelector->setToolTip(tr("This API does not support shader debugging"));
|
||||
else if(!action || !(action->flags & ActionFlags::Dispatch))
|
||||
ui->computeDebugSelector->setToolTip(tr("No dispatch selected"));
|
||||
else if(!state.computeShader.reflection)
|
||||
ui->computeDebugSelector->setToolTip(tr("No compute shader bound"));
|
||||
else if(!state.computeShader.reflection->debugInfo.debuggable)
|
||||
ui->computeDebugSelector->setToolTip(
|
||||
tr("This shader doesn't support debugging: %1")
|
||||
.arg(state.computeShader.reflection->debugInfo.debugStatus));
|
||||
else
|
||||
ui->computeDebugSelector->setToolTip(tr("Invalid dispatch/threadgroup dimensions."));
|
||||
}
|
||||
|
||||
// highlight the appropriate stages in the flowchart
|
||||
if(action == NULL)
|
||||
{
|
||||
@@ -3942,3 +4001,93 @@ void GLPipelineStateViewer::on_meshView_clicked()
|
||||
m_Ctx.ShowMeshPreview();
|
||||
ToolWindowManager::raiseToolWindow(m_Ctx.GetMeshPreview()->Widget());
|
||||
}
|
||||
|
||||
void GLPipelineStateViewer::on_computeDebugSelector_clicked()
|
||||
{
|
||||
// Check whether debugging is valid for this event before showing the dialog
|
||||
if(!m_Ctx.IsCaptureLoaded())
|
||||
return;
|
||||
|
||||
const ActionDescription *action = m_Ctx.CurAction();
|
||||
|
||||
if(!action)
|
||||
return;
|
||||
|
||||
const ShaderReflection *shaderDetails =
|
||||
m_Ctx.CurPipelineState().GetShaderReflection(ShaderStage::Compute);
|
||||
|
||||
if(!shaderDetails)
|
||||
return;
|
||||
|
||||
RDDialog::show(m_ComputeDebugSelector);
|
||||
}
|
||||
|
||||
void GLPipelineStateViewer::computeDebugSelector_beginDebug(const rdcfixedarray<uint32_t, 3> &group,
|
||||
const rdcfixedarray<uint32_t, 3> &thread)
|
||||
{
|
||||
const ActionDescription *action = m_Ctx.CurAction();
|
||||
|
||||
if(!action)
|
||||
return;
|
||||
|
||||
const ShaderReflection *shaderDetails =
|
||||
m_Ctx.CurPipelineState().GetShaderReflection(ShaderStage::Compute);
|
||||
|
||||
if(!shaderDetails)
|
||||
return;
|
||||
|
||||
struct threadSelect
|
||||
{
|
||||
rdcfixedarray<uint32_t, 3> g;
|
||||
rdcfixedarray<uint32_t, 3> t;
|
||||
} debugThread = {
|
||||
// g[]
|
||||
{group[0], group[1], group[2]},
|
||||
// t[]
|
||||
{thread[0], thread[1], thread[2]},
|
||||
};
|
||||
|
||||
bool done = false;
|
||||
ShaderDebugTrace *trace = NULL;
|
||||
|
||||
m_Ctx.Replay().AsyncInvoke([&trace, &done, debugThread](IReplayController *r) {
|
||||
trace = r->DebugThread(debugThread.g, debugThread.t);
|
||||
|
||||
if(trace->debugger == NULL)
|
||||
{
|
||||
r->FreeTrace(trace);
|
||||
trace = NULL;
|
||||
}
|
||||
|
||||
done = true;
|
||||
});
|
||||
|
||||
QString debugContext = lit("Group [%1,%2,%3] Thread [%4,%5,%6]")
|
||||
.arg(group[0])
|
||||
.arg(group[1])
|
||||
.arg(group[2])
|
||||
.arg(thread[0])
|
||||
.arg(thread[1])
|
||||
.arg(thread[2]);
|
||||
|
||||
// wait a short while before displaying the progress dialog (which won't show if we're already
|
||||
// done by the time we reach it)
|
||||
for(int i = 0; !done && i < 100; i++)
|
||||
QThread::msleep(5);
|
||||
|
||||
ShowProgressDialog(this, tr("Debugging %1").arg(debugContext), [&done]() { return done; });
|
||||
|
||||
if(!trace)
|
||||
{
|
||||
RDDialog::critical(
|
||||
this, tr("Error debugging"),
|
||||
tr("Error debugging thread - make sure a valid group and thread is selected"));
|
||||
return;
|
||||
}
|
||||
|
||||
// viewer takes ownership of the trace
|
||||
IShaderViewer *s = m_Ctx.DebugShader(
|
||||
shaderDetails, m_Ctx.CurPipelineState().GetComputePipelineObject(), trace, debugContext);
|
||||
|
||||
m_Ctx.AddDockWindow(s->Widget(), DockReference::AddTo, this);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ class GLPipelineStateViewer;
|
||||
|
||||
class QXmlStreamWriter;
|
||||
|
||||
class ComputeDebugSelector;
|
||||
class RDLabel;
|
||||
class RDTreeWidget;
|
||||
class RDTreeWidgetItem;
|
||||
@@ -83,10 +84,15 @@ private slots:
|
||||
void ubo_itemActivated(RDTreeWidgetItem *item, int column);
|
||||
void vertex_leave(QEvent *e);
|
||||
|
||||
void on_computeDebugSelector_clicked();
|
||||
void computeDebugSelector_beginDebug(const rdcfixedarray<uint32_t, 3> &group,
|
||||
const rdcfixedarray<uint32_t, 3> &thread);
|
||||
|
||||
private:
|
||||
Ui::GLPipelineStateViewer *ui;
|
||||
ICaptureContext &m_Ctx;
|
||||
PipelineStateViewer &m_Common;
|
||||
ComputeDebugSelector *m_ComputeDebugSelector;
|
||||
|
||||
QString MakeGenericValueString(uint32_t compCount, CompType compType,
|
||||
const GLPipe::VertexAttribute &val);
|
||||
|
||||
@@ -4744,6 +4744,23 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="computeDebugSelector">
|
||||
<property name="text">
|
||||
<string>Debug</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../Resources/resources.qrc">
|
||||
<normaloff>:/wrench.png</normaloff>:/wrench.png</iconset>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="csShaderSpacer">
|
||||
<property name="orientation">
|
||||
|
||||
Reference in New Issue
Block a user