diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp b/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp index 000bfe986..744a9fcc3 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp @@ -1616,14 +1616,12 @@ Program::Program(const byte *bytes, size_t length) // true destination inst.args.push_back(Symbol(SymbolType::BasicBlock, op.ops[0])); - f.blocks[op.ops[0]].preds.insert(0, &f.blocks[curBlock]); if(op.ops.size() > 1) { // false destination inst.args.push_back(Symbol(SymbolType::BasicBlock, op.ops[1])); - f.blocks[op.ops[1]].preds.insert(0, &f.blocks[curBlock]); // predicate @@ -1634,6 +1632,62 @@ Program::Program(const byte *bytes, size_t length) f.instructions.push_back(inst); } + else if(IS_KNOWN(op.id, FunctionRecord::INST_SWITCH)) + { + Instruction inst; + + inst.op = Instruction::Switch; + + inst.type = GetVoidType(); + + uint64_t typeIdx = op.ops[0]; + + static const uint64_t SWITCH_INST_MAGIC = 0x4B5; + if((typeIdx >> 16) == SWITCH_INST_MAGIC) + { + // type of condition + const Type *condType = &m_Types[op.ops[1]]; + + RDCASSERT(condType->bitWidth <= 64); + + // condition + inst.args.push_back(getSymbol(op.ops[2])); + + // default block + inst.args.push_back(Symbol(SymbolType::BasicBlock, op.ops[3])); + f.blocks[op.ops[3]].preds.insert(0, &f.blocks[curBlock]); + + RDCERR("Unsupported switch instruction version"); + } + else + { + // type of condition, ignored + // op.ops[0] + + // condition + inst.args.push_back(getSymbol(op.ops[1])); + + // default block + inst.args.push_back(Symbol(SymbolType::BasicBlock, op.ops[2])); + f.blocks[op.ops[2]].preds.insert(0, &f.blocks[curBlock]); + + uint64_t numCases = (op.ops.size() - 3) / 2; + + for(uint64_t c = 0; c < numCases; c++) + { + // case value, absolute not relative + inst.args.push_back(m_Symbols[op.ops[3 + c * 2 + 0]]); + + // case block + inst.args.push_back(Symbol(SymbolType::BasicBlock, op.ops[3 + c * 2 + 1])); + f.blocks[op.ops[3 + c * 2 + 1]].preds.insert(0, &f.blocks[curBlock]); + } + } + + curBlock++; + + f.instructions.push_back(inst); + } else if(IS_KNOWN(op.id, FunctionRecord::INST_PHI)) { Instruction inst; @@ -1802,7 +1856,8 @@ Program::Program(const byte *bytes, size_t length) for(size_t i = 0, resultID = 1; i < f.instructions.size(); i++) { if(f.instructions[i].op == Instruction::Branch || - f.instructions[i].op == Instruction::Unreachable) + f.instructions[i].op == Instruction::Unreachable || + f.instructions[i].op == Instruction::Switch) { curBlock++; if(f.blocks[curBlock].name.empty()) diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.h b/renderdoc/driver/shaders/dxil/dxil_bytecode.h index d33d35f94..1a27c268d 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.h +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.h @@ -388,6 +388,7 @@ struct Instruction InsertValue, Branch, Phi, + Switch, } op = Unknown; InstructionFlags opFlags = InstructionFlags::NoFlags; diff --git a/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp b/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp index 77802c848..6815f8983 100644 --- a/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp @@ -395,8 +395,12 @@ void Program::MakeDisassemblyString() switch(s.type) { case SymbolType::Unknown: - case SymbolType::Alias: - case SymbolType::Literal: ret = "???"; break; + case SymbolType::Alias: ret = "???"; break; + case SymbolType::Literal: + if(withTypes) + ret += "i32 "; + ret += StringFormat::Fmt("%lld", s.idx); + break; case SymbolType::Metadata: if(withTypes) ret += "metadata "; @@ -835,6 +839,25 @@ void Program::MakeDisassemblyString() } break; } + case Instruction::Switch: + { + m_Disassembly += "switch "; + m_Disassembly += argToString(inst.args[0], true); + m_Disassembly += ", "; + m_Disassembly += argToString(inst.args[1], true); + m_Disassembly += " ["; + m_Disassembly += "\n"; + instructionLine++; + for(size_t a = 2; a < inst.args.size(); a += 2) + { + m_Disassembly += + StringFormat::Fmt(" %s, %s\n", argToString(inst.args[a], true).c_str(), + argToString(inst.args[a + 1], true).c_str()); + instructionLine++; + } + m_Disassembly += " ]"; + break; + } } if(inst.debugLoc != ~0U) @@ -905,7 +928,8 @@ void Program::MakeDisassemblyString() m_Disassembly += "\n"; instructionLine++; - if(inst.op == Instruction::Branch || inst.op == Instruction::Unreachable) + if(inst.op == Instruction::Branch || inst.op == Instruction::Unreachable || + inst.op == Instruction::Switch) { m_Disassembly += "\n"; instructionLine++; @@ -939,6 +963,7 @@ void Program::MakeDisassemblyString() m_Disassembly += labelName; m_Disassembly += "\n"; + instructionLine++; } } m_Disassembly += "}\n\n";