mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-25 16:06:31 +00:00
Pass through line-mapping information for each instruction to UI
* This lets the UI highlight the source line as stepping happens, as well as allowing stepping purely in HLSL.
This commit is contained in:
@@ -257,6 +257,7 @@ TEMPLATE_ARRAY_INSTANTIATE(rdcarray, PathEntry)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, PixelModification)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ResourceDescription)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ResourceId)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, LineColumnInfo)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderCompileFlag)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderConstant)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderDebugState)
|
||||
|
||||
@@ -105,24 +105,6 @@ ShaderViewer::ShaderViewer(ICaptureContext &ctx, QWidget *parent)
|
||||
QObject::connect(m_DisassemblyView, &ScintillaEdit::keyPressed, this,
|
||||
&ShaderViewer::readonly_keyPressed);
|
||||
|
||||
// C# LightCoral
|
||||
m_DisassemblyView->markerSetBack(CURRENT_MARKER, SCINTILLA_COLOUR(240, 128, 128));
|
||||
m_DisassemblyView->markerSetBack(CURRENT_MARKER + 1, SCINTILLA_COLOUR(240, 128, 128));
|
||||
m_DisassemblyView->markerDefine(CURRENT_MARKER, SC_MARK_SHORTARROW);
|
||||
m_DisassemblyView->markerDefine(CURRENT_MARKER + 1, SC_MARK_BACKGROUND);
|
||||
|
||||
// C# LightSlateGray
|
||||
m_DisassemblyView->markerSetBack(FINISHED_MARKER, SCINTILLA_COLOUR(119, 136, 153));
|
||||
m_DisassemblyView->markerSetBack(FINISHED_MARKER + 1, SCINTILLA_COLOUR(119, 136, 153));
|
||||
m_DisassemblyView->markerDefine(FINISHED_MARKER, SC_MARK_ROUNDRECT);
|
||||
m_DisassemblyView->markerDefine(FINISHED_MARKER + 1, SC_MARK_BACKGROUND);
|
||||
|
||||
// C# Red
|
||||
m_DisassemblyView->markerSetBack(BREAKPOINT_MARKER, SCINTILLA_COLOUR(255, 0, 0));
|
||||
m_DisassemblyView->markerSetBack(BREAKPOINT_MARKER + 1, SCINTILLA_COLOUR(255, 0, 0));
|
||||
m_DisassemblyView->markerDefine(BREAKPOINT_MARKER, SC_MARK_CIRCLE);
|
||||
m_DisassemblyView->markerDefine(BREAKPOINT_MARKER + 1, SC_MARK_BACKGROUND);
|
||||
|
||||
m_Scintillas.push_back(m_DisassemblyView);
|
||||
|
||||
m_DisassemblyFrame = new QWidget(this);
|
||||
@@ -355,7 +337,6 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR
|
||||
QObject::connect(m_DisassemblyView, &ScintillaEdit::buttonReleased, this,
|
||||
&ShaderViewer::disassembly_buttonReleased);
|
||||
|
||||
// suppress the built-in context menu and hook up our own
|
||||
if(trace)
|
||||
{
|
||||
if(m_Stage == ShaderStage::Vertex)
|
||||
@@ -371,14 +352,8 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR
|
||||
ANALYTIC_SET(ShaderDebug.Compute, true);
|
||||
}
|
||||
|
||||
m_DisassemblyView->usePopUp(SC_POPUP_NEVER);
|
||||
|
||||
m_DisassemblyFrame->layout()->removeWidget(m_DisassemblyToolbar);
|
||||
|
||||
m_DisassemblyView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
QObject::connect(m_DisassemblyView, &ScintillaEdit::customContextMenuRequested, this,
|
||||
&ShaderViewer::disassembly_contextMenu);
|
||||
|
||||
m_DisassemblyView->setMouseDwellTime(500);
|
||||
|
||||
QObject::connect(m_DisassemblyView, &ScintillaEdit::dwellStart, this,
|
||||
@@ -394,7 +369,7 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR
|
||||
else
|
||||
setWindowTitle(shader->entryPoint);
|
||||
|
||||
int fileIdx = 0;
|
||||
m_FileScintillas.reserve(shader->debugInfo.files.count());
|
||||
|
||||
QWidget *sel = NULL;
|
||||
for(const ShaderSourceFile &f : shader->debugInfo.files)
|
||||
@@ -407,7 +382,7 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR
|
||||
if(sel == NULL)
|
||||
sel = scintilla;
|
||||
|
||||
fileIdx++;
|
||||
m_FileScintillas.push_back(scintilla);
|
||||
}
|
||||
|
||||
if(trace || sel == NULL)
|
||||
@@ -491,14 +466,6 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR
|
||||
ui->locals->hide();
|
||||
}
|
||||
|
||||
m_DisassemblyView->setMarginWidthN(1, 20.0 * devicePixelRatioF());
|
||||
|
||||
// display current line in margin 2, distinct from breakpoint in margin 1
|
||||
sptr_t markMask = (1 << CURRENT_MARKER) | (1 << FINISHED_MARKER);
|
||||
|
||||
m_DisassemblyView->setMarginMaskN(1, m_DisassemblyView->marginMaskN(1) & ~markMask);
|
||||
m_DisassemblyView->setMarginMaskN(2, m_DisassemblyView->marginMaskN(2) | markMask);
|
||||
|
||||
QObject::connect(ui->stepBack, &QToolButton::clicked, this, &ShaderViewer::stepBack);
|
||||
QObject::connect(ui->stepNext, &QToolButton::clicked, this, &ShaderViewer::stepNext);
|
||||
QObject::connect(ui->runBack, &QToolButton::clicked, this, &ShaderViewer::runBack);
|
||||
@@ -507,19 +474,38 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR
|
||||
QObject::connect(ui->runToSample, &QToolButton::clicked, this, &ShaderViewer::runToSample);
|
||||
QObject::connect(ui->runToNaNOrInf, &QToolButton::clicked, this, &ShaderViewer::runToNanOrInf);
|
||||
|
||||
QObject::connect(new QShortcut(QKeySequence(Qt::Key_F10), m_DisassemblyView),
|
||||
&QShortcut::activated, this, &ShaderViewer::stepNext);
|
||||
QObject::connect(new QShortcut(QKeySequence(Qt::Key_F10 | Qt::ShiftModifier), m_DisassemblyView),
|
||||
for(ScintillaEdit *edit : m_Scintillas)
|
||||
{
|
||||
edit->setMarginWidthN(1, 20.0 * devicePixelRatioF());
|
||||
|
||||
// display current line in margin 2, distinct from breakpoint in margin 1
|
||||
sptr_t markMask = (1 << CURRENT_MARKER) | (1 << FINISHED_MARKER);
|
||||
|
||||
edit->setMarginMaskN(1, edit->marginMaskN(1) & ~markMask);
|
||||
edit->setMarginMaskN(2, edit->marginMaskN(2) | markMask);
|
||||
|
||||
// suppress the built-in context menu and hook up our own
|
||||
edit->usePopUp(SC_POPUP_NEVER);
|
||||
|
||||
edit->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
QObject::connect(edit, &ScintillaEdit::customContextMenuRequested, this,
|
||||
&ShaderViewer::debug_contextMenu);
|
||||
}
|
||||
|
||||
// register the shortcuts globally for this shader viewer so it works regardless of the active
|
||||
// scintilla
|
||||
QObject::connect(new QShortcut(QKeySequence(Qt::Key_F10), this), &QShortcut::activated, this,
|
||||
&ShaderViewer::stepNext);
|
||||
QObject::connect(new QShortcut(QKeySequence(Qt::Key_F10 | Qt::ShiftModifier), this),
|
||||
&QShortcut::activated, this, &ShaderViewer::stepBack);
|
||||
QObject::connect(
|
||||
new QShortcut(QKeySequence(Qt::Key_F10 | Qt::ControlModifier), m_DisassemblyView),
|
||||
&QShortcut::activated, this, &ShaderViewer::runToCursor);
|
||||
QObject::connect(new QShortcut(QKeySequence(Qt::Key_F5), m_DisassemblyView),
|
||||
&QShortcut::activated, this, &ShaderViewer::run);
|
||||
QObject::connect(new QShortcut(QKeySequence(Qt::Key_F5 | Qt::ShiftModifier), m_DisassemblyView),
|
||||
QObject::connect(new QShortcut(QKeySequence(Qt::Key_F10 | Qt::ControlModifier), this),
|
||||
&QShortcut::activated, this, &ShaderViewer::runToCursor);
|
||||
QObject::connect(new QShortcut(QKeySequence(Qt::Key_F5), this), &QShortcut::activated, this,
|
||||
&ShaderViewer::run);
|
||||
QObject::connect(new QShortcut(QKeySequence(Qt::Key_F5 | Qt::ShiftModifier), this),
|
||||
&QShortcut::activated, this, &ShaderViewer::runBack);
|
||||
QObject::connect(new QShortcut(QKeySequence(Qt::Key_F9), m_DisassemblyView),
|
||||
&QShortcut::activated, [this]() { ToggleBreakpoint(); });
|
||||
QObject::connect(new QShortcut(QKeySequence(Qt::Key_F9), this), &QShortcut::activated,
|
||||
[this]() { ToggleBreakpoint(); });
|
||||
|
||||
// event filter to pick up tooltip events
|
||||
ui->constants->installEventFilter(this);
|
||||
@@ -541,6 +527,8 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR
|
||||
}
|
||||
|
||||
ui->watch->resizeRowsToContents();
|
||||
|
||||
ToolWindowManager::raiseToolWindow(m_DisassemblyFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -641,6 +629,41 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR
|
||||
ui->docking->setToolWindowProperties(
|
||||
ui->outputSig, ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow);
|
||||
}
|
||||
|
||||
for(ScintillaEdit *edit : m_Scintillas)
|
||||
{
|
||||
// C# LightCoral
|
||||
edit->markerSetBack(CURRENT_MARKER, SCINTILLA_COLOUR(240, 128, 128));
|
||||
edit->markerSetBack(CURRENT_MARKER + 1, SCINTILLA_COLOUR(240, 128, 128));
|
||||
edit->markerDefine(CURRENT_MARKER, SC_MARK_SHORTARROW);
|
||||
edit->markerDefine(CURRENT_MARKER + 1, SC_MARK_BACKGROUND);
|
||||
edit->indicSetFore(CURRENT_INDICATOR, SCINTILLA_COLOUR(240, 128, 128));
|
||||
edit->indicSetAlpha(CURRENT_INDICATOR, 220);
|
||||
edit->indicSetOutlineAlpha(CURRENT_INDICATOR, 255);
|
||||
edit->indicSetUnder(CURRENT_INDICATOR, true);
|
||||
edit->indicSetStyle(CURRENT_INDICATOR, INDIC_STRAIGHTBOX);
|
||||
edit->indicSetHoverFore(CURRENT_INDICATOR, SCINTILLA_COLOUR(240, 128, 128));
|
||||
edit->indicSetHoverStyle(CURRENT_INDICATOR, INDIC_STRAIGHTBOX);
|
||||
|
||||
// C# LightSlateGray
|
||||
edit->markerSetBack(FINISHED_MARKER, SCINTILLA_COLOUR(119, 136, 153));
|
||||
edit->markerSetBack(FINISHED_MARKER + 1, SCINTILLA_COLOUR(119, 136, 153));
|
||||
edit->markerDefine(FINISHED_MARKER, SC_MARK_ROUNDRECT);
|
||||
edit->markerDefine(FINISHED_MARKER + 1, SC_MARK_BACKGROUND);
|
||||
edit->indicSetFore(FINISHED_INDICATOR, SCINTILLA_COLOUR(119, 136, 153));
|
||||
edit->indicSetAlpha(FINISHED_INDICATOR, 220);
|
||||
edit->indicSetOutlineAlpha(FINISHED_INDICATOR, 255);
|
||||
edit->indicSetUnder(FINISHED_INDICATOR, true);
|
||||
edit->indicSetStyle(FINISHED_INDICATOR, INDIC_STRAIGHTBOX);
|
||||
edit->indicSetHoverFore(FINISHED_INDICATOR, SCINTILLA_COLOUR(119, 136, 153));
|
||||
edit->indicSetHoverStyle(FINISHED_INDICATOR, INDIC_STRAIGHTBOX);
|
||||
|
||||
// C# Red
|
||||
edit->markerSetBack(BREAKPOINT_MARKER, SCINTILLA_COLOUR(255, 0, 0));
|
||||
edit->markerSetBack(BREAKPOINT_MARKER + 1, SCINTILLA_COLOUR(255, 0, 0));
|
||||
edit->markerDefine(BREAKPOINT_MARKER, SC_MARK_CIRCLE);
|
||||
edit->markerDefine(BREAKPOINT_MARKER + 1, SC_MARK_BACKGROUND);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderViewer::updateWindowTitle()
|
||||
@@ -793,12 +816,33 @@ void ShaderViewer::editable_keyPressed(QKeyEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderViewer::disassembly_contextMenu(const QPoint &pos)
|
||||
void ShaderViewer::debug_contextMenu(const QPoint &pos)
|
||||
{
|
||||
int scintillaPos = m_DisassemblyView->positionFromPoint(pos.x(), pos.y());
|
||||
ScintillaEdit *edit = qobject_cast<ScintillaEdit *>(QObject::sender());
|
||||
|
||||
bool isDisasm = (edit == m_DisassemblyView);
|
||||
|
||||
int scintillaPos = edit->positionFromPoint(pos.x(), pos.y());
|
||||
|
||||
QMenu contextMenu(this);
|
||||
|
||||
QAction gotoOther(isDisasm ? tr("Go to Source") : tr("Go to Disassembly"), this);
|
||||
|
||||
QObject::connect(&gotoOther, &QAction::triggered, [this, isDisasm]() {
|
||||
if(isDisasm && m_CurInstructionScintilla)
|
||||
{
|
||||
ToolWindowManager::raiseToolWindow(m_CurInstructionScintilla);
|
||||
m_CurInstructionScintilla->setFocus(Qt::MouseFocusReason);
|
||||
}
|
||||
else if(!isDisasm)
|
||||
{
|
||||
ToolWindowManager::raiseToolWindow(m_DisassemblyFrame);
|
||||
m_DisassemblyFrame->setFocus(Qt::MouseFocusReason);
|
||||
}
|
||||
|
||||
updateDebugging();
|
||||
});
|
||||
|
||||
QAction intDisplay(tr("Integer register display"), this);
|
||||
QAction floatDisplay(tr("Float register display"), this);
|
||||
|
||||
@@ -811,6 +855,12 @@ void ShaderViewer::disassembly_contextMenu(const QPoint &pos)
|
||||
QObject::connect(&intDisplay, &QAction::triggered, this, &ShaderViewer::on_intView_clicked);
|
||||
QObject::connect(&floatDisplay, &QAction::triggered, this, &ShaderViewer::on_floatView_clicked);
|
||||
|
||||
if(isDisasm && m_CurInstructionScintilla == NULL)
|
||||
gotoOther.setEnabled(false);
|
||||
|
||||
contextMenu.addAction(&gotoOther);
|
||||
contextMenu.addSeparator();
|
||||
|
||||
contextMenu.addAction(&intDisplay);
|
||||
contextMenu.addAction(&floatDisplay);
|
||||
contextMenu.addSeparator();
|
||||
@@ -831,22 +881,26 @@ void ShaderViewer::disassembly_contextMenu(const QPoint &pos)
|
||||
contextMenu.addAction(&runCursor);
|
||||
contextMenu.addSeparator();
|
||||
|
||||
if(!isDisasm)
|
||||
{
|
||||
addBreakpoint.setEnabled(false);
|
||||
runCursor.setEnabled(false);
|
||||
}
|
||||
|
||||
QAction copyText(tr("Copy"), this);
|
||||
QAction selectAll(tr("Select All"), this);
|
||||
|
||||
copyText.setEnabled(!m_DisassemblyView->selectionEmpty());
|
||||
copyText.setEnabled(!edit->selectionEmpty());
|
||||
|
||||
QObject::connect(©Text, &QAction::triggered, [this] {
|
||||
m_DisassemblyView->copyRange(m_DisassemblyView->selectionStart(),
|
||||
m_DisassemblyView->selectionEnd());
|
||||
});
|
||||
QObject::connect(&selectAll, &QAction::triggered, [this] { m_DisassemblyView->selectAll(); });
|
||||
QObject::connect(©Text, &QAction::triggered,
|
||||
[this, edit] { edit->copyRange(edit->selectionStart(), edit->selectionEnd()); });
|
||||
QObject::connect(&selectAll, &QAction::triggered, [this, edit] { edit->selectAll(); });
|
||||
|
||||
contextMenu.addAction(©Text);
|
||||
contextMenu.addAction(&selectAll);
|
||||
contextMenu.addSeparator();
|
||||
|
||||
RDDialog::show(&contextMenu, m_DisassemblyView->viewport()->mapToGlobal(pos));
|
||||
RDDialog::show(&contextMenu, edit->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void ShaderViewer::disassembly_buttonReleased(QMouseEvent *event)
|
||||
@@ -1015,7 +1069,36 @@ bool ShaderViewer::stepBack()
|
||||
if(CurrentStep() == 0)
|
||||
return false;
|
||||
|
||||
SetCurrentStep(CurrentStep() - 1);
|
||||
if(isSourceDebugging())
|
||||
{
|
||||
const ShaderDebugState &oldstate = m_Trace->states[CurrentStep()];
|
||||
|
||||
LineColumnInfo oldLine = m_Trace->lineInfo[oldstate.nextInstruction];
|
||||
|
||||
while(CurrentStep() < m_Trace->states.count())
|
||||
{
|
||||
m_CurrentStep--;
|
||||
|
||||
const ShaderDebugState &state = m_Trace->states[m_CurrentStep];
|
||||
|
||||
if(m_Breakpoints.contains((int)state.nextInstruction))
|
||||
break;
|
||||
|
||||
if(m_CurrentStep == 0)
|
||||
break;
|
||||
|
||||
if(m_Trace->lineInfo[state.nextInstruction] == oldLine)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
SetCurrentStep(CurrentStep());
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCurrentStep(CurrentStep() - 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1028,7 +1111,36 @@ bool ShaderViewer::stepNext()
|
||||
if(CurrentStep() + 1 >= m_Trace->states.count())
|
||||
return false;
|
||||
|
||||
SetCurrentStep(CurrentStep() + 1);
|
||||
if(isSourceDebugging())
|
||||
{
|
||||
const ShaderDebugState &oldstate = m_Trace->states[CurrentStep()];
|
||||
|
||||
LineColumnInfo oldLine = m_Trace->lineInfo[oldstate.nextInstruction];
|
||||
|
||||
while(CurrentStep() < m_Trace->states.count())
|
||||
{
|
||||
m_CurrentStep++;
|
||||
|
||||
const ShaderDebugState &state = m_Trace->states[m_CurrentStep];
|
||||
|
||||
if(m_Breakpoints.contains((int)state.nextInstruction))
|
||||
break;
|
||||
|
||||
if(m_CurrentStep + 1 >= m_Trace->states.count())
|
||||
break;
|
||||
|
||||
if(m_Trace->lineInfo[state.nextInstruction] == oldLine)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
SetCurrentStep(CurrentStep());
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCurrentStep(CurrentStep() + 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1244,6 +1356,18 @@ void ShaderViewer::updateDebugging()
|
||||
m_DisassemblyView->markerDeleteAll(FINISHED_MARKER);
|
||||
m_DisassemblyView->markerDeleteAll(FINISHED_MARKER + 1);
|
||||
|
||||
if(m_CurInstructionScintilla)
|
||||
{
|
||||
m_CurInstructionScintilla->markerDeleteAll(CURRENT_MARKER);
|
||||
m_CurInstructionScintilla->markerDeleteAll(CURRENT_MARKER + 1);
|
||||
m_CurInstructionScintilla->markerDeleteAll(FINISHED_MARKER);
|
||||
m_CurInstructionScintilla->markerDeleteAll(FINISHED_MARKER + 1);
|
||||
|
||||
m_CurInstructionScintilla->indicatorClearRange(0, m_CurInstructionScintilla->length());
|
||||
|
||||
m_CurInstructionScintilla = NULL;
|
||||
}
|
||||
|
||||
for(sptr_t i = 0; i < m_DisassemblyView->lineCount(); i++)
|
||||
{
|
||||
if(QString::fromUtf8(m_DisassemblyView->getLine(i).trimmed())
|
||||
@@ -1262,8 +1386,64 @@ void ShaderViewer::updateDebugging()
|
||||
|
||||
ui->callstack->clear();
|
||||
|
||||
for(const rdcstr &s : state.callstack)
|
||||
ui->callstack->insertItem(0, s);
|
||||
if(state.nextInstruction < m_Trace->lineInfo.size())
|
||||
{
|
||||
LineColumnInfo &lineInfo = m_Trace->lineInfo[state.nextInstruction];
|
||||
|
||||
for(const rdcstr &s : lineInfo.callstack)
|
||||
ui->callstack->insertItem(0, s);
|
||||
|
||||
if(lineInfo.fileIndex >= 0 && lineInfo.fileIndex < m_FileScintillas.count())
|
||||
{
|
||||
m_CurInstructionScintilla = m_FileScintillas[lineInfo.fileIndex];
|
||||
|
||||
for(sptr_t line = lineInfo.lineStart; line <= lineInfo.lineEnd; line++)
|
||||
{
|
||||
if(line == lineInfo.lineEnd)
|
||||
m_CurInstructionScintilla->markerAdd(line - 1, done ? FINISHED_MARKER : CURRENT_MARKER);
|
||||
|
||||
if(lineInfo.colStart == 0)
|
||||
{
|
||||
// with no column info, add a marker on the whole line
|
||||
m_CurInstructionScintilla->markerAdd(line - 1,
|
||||
done ? FINISHED_MARKER + 1 : CURRENT_MARKER + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise add an indicator on the column range.
|
||||
|
||||
// Start from the full position/length for this line
|
||||
sptr_t pos = m_CurInstructionScintilla->positionFromLine(line - 1);
|
||||
sptr_t len = m_CurInstructionScintilla->lineEndPosition(line - 1) - pos;
|
||||
|
||||
// if we're on the last line of the range, restrict the length to end on the last column
|
||||
if(line == lineInfo.lineEnd && lineInfo.colEnd != 0)
|
||||
len = lineInfo.colEnd;
|
||||
|
||||
// if we're on the start of the range (which may also be the last line above too), shift
|
||||
// inwards towards the first column
|
||||
if(line == lineInfo.lineStart)
|
||||
{
|
||||
pos += lineInfo.colStart - 1;
|
||||
len -= lineInfo.colStart - 1;
|
||||
}
|
||||
|
||||
m_CurInstructionScintilla->setIndicatorCurrent(done ? FINISHED_INDICATOR
|
||||
: CURRENT_INDICATOR);
|
||||
m_CurInstructionScintilla->indicatorFillRange(pos, len);
|
||||
}
|
||||
}
|
||||
|
||||
if(isSourceDebugging() ||
|
||||
ui->docking->areaOf(m_CurInstructionScintilla) != ui->docking->areaOf(m_DisassemblyFrame))
|
||||
ToolWindowManager::raiseToolWindow(m_CurInstructionScintilla);
|
||||
|
||||
int pos = m_CurInstructionScintilla->positionFromLine(lineInfo.lineStart - 1);
|
||||
m_CurInstructionScintilla->setSelection(pos, pos);
|
||||
|
||||
ensureLineScrolled(m_CurInstructionScintilla, lineInfo.lineStart - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(ui->constants->topLevelItemCount() == 0)
|
||||
{
|
||||
@@ -1707,7 +1887,7 @@ void ShaderViewer::ensureLineScrolled(ScintillaEdit *s, int line)
|
||||
int linesVisible = s->linesOnScreen();
|
||||
|
||||
if(s->isVisible() && (line < firstLine || line > (firstLine + linesVisible)))
|
||||
s->scrollCaret();
|
||||
s->setFirstVisibleLine(qMax(0, line - linesVisible / 2));
|
||||
}
|
||||
|
||||
int ShaderViewer::CurrentStep()
|
||||
@@ -2276,6 +2456,11 @@ void ShaderViewer::hideVariableTooltip()
|
||||
m_TooltipVarIdx = -1;
|
||||
}
|
||||
|
||||
bool ShaderViewer::isSourceDebugging()
|
||||
{
|
||||
return !m_DisassemblyFrame->isVisible();
|
||||
}
|
||||
|
||||
void ShaderViewer::on_findReplace_clicked()
|
||||
{
|
||||
if(m_FindReplace->isVisible())
|
||||
|
||||
@@ -117,7 +117,7 @@ private slots:
|
||||
// manual slots
|
||||
void readonly_keyPressed(QKeyEvent *event);
|
||||
void editable_keyPressed(QKeyEvent *event);
|
||||
void disassembly_contextMenu(const QPoint &pos);
|
||||
void debug_contextMenu(const QPoint &pos);
|
||||
void disassembly_buttonReleased(QMouseEvent *event);
|
||||
void disassemble_typeChanged(int index);
|
||||
void watch_keyPress(QKeyEvent *event);
|
||||
@@ -162,6 +162,8 @@ private:
|
||||
void updateVariableTooltip();
|
||||
void hideVariableTooltip();
|
||||
|
||||
bool isSourceDebugging();
|
||||
|
||||
VariableCategory m_TooltipVarCat = VariableCategory::Temporaries;
|
||||
int m_TooltipVarIdx = -1;
|
||||
int m_TooltipArrayIdx = -1;
|
||||
@@ -182,6 +184,9 @@ private:
|
||||
ScintillaEdit *m_FindResults = NULL;
|
||||
QList<ScintillaEdit *> m_Scintillas;
|
||||
|
||||
ScintillaEdit *m_CurInstructionScintilla = NULL;
|
||||
QList<ScintillaEdit *> m_FileScintillas;
|
||||
|
||||
FindReplace *m_FindReplace;
|
||||
|
||||
struct FindState
|
||||
@@ -211,6 +216,9 @@ private:
|
||||
static const int BREAKPOINT_MARKER = 2;
|
||||
static const int FINISHED_MARKER = 4;
|
||||
|
||||
static const int CURRENT_INDICATOR = 20;
|
||||
static const int FINISHED_INDICATOR = 21;
|
||||
|
||||
static const int INDICATOR_FINDRESULT = 0;
|
||||
static const int INDICATOR_REGHIGHLIGHT = 1;
|
||||
|
||||
|
||||
@@ -289,6 +289,61 @@ components are used). This list will have the same number of elements as :data:`
|
||||
};
|
||||
DECLARE_REFLECTION_STRUCT(LocalVariableMapping);
|
||||
|
||||
DOCUMENT("Details the current region of code that an instruction maps to");
|
||||
struct LineColumnInfo
|
||||
{
|
||||
DOCUMENT("");
|
||||
bool operator==(const LineColumnInfo &o) const
|
||||
{
|
||||
return fileIndex == o.fileIndex && lineStart == o.lineStart && lineEnd == o.lineEnd &&
|
||||
colStart == o.colStart && colEnd == o.colEnd && callstack == o.callstack;
|
||||
}
|
||||
bool operator<(const LineColumnInfo &o) const
|
||||
{
|
||||
if(!(fileIndex == o.fileIndex))
|
||||
return fileIndex < o.fileIndex;
|
||||
if(!(lineStart == o.lineStart))
|
||||
return lineStart < o.lineStart;
|
||||
if(!(lineEnd == o.lineEnd))
|
||||
return lineEnd < o.lineEnd;
|
||||
if(!(colStart == o.colStart))
|
||||
return colStart < o.colStart;
|
||||
if(!(colEnd == o.colEnd))
|
||||
return colEnd < o.colEnd;
|
||||
if(!(callstack == o.callstack))
|
||||
return callstack < o.callstack;
|
||||
return false;
|
||||
}
|
||||
|
||||
DOCUMENT("The current file, as an index into the list of files for this shader.");
|
||||
int32_t fileIndex = -1;
|
||||
|
||||
DOCUMENT("The line-number (starting from 1) of the start of the current section of code.");
|
||||
uint32_t lineStart = 0;
|
||||
|
||||
DOCUMENT("The line-number (starting from 1) of the end of the current section of code.");
|
||||
uint32_t lineEnd = 0;
|
||||
|
||||
DOCUMENT(R"(The column number (starting from 1) of the start of the code on the line specified by
|
||||
:data:`lineStart`. If set to 0, no column information is available and the whole lines should be
|
||||
treated as covering the code.
|
||||
)");
|
||||
uint32_t colStart = 0;
|
||||
|
||||
DOCUMENT(R"(The column number (starting from 1) of the end of the code on the line specified by
|
||||
:data:`lineEnd`. If set to 0, no column information is available and the whole lines should be
|
||||
treated as covering the code.
|
||||
)");
|
||||
uint32_t colEnd = 0;
|
||||
|
||||
DOCUMENT(R"(A ``list`` of ``str`` with each function call in the current callstack at this line.
|
||||
|
||||
The oldest/outer function is first in the list, the newest/inner function is last.
|
||||
)");
|
||||
rdcarray<rdcstr> callstack;
|
||||
};
|
||||
DECLARE_REFLECTION_STRUCT(LineColumnInfo);
|
||||
|
||||
DOCUMENT(R"(This stores the current state of shader debugging at one particular step in the shader,
|
||||
with all mutable variable contents.
|
||||
)");
|
||||
@@ -298,8 +353,7 @@ struct ShaderDebugState
|
||||
bool operator==(const ShaderDebugState &o) const
|
||||
{
|
||||
return registers == o.registers && outputs == o.outputs && indexableTemps == o.indexableTemps &&
|
||||
locals == o.locals && nextInstruction == o.nextInstruction && flags == o.flags &&
|
||||
callstack == o.callstack;
|
||||
locals == o.locals && nextInstruction == o.nextInstruction && flags == o.flags;
|
||||
}
|
||||
bool operator<(const ShaderDebugState &o) const
|
||||
{
|
||||
@@ -315,8 +369,6 @@ struct ShaderDebugState
|
||||
return nextInstruction < o.nextInstruction;
|
||||
if(!(flags == o.flags))
|
||||
return flags < o.flags;
|
||||
if(!(callstack == o.callstack))
|
||||
return callstack < o.callstack;
|
||||
return false;
|
||||
}
|
||||
DOCUMENT("The temporary variables for this shader as a list of :class:`ShaderVariable`.");
|
||||
@@ -332,9 +384,6 @@ to which registers, and their type
|
||||
)");
|
||||
rdcarray<LocalVariableMapping> locals;
|
||||
|
||||
DOCUMENT("An optional callstack listing function calls at the present instruction");
|
||||
rdcarray<rdcstr> callstack;
|
||||
|
||||
DOCUMENT(R"(The next instruction to be executed after this state. The initial state before any
|
||||
shader execution happened will have ``nextInstruction == 0``.
|
||||
)");
|
||||
@@ -368,6 +417,11 @@ instruction was executed
|
||||
|
||||
DOCUMENT("A flag indicating whether this trace has locals information");
|
||||
bool hasLocals = false;
|
||||
|
||||
DOCUMENT(R"(A ``list`` of :class:`LineColumnInfo` detailing which source lines each instruction
|
||||
corresponds to
|
||||
)");
|
||||
rdcarray<LineColumnInfo> lineInfo;
|
||||
};
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(ShaderDebugTrace);
|
||||
|
||||
@@ -940,8 +940,8 @@ ShaderDebugTrace D3D11Replay::DebugVertex(uint32_t eventId, uint32_t vertid, uin
|
||||
|
||||
vector<ShaderDebugState> states;
|
||||
|
||||
dxbc->m_DebugInfo->GetStack(0, dxbc->GetInstruction(0).offset, initialState.callstack);
|
||||
dxbc->m_DebugInfo->GetLocals(0, dxbc->GetInstruction(0).offset, initialState.locals);
|
||||
if(dxbc->m_DebugInfo)
|
||||
dxbc->m_DebugInfo->GetLocals(0, dxbc->GetInstruction(0).offset, initialState.locals);
|
||||
|
||||
states.push_back((State)initialState);
|
||||
|
||||
@@ -954,9 +954,9 @@ ShaderDebugTrace D3D11Replay::DebugVertex(uint32_t eventId, uint32_t vertid, uin
|
||||
|
||||
initialState = initialState.GetNext(global, NULL);
|
||||
|
||||
if(dxbc->m_DebugInfo)
|
||||
{
|
||||
const ASMOperation &op = dxbc->GetInstruction((size_t)initialState.nextInstruction);
|
||||
dxbc->m_DebugInfo->GetStack(initialState.nextInstruction, op.offset, initialState.callstack);
|
||||
dxbc->m_DebugInfo->GetLocals(initialState.nextInstruction, op.offset, initialState.locals);
|
||||
}
|
||||
|
||||
@@ -971,7 +971,14 @@ ShaderDebugTrace D3D11Replay::DebugVertex(uint32_t eventId, uint32_t vertid, uin
|
||||
|
||||
ret.states = states;
|
||||
|
||||
ret.hasLocals = dxbc->m_DebugInfo->HasLocals();
|
||||
ret.hasLocals = dxbc->m_DebugInfo && dxbc->m_DebugInfo->HasLocals();
|
||||
|
||||
ret.lineInfo.resize(dxbc->GetNumInstructions());
|
||||
for(size_t i = 0; i < dxbc->GetNumInstructions(); i++)
|
||||
{
|
||||
const ASMOperation &op = dxbc->GetInstruction(i);
|
||||
dxbc->m_DebugInfo->GetLineInfo(i, op.offset, ret.lineInfo[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1821,8 +1828,8 @@ ShaderDebugTrace D3D11Replay::DebugPixel(uint32_t eventId, uint32_t x, uint32_t
|
||||
|
||||
vector<ShaderDebugState> states;
|
||||
|
||||
dxbc->m_DebugInfo->GetStack(0, dxbc->GetInstruction(0).offset, quad[destIdx].callstack);
|
||||
dxbc->m_DebugInfo->GetLocals(0, dxbc->GetInstruction(0).offset, quad[destIdx].locals);
|
||||
if(dxbc->m_DebugInfo)
|
||||
dxbc->m_DebugInfo->GetLocals(0, dxbc->GetInstruction(0).offset, quad[destIdx].locals);
|
||||
|
||||
states.push_back((State)quad[destIdx]);
|
||||
|
||||
@@ -1860,9 +1867,9 @@ ShaderDebugTrace D3D11Replay::DebugPixel(uint32_t eventId, uint32_t x, uint32_t
|
||||
{
|
||||
State &s = curquad[destIdx];
|
||||
|
||||
if(dxbc->m_DebugInfo)
|
||||
{
|
||||
const ASMOperation &op = dxbc->GetInstruction((size_t)s.nextInstruction);
|
||||
dxbc->m_DebugInfo->GetStack(s.nextInstruction, op.offset, s.callstack);
|
||||
dxbc->m_DebugInfo->GetLocals(s.nextInstruction, op.offset, s.locals);
|
||||
}
|
||||
|
||||
@@ -1959,7 +1966,14 @@ ShaderDebugTrace D3D11Replay::DebugPixel(uint32_t eventId, uint32_t x, uint32_t
|
||||
|
||||
traces[destIdx].states = states;
|
||||
|
||||
traces[destIdx].hasLocals = dxbc->m_DebugInfo->HasLocals();
|
||||
traces[destIdx].hasLocals = dxbc->m_DebugInfo && dxbc->m_DebugInfo->HasLocals();
|
||||
|
||||
traces[destIdx].lineInfo.resize(dxbc->GetNumInstructions());
|
||||
for(size_t i = 0; i < dxbc->GetNumInstructions(); i++)
|
||||
{
|
||||
const ASMOperation &op = dxbc->GetInstruction(i);
|
||||
dxbc->m_DebugInfo->GetLineInfo(i, op.offset, traces[destIdx].lineInfo[i]);
|
||||
}
|
||||
|
||||
return traces[destIdx];
|
||||
}
|
||||
@@ -2018,8 +2032,8 @@ ShaderDebugTrace D3D11Replay::DebugThread(uint32_t eventId, const uint32_t group
|
||||
|
||||
vector<ShaderDebugState> states;
|
||||
|
||||
dxbc->m_DebugInfo->GetStack(0, dxbc->GetInstruction(0).offset, initialState.callstack);
|
||||
dxbc->m_DebugInfo->GetLocals(0, dxbc->GetInstruction(0).offset, initialState.locals);
|
||||
if(dxbc->m_DebugInfo)
|
||||
dxbc->m_DebugInfo->GetLocals(0, dxbc->GetInstruction(0).offset, initialState.locals);
|
||||
|
||||
states.push_back((State)initialState);
|
||||
|
||||
@@ -2030,9 +2044,9 @@ ShaderDebugTrace D3D11Replay::DebugThread(uint32_t eventId, const uint32_t group
|
||||
|
||||
initialState = initialState.GetNext(global, NULL);
|
||||
|
||||
if(dxbc->m_DebugInfo)
|
||||
{
|
||||
const ASMOperation &op = dxbc->GetInstruction((size_t)initialState.nextInstruction);
|
||||
dxbc->m_DebugInfo->GetStack(initialState.nextInstruction, op.offset, initialState.callstack);
|
||||
dxbc->m_DebugInfo->GetLocals(initialState.nextInstruction, op.offset, initialState.locals);
|
||||
}
|
||||
|
||||
@@ -2047,7 +2061,14 @@ ShaderDebugTrace D3D11Replay::DebugThread(uint32_t eventId, const uint32_t group
|
||||
|
||||
ret.states = states;
|
||||
|
||||
ret.hasLocals = dxbc->m_DebugInfo->HasLocals();
|
||||
ret.hasLocals = dxbc->m_DebugInfo && dxbc->m_DebugInfo->HasLocals();
|
||||
|
||||
ret.lineInfo.resize(dxbc->GetNumInstructions());
|
||||
for(size_t i = 0; i < dxbc->GetNumInstructions(); i++)
|
||||
{
|
||||
const ASMOperation &op = dxbc->GetInstruction(i);
|
||||
dxbc->m_DebugInfo->GetLineInfo(i, op.offset, ret.lineInfo[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -665,9 +665,7 @@ void DXBCFile::MakeDisassemblyString()
|
||||
}
|
||||
}
|
||||
|
||||
int32_t prevFile = -1;
|
||||
int32_t prevLine = -1;
|
||||
std::string prevFunc;
|
||||
LineColumnInfo prevLineInfo;
|
||||
|
||||
size_t debugInst = 0;
|
||||
|
||||
@@ -694,27 +692,33 @@ void DXBCFile::MakeDisassemblyString()
|
||||
|
||||
if(m_DebugInfo)
|
||||
{
|
||||
int32_t fileID = prevFile;
|
||||
int32_t lineNum = prevLine;
|
||||
std::string func = prevFunc;
|
||||
LineColumnInfo lineInfo = prevLineInfo;
|
||||
|
||||
m_DebugInfo->GetLineInfo(debugInst, m_Instructions[i].offset, fileID, lineNum, func);
|
||||
m_DebugInfo->GetLineInfo(debugInst, m_Instructions[i].offset, lineInfo);
|
||||
|
||||
if(fileID >= 0 && lineNum >= 0 && (fileID != prevFile || lineNum != prevLine))
|
||||
if(lineInfo.fileIndex >= 0 && lineInfo.lineStart >= 0 &&
|
||||
(lineInfo.fileIndex != prevLineInfo.fileIndex ||
|
||||
lineInfo.lineStart != prevLineInfo.lineStart))
|
||||
{
|
||||
string line = "";
|
||||
if(fileID >= (int32_t)fileLines.size())
|
||||
if(lineInfo.fileIndex >= (int32_t)fileLines.size())
|
||||
{
|
||||
line = "Unknown file";
|
||||
}
|
||||
else if(fileLines[fileID].empty())
|
||||
else if(fileLines[lineInfo.fileIndex].empty())
|
||||
{
|
||||
line = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
int32_t lineIdx = RDCMIN(lineNum, (int32_t)fileLines[fileID].size() - 1);
|
||||
line = fileLines[fileID][lineIdx];
|
||||
std::vector<std::string> &lines = fileLines[lineInfo.fileIndex];
|
||||
|
||||
int32_t lineIdx = RDCMIN(lineInfo.lineStart, (uint32_t)lines.size() - 1);
|
||||
|
||||
// line numbers are 1-based but we want a 0-based index
|
||||
if(lineIdx > 0)
|
||||
lineIdx--;
|
||||
line = lines[lineIdx];
|
||||
}
|
||||
|
||||
size_t startLine = line.find_first_not_of(" \t");
|
||||
@@ -724,23 +728,27 @@ void DXBCFile::MakeDisassemblyString()
|
||||
|
||||
m_Disassembly += "\n";
|
||||
|
||||
if(((fileID != prevFile || func != prevFunc) && fileID < (int32_t)fileLines.size()) ||
|
||||
if(((lineInfo.fileIndex != prevLineInfo.fileIndex ||
|
||||
lineInfo.callstack.back() != prevLineInfo.callstack.back()) &&
|
||||
lineInfo.fileIndex < (int32_t)fileLines.size()) ||
|
||||
line == "")
|
||||
{
|
||||
m_Disassembly += " "; // "0000: "
|
||||
for(int in = 0; in < indent; in++)
|
||||
m_Disassembly += " ";
|
||||
|
||||
std::string func = lineInfo.callstack.back();
|
||||
|
||||
if(!func.empty())
|
||||
{
|
||||
m_Disassembly +=
|
||||
StringFormat::Fmt("%s:%d - %s()\n", m_DebugInfo->Files[fileID].first.c_str(),
|
||||
lineNum + 1, func.c_str());
|
||||
m_Disassembly += StringFormat::Fmt("%s:%d - %s()\n",
|
||||
m_DebugInfo->Files[lineInfo.fileIndex].first.c_str(),
|
||||
lineInfo.lineStart, func.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Disassembly +=
|
||||
StringFormat::Fmt("%s:%d\n", m_DebugInfo->Files[fileID].first.c_str(), lineNum + 1);
|
||||
m_Disassembly += StringFormat::Fmt(
|
||||
"%s:%d\n", m_DebugInfo->Files[lineInfo.fileIndex].first.c_str(), lineInfo.lineStart);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -753,9 +761,7 @@ void DXBCFile::MakeDisassemblyString()
|
||||
}
|
||||
}
|
||||
|
||||
prevFile = fileID;
|
||||
prevLine = lineNum;
|
||||
prevFunc = func;
|
||||
prevLineInfo = lineInfo;
|
||||
}
|
||||
|
||||
char buf[64] = {0};
|
||||
|
||||
@@ -330,9 +330,7 @@ public:
|
||||
|
||||
vector<pair<string, string> > Files; // <filename, source>
|
||||
|
||||
virtual void GetLineInfo(size_t instruction, uintptr_t offset, int32_t &fileIdx, int32_t &lineNum,
|
||||
std::string &funcName) const = 0;
|
||||
virtual void GetStack(size_t instruction, uintptr_t offset, rdcarray<rdcstr> &stack) const = 0;
|
||||
virtual void GetLineInfo(size_t instruction, uintptr_t offset, LineColumnInfo &lineInfo) const = 0;
|
||||
|
||||
virtual bool HasLocals() const = 0;
|
||||
virtual void GetLocals(size_t instruction, uintptr_t offset,
|
||||
|
||||
@@ -98,8 +98,7 @@ SDBGChunk::SDBGChunk(void *data)
|
||||
m_HasDebugInfo = true;
|
||||
}
|
||||
|
||||
void SDBGChunk::GetLineInfo(size_t instruction, uintptr_t offset, int32_t &fileIdx,
|
||||
int32_t &lineNum, std::string &func) const
|
||||
void SDBGChunk::GetLineInfo(size_t instruction, uintptr_t offset, LineColumnInfo &lineInfo) const
|
||||
{
|
||||
if(instruction < m_Instructions.size())
|
||||
{
|
||||
@@ -108,18 +107,16 @@ void SDBGChunk::GetLineInfo(size_t instruction, uintptr_t offset, int32_t &fileI
|
||||
{
|
||||
const SDBGSymbol &sym = m_SymbolTable[symID];
|
||||
|
||||
fileIdx = sym.fileID;
|
||||
lineNum = sym.lineNum - 1;
|
||||
func = m_Entry;
|
||||
lineInfo.fileIndex = sym.fileID;
|
||||
lineInfo.lineStart = sym.lineNum;
|
||||
lineInfo.lineEnd = sym.lineNum;
|
||||
lineInfo.colStart = 0;
|
||||
lineInfo.colEnd = 0;
|
||||
lineInfo.callstack = {m_Entry};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SDBGChunk::GetStack(size_t instruction, uintptr_t offset, rdcarray<rdcstr> &stack) const
|
||||
{
|
||||
stack = {"Stack not available"};
|
||||
}
|
||||
|
||||
bool SDBGChunk::HasLocals() const
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -260,9 +260,7 @@ public:
|
||||
string GetEntryFunction() const { return m_Entry; }
|
||||
string GetShaderProfile() const { return m_Profile; }
|
||||
uint32_t GetShaderCompileFlags() const { return m_ShaderFlags; }
|
||||
void GetLineInfo(size_t instruction, uintptr_t offset, int32_t &fileIdx, int32_t &lineNum,
|
||||
std::string &func) const;
|
||||
void GetStack(size_t instruction, uintptr_t offset, rdcarray<rdcstr> &stack) const;
|
||||
void GetLineInfo(size_t instruction, uintptr_t offset, LineColumnInfo &lineInfo) const;
|
||||
|
||||
bool HasLocals() const;
|
||||
void GetLocals(size_t instruction, uintptr_t offset, rdcarray<LocalVariableMapping> &locals) const;
|
||||
|
||||
@@ -1257,7 +1257,6 @@ SPDBChunk::SPDBChunk(void *chunk)
|
||||
lineCol.fileIndex = fileIdx;
|
||||
lineCol.lineStart = line.linenumStart;
|
||||
lineCol.lineEnd = line.linenumStart + line.deltaLineEnd;
|
||||
lineCol.statement = line.fStatement;
|
||||
|
||||
if(hasColumns)
|
||||
{
|
||||
@@ -1313,7 +1312,7 @@ SPDBChunk::SPDBChunk(void *chunk)
|
||||
}
|
||||
|
||||
for(auto it = m_Lines.begin(); it != m_Lines.end(); ++it)
|
||||
it->second.stack.push_back(m_Functions[0].name);
|
||||
it->second.callstack.push_back(m_Functions[0].name);
|
||||
|
||||
SPDBLOG("Applying %zu inline sites", inlines.size());
|
||||
|
||||
@@ -1360,12 +1359,11 @@ SPDBChunk::SPDBChunk(void *chunk)
|
||||
loc.lineEnd + inlines[i].baseLineNum, loc.colEnd);
|
||||
|
||||
it->second.fileIndex = fileIdx;
|
||||
it->second.funcIndex = inlines[i].id;
|
||||
it->second.lineStart = loc.lineStart + inlines[i].baseLineNum;
|
||||
it->second.lineEnd = loc.lineEnd + inlines[i].baseLineNum;
|
||||
it->second.colStart = loc.colStart;
|
||||
it->second.colEnd = loc.colEnd;
|
||||
it->second.stack.push_back(m_Functions[inlines[i].id].name);
|
||||
it->second.callstack.push_back(m_Functions[inlines[i].id].name);
|
||||
nPatched++;
|
||||
}
|
||||
}
|
||||
@@ -1428,29 +1426,12 @@ SPDBChunk::SPDBChunk(void *chunk)
|
||||
m_HasDebugInfo = true;
|
||||
}
|
||||
|
||||
void SPDBChunk::GetLineInfo(size_t instruction, uintptr_t offset, int32_t &fileIdx,
|
||||
int32_t &lineNum, std::string &func) const
|
||||
void SPDBChunk::GetLineInfo(size_t instruction, uintptr_t offset, LineColumnInfo &lineInfo) const
|
||||
{
|
||||
auto it = m_Lines.lower_bound((uint32_t)offset);
|
||||
|
||||
if(it != m_Lines.end() && (uintptr_t)it->first <= offset)
|
||||
{
|
||||
fileIdx = it->second.fileIndex;
|
||||
lineNum = it->second.lineStart - 1; // 0-indexed
|
||||
func = it->second.stack.back();
|
||||
}
|
||||
}
|
||||
|
||||
void SPDBChunk::GetStack(size_t instruction, uintptr_t offset, rdcarray<rdcstr> &stack) const
|
||||
{
|
||||
auto it = m_Lines.lower_bound((uint32_t)offset);
|
||||
|
||||
if(it != m_Lines.end() && (uintptr_t)it->first <= offset)
|
||||
{
|
||||
stack.resize(it->second.stack.size());
|
||||
for(size_t i = 0; i < stack.size(); i++)
|
||||
stack[i] = it->second.stack[i];
|
||||
}
|
||||
lineInfo = it->second;
|
||||
}
|
||||
|
||||
bool SPDBChunk::HasLocals() const
|
||||
|
||||
@@ -205,17 +205,6 @@ struct FileChecksum
|
||||
uint8_t hashData[1];
|
||||
};
|
||||
|
||||
struct LineColumnInfo
|
||||
{
|
||||
int32_t fileIndex = -1;
|
||||
uint32_t funcIndex = 0;
|
||||
uint32_t lineStart = 0, lineEnd = 0;
|
||||
uint32_t colStart = 0, colEnd = 0;
|
||||
bool statement = true;
|
||||
|
||||
std::vector<std::string> stack;
|
||||
};
|
||||
|
||||
struct InstructionLocation
|
||||
{
|
||||
bool statement = true;
|
||||
@@ -278,9 +267,7 @@ public:
|
||||
std::string GetEntryFunction() const { return m_Entry; }
|
||||
std::string GetShaderProfile() const { return m_Profile; }
|
||||
uint32_t GetShaderCompileFlags() const { return m_ShaderFlags; }
|
||||
void GetLineInfo(size_t instruction, uintptr_t offset, int32_t &fileIdx, int32_t &lineNum,
|
||||
std::string &func) const;
|
||||
void GetStack(size_t instruction, uintptr_t offset, rdcarray<rdcstr> &stack) const;
|
||||
void GetLineInfo(size_t instruction, uintptr_t offset, LineColumnInfo &lineInfo) const;
|
||||
|
||||
bool HasLocals() const;
|
||||
void GetLocals(size_t instruction, uintptr_t offset, rdcarray<LocalVariableMapping> &locals) const;
|
||||
|
||||
@@ -354,6 +354,19 @@ void DoSerialise(SerialiserType &ser, LocalVariableMapping &el)
|
||||
SIZE_CHECK(40);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, LineColumnInfo &el)
|
||||
{
|
||||
SERIALISE_MEMBER(fileIndex);
|
||||
SERIALISE_MEMBER(lineStart);
|
||||
SERIALISE_MEMBER(lineEnd);
|
||||
SERIALISE_MEMBER(colStart);
|
||||
SERIALISE_MEMBER(colEnd);
|
||||
SERIALISE_MEMBER(callstack);
|
||||
|
||||
SIZE_CHECK(40);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, ShaderDebugState &el)
|
||||
{
|
||||
@@ -363,9 +376,8 @@ void DoSerialise(SerialiserType &ser, ShaderDebugState &el)
|
||||
SERIALISE_MEMBER(locals);
|
||||
SERIALISE_MEMBER(nextInstruction);
|
||||
SERIALISE_MEMBER(flags);
|
||||
SERIALISE_MEMBER(callstack);
|
||||
|
||||
SIZE_CHECK(88);
|
||||
SIZE_CHECK(72);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
@@ -375,8 +387,9 @@ void DoSerialise(SerialiserType &ser, ShaderDebugTrace &el)
|
||||
SERIALISE_MEMBER(constantBlocks);
|
||||
SERIALISE_MEMBER(states);
|
||||
SERIALISE_MEMBER(hasLocals);
|
||||
SERIALISE_MEMBER(lineInfo);
|
||||
|
||||
SIZE_CHECK(56);
|
||||
SIZE_CHECK(72);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
|
||||
Reference in New Issue
Block a user