Mesh Shader Debugging

This commit is contained in:
Honeybunch
2024-11-19 09:29:26 -08:00
committed by Baldur Karlsson
parent a48f11d2b5
commit 3ea9735866
24 changed files with 410 additions and 8 deletions
@@ -65,6 +65,21 @@ ComputeDebugSelector::~ComputeDebugSelector()
delete ui;
}
void ComputeDebugSelector::SetDefaultDispatch(const rdcfixedarray<uint32_t, 3> &group,
const rdcfixedarray<uint32_t, 3> &thread)
{
QSignalBlocker blockers[6] = {QSignalBlocker(ui->groupX), QSignalBlocker(ui->groupY),
QSignalBlocker(ui->groupZ), QSignalBlocker(ui->threadX),
QSignalBlocker(ui->threadY), QSignalBlocker(ui->threadZ)};
ui->groupX->setValue(group[0]);
ui->groupY->setValue(group[1]);
ui->groupZ->setValue(group[2]);
ui->threadX->setValue(thread[0]);
ui->threadY->setValue(thread[1]);
ui->threadZ->setValue(thread[2]);
}
void ComputeDebugSelector::SetThreadBounds(const rdcfixedarray<uint32_t, 3> &group,
const rdcfixedarray<uint32_t, 3> &thread)
{
@@ -40,6 +40,8 @@ public:
explicit ComputeDebugSelector(QWidget *parent = 0);
~ComputeDebugSelector();
void SetDefaultDispatch(const rdcfixedarray<uint32_t, 3> &group,
const rdcfixedarray<uint32_t, 3> &thread);
void SetThreadBounds(const rdcfixedarray<uint32_t, 3> &group,
const rdcfixedarray<uint32_t, 3> &thread);
+170
View File
@@ -39,6 +39,7 @@
#include "Code/QRDUtils.h"
#include "Code/Resources.h"
#include "Widgets/CollapseGroupBox.h"
#include "Widgets/ComputeDebugSelector.h"
#include "Widgets/Extended/RDLabel.h"
#include "Widgets/Extended/RDSplitter.h"
#include "Windows/Dialogs/AxisMappingDialog.h"
@@ -2361,6 +2362,8 @@ BufferViewer::BufferViewer(ICaptureContext &ctx, bool meshview, QWidget *parent)
m_ModelOut1 = new BufferItemModel(ui->out1Table, false, meshview, this);
m_ModelOut2 = new BufferItemModel(ui->out2Table, false, meshview, this);
m_MeshDebugSelector = new ComputeDebugSelector(this);
// we keep the old UI names for serialised layouts compatibility
QString containerNames[] = {
lit("vsinData"),
@@ -2440,6 +2443,9 @@ BufferViewer::BufferViewer(ICaptureContext &ctx, bool meshview, QWidget *parent)
m_DebugVert = new QAction(tr("&Debug this Vertex"), this);
m_DebugVert->setIcon(Icons::wrench());
m_DebugMeshThread = new QAction(tr("&Debug Mesh Thread"), this);
m_DebugMeshThread->setIcon(Icons::wrench());
m_FilterMesh = new QAction(tr("&Filter to this Meshlet"), this);
m_FilterMesh->setIcon(Icons::filter());
@@ -2458,6 +2464,7 @@ BufferViewer::BufferViewer(ICaptureContext &ctx, bool meshview, QWidget *parent)
QObject::connect(m_ExportBytes, &QAction::triggered,
[this] { exportData(BufferExport(BufferExport::RawBytes)); });
QObject::connect(m_DebugVert, &QAction::triggered, this, &BufferViewer::debugVertex);
QObject::connect(m_DebugMeshThread, &QAction::triggered, this, &BufferViewer::debugMeshThread);
QObject::connect(m_RemoveFilter, &QAction::triggered,
[this]() { SetMeshFilter(MeshFilter::None); });
QObject::connect(m_FilterMesh, &QAction::triggered, [this]() {
@@ -2624,6 +2631,9 @@ BufferViewer::BufferViewer(ICaptureContext &ctx, bool meshview, QWidget *parent)
ui->fixedVars->setTooltipElidedItems(false);
ui->fixedVars->installEventFilter(this);
QObject::connect(m_MeshDebugSelector, &ComputeDebugSelector::beginDebug, this,
&BufferViewer::meshDebugSelector_beginDebug);
Reset();
m_Ctx.AddCaptureViewer(this);
@@ -3093,6 +3103,37 @@ void BufferViewer::stageRowMenu(MeshDataStage stage, QMenu *menu, const QPoint &
menu->addAction(m_RemoveFilter);
menu->addAction(m_FilterMesh);
menu->addAction(m_GotoTask);
const ShaderReflection *shaderDetails =
m_Ctx.CurPipelineState().GetShaderReflection(ShaderStage::Mesh);
m_DebugMeshThread->setEnabled(false);
if(!m_Ctx.APIProps().shaderDebugging)
{
m_DebugMeshThread->setToolTip(tr("This API does not support shader debugging"));
}
else if(!m_Ctx.CurAction() ||
!(m_Ctx.CurAction()->flags & (ActionFlags::Drawcall | ActionFlags::MeshDispatch)))
{
m_DebugMeshThread->setToolTip(tr("No draw call selected"));
}
else if(!shaderDetails)
{
m_DebugMeshThread->setToolTip(tr("No mesh shader bound"));
}
else if(!shaderDetails->debugInfo.debuggable)
{
m_DebugMeshThread->setToolTip(
tr("This shader doesn't support debugging: %1").arg(shaderDetails->debugInfo.debugStatus));
}
else
{
m_DebugMeshThread->setEnabled(true);
m_DebugMeshThread->setToolTip(QString());
}
menu->addAction(m_DebugMeshThread);
menu->addSeparator();
m_GotoTask->setEnabled(m_Ctx.CurPipelineState().GetShaderReflection(ShaderStage::Task));
@@ -6638,6 +6679,135 @@ void BufferViewer::debugVertex()
m_Ctx.AddDockWindow(s->Widget(), DockReference::AddTo, this);
}
void BufferViewer::debugMeshThread()
{
if(!m_Ctx.IsCaptureLoaded())
return;
const ActionDescription *action = m_Ctx.CurAction();
if(!action)
return;
if(!m_CurView)
return;
QModelIndex idx = m_CurView->selectionModel()->currentIndex();
if(!idx.isValid())
{
GUIInvoke::call(this, [this]() {
RDDialog::critical(this, tr("Error debugging"),
tr("Error debugging meshlet - make sure a valid meshlet is selected"));
});
return;
}
uint32_t taskIndex = 0, meshletIndex = 0;
GetIndicesForMeshRow((uint32_t)idx.row(), taskIndex, meshletIndex);
const ShaderReflection *shaderDetails =
m_Ctx.CurPipelineState().GetShaderReflection(ShaderStage::Mesh);
if(!shaderDetails)
return;
rdcfixedarray<uint32_t, 3> threadGroupSize = action->dispatchThreadsDimension[0] == 0
? shaderDetails->dispatchThreadsDimension
: action->dispatchThreadsDimension;
m_MeshDebugSelector->SetThreadBounds(action->dispatchDimension, threadGroupSize);
// Calculate 3d group id from 1d meshlet index and dispatch dimensions
// Imagine 8x2x4 with idx 60
// 8x2 = 16
// 8x2x4 = 64
// 60 % x = 4
// 60 % (x * y) = 12 / x = 1
// 60 / (x * y) = 3
// index 60 is id (4,1,3)
// 4 + (8 * 1) + (16 * 3) = 60
uint32_t xDim = action->dispatchDimension[0];
uint32_t yDim = action->dispatchDimension[1];
uint32_t zDim = action->dispatchDimension[2];
rdcfixedarray<uint32_t, 3> meshletGroup = {
meshletIndex % xDim,
(meshletIndex % (xDim * yDim)) / xDim,
meshletIndex / (xDim * yDim),
};
m_MeshDebugSelector->SetDefaultDispatch(meshletGroup, {0, 0, 0});
RDDialog::show(m_MeshDebugSelector);
}
void BufferViewer::meshDebugSelector_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::Mesh);
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->DebugMeshThread(debugThread.g, debugThread.t);
if(trace->debugger == NULL)
{
r->FreeTrace(trace);
trace = NULL;
}
done = true;
});
QString debugContext = lit("Mesh 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);
}
void BufferViewer::SyncViews(RDTableView *primary, bool selection, bool scroll)
{
if(!ui->syncViews->isChecked())
+6
View File
@@ -34,6 +34,7 @@ namespace Ui
class BufferViewer;
}
class ComputeDebugSelector;
class RDSpinBox64;
class QItemSelection;
class QMenu;
@@ -164,12 +165,16 @@ private slots:
void updateExportActionNames();
void exportData(const BufferExport &params);
void debugVertex();
void debugMeshThread();
void meshDebugSelector_beginDebug(const rdcfixedarray<uint32_t, 3> &group,
const rdcfixedarray<uint32_t, 3> &thread);
void fixedVars_contextMenu(const QPoint &pos);
private:
bool eventFilter(QObject *watched, QEvent *event) override;
Ui::BufferViewer *ui;
ICaptureContext &m_Ctx;
ComputeDebugSelector *m_MeshDebugSelector;
IReplayOutput *m_Output;
@@ -323,6 +328,7 @@ private:
QAction *m_ExportCSV = NULL;
QAction *m_ExportBytes = NULL;
QAction *m_DebugVert = NULL;
QAction *m_DebugMeshThread = NULL;
QAction *m_FilterMesh = NULL;
QAction *m_RemoveFilter = NULL;
QAction *m_GotoTask = NULL;
@@ -266,6 +266,10 @@ ShaderMessageViewer::ShaderMessageViewer(ICaptureContext &ctx, ShaderStageMask s
inputs.view = msg.location.pixel.view;
trace = r->DebugPixel(msg.location.pixel.x, msg.location.pixel.y, inputs);
}
else if(msg.stage == ShaderStage::Mesh)
{
trace = r->DebugMeshThread(msg.location.mesh.meshGroup, msg.location.mesh.thread);
}
if(trace && trace->debugger == NULL)
{
+11
View File
@@ -1021,6 +1021,17 @@ bucket when the pixel values are divided between ``minval`` and ``maxval``.
virtual ShaderDebugTrace *DebugThread(const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid) = 0;
DOCUMENT(R"(Retrieve a debugging trace from running a mesh shader.
:param Tuple[int,int,int] groupid: A list containing the 3D workgroup index.
:param Tuple[int,int,int] threadid: A list containing the 3D thread index within the workgroup.
:return: The resulting trace resulting from debugging. Destroy with
:meth:`FreeTrace`.
:rtype: ShaderDebugTrace
)");
virtual ShaderDebugTrace *DebugMeshThread(const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid) = 0;
DOCUMENT(R"(Continue a shader's debugging with a given shader debugger instance. This will run an
implementation defined number of steps and then return those steps in a list. This may be a fixed
number of steps or it may run for a fixed length of time and return as many steps as can be
+5
View File
@@ -357,6 +357,11 @@ public:
{
return new ShaderDebugTrace();
}
ShaderDebugTrace *DebugMeshThread(uint32_t eventId, const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid)
{
return new ShaderDebugTrace();
}
rdcarray<ShaderDebugState> ContinueDebug(ShaderDebugger *debugger) { return {}; }
void FreeDebugger(ShaderDebugger *debugger) { delete debugger; }
void BuildTargetShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry,
+38
View File
@@ -1684,6 +1684,44 @@ ShaderDebugTrace *ReplayProxy::DebugThread(uint32_t eventId,
PROXY_FUNCTION(DebugThread, eventId, groupid, threadid);
}
template <typename ParamSerialiser, typename ReturnSerialiser>
ShaderDebugTrace *ReplayProxy::Proxied_DebugMeshThread(ParamSerialiser &paramser,
ReturnSerialiser &retser, uint32_t eventId,
const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid)
{
const ReplayProxyPacket expectedPacket = eReplayProxy_DebugMeshThread;
ReplayProxyPacket packet = eReplayProxy_DebugMeshThread;
ShaderDebugTrace *ret;
{
BEGIN_PARAMS();
SERIALISE_ELEMENT(eventId);
SERIALISE_ELEMENT(groupid);
SERIALISE_ELEMENT(threadid);
END_PARAMS();
}
{
REMOTE_EXECUTION();
if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored)
ret = m_Remote->DebugMeshThread(eventId, groupid, threadid);
else
ret = new ShaderDebugTrace;
}
SERIALISE_RETURN(*ret);
return ret;
}
ShaderDebugTrace *ReplayProxy::DebugMeshThread(uint32_t eventId,
const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid)
{
PROXY_FUNCTION(DebugMeshThread, eventId, groupid, threadid);
}
template <typename ParamSerialiser, typename ReturnSerialiser>
rdcarray<ShaderDebugState> ReplayProxy::Proxied_ContinueDebug(ParamSerialiser &paramser,
ReturnSerialiser &retser,
+4
View File
@@ -89,6 +89,7 @@ enum ReplayProxyPacket
eReplayProxy_DebugVertex,
eReplayProxy_DebugPixel,
eReplayProxy_DebugThread,
eReplayProxy_DebugMeshThread,
eReplayProxy_RenderOverlay,
@@ -552,6 +553,9 @@ public:
IMPLEMENT_FUNCTION_PROXIED(ShaderDebugTrace *, DebugThread, uint32_t eventId,
const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid);
IMPLEMENT_FUNCTION_PROXIED(ShaderDebugTrace *, DebugMeshThread, uint32_t eventId,
const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid);
IMPLEMENT_FUNCTION_PROXIED(rdcarray<ShaderDebugState>, ContinueDebug, ShaderDebugger *debugger);
IMPLEMENT_FUNCTION_PROXIED(void, FreeDebugger, ShaderDebugger *debugger);
+2
View File
@@ -288,6 +288,8 @@ public:
const DebugPixelInputs &inputs);
ShaderDebugTrace *DebugThread(uint32_t eventId, const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid);
ShaderDebugTrace *DebugMeshThread(uint32_t eventId, const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid);
rdcarray<ShaderDebugState> ContinueDebug(ShaderDebugger *debugger);
void FreeDebugger(ShaderDebugger *debugger);
@@ -2688,6 +2688,14 @@ ShaderDebugTrace *D3D11Replay::DebugThread(uint32_t eventId,
return ret;
}
ShaderDebugTrace *D3D11Replay::DebugMeshThread(uint32_t eventId,
const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid)
{
// Not supported
return new ShaderDebugTrace;
}
rdcarray<ShaderDebugState> D3D11Replay::ContinueDebug(ShaderDebugger *debugger)
{
DXBCDebug::InterpretDebugger *interpreter = (DXBCDebug::InterpretDebugger *)debugger;
+2
View File
@@ -251,6 +251,8 @@ public:
const DebugPixelInputs &inputs);
ShaderDebugTrace *DebugThread(uint32_t eventId, const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid);
ShaderDebugTrace *DebugMeshThread(uint32_t eventId, const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid);
rdcarray<ShaderDebugState> ContinueDebug(ShaderDebugger *debugger);
void FreeDebugger(ShaderDebugger *debugger);
@@ -3377,6 +3377,14 @@ ShaderDebugTrace *D3D12Replay::DebugThread(uint32_t eventId,
return ret;
}
ShaderDebugTrace *D3D12Replay::DebugMeshThread(uint32_t eventId,
const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid)
{
// Not implemented yet
return new ShaderDebugTrace;
}
rdcarray<ShaderDebugState> D3D12Replay::ContinueDebug(ShaderDebugger *debugger)
{
if(!debugger)
+8
View File
@@ -4300,6 +4300,14 @@ ShaderDebugTrace *GLReplay::DebugThread(uint32_t eventId, const rdcfixedarray<ui
return new ShaderDebugTrace();
}
ShaderDebugTrace *GLReplay::DebugMeshThread(uint32_t eventId,
const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid)
{
GLNOTIMP("DebugMeshThread");
return new ShaderDebugTrace();
}
rdcarray<ShaderDebugState> GLReplay::ContinueDebug(ShaderDebugger *debugger)
{
GLNOTIMP("ContinueDebug");
+2
View File
@@ -260,6 +260,8 @@ public:
const DebugPixelInputs &inputs);
ShaderDebugTrace *DebugThread(uint32_t eventId, const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid);
ShaderDebugTrace *DebugMeshThread(uint32_t eventId, const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid);
rdcarray<ShaderDebugState> ContinueDebug(ShaderDebugger *debugger);
void FreeDebugger(ShaderDebugger *debugger);
uint32_t PickVertex(uint32_t eventId, int32_t width, int32_t height, const MeshDisplay &cfg,
@@ -3521,6 +3521,12 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
break;
}
case Op::SetMeshOutputsEXT:
{
// Ignore mesh outputs, nothing to do, really
break;
}
// TODO sparse sampling
case Op::ImageSparseSampleImplicitLod:
case Op::ImageSparseSampleExplicitLod:
@@ -3750,7 +3756,6 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
case Op::ConvertSampledImageToUNV:
case Op::SamplerImageAddressingModeNV:
case Op::EmitMeshTasksEXT:
case Op::SetMeshOutputsEXT:
case Op::HitObjectRecordHitMotionNV:
case Op::HitObjectRecordHitWithIndexMotionNV:
case Op::HitObjectRecordMissMotionNV:
@@ -437,6 +437,7 @@ void Reflector::CheckDebuggable(bool &debuggable, rdcstr &debugStatus) const
"SPV_GOOGLE_user_type",
"SPV_KHR_physical_storage_buffer",
"SPV_KHR_relaxed_extended_instruction",
"SPV_EXT_mesh_shader",
};
// whitelist supported extensions
@@ -554,6 +555,7 @@ void Reflector::CheckDebuggable(bool &debuggable, rdcstr &debugStatus) const
case Capability::UniformDecoration:
case Capability::SignedZeroInfNanPreserve:
case Capability::PhysicalStorageBufferAddresses:
case Capability::MeshShadingEXT:
{
supported = true;
break;
@@ -646,13 +648,6 @@ void Reflector::CheckDebuggable(bool &debuggable, rdcstr &debugStatus) const
break;
}
// mesh shading
case Capability::MeshShadingEXT:
{
supported = false;
break;
}
// no plans to support these - mostly Kernel/OpenCL related or vendor extensions
case Capability::Addresses:
case Capability::Linkage:
+2
View File
@@ -451,6 +451,8 @@ public:
const DebugPixelInputs &inputs);
ShaderDebugTrace *DebugThread(uint32_t eventId, const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid);
ShaderDebugTrace *DebugMeshThread(uint32_t eventId, const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid);
rdcarray<ShaderDebugState> ContinueDebug(ShaderDebugger *debugger);
void FreeDebugger(ShaderDebugger *debugger);
@@ -5080,6 +5080,89 @@ ShaderDebugTrace *VulkanReplay::DebugThread(uint32_t eventId,
return ret;
}
ShaderDebugTrace *VulkanReplay::DebugMeshThread(uint32_t eventId,
const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid)
{
const VulkanRenderState &state = m_pDriver->GetRenderState();
VulkanCreationInfo &c = m_pDriver->m_CreationInfo;
rdcstr regionName =
StringFormat::Fmt("DebugMeshThread @ %u of (%u,%u,%u) (%u,%u,%u)", eventId, groupid[0],
groupid[1], groupid[2], threadid[0], threadid[1], threadid[2]);
VkMarkerRegion region(regionName);
if(Vulkan_Debug_ShaderDebugLogging())
RDCLOG("%s", regionName.c_str());
const ActionDescription *action = m_pDriver->GetAction(eventId);
if(!(action->flags & ActionFlags::MeshDispatch))
{
RDCLOG("No mesh dispatch selected");
return new ShaderDebugTrace();
}
// get ourselves in pristine state before this dispatch (without any side effects it may have had)
m_pDriver->ReplayLog(0, eventId, eReplay_WithoutDraw);
const VulkanCreationInfo::Pipeline &pipe = c.m_Pipeline[state.graphics.pipeline];
const VulkanCreationInfo::ShaderEntry &shaderEntry =
state.graphics.shaderObject
? c.m_ShaderObject[state.shaderObjects[(size_t)ShaderStage::Mesh]].shad
: pipe.shaders[(size_t)ShaderStage::Mesh];
VulkanCreationInfo::ShaderModule &shader = c.m_ShaderModule[shaderEntry.module];
rdcstr entryPoint = shaderEntry.entryPoint;
const rdcarray<SpecConstant> &spec = shaderEntry.specialization;
VulkanCreationInfo::ShaderModuleReflection &shadRefl =
shader.GetReflection(ShaderStage::Mesh, entryPoint, state.graphics.pipeline);
if(!shadRefl.refl->debugInfo.debuggable)
{
RDCLOG("Shader is not debuggable: %s", shadRefl.refl->debugInfo.debugStatus.c_str());
return new ShaderDebugTrace();
}
shadRefl.PopulateDisassembly(shader.spirv);
VulkanAPIWrapper *apiWrapper =
new VulkanAPIWrapper(m_pDriver, c, ShaderStage::Mesh, eventId, shadRefl.refl->resourceId);
uint32_t threadDim[3];
threadDim[0] = shadRefl.refl->dispatchThreadsDimension[0];
threadDim[1] = shadRefl.refl->dispatchThreadsDimension[1];
threadDim[2] = shadRefl.refl->dispatchThreadsDimension[2];
std::map<ShaderBuiltin, ShaderVariable> &builtins = apiWrapper->builtin_inputs;
builtins[ShaderBuiltin::DispatchSize] =
ShaderVariable(rdcstr(), action->dispatchDimension[0], action->dispatchDimension[1],
action->dispatchDimension[2], 0U);
builtins[ShaderBuiltin::DispatchThreadIndex] = ShaderVariable(
rdcstr(), groupid[0] * threadDim[0] + threadid[0], groupid[1] * threadDim[1] + threadid[1],
groupid[2] * threadDim[2] + threadid[2], 0U);
builtins[ShaderBuiltin::GroupIndex] =
ShaderVariable(rdcstr(), groupid[0], groupid[1], groupid[2], 0U);
builtins[ShaderBuiltin::GroupSize] =
ShaderVariable(rdcstr(), threadDim[0], threadDim[1], threadDim[2], 0U);
builtins[ShaderBuiltin::GroupThreadIndex] =
ShaderVariable(rdcstr(), threadid[0], threadid[1], threadid[2], 0U);
builtins[ShaderBuiltin::GroupFlatIndex] = ShaderVariable(
rdcstr(), threadid[2] * threadDim[0] * threadDim[1] + threadid[1] * threadDim[0] + threadid[0],
0U, 0U, 0U);
builtins[ShaderBuiltin::DeviceIndex] = ShaderVariable(rdcstr(), 0U, 0U, 0U, 0U);
builtins[ShaderBuiltin::DrawIndex] = ShaderVariable(rdcstr(), action->drawIndex, 0U, 0U, 0U);
rdcspv::Debugger *debugger = new rdcspv::Debugger;
debugger->Parse(shader.spirv.GetSPIRV());
ShaderDebugTrace *ret = debugger->BeginDebug(apiWrapper, ShaderStage::Mesh, entryPoint, spec,
shadRefl.instructionLines, shadRefl.patchData, 0);
apiWrapper->ResetReplay();
return ret;
}
rdcarray<ShaderDebugState> VulkanReplay::ContinueDebug(ShaderDebugger *debugger)
{
rdcspv::Debugger *spvDebugger = (rdcspv::Debugger *)debugger;
+7
View File
@@ -296,6 +296,13 @@ ShaderDebugTrace *DummyDriver::DebugVertex(uint32_t eventId, uint32_t vertid, ui
return new ShaderDebugTrace;
}
ShaderDebugTrace *DummyDriver::DebugMeshThread(uint32_t eventId,
const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid)
{
return new ShaderDebugTrace;
}
ShaderDebugTrace *DummyDriver::DebugPixel(uint32_t eventId, uint32_t x, uint32_t y,
const DebugPixelInputs &inputs)
{
+2
View File
@@ -114,6 +114,8 @@ public:
const DebugPixelInputs &inputs);
ShaderDebugTrace *DebugThread(uint32_t eventId, const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid);
ShaderDebugTrace *DebugMeshThread(uint32_t eventId, const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid);
rdcarray<ShaderDebugState> ContinueDebug(ShaderDebugger *debugger);
void FreeDebugger(ShaderDebugger *debugger);
+18
View File
@@ -1698,6 +1698,24 @@ ShaderDebugTrace *ReplayController::DebugThread(const rdcfixedarray<uint32_t, 3>
return ret;
}
ShaderDebugTrace *ReplayController::DebugMeshThread(const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid)
{
CHECK_REPLAY_THREAD();
RENDERDOC_PROFILEFUNCTION();
ShaderDebugTrace *ret = m_pDevice->DebugMeshThread(m_EventID, groupid, threadid);
FatalErrorCheck();
SetFrameEvent(m_EventID, true);
if(ret->debugger)
m_Debuggers.push_back(ret->debugger);
return ret;
}
rdcarray<ShaderDebugState> ReplayController::ContinueDebug(ShaderDebugger *debugger)
{
CHECK_REPLAY_THREAD();
+2
View File
@@ -214,6 +214,8 @@ public:
ShaderDebugTrace *DebugPixel(uint32_t x, uint32_t y, const DebugPixelInputs &inputs);
ShaderDebugTrace *DebugThread(const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid);
ShaderDebugTrace *DebugMeshThread(const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid);
rdcarray<ShaderDebugState> ContinueDebug(ShaderDebugger *debugger);
void FreeTrace(ShaderDebugTrace *trace);
+3
View File
@@ -231,6 +231,9 @@ public:
const DebugPixelInputs &inputs) = 0;
virtual ShaderDebugTrace *DebugThread(uint32_t eventId, const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid) = 0;
virtual ShaderDebugTrace *DebugMeshThread(uint32_t eventId,
const rdcfixedarray<uint32_t, 3> &groupid,
const rdcfixedarray<uint32_t, 3> &threadid) = 0;
virtual rdcarray<ShaderDebugState> ContinueDebug(ShaderDebugger *debugger) = 0;
virtual void FreeDebugger(ShaderDebugger *debugger) = 0;