mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-28 17:36:36 +00:00
DXIL Disassembly: Include GlobalVar in SSA Id generation
During SettleIDs() check that all instruction arguments that require an SSA Id have one set Moved DXILDebug::Id, INVALID_ID, DXIL::GetSSAId() out of DXIL Debugger
This commit is contained in:
@@ -45,6 +45,8 @@ namespace DXILDebug
|
||||
{
|
||||
class Debugger;
|
||||
struct ThreadState;
|
||||
const uint32_t INVALID_ID = ~0U;
|
||||
typedef uint32_t Id;
|
||||
};
|
||||
|
||||
namespace DXIL
|
||||
@@ -1283,7 +1285,7 @@ struct Instruction : public ForwardReferencableValue<Instruction>
|
||||
// For DXC Compatibility mode: slot contains a number assigned to instructions that don't have
|
||||
// names and return a value, used for disassembly
|
||||
|
||||
// Otherwise a unique global ID used by the debugger and disassemvbly
|
||||
// Otherwise a unique global ID used by the debugger and disassembly
|
||||
uint32_t slot = ~0U;
|
||||
InstructionFlags &opFlags() { return (InstructionFlags &)flags; }
|
||||
InstructionFlags opFlags() const { return (InstructionFlags)flags; }
|
||||
@@ -1724,6 +1726,7 @@ bool getival(const Value *v, T &out)
|
||||
}
|
||||
|
||||
bool IsSSA(const Value *dxilValue);
|
||||
DXILDebug::Id GetSSAId(const DXIL::Value *value);
|
||||
bool IsDXCNop(const Instruction &inst);
|
||||
bool IsLLVMDebugCall(const Instruction &inst);
|
||||
|
||||
|
||||
@@ -31,17 +31,6 @@
|
||||
using namespace DXIL;
|
||||
using namespace DXDebug;
|
||||
|
||||
const uint32_t DXIL_INVALID_ID = ~0U;
|
||||
|
||||
DXILDebug::Id GetSSAId(DXIL::Value *value)
|
||||
{
|
||||
if(const Instruction *inst = cast<Instruction>(value))
|
||||
return inst->slot;
|
||||
|
||||
RDCERR("Unhandled DXIL::Value type");
|
||||
return DXIL_INVALID_ID;
|
||||
}
|
||||
|
||||
static bool OperationFlushing(const Operation op, DXOp dxOpCode)
|
||||
{
|
||||
if(dxOpCode != DXOp::NumOpCodes)
|
||||
@@ -1283,7 +1272,7 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
|
||||
}
|
||||
else
|
||||
{
|
||||
resultId = DXIL_INVALID_ID;
|
||||
resultId = DXILDebug::INVALID_ID;
|
||||
result.name.clear();
|
||||
}
|
||||
break;
|
||||
@@ -2379,14 +2368,14 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
|
||||
const StackAllocPointer &ptr = itPtr->second;
|
||||
Id baseMemoryId = ptr.baseMemoryId;
|
||||
RDCASSERT(ptr.backingMemory);
|
||||
RDCASSERTNOTEQUAL(baseMemoryId, DXIL_INVALID_ID);
|
||||
RDCASSERTNOTEQUAL(baseMemoryId, DXILDebug::INVALID_ID);
|
||||
auto itAlloc = m_StackAllocs.find(baseMemoryId);
|
||||
RDCASSERT(itAlloc != m_StackAllocs.end());
|
||||
StackAlloc &alloc = itAlloc->second;
|
||||
|
||||
ShaderVariable arg;
|
||||
RDCASSERT(GetShaderVariable(inst.args[1], opCode, dxOpCode, arg));
|
||||
RDCASSERTEQUAL(resultId, DXIL_INVALID_ID);
|
||||
RDCASSERTEQUAL(resultId, DXILDebug::INVALID_ID);
|
||||
|
||||
// Memory copy from value to backing memory
|
||||
VarType type = ConvertDXILTypeToVarType(inst.args[1]->type);
|
||||
@@ -2895,8 +2884,8 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
|
||||
}
|
||||
|
||||
// Update the result variable after the dormant variables have been brought back
|
||||
RDCASSERT(!(result.name.empty() ^ (resultId == DXIL_INVALID_ID)));
|
||||
if(!result.name.empty() && resultId != DXIL_INVALID_ID)
|
||||
RDCASSERT(!(result.name.empty() ^ (resultId == DXILDebug::INVALID_ID)));
|
||||
if(!result.name.empty() && resultId != DXILDebug::INVALID_ID)
|
||||
{
|
||||
if(recordChange)
|
||||
SetResult(resultId, result, opCode, dxOpCode, eventFlags);
|
||||
@@ -4639,7 +4628,7 @@ ShaderDebugTrace *Debugger::BeginDebug(uint32_t eventId, const DXBC::DXBCContain
|
||||
const uint32_t maxInst = i + 1;
|
||||
{
|
||||
Id resultId = inst.slot;
|
||||
if(resultId != DXIL_INVALID_ID)
|
||||
if(resultId != DXILDebug::INVALID_ID)
|
||||
{
|
||||
// The result SSA should not have been referenced before
|
||||
RDCASSERTEQUAL(ssaRefs.count(resultId), 0);
|
||||
@@ -4670,6 +4659,12 @@ ShaderDebugTrace *Debugger::BeginDebug(uint32_t eventId, const DXBC::DXBCContain
|
||||
if(DXIL::IsSSA(arg))
|
||||
{
|
||||
Id argId = GetSSAId(arg);
|
||||
// Add GlobalVar args to the SSA refs (they won't be the result of an instruction)
|
||||
if(cast<GlobalVar>(arg))
|
||||
{
|
||||
if(ssaRefs.count(argId) == 0)
|
||||
ssaRefs.insert(argId);
|
||||
}
|
||||
if(!isPhiNode)
|
||||
{
|
||||
// For non phi-nodes the argument SSA should already exist as the result of a previous operation
|
||||
|
||||
@@ -43,7 +43,6 @@ typedef DXDebug::GatherChannel GatherChannel;
|
||||
typedef DXBCBytecode::SamplerMode SamplerMode;
|
||||
typedef DXBC::InterpolationMode InterpolationMode;
|
||||
|
||||
typedef uint32_t Id;
|
||||
class Debugger;
|
||||
struct GlobalState;
|
||||
|
||||
|
||||
@@ -110,14 +110,14 @@ bool DXIL::IsSSA(const Value *dxilValue)
|
||||
{
|
||||
if(const Instruction *inst = cast<Instruction>(dxilValue))
|
||||
return true;
|
||||
if(const GlobalVar *gv = cast<GlobalVar>(dxilValue))
|
||||
return true;
|
||||
if(const Constant *c = cast<Constant>(dxilValue))
|
||||
return false;
|
||||
if(const Literal *lit = cast<Literal>(dxilValue))
|
||||
return false;
|
||||
if(const Block *block = cast<Block>(dxilValue))
|
||||
return false;
|
||||
if(const GlobalVar *gv = cast<GlobalVar>(dxilValue))
|
||||
return false;
|
||||
if(const Function *func = cast<Function>(dxilValue))
|
||||
return false;
|
||||
if(const Metadata *meta = cast<Metadata>(dxilValue))
|
||||
@@ -127,6 +127,17 @@ bool DXIL::IsSSA(const Value *dxilValue)
|
||||
return false;
|
||||
}
|
||||
|
||||
DXILDebug::Id DXIL::GetSSAId(const DXIL::Value *value)
|
||||
{
|
||||
if(const Instruction *inst = cast<Instruction>(value))
|
||||
return inst->slot;
|
||||
if(const GlobalVar *gv = cast<GlobalVar>(value))
|
||||
return gv->ssaId;
|
||||
|
||||
RDCERR("Unhandled DXIL::Value type");
|
||||
return DXILDebug::INVALID_ID;
|
||||
}
|
||||
|
||||
static const char *shaderNames[] = {
|
||||
"Pixel", "Vertex", "Geometry", "Hull", "Domain",
|
||||
"Compute", "Library", "RayGeneration", "Intersection", "AnyHit",
|
||||
@@ -1060,6 +1071,13 @@ void Program::SettleIDs()
|
||||
AssignMetaSlot(m_MetaSlots, m_NextMetaSlot, m.children[c]);
|
||||
}
|
||||
}
|
||||
// assign SSA ID for global variables
|
||||
for(GlobalVar *g : m_GlobalVars)
|
||||
{
|
||||
if(g->ssaId == ~0U)
|
||||
g->ssaId = m_NextSSAId++;
|
||||
}
|
||||
|
||||
rdcarray<Metadata *> &metaSlots = m_MetaSlots;
|
||||
uint32_t &nextMetaSlot = m_NextMetaSlot;
|
||||
for(size_t i = 0; i < m_Functions.size(); i++)
|
||||
@@ -1093,6 +1111,14 @@ void Program::SettleIDs()
|
||||
inst->slot = slot++;
|
||||
#endif
|
||||
}
|
||||
#if DISABLED(DXC_COMPATIBLE_DISASM)
|
||||
// Check all arguments have valid SSA IDs
|
||||
for(const Value *arg : inst->args)
|
||||
{
|
||||
if(IsSSA(arg))
|
||||
RDCASSERTNOTEQUAL(GetSSAId(arg), ~0U);
|
||||
}
|
||||
#endif
|
||||
if(inst->op == Operation::Call)
|
||||
{
|
||||
Function *callFunc = (Function *)inst->getFuncCall();
|
||||
|
||||
Reference in New Issue
Block a user