mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-07 15:20:58 +00:00
Display source variables mapped to OpUndef as <undefined value>
* Undefined values are still 0xccccccccc, since that value can propagate through operations. But source variables mapped directly to an OpUndef are displayed in a more semantically clear way.
This commit is contained in:
@@ -3415,7 +3415,8 @@ QString ShaderViewer::getRegNames(const RDTreeWidgetItem *item, uint32_t swizzle
|
||||
}
|
||||
|
||||
const RDTreeWidgetItem *ShaderViewer::evaluateVar(const RDTreeWidgetItem *item, uint32_t swizzle,
|
||||
ShaderVariable *var)
|
||||
ShaderVariable *var,
|
||||
SourceVariableMapping *mappingPtr)
|
||||
{
|
||||
VariableTag tag = item->tag().value<VariableTag>();
|
||||
|
||||
@@ -3528,13 +3529,16 @@ const RDTreeWidgetItem *ShaderViewer::evaluateVar(const RDTreeWidgetItem *item,
|
||||
for(int i = 0; i < item->childCount(); i++)
|
||||
{
|
||||
ret.members.push_back(ShaderVariable());
|
||||
if(!evaluateVar(item->child(i), ~0U, &ret.members.back()))
|
||||
if(!evaluateVar(item->child(i), ~0U, &ret.members.back(), NULL))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
if(mappingPtr)
|
||||
*mappingPtr = mapping;
|
||||
|
||||
if(mapping.variables.empty())
|
||||
return NULL;
|
||||
|
||||
@@ -3575,6 +3579,9 @@ const RDTreeWidgetItem *ShaderViewer::evaluateVar(const RDTreeWidgetItem *item,
|
||||
}
|
||||
}
|
||||
|
||||
if(mappingPtr)
|
||||
*mappingPtr = mapping;
|
||||
|
||||
ShaderVariable &ret = *var;
|
||||
ret.name = mapping.name;
|
||||
ret.flags |= ShaderVariableFlags::RowMajorMatrix;
|
||||
@@ -3649,14 +3656,15 @@ const RDTreeWidgetItem *ShaderViewer::evaluateVar(const RDTreeWidgetItem *item,
|
||||
}
|
||||
|
||||
const RDTreeWidgetItem *ShaderViewer::getVarFromPath(const rdcstr &path, const RDTreeWidgetItem *root,
|
||||
ShaderVariable *var, uint32_t *swizzlePtr)
|
||||
ShaderVariable *var, uint32_t *swizzlePtr,
|
||||
SourceVariableMapping *mappingPtr)
|
||||
{
|
||||
VariableTag tag = root->tag().value<VariableTag>();
|
||||
|
||||
// if the path is an exact match, return the evaluation directly
|
||||
if(tag.absoluteRefPath == path)
|
||||
{
|
||||
return evaluateVar(root, ~0U, var);
|
||||
return evaluateVar(root, ~0U, var, mappingPtr);
|
||||
}
|
||||
|
||||
for(int i = 0; i < root->childCount(); i++)
|
||||
@@ -3672,7 +3680,7 @@ const RDTreeWidgetItem *ShaderViewer::getVarFromPath(const rdcstr &path, const R
|
||||
// if the path is an exact match, return the evaluation directly
|
||||
if(tag.absoluteRefPath == path)
|
||||
{
|
||||
return evaluateVar(child, ~0U, var);
|
||||
return evaluateVar(child, ~0U, var, mappingPtr);
|
||||
}
|
||||
|
||||
// after the common prefix, if the next value is . or [ then this is the next child, so recurse.
|
||||
@@ -3684,7 +3692,7 @@ const RDTreeWidgetItem *ShaderViewer::getVarFromPath(const rdcstr &path, const R
|
||||
if(common == tag.absoluteRefPath &&
|
||||
(path[tag.absoluteRefPath.size()] == '.' || path[tag.absoluteRefPath.size()] == '['))
|
||||
{
|
||||
return getVarFromPath(path, child, var, swizzlePtr);
|
||||
return getVarFromPath(path, child, var, swizzlePtr, mappingPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3726,7 +3734,7 @@ const RDTreeWidgetItem *ShaderViewer::getVarFromPath(const rdcstr &path, const R
|
||||
if(swizzlePtr)
|
||||
*swizzlePtr = swizzleMask;
|
||||
|
||||
return evaluateVar(root, swizzleMask, var);
|
||||
return evaluateVar(root, swizzleMask, var, mappingPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3734,7 +3742,8 @@ const RDTreeWidgetItem *ShaderViewer::getVarFromPath(const rdcstr &path, const R
|
||||
}
|
||||
|
||||
const RDTreeWidgetItem *ShaderViewer::getVarFromPath(const rdcstr &path, ShaderVariable *var,
|
||||
uint32_t *swizzle)
|
||||
uint32_t *swizzle,
|
||||
SourceVariableMapping *mapping)
|
||||
{
|
||||
if(!m_Trace || m_States.empty())
|
||||
return NULL;
|
||||
@@ -3765,7 +3774,7 @@ const RDTreeWidgetItem *ShaderViewer::getVarFromPath(const rdcstr &path, ShaderV
|
||||
|
||||
if(item->text(0) == root)
|
||||
{
|
||||
const RDTreeWidgetItem *ret = getVarFromPath(path, item, var, swizzle);
|
||||
const RDTreeWidgetItem *ret = getVarFromPath(path, item, var, swizzle, mapping);
|
||||
if(ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -3781,7 +3790,7 @@ const RDTreeWidgetItem *ShaderViewer::getVarFromPath(const rdcstr &path, ShaderV
|
||||
VariableTag tag = item->tag().value<VariableTag>();
|
||||
|
||||
const RDTreeWidgetItem *ret =
|
||||
getVarFromPath(tag.absoluteRefPath + "." + path, child, var, swizzle);
|
||||
getVarFromPath(tag.absoluteRefPath + "." + path, child, var, swizzle, mapping);
|
||||
if(ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -4515,6 +4524,7 @@ void ShaderViewer::markWatchStale(RDTreeWidgetItem *item)
|
||||
|
||||
bool ShaderViewer::updateWatchVariable(RDTreeWidgetItem *watchItem, const RDTreeWidgetItem *varItem,
|
||||
const rdcstr &path, uint32_t swizzle,
|
||||
const SourceVariableMapping &mapping,
|
||||
const ShaderVariable &var, QChar regcast)
|
||||
{
|
||||
if(!var.members.empty())
|
||||
@@ -4577,7 +4587,7 @@ bool ShaderViewer::updateWatchVariable(RDTreeWidgetItem *watchItem, const RDTree
|
||||
rdcstr sep = var.members[i].name[0] == '[' ? "" : ".";
|
||||
|
||||
updateWatchVariable(watchItem->child(idx), varItem->child(i),
|
||||
path + sep + var.members[i].name, ~0U, var.members[i], regcast);
|
||||
path + sep + var.members[i].name, ~0U, mapping, var.members[i], regcast);
|
||||
}
|
||||
|
||||
// any children that weren't marked as valid are now stale
|
||||
@@ -4644,7 +4654,8 @@ bool ShaderViewer::updateWatchVariable(RDTreeWidgetItem *watchItem, const RDTree
|
||||
QVariant(),
|
||||
});
|
||||
|
||||
updateWatchVariable(item, varItem->child(r), path + ".row" + ToStr(r), ~0U, rowVar, regcast);
|
||||
updateWatchVariable(item, varItem->child(r), path + ".row" + ToStr(r), ~0U, mapping, rowVar,
|
||||
regcast);
|
||||
item->setText(1, getRegNames(varItem, ~0U, r));
|
||||
item->setTag(QVariant());
|
||||
watchItem->addChild(item);
|
||||
@@ -4787,8 +4798,16 @@ bool ShaderViewer::updateWatchVariable(RDTreeWidgetItem *watchItem, const RDTree
|
||||
val += lit(", ");
|
||||
}
|
||||
|
||||
QString typeString = TypeString(var);
|
||||
|
||||
if(mapping.type != VarType::Unknown && mapping.undefinedValue)
|
||||
{
|
||||
typeString = lit("-");
|
||||
val = tr("<undefined value>");
|
||||
}
|
||||
|
||||
watchItem->setText(1, getRegNames(varItem, swizzle));
|
||||
watchItem->setText(2, TypeString(var));
|
||||
watchItem->setText(2, typeString);
|
||||
|
||||
if(!swatchColor.isValid())
|
||||
{
|
||||
@@ -4844,12 +4863,13 @@ void ShaderViewer::updateWatchVariables()
|
||||
if(!match.captured(2).isEmpty())
|
||||
regcast = match.captured(2)[1];
|
||||
|
||||
SourceVariableMapping mapping;
|
||||
ShaderVariable var;
|
||||
uint32_t swizzle = ~0U;
|
||||
const RDTreeWidgetItem *varItem = getVarFromPath(path, &var, &swizzle);
|
||||
const RDTreeWidgetItem *varItem = getVarFromPath(path, &var, &swizzle, &mapping);
|
||||
if(varItem)
|
||||
{
|
||||
if(updateWatchVariable(item, varItem, path, swizzle, var, regcast))
|
||||
if(updateWatchVariable(item, varItem, path, swizzle, mapping, var, regcast))
|
||||
continue;
|
||||
|
||||
error = tr("Couldn't evaluate watch for '%1'").arg(expr);
|
||||
@@ -5181,6 +5201,12 @@ RDTreeWidgetItem *ShaderViewer::makeSourceVariableNode(const SourceVariableMappi
|
||||
}
|
||||
}
|
||||
|
||||
if(l.undefinedValue)
|
||||
{
|
||||
typeName = lit("-");
|
||||
value = tr("<undefined value>");
|
||||
}
|
||||
|
||||
RDTreeWidgetItem *node = new RDTreeWidgetItem({localName, QString(), typeName, value});
|
||||
|
||||
for(RDTreeWidgetItem *c : children)
|
||||
@@ -6099,8 +6125,9 @@ void ShaderViewer::updateVariableTooltip()
|
||||
return;
|
||||
|
||||
ShaderVariable var;
|
||||
SourceVariableMapping mapping;
|
||||
|
||||
if(!getVarFromPath(m_TooltipVarPath, &var))
|
||||
if(!getVarFromPath(m_TooltipVarPath, &var, NULL, &mapping))
|
||||
return;
|
||||
|
||||
if(var.type != VarType::Unknown)
|
||||
@@ -6125,6 +6152,9 @@ void ShaderViewer::updateVariableTooltip()
|
||||
tooltip += lit("</pre>");
|
||||
}
|
||||
|
||||
if(mapping.type != VarType::Unknown && mapping.undefinedValue)
|
||||
tooltip = tr("%1: <undefined value>").arg(var.name);
|
||||
|
||||
QToolTip::showText(m_TooltipPos, tooltip);
|
||||
return;
|
||||
}
|
||||
@@ -6141,8 +6171,13 @@ void ShaderViewer::updateVariableTooltip()
|
||||
}
|
||||
else if(!var.members.empty())
|
||||
{
|
||||
QString tooltip = tr("%1: { ... }").arg(var.name);
|
||||
|
||||
if(mapping.type != VarType::Unknown && mapping.undefinedValue)
|
||||
tooltip = tr("%1: <undefined value>").arg(var.name);
|
||||
|
||||
// other structs
|
||||
QToolTip::showText(m_TooltipPos, lit("{ ... }"));
|
||||
QToolTip::showText(m_TooltipPos, tooltip);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -402,8 +402,8 @@ private:
|
||||
void updateDebugState();
|
||||
void markWatchStale(RDTreeWidgetItem *item);
|
||||
bool updateWatchVariable(RDTreeWidgetItem *watchItem, const RDTreeWidgetItem *varItem,
|
||||
const rdcstr &path, uint32_t swizzle, const ShaderVariable &var,
|
||||
QChar regcast);
|
||||
const rdcstr &path, uint32_t swizzle, const SourceVariableMapping &mapping,
|
||||
const ShaderVariable &var, QChar regcast);
|
||||
void updateWatchVariables();
|
||||
|
||||
void updateAccessedResources();
|
||||
@@ -452,9 +452,11 @@ private:
|
||||
|
||||
QString getRegNames(const RDTreeWidgetItem *item, uint32_t swizzle, uint32_t child = ~0U);
|
||||
const RDTreeWidgetItem *evaluateVar(const RDTreeWidgetItem *item, uint32_t swizzle,
|
||||
ShaderVariable *var);
|
||||
ShaderVariable *var, SourceVariableMapping *mapping);
|
||||
const RDTreeWidgetItem *getVarFromPath(const rdcstr &path, const RDTreeWidgetItem *root,
|
||||
ShaderVariable *var, uint32_t *swizzle);
|
||||
ShaderVariable *var, uint32_t *swizzle,
|
||||
SourceVariableMapping *mapping);
|
||||
const RDTreeWidgetItem *getVarFromPath(const rdcstr &path, ShaderVariable *var = NULL,
|
||||
uint32_t *swizzle = NULL);
|
||||
uint32_t *swizzle = NULL,
|
||||
SourceVariableMapping *mapping = NULL);
|
||||
};
|
||||
|
||||
@@ -676,6 +676,13 @@ struct SourceVariableMapping
|
||||
)");
|
||||
VarType type = VarType::Unknown;
|
||||
|
||||
DOCUMENT(R"(A flag indicating if this mapping indicates an undefined value - the meaning of which
|
||||
is compiler defined but may mean either uninitialised data, unassigned values, or optimised away values.
|
||||
|
||||
:type: bool
|
||||
)");
|
||||
bool undefinedValue = false;
|
||||
|
||||
DOCUMENT(R"(The number of rows in this variable - 1 for vectors, >1 for matrices.
|
||||
|
||||
:type: int
|
||||
|
||||
@@ -2626,11 +2626,24 @@ void Debugger::FillDebugSourceVars(rdcarray<InstructionSourceInfo> &instInfo) co
|
||||
|
||||
if(n->children.empty())
|
||||
{
|
||||
RDCASSERTNOTEQUAL(n->rows * n->columns, 0);
|
||||
for(uint32_t c = 0; c < n->rows * n->columns; ++c)
|
||||
ConstIter it = GetID(n->debugVar);
|
||||
|
||||
if(it.opcode() == Op::Undef)
|
||||
{
|
||||
sourceVar.rows = sourceVar.columns = 1;
|
||||
sourceVar.undefinedValue = true;
|
||||
|
||||
sourceVar.variables.push_back(DebugVariableReference(
|
||||
DebugVariableType::Variable, GetRawName(n->debugVar) + n->debugVarSuffix, c));
|
||||
DebugVariableType::Variable, GetRawName(n->debugVar) + n->debugVarSuffix, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCASSERTNOTEQUAL(n->rows * n->columns, 0);
|
||||
for(uint32_t c = 0; c < n->rows * n->columns; ++c)
|
||||
{
|
||||
sourceVar.variables.push_back(DebugVariableReference(
|
||||
DebugVariableType::Variable, GetRawName(n->debugVar) + n->debugVarSuffix, c));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user