mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 17:10:47 +00:00
Add watch variables handling to qt shader viewer
This commit is contained in:
@@ -405,6 +405,20 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR
|
||||
&QShortcut::activated, [this]() { ToggleBreakpoint(); });
|
||||
|
||||
SetCurrentStep(0);
|
||||
|
||||
QObject::connect(ui->watch, &RDTableWidget::keyPress, this, &ShaderViewer::watch_keyPress);
|
||||
|
||||
ui->watch->insertRow(0);
|
||||
|
||||
for(int i = 0; i < ui->watch->columnCount(); i++)
|
||||
{
|
||||
QTableWidgetItem *item = new QTableWidgetItem();
|
||||
if(i > 0)
|
||||
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
|
||||
ui->watch->setItem(0, i, item);
|
||||
}
|
||||
|
||||
ui->watch->resizeRowsToContents();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -675,6 +689,58 @@ void ShaderViewer::disassembly_contextMenu(const QPoint &pos)
|
||||
RDDialog::show(&contextMenu, m_DisassemblyView->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void ShaderViewer::watch_keyPress(QKeyEvent *event)
|
||||
{
|
||||
if(event->key() == Qt::Key_Delete || event->key() == Qt::Key_Backspace)
|
||||
{
|
||||
QList<QTableWidgetItem *> items = ui->watch->selectedItems();
|
||||
if(!items.isEmpty() && items.back()->row() < ui->watch->rowCount() - 1)
|
||||
ui->watch->removeRow(items.back()->row());
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderViewer::on_watch_itemChanged(QTableWidgetItem *item)
|
||||
{
|
||||
// ignore changes to the type/value columns. Only look at name changes, which must be by the user
|
||||
if(item->column() != 0)
|
||||
return;
|
||||
|
||||
static bool recurse = false;
|
||||
|
||||
if(recurse)
|
||||
return;
|
||||
|
||||
recurse = true;
|
||||
|
||||
// if the item is now empty, remove it
|
||||
if(item->text().isEmpty())
|
||||
ui->watch->removeRow(item->row());
|
||||
|
||||
// ensure we have a trailing row for adding new watch items.
|
||||
|
||||
if(ui->watch->rowCount() == 0 || ui->watch->item(ui->watch->rowCount() - 1, 0) == NULL ||
|
||||
!ui->watch->item(ui->watch->rowCount() - 1, 0)->text().isEmpty())
|
||||
{
|
||||
// add a new row if needed
|
||||
if(ui->watch->rowCount() == 0 || ui->watch->item(ui->watch->rowCount() - 1, 0) != NULL)
|
||||
ui->watch->insertRow(ui->watch->rowCount());
|
||||
|
||||
for(int i = 0; i < ui->watch->columnCount(); i++)
|
||||
{
|
||||
QTableWidgetItem *newItem = new QTableWidgetItem();
|
||||
if(i > 0)
|
||||
newItem->setFlags(newItem->flags() & ~Qt::ItemIsEditable);
|
||||
ui->watch->setItem(ui->watch->rowCount() - 1, i, newItem);
|
||||
}
|
||||
}
|
||||
|
||||
ui->watch->resizeRowsToContents();
|
||||
|
||||
recurse = false;
|
||||
|
||||
updateDebugging();
|
||||
}
|
||||
|
||||
bool ShaderViewer::stepBack()
|
||||
{
|
||||
if(!m_Trace)
|
||||
@@ -1082,7 +1148,145 @@ void ShaderViewer::updateDebugging()
|
||||
|
||||
ui->variables->setUpdatesEnabled(true);
|
||||
|
||||
// TODO watch registers
|
||||
ui->watch->setUpdatesEnabled(false);
|
||||
|
||||
for(int i = 0; i < ui->watch->rowCount() - 1; i++)
|
||||
{
|
||||
QTableWidgetItem *item = ui->watch->item(i, 0);
|
||||
ui->watch->setItem(i, 1, new QTableWidgetItem(tr("register", "watch type")));
|
||||
|
||||
QString reg = item->text().trimmed();
|
||||
|
||||
QRegularExpression regexp(lit("^([rvo])([0-9]+)(\\.[xyzwrgba]+)?(,[xfiudb])?$"));
|
||||
|
||||
QRegularExpressionMatch match = regexp.match(reg);
|
||||
|
||||
// try indexable temps
|
||||
if(!match.hasMatch())
|
||||
{
|
||||
regexp = QRegularExpression(lit("^(x[0-9]+)\\[([0-9]+)\\](\\.[xyzwrgba]+)?(,[xfiudb])?$"));
|
||||
|
||||
match = regexp.match(reg);
|
||||
}
|
||||
|
||||
if(match.hasMatch())
|
||||
{
|
||||
QString regtype = match.captured(1);
|
||||
QString regidx = match.captured(2);
|
||||
QString swizzle = match.captured(3).replace(QLatin1Char('.'), QString());
|
||||
QString regcast = match.captured(4).replace(QLatin1Char(','), QString());
|
||||
|
||||
if(regcast.isEmpty())
|
||||
{
|
||||
if(ui->intView->isChecked())
|
||||
regcast = lit("i");
|
||||
else
|
||||
regcast = lit("f");
|
||||
}
|
||||
|
||||
const rdctype::array<ShaderVariable> *vars = NULL;
|
||||
|
||||
bool ok = false;
|
||||
|
||||
if(regtype == lit("r"))
|
||||
{
|
||||
vars = &state.registers;
|
||||
}
|
||||
else if(regtype == lit("v"))
|
||||
{
|
||||
vars = &m_Trace->inputs;
|
||||
}
|
||||
else if(regtype == lit("o"))
|
||||
{
|
||||
vars = &state.outputs;
|
||||
}
|
||||
else if(regtype[0] == QLatin1Char('x'))
|
||||
{
|
||||
QString tempArrayIndexStr = regtype.mid(1);
|
||||
int tempArrayIndex = tempArrayIndexStr.toInt(&ok);
|
||||
|
||||
if(ok && tempArrayIndex >= 0 && tempArrayIndex < state.indexableTemps.count)
|
||||
{
|
||||
vars = &state.indexableTemps[tempArrayIndex];
|
||||
}
|
||||
}
|
||||
|
||||
ok = false;
|
||||
int regindex = regidx.toInt(&ok);
|
||||
|
||||
if(vars && ok && regindex >= 0 && regindex < vars->count)
|
||||
{
|
||||
const ShaderVariable &vr = vars->elems[regindex];
|
||||
|
||||
if(swizzle.isEmpty())
|
||||
{
|
||||
swizzle = lit("xyzw").left((int)vr.columns);
|
||||
|
||||
if(regcast == lit("d") && swizzle.count() > 2)
|
||||
swizzle = lit("xy");
|
||||
}
|
||||
|
||||
QString val;
|
||||
|
||||
for(int s = 0; s < swizzle.count(); s++)
|
||||
{
|
||||
QChar swiz = swizzle[s];
|
||||
|
||||
int elindex = 0;
|
||||
if(swiz == QLatin1Char('x') || swiz == QLatin1Char('r'))
|
||||
elindex = 0;
|
||||
if(swiz == QLatin1Char('y') || swiz == QLatin1Char('g'))
|
||||
elindex = 1;
|
||||
if(swiz == QLatin1Char('z') || swiz == QLatin1Char('b'))
|
||||
elindex = 2;
|
||||
if(swiz == QLatin1Char('w') || swiz == QLatin1Char('a'))
|
||||
elindex = 3;
|
||||
|
||||
if(regcast == lit("i"))
|
||||
{
|
||||
val += Formatter::Format(vr.value.iv[elindex]);
|
||||
}
|
||||
else if(regcast == lit("f"))
|
||||
{
|
||||
val += Formatter::Format(vr.value.fv[elindex]);
|
||||
}
|
||||
else if(regcast == lit("u"))
|
||||
{
|
||||
val += Formatter::Format(vr.value.uv[elindex]);
|
||||
}
|
||||
else if(regcast == lit("x"))
|
||||
{
|
||||
val += Formatter::Format(vr.value.uv[elindex], true);
|
||||
}
|
||||
else if(regcast == lit("b"))
|
||||
{
|
||||
val += QFormatStr("%1").arg(vr.value.uv[elindex], 32, 2, QLatin1Char('0'));
|
||||
}
|
||||
else if(regcast == lit("d"))
|
||||
{
|
||||
if(elindex < 2)
|
||||
val += Formatter::Format(vr.value.dv[elindex]);
|
||||
else
|
||||
val += lit("-");
|
||||
}
|
||||
|
||||
if(s < swizzle.count() - 1)
|
||||
val += lit(", ");
|
||||
}
|
||||
|
||||
item = new QTableWidgetItem(val);
|
||||
item->setData(Qt::UserRole, QVariant::fromValue(vr));
|
||||
|
||||
ui->watch->setItem(i, 2, item);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ui->watch->setItem(i, 2, new QTableWidgetItem(tr("Error evaluating expression")));
|
||||
}
|
||||
|
||||
ui->watch->setUpdatesEnabled(true);
|
||||
}
|
||||
|
||||
void ShaderViewer::ensureLineScrolled(ScintillaEdit *s, int line)
|
||||
|
||||
@@ -38,6 +38,7 @@ struct ShaderDebugTrace;
|
||||
struct ShaderReflection;
|
||||
class ScintillaEdit;
|
||||
class FindReplace;
|
||||
class QTableWidgetItem;
|
||||
|
||||
// from Scintilla
|
||||
typedef intptr_t sptr_t;
|
||||
@@ -98,10 +99,13 @@ private slots:
|
||||
void on_intView_clicked();
|
||||
void on_floatView_clicked();
|
||||
|
||||
void on_watch_itemChanged(QTableWidgetItem *item);
|
||||
|
||||
// manual slots
|
||||
void readonly_keyPressed(QKeyEvent *event);
|
||||
void editable_keyPressed(QKeyEvent *event);
|
||||
void disassembly_contextMenu(const QPoint &pos);
|
||||
void watch_keyPress(QKeyEvent *event);
|
||||
void performFind();
|
||||
void performFindAll();
|
||||
void performReplace();
|
||||
|
||||
@@ -430,6 +430,21 @@
|
||||
<height>131</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderHighlightSections">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
|
||||
Reference in New Issue
Block a user