diff --git a/qrenderdoc/Windows/ShaderViewer.cpp b/qrenderdoc/Windows/ShaderViewer.cpp index 267aef6bc..495984e98 100644 --- a/qrenderdoc/Windows/ShaderViewer.cpp +++ b/qrenderdoc/Windows/ShaderViewer.cpp @@ -2617,6 +2617,8 @@ void ShaderViewer::runTo(const rdcarray &runToInstructions, bool forwa if(!m_Trace || m_States.empty()) return; + condition |= ShaderEvents::DebugBreak; + m_VariablesChanged.clear(); bool firstStep = true; diff --git a/renderdoc/api/replay/replay_enums.h b/renderdoc/api/replay/replay_enums.h index c4c8f8d5a..69b4fd81c 100644 --- a/renderdoc/api/replay/replay_enums.h +++ b/renderdoc/api/replay/replay_enums.h @@ -4879,12 +4879,17 @@ DOCUMENT(R"(A set of flags for events that may occur while debugging a shader .. data:: GeneratedNanOrInf A floating point operation generated a ``NaN`` or ``infinity`` result. + +.. data:: DebugBreak + + A debugbreak event was emitted. )"); enum class ShaderEvents : uint32_t { NoEvent = 0, SampleLoadGather = 0x1, GeneratedNanOrInf = 0x2, + DebugBreak = 0x4, }; BITMASK_OPERATORS(ShaderEvents); diff --git a/renderdoc/driver/shaders/spirv/spirv_debug.cpp b/renderdoc/driver/shaders/spirv/spirv_debug.cpp index 0fb4db207..464fc8a46 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug.cpp @@ -438,6 +438,12 @@ ShaderVariable ThreadState::ReadPointerValue(Id pointer) return debugger.ReadFromPointer(GetSrc(pointer)); } +void ThreadState::DebugBreak() +{ + if(m_State) + m_State->flags |= ShaderEvents::DebugBreak; +} + void ThreadState::SetDst(Id id, const ShaderVariable &val) { if(m_State && ContainsNaNInf(val)) @@ -1567,8 +1573,8 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray const ExtInstDispatcher &dispatch = global.extInsts[extinst]; - // ignore nonsemantic instructions - if(dispatch.nonsemantic) + // ignore nonsemantic instructions that we have no implementations for + if(dispatch.skippedNonsemantic) break; uint32_t instruction = it.word(4); diff --git a/renderdoc/driver/shaders/spirv/spirv_debug.h b/renderdoc/driver/shaders/spirv/spirv_debug.h index 4fb3c9d2e..d0853253c 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug.h +++ b/renderdoc/driver/shaders/spirv/spirv_debug.h @@ -116,7 +116,7 @@ typedef ShaderVariable (*ExtInstImpl)(ThreadState &, uint32_t, const rdcarray names; rdcarray functions; }; @@ -269,6 +269,8 @@ struct ThreadState void WritePointerValue(Id pointer, const ShaderVariable &val); ShaderVariable ReadPointerValue(Id pointer); + void DebugBreak(); + private: void EnterFunction(const rdcarray &arguments); void SetDst(Id id, const ShaderVariable &val); diff --git a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp index ac6431c31..1586af5f2 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp @@ -255,6 +255,12 @@ static const void *VarElemPointer(const ShaderVariable &var, uint32_t comp) namespace rdcspv { +ShaderVariable ThreadDebugBreak(ThreadState &state, uint32_t, const rdcarray &) +{ + state.DebugBreak(); + return ShaderVariable("void", 0U, 0U, 0U, 0U); +} + rdcstr GetRawName(Id id) { // 32-bit value means at most 10 decimal digits, plus a preceeding _, plus trailing NULL. @@ -971,13 +977,29 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *api, const ShaderStage s global.extInsts[id] = extinst; } + else if(setname == "NonSemantic.DebugBreak") + { + ExtInstDispatcher extinst; + + extinst.name = setname; + + // idx 0 is unused, fill with a dummy function + extinst.names.push_back("__"); + extinst.functions.push_back(&ThreadDebugBreak); + extinst.names.push_back("DebugBreak"); + extinst.functions.push_back(&ThreadDebugBreak); + + global.extInsts[id] = extinst; + + RDCLOG("extinst set %u is debug break", id.value()); + } else if(setname.beginsWith("NonSemantic.")) { ExtInstDispatcher extinst; extinst.name = setname; - extinst.nonsemantic = true; + extinst.skippedNonsemantic = true; global.extInsts[id] = extinst; } diff --git a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp index d81dac90f..1dac79093 100644 --- a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp @@ -1635,6 +1635,7 @@ rdcstr Reflector::Disassemble(const rdcstr &entryPoint, const bool IsGLSL450 = knownExtSet[ExtSet_GLSL450] == decoded.set; const bool IsDebugPrintf = knownExtSet[ExtSet_Printf] == decoded.set; const bool IsShaderDbg = knownExtSet[ExtSet_ShaderDbg] == decoded.set; + const bool IsDebugBreak = knownExtSet[ExtSet_DebugBreak] == decoded.set; // GLSL.std.450 all parameters are Ids const bool idParams = IsGLSL450 || setname.beginsWith("NonSemantic."); @@ -1715,6 +1716,8 @@ rdcstr Reflector::Disassemble(const rdcstr &entryPoint, ret += StringFormat::Fmt("%s::%s(", setname.c_str(), ToStr(GLSLstd450(inst)).c_str()); else if(IsDebugPrintf) ret += "DebugPrintf("; + else if(IsDebugBreak) + ret += "DebugBreak("; else ret += StringFormat::Fmt("%s::[%u](", setname.c_str(), inst); diff --git a/renderdoc/driver/shaders/spirv/spirv_processor.cpp b/renderdoc/driver/shaders/spirv/spirv_processor.cpp index 2cc3e7df3..f7047d7e5 100644 --- a/renderdoc/driver/shaders/spirv/spirv_processor.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_processor.cpp @@ -569,6 +569,8 @@ void Processor::RegisterOp(Iter it) knownExtSet[ExtSet_Printf] = decoded.result; else if(decoded.name == "NonSemantic.Shader.DebugInfo.100") knownExtSet[ExtSet_ShaderDbg] = decoded.result; + else if(decoded.name == "NonSemantic.DebugBreak") + knownExtSet[ExtSet_DebugBreak] = decoded.result; } else if(opdata.op == Op::EntryPoint) { diff --git a/renderdoc/driver/shaders/spirv/spirv_processor.h b/renderdoc/driver/shaders/spirv/spirv_processor.h index b5d0126f9..d1ad9f2c1 100644 --- a/renderdoc/driver/shaders/spirv/spirv_processor.h +++ b/renderdoc/driver/shaders/spirv/spirv_processor.h @@ -624,6 +624,7 @@ protected: ExtSet_GLSL450 = 0, ExtSet_Printf = 1, ExtSet_ShaderDbg = 2, + ExtSet_DebugBreak = 3, ExtSet_Count, };