mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-20 04:35:58 +00:00
Use QList for variables in ShaderViewer
* Using a linked list instead of a vector makes insert/erase operations for variables being created and destroyed significantly faster.
This commit is contained in:
+150
-159
@@ -2341,114 +2341,108 @@ void ShaderViewer::runToResourceAccess(bool forward, VarType type, const Bindpoi
|
||||
|
||||
void ShaderViewer::applyBackwardsChange()
|
||||
{
|
||||
if(!IsFirstState())
|
||||
if(IsFirstState())
|
||||
return;
|
||||
|
||||
for(const ShaderVariableChange &c : GetCurrentState().changes)
|
||||
{
|
||||
rdcarray<ShaderVariable> newVariables;
|
||||
|
||||
for(const ShaderVariableChange &c : GetCurrentState().changes)
|
||||
// if the before name is empty, this is a variable that came into scope/was created
|
||||
if(c.before.name.empty())
|
||||
{
|
||||
// if the before name is empty, this is a variable that came into scope/was created
|
||||
if(c.before.name.empty())
|
||||
// delete the matching variable (should only be one)
|
||||
for(int i = 0; i < m_Variables.count(); i++)
|
||||
{
|
||||
// delete the matching variable (should only be one)
|
||||
for(size_t i = 0; i < m_Variables.size(); i++)
|
||||
if(c.after.name == m_Variables[i].name)
|
||||
{
|
||||
if(c.after.name == m_Variables[i].name)
|
||||
{
|
||||
m_Variables.erase(i);
|
||||
break;
|
||||
}
|
||||
m_Variables.removeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ShaderVariable *v = NULL;
|
||||
for(size_t i = 0; i < m_Variables.size(); i++)
|
||||
{
|
||||
if(c.before.name == m_Variables[i].name)
|
||||
{
|
||||
v = &m_Variables[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(v)
|
||||
*v = c.before;
|
||||
else
|
||||
newVariables.push_back(c.before);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ShaderVariable *v = NULL;
|
||||
for(int i = 0; i < m_Variables.count(); i++)
|
||||
{
|
||||
if(c.before.name == m_Variables[i].name)
|
||||
{
|
||||
v = &m_Variables[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_Variables.insert(0, newVariables);
|
||||
|
||||
m_CurrentStateIdx--;
|
||||
if(v)
|
||||
*v = c.before;
|
||||
else
|
||||
m_Variables.insert(0, c.before);
|
||||
}
|
||||
}
|
||||
|
||||
m_CurrentStateIdx--;
|
||||
}
|
||||
|
||||
void ShaderViewer::applyForwardsChange()
|
||||
{
|
||||
if(!IsLastState())
|
||||
if(IsLastState())
|
||||
return;
|
||||
|
||||
m_CurrentStateIdx++;
|
||||
|
||||
rdcarray<AccessedResourceData> newAccessedResources;
|
||||
|
||||
for(const ShaderVariableChange &c : GetCurrentState().changes)
|
||||
{
|
||||
m_CurrentStateIdx++;
|
||||
|
||||
rdcarray<ShaderVariable> newVariables;
|
||||
rdcarray<AccessedResourceData> newAccessedResources;
|
||||
|
||||
for(const ShaderVariableChange &c : GetCurrentState().changes)
|
||||
// if the after name is empty, this is a variable going out of scope/being deleted
|
||||
if(c.after.name.empty())
|
||||
{
|
||||
// if the after name is empty, this is a variable going out of scope/being deleted
|
||||
if(c.after.name.empty())
|
||||
// delete the matching variable (should only be one)
|
||||
for(int i = 0; i < m_Variables.count(); i++)
|
||||
{
|
||||
// delete the matching variable (should only be one)
|
||||
for(size_t i = 0; i < m_Variables.size(); i++)
|
||||
if(c.before.name == m_Variables[i].name)
|
||||
{
|
||||
if(c.before.name == m_Variables[i].name)
|
||||
{
|
||||
m_Variables.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ShaderVariable *v = NULL;
|
||||
for(size_t i = 0; i < m_Variables.size(); i++)
|
||||
{
|
||||
if(c.after.name == m_Variables[i].name)
|
||||
{
|
||||
v = &m_Variables[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(v)
|
||||
*v = c.after;
|
||||
else
|
||||
newVariables.push_back(c.after);
|
||||
|
||||
if(c.after.type == VarType::ReadOnlyResource || c.after.type == VarType::ReadWriteResource)
|
||||
{
|
||||
bool found = false;
|
||||
for(size_t i = 0; i < m_AccessedResources.size(); i++)
|
||||
{
|
||||
if(c.after.GetBinding() == m_AccessedResources[i].resource.GetBinding())
|
||||
{
|
||||
found = true;
|
||||
if(m_AccessedResources[i].steps.indexOf(m_CurrentStateIdx) < 0)
|
||||
m_AccessedResources[i].steps.push_back(m_CurrentStateIdx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found)
|
||||
newAccessedResources.push_back({c.after, {m_CurrentStateIdx}});
|
||||
m_Variables.removeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ShaderVariable *v = NULL;
|
||||
for(int i = 0; i < m_Variables.count(); i++)
|
||||
{
|
||||
if(c.after.name == m_Variables[i].name)
|
||||
{
|
||||
v = &m_Variables[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_Variables.insert(0, newVariables);
|
||||
m_AccessedResources.insert(0, newAccessedResources);
|
||||
if(v)
|
||||
*v = c.after;
|
||||
else
|
||||
m_Variables.insert(0, c.after);
|
||||
|
||||
if(c.after.type == VarType::ReadOnlyResource || c.after.type == VarType::ReadWriteResource)
|
||||
{
|
||||
bool found = false;
|
||||
for(size_t i = 0; i < m_AccessedResources.size(); i++)
|
||||
{
|
||||
if(c.after.GetBinding() == m_AccessedResources[i].resource.GetBinding())
|
||||
{
|
||||
found = true;
|
||||
if(m_AccessedResources[i].steps.indexOf(m_CurrentStateIdx) < 0)
|
||||
m_AccessedResources[i].steps.push_back(m_CurrentStateIdx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found)
|
||||
newAccessedResources.push_back({c.after, {m_CurrentStateIdx}});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_AccessedResources.insert(0, newAccessedResources);
|
||||
}
|
||||
|
||||
QString ShaderViewer::stringRep(const ShaderVariable &var, uint32_t row)
|
||||
@@ -4765,6 +4759,66 @@ RDTreeWidgetItem *ShaderViewer::makeAccessedResourceNode(const ShaderVariable &v
|
||||
return node;
|
||||
}
|
||||
|
||||
// this function is a bit messy, we want a base recursion container of either QList or rdcarray
|
||||
// but further recursion is always rdcarray because of ShaderVariable::members
|
||||
template <typename Container>
|
||||
const ShaderVariable *GetShaderDebugVariable(rdcstr path, const Container &vars)
|
||||
{
|
||||
rdcstr elem;
|
||||
|
||||
// pick out the next element in the path
|
||||
// if this is an array index, grab that
|
||||
if(path[0] == '[')
|
||||
{
|
||||
int idx = path.indexOf(']');
|
||||
if(idx < 0)
|
||||
return NULL;
|
||||
elem = path.substr(0, idx + 1);
|
||||
|
||||
// skip past any .s
|
||||
if(path[idx + 1] == '.')
|
||||
idx++;
|
||||
|
||||
path = path.substr(idx + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise look for the next identifier
|
||||
int idx = path.find_first_of("[.");
|
||||
if(idx < 0)
|
||||
{
|
||||
// no results means that all that's left of the path is an identifier
|
||||
elem.swap(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
elem = path.substr(0, idx);
|
||||
|
||||
// skip past any .s
|
||||
if(path[idx] == '.')
|
||||
idx++;
|
||||
|
||||
path = path.substr(idx);
|
||||
}
|
||||
}
|
||||
|
||||
// look in our current set of vars for a matching variable
|
||||
for(int i = 0; i < vars.count(); i++)
|
||||
{
|
||||
if(vars[i].name == elem)
|
||||
{
|
||||
// If there's no more path, we've found the exact match, otherwise continue
|
||||
if(path.empty())
|
||||
return &vars[i];
|
||||
|
||||
// otherwise recurse
|
||||
return GetShaderDebugVariable(path, vars[i].members);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const ShaderVariable *ShaderViewer::GetDebugVariable(const DebugVariableReference &r)
|
||||
{
|
||||
if(r.type == DebugVariableType::ReadOnlyResource)
|
||||
@@ -4791,80 +4845,17 @@ const ShaderVariable *ShaderViewer::GetDebugVariable(const DebugVariableReferenc
|
||||
|
||||
return NULL;
|
||||
}
|
||||
else if(r.type == DebugVariableType::Input || r.type == DebugVariableType::Constant ||
|
||||
r.type == DebugVariableType::Variable)
|
||||
else if(r.type == DebugVariableType::Input)
|
||||
{
|
||||
rdcarray<ShaderVariable> *vars =
|
||||
r.type == DebugVariableType::Input
|
||||
? &m_Trace->inputs
|
||||
: (r.type == DebugVariableType::Constant ? &m_Trace->constantBlocks : &m_Variables);
|
||||
|
||||
rdcstr path = r.name;
|
||||
|
||||
while(!path.empty())
|
||||
{
|
||||
rdcstr elem;
|
||||
|
||||
// pick out the next element in the path
|
||||
// if this is an array index, grab that
|
||||
if(path[0] == '[')
|
||||
{
|
||||
int idx = path.indexOf(']');
|
||||
if(idx < 0)
|
||||
break;
|
||||
elem = path.substr(0, idx + 1);
|
||||
|
||||
// skip past any .s
|
||||
if(path[idx + 1] == '.')
|
||||
idx++;
|
||||
|
||||
path = path.substr(idx + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise look for the next identifier
|
||||
int idx = path.find_first_of("[.");
|
||||
if(idx < 0)
|
||||
{
|
||||
// no results means that all that's left of the path is an identifier
|
||||
elem.swap(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
elem = path.substr(0, idx);
|
||||
|
||||
// skip past any .s
|
||||
if(path[idx] == '.')
|
||||
idx++;
|
||||
|
||||
path = path.substr(idx);
|
||||
}
|
||||
}
|
||||
|
||||
// look in our current set of vars for a matching variable
|
||||
bool found = false;
|
||||
for(size_t i = 0; i < vars->size(); i++)
|
||||
{
|
||||
if(vars->at(i).name == elem)
|
||||
{
|
||||
// found the match.
|
||||
found = true;
|
||||
|
||||
// If there's no more path, we've found the exact match, otherwise continue
|
||||
if(path.empty())
|
||||
return &vars->at(i);
|
||||
|
||||
vars = &vars->at(i).members;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found)
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return GetShaderDebugVariable(r.name, m_Trace->inputs);
|
||||
}
|
||||
else if(r.type == DebugVariableType::Constant)
|
||||
{
|
||||
return GetShaderDebugVariable(r.name, m_Trace->constantBlocks);
|
||||
}
|
||||
else if(r.type == DebugVariableType::Variable)
|
||||
{
|
||||
return GetShaderDebugVariable(r.name, m_Variables);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -301,7 +301,7 @@ private:
|
||||
size_t m_FirstSourceStateIdx = ~0U;
|
||||
rdcarray<ShaderDebugState> m_States;
|
||||
size_t m_CurrentStateIdx = 0;
|
||||
rdcarray<ShaderVariable> m_Variables;
|
||||
QList<ShaderVariable> m_Variables;
|
||||
|
||||
// true when debugging while we're populating the initial trace. Lets us queue up commands and
|
||||
// process them once we've initialised properly
|
||||
|
||||
Reference in New Issue
Block a user