From 79e80c83379020970afaaa3268c6db1b1de78563 Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Mon, 28 Apr 2025 11:28:14 +0100 Subject: [PATCH] Added assert for Op::ControlBarrier that the workgroup is converged New helper method ThreadState::WorkgroupIsDiverged() --- .../driver/shaders/spirv/spirv_debug.cpp | 27 ++++++++++++++++++- renderdoc/driver/shaders/spirv/spirv_debug.h | 3 +++ .../shaders/spirv/spirv_debug_setup.cpp | 5 ++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/renderdoc/driver/shaders/spirv/spirv_debug.cpp b/renderdoc/driver/shaders/spirv/spirv_debug.cpp index 766a83522..ae35222a1 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug.cpp @@ -739,6 +739,26 @@ void ThreadState::EnterEntryPoint(ShaderDebugState *state) EnterFunction({}); m_State = NULL; + currentInstruction = nextInstruction; +} + +bool ThreadState::WorkgroupIsDiverged(const rdcarray &workgroup) +{ + uint32_t instr0 = ~0U; + for(size_t i = 0; i < workgroup.size(); i++) + { + if(workgroup[i].Finished()) + continue; + if(instr0 == ~0U) + { + instr0 = workgroup[i].currentInstruction; + continue; + } + // not executing the same instruction + if(workgroup[i].currentInstruction != instr0) + return true; + } + return false; } void ThreadState::StepNext(ShaderDebugState *state, const rdcarray &workgroup, @@ -3741,11 +3761,16 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray ////////////////////////////////////////////////////////////////////////////// case Op::MemoryBarrier: - case Op::ControlBarrier: { // do nothing for now break; } + case Op::ControlBarrier: + { + // For thread barriers the threads must be converged + RDCASSERT(!WorkgroupIsDiverged(workgroup)); + break; + } case Op::Label: case Op::SelectionMerge: case Op::LoopMerge: diff --git a/renderdoc/driver/shaders/spirv/spirv_debug.h b/renderdoc/driver/shaders/spirv/spirv_debug.h index d52a2543f..bbb45ab5f 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug.h +++ b/renderdoc/driver/shaders/spirv/spirv_debug.h @@ -202,6 +202,7 @@ struct ThreadState bool Finished() const; + uint32_t currentInstruction; uint32_t nextInstruction; const GlobalState &global; @@ -269,6 +270,8 @@ private: void SkipIgnoredInstructions(); void SetConvergencePoint(Id block); + static bool WorkgroupIsDiverged(const rdcarray &workgroup); + ShaderDebugState *m_State = NULL; }; diff --git a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp index 3c5a83595..ddeb0b74c 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp @@ -2728,6 +2728,11 @@ rdcarray Debugger::ContinueDebug() if(thread.diverged) ++countDivergedThreads; } + for(size_t lane = 0; lane < workgroup.size(); lane++) + { + if(activeMask[lane]) + workgroup[lane].currentInstruction = workgroup[lane].nextInstruction; + } if(countConvergePointThreads) { // all the active threads should have a convergence point if any have one