Update Spirv debugger methods to be const methods

Add read/write locking for containers "usedNames" and "dynamicNames"
This commit is contained in:
Jake Turner
2025-09-24 14:09:43 +01:00
parent 64b9e517e0
commit e6f75e1530
3 changed files with 61 additions and 50 deletions
@@ -193,7 +193,7 @@ void ThreadState::FillCallstack(rdcarray<Id> &funcs)
void ThreadState::EnterFunction(const rdcarray<Id> &arguments)
{
Iter it = debugger.GetIterForInstruction(nextInstruction);
ConstIter it = debugger.GetIterForInstruction(nextInstruction);
RDCASSERT(OpDecoder(it).op == Op::Function);
@@ -255,7 +255,7 @@ void ThreadState::EnterFunction(const rdcarray<Id> &arguments)
it++;
size_t numVars = 0;
Iter varCounter = it;
ConstIter varCounter = it;
while(OpDecoder(varCounter).op == Op::Variable || OpDecoder(varCounter).op == Op::Line ||
OpDecoder(varCounter).op == Op::NoLine)
{
@@ -664,7 +664,7 @@ void ThreadState::JumpToLabel(Id target)
nextInstruction = labelInstruction + 1;
// if jumping to an empty unconditional loop header, continue to the loop block
Iter it = debugger.GetIterForInstruction(nextInstruction);
ConstIter it = debugger.GetIterForInstruction(nextInstruction);
if(it.opcode() == Op::LoopMerge)
{
OpLoopMerge merge(it);
@@ -717,7 +717,7 @@ void ThreadState::SkipIgnoredInstructions()
// in pixel shaders, but otherwise skip them.
while(true)
{
Iter it = debugger.GetIterForInstruction(nextInstruction);
ConstIter it = debugger.GetIterForInstruction(nextInstruction);
rdcspv::Op op = it.opcode();
if(op == Op::Line || op == Op::NoLine || op == Op::Undef)
{
@@ -795,7 +795,7 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
{
m_State = state;
Iter it = debugger.GetIterForInstruction(nextInstruction);
ConstIter it = debugger.GetIterForInstruction(nextInstruction);
nextInstruction++;
diverged = false;
enteredPoints.clear();
+21 -19
View File
@@ -422,18 +422,18 @@ public:
rdcarray<ShaderDebugState> ContinueDebug();
Iter GetIterForInstruction(uint32_t inst);
uint32_t GetInstructionForIter(Iter it);
uint32_t GetInstructionForFunction(Id id);
uint32_t GetInstructionForLabel(Id id);
const DataType &GetType(Id typeId);
const DataType &GetTypeForId(Id ssaId);
const Decorations &GetDecorations(Id typeId);
ConstIter GetIterForInstruction(uint32_t inst) const;
uint32_t GetInstructionForIter(ConstIter it) const;
uint32_t GetInstructionForFunction(Id id) const;
uint32_t GetInstructionForLabel(Id id) const;
const DataType &GetType(Id typeId) const;
const DataType &GetTypeForId(Id ssaId) const;
const Decorations &GetDecorations(Id typeId) const;
bool IsDebugExtInstSet(Id id) const;
bool HasDebugInfo() const { return m_DebugInfo.valid; }
bool InDebugScope(uint32_t inst) const;
rdcstr GetHumanName(Id id);
void AllocateVariable(Id id, Id typeId, ShaderVariable &outVar);
rdcstr GetHumanName(Id id) const;
void AllocateVariable(Id id, Id typeId, ShaderVariable &outVar) const;
ShaderVariable ReadFromPointer(const ShaderVariable &v) const;
ShaderVariable GetPointerValue(const ShaderVariable &v) const;
@@ -449,12 +449,13 @@ public:
bool ArePointersAndEqual(const ShaderVariable &a, const ShaderVariable &b) const;
void WriteThroughPointer(ShaderVariable &ptr, const ShaderVariable &val);
ShaderVariable MakeCompositePointer(const ShaderVariable &base, Id id, rdcarray<uint32_t> &indices);
ShaderVariable MakeCompositePointer(const ShaderVariable &base, Id id,
rdcarray<uint32_t> &indices) const;
DebugAPIWrapper *GetAPIWrapper();
uint32_t GetNumInstructions() { return (uint32_t)instructionOffsets.size(); }
GlobalState GetGlobal() { return global; }
const rdcarray<Id> &GetLiveGlobals() { return liveGlobals; }
DebugAPIWrapper *GetAPIWrapper() const;
uint32_t GetNumInstructions() const { return (uint32_t)instructionOffsets.size(); }
GlobalState GetGlobal() const { return global; }
const rdcarray<Id> &GetLiveGlobals() const { return liveGlobals; }
ThreadState &GetActiveLane() { return workgroup[activeLaneIndex]; }
const ThreadState &GetActiveLane() const { return workgroup[activeLaneIndex]; }
uint32_t GetSubgroupSize() const { return subgroupSize; }
@@ -479,9 +480,9 @@ private:
void MakeSignatureNames(const rdcarray<SPIRVInterfaceAccess> &sigList, rdcarray<rdcstr> &sigNames);
void FillCallstack(ThreadState &thread, ShaderDebugState &state);
void FillDebugSourceVars(rdcarray<InstructionSourceInfo> &instInfo);
void FillDefaultSourceVars(rdcarray<InstructionSourceInfo> &instInfo);
void FillCallstack(ThreadState &thread, ShaderDebugState &state) const;
void FillDebugSourceVars(rdcarray<InstructionSourceInfo> &instInfo) const;
void FillDefaultSourceVars(rdcarray<InstructionSourceInfo> &instInfo) const;
/////////////////////////////////////////////////////////
// debug data
@@ -539,8 +540,9 @@ private:
rdcarray<size_t> instructionOffsets;
std::set<rdcstr> usedNames;
std::map<Id, rdcstr> dynamicNames;
mutable std::set<rdcstr> usedNames;
mutable Threading::RWLock dynamicNamesLock;
mutable std::map<Id, rdcstr> dynamicNames;
struct
{
@@ -329,39 +329,39 @@ void Debugger::Parse(const rdcarray<uint32_t> &spirvWords)
Processor::Parse(spirvWords);
}
Iter Debugger::GetIterForInstruction(uint32_t inst)
ConstIter Debugger::GetIterForInstruction(uint32_t inst) const
{
return Iter(m_SPIRV, instructionOffsets[inst]);
return ConstIter(m_SPIRV, instructionOffsets[inst]);
}
uint32_t Debugger::GetInstructionForIter(Iter it)
uint32_t Debugger::GetInstructionForIter(ConstIter it) const
{
return instructionOffsets.indexOf(it.offs());
}
uint32_t Debugger::GetInstructionForFunction(Id id)
uint32_t Debugger::GetInstructionForFunction(Id id) const
{
return instructionOffsets.indexOf(functions[id].begin);
}
uint32_t Debugger::GetInstructionForLabel(Id id)
uint32_t Debugger::GetInstructionForLabel(Id id) const
{
uint32_t ret = labelInstruction[id];
RDCASSERT(ret);
return ret;
}
const rdcspv::DataType &Debugger::GetType(Id typeId)
const rdcspv::DataType &Debugger::GetType(Id typeId) const
{
return dataTypes[typeId];
}
const rdcspv::DataType &Debugger::GetTypeForId(Id ssaId)
const rdcspv::DataType &Debugger::GetTypeForId(Id ssaId) const
{
return dataTypes[idTypes[ssaId]];
}
const Decorations &Debugger::GetDecorations(Id typeId)
const Decorations &Debugger::GetDecorations(Id typeId) const
{
return decorations[typeId];
}
@@ -1772,7 +1772,7 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *api, const ShaderStage s
return ret;
}
void Debugger::FillCallstack(ThreadState &thread, ShaderDebugState &state)
void Debugger::FillCallstack(ThreadState &thread, ShaderDebugState &state) const
{
rdcarray<Id> funcs;
thread.FillCallstack(funcs);
@@ -1793,7 +1793,7 @@ void Debugger::FillCallstack(ThreadState &thread, ShaderDebugState &state)
}
}
void Debugger::FillDebugSourceVars(rdcarray<InstructionSourceInfo> &instInfo)
void Debugger::FillDebugSourceVars(rdcarray<InstructionSourceInfo> &instInfo) const
{
for(InstructionSourceInfo &i : instInfo)
{
@@ -2459,7 +2459,7 @@ void Debugger::FillDebugSourceVars(rdcarray<InstructionSourceInfo> &instInfo)
}
}
void Debugger::FillDefaultSourceVars(rdcarray<InstructionSourceInfo> &instInfo)
void Debugger::FillDefaultSourceVars(rdcarray<InstructionSourceInfo> &instInfo) const
{
rdcarray<SourceVariableMapping> sourceVars;
rdcarray<Id> debugVars;
@@ -2475,7 +2475,7 @@ void Debugger::FillDefaultSourceVars(rdcarray<InstructionSourceInfo> &instInfo)
size_t offs = instructionOffsets[i.instruction];
Iter it(m_SPIRV, offs);
ConstIter it(m_SPIRV, offs);
OpDecoder opdata(it);
@@ -2884,7 +2884,7 @@ ShaderVariable Debugger::MakePointerVariable(Id id, const ShaderVariable *v, uin
}
ShaderVariable Debugger::MakeCompositePointer(const ShaderVariable &base, Id id,
rdcarray<uint32_t> &indices)
rdcarray<uint32_t> &indices) const
{
const ShaderVariable *leaf = &base;
@@ -3621,12 +3621,15 @@ void Debugger::WriteThroughPointer(ShaderVariable &ptr, const ShaderVariable &va
}
}
rdcstr Debugger::GetHumanName(Id id)
rdcstr Debugger::GetHumanName(Id id) const
{
// see if we have a dynamic name assigned (to disambiguate), if so use that
auto it = dynamicNames.find(id);
if(it != dynamicNames.end())
return it->second;
{
SCOPED_READLOCK(dynamicNamesLock);
// see if we have a dynamic name assigned (to disambiguate), if so use that
auto it = dynamicNames.find(id);
if(it != dynamicNames.end())
return it->second;
}
// otherwise try the string first
rdcstr name = strings[id];
@@ -3638,20 +3641,26 @@ rdcstr Debugger::GetHumanName(Id id)
rdcstr basename = name;
// otherwise check to see if it's been used before. If so give it a new name
int alias = 2;
while(usedNames.find(name) != usedNames.end())
{
name = basename + "@" + ToStr(alias);
alias++;
SCOPED_READLOCK(dynamicNamesLock);
int alias = 2;
while(usedNames.find(name) != usedNames.end())
{
name = basename + "@" + ToStr(alias);
alias++;
}
}
usedNames.insert(name);
dynamicNames[id] = name;
{
SCOPED_WRITELOCK(dynamicNamesLock);
usedNames.insert(name);
dynamicNames[id] = name;
}
return name;
}
void Debugger::AllocateVariable(Id id, Id typeId, ShaderVariable &outVar)
void Debugger::AllocateVariable(Id id, Id typeId, ShaderVariable &outVar) const
{
// allocs should always be pointers
RDCASSERT(dataTypes[typeId].type == DataType::PointerType);
@@ -4514,7 +4523,7 @@ void Debugger::RegisterOp(Iter it)
}
// Must be called from the replay manager thread (the debugger thread)
DebugAPIWrapper *Debugger::GetAPIWrapper()
DebugAPIWrapper *Debugger::GetAPIWrapper() const
{
CHECK_DEBUGGER_THREAD();
return apiWrapper;