From 208d8d941eb94c7d65e12a589f19b77066c083db Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Mon, 23 Jun 2025 15:53:57 +0100 Subject: [PATCH] Set merge point per thread in the SPIRV debugger not per tangle void ThreadState::SkipIgnoredInstructions() processes merge instructions before control flow is updated and the tangle might have diverged and the merge point would be set to for threads in the tangle without executing the merge instruction --- .../shaders/spirv/spirv_debug_setup.cpp | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp index c86e0df9f..ac6431c31 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp @@ -2608,7 +2608,7 @@ rdcarray Debugger::ContinueDebug() if(!tangle.IsAliveActive()) continue; - rdcarray threadRefs = tangle.GetThreadRefs(); + const rdcarray &threadRefs = tangle.GetThreadRefs(); // calculate the current active thread mask from the threads in the tangle { // one bool per workgroup thread @@ -2633,7 +2633,7 @@ rdcarray Debugger::ContinueDebug() ExecutionPoint newFunctionReturnPoint = INVALID_EXECUTION_POINT; uint32_t countActiveThreads = 0; uint32_t countDivergedThreads = 0; - uint32_t countConvergePointThreads = 0; + uint32_t countIdentialConvergePointThreads = 0; uint32_t countFunctionReturnThreads = 0; // step all active members of the workgroup @@ -2748,6 +2748,7 @@ rdcarray Debugger::ContinueDebug() threadExecutionStates[threadId] = thread.enteredPoints; uint32_t threadConvergeInstruction = thread.convergenceInstruction; + tangle.SetThreadMergePoint(threadId, threadConvergeInstruction); // the thread activated a new convergence point if(threadConvergeInstruction != INVALID_EXECUTION_POINT) { @@ -2756,13 +2757,10 @@ rdcarray Debugger::ContinueDebug() newConvergeInstruction = threadConvergeInstruction; RDCASSERTNOTEQUAL(newConvergeInstruction, INVALID_EXECUTION_POINT); } - else - { - // All the threads in the tangle should set the same convergence point - RDCASSERTEQUAL(threadConvergeInstruction, newConvergeInstruction); - } - ++countConvergePointThreads; + if(newConvergeInstruction == threadConvergeInstruction) + ++countIdentialConvergePointThreads; } + uint32_t threadFunctionReturnPoint = thread.functionReturnPoint; // the thread activated a new function return point if(threadFunctionReturnPoint != INVALID_EXECUTION_POINT) @@ -2791,12 +2789,11 @@ rdcarray Debugger::ContinueDebug() if(activeMask[lane]) workgroup[lane].currentInstruction = workgroup[lane].nextInstruction; } - if(countConvergePointThreads) - { - // all the active threads should have a convergence point if any have one - RDCASSERTEQUAL(countConvergePointThreads, countActiveThreads); + // If the tangle has a common merge point set it here (this will clear the thread merge point) + // otherwise the convergence point will come from the threads during control flow divergence porcessing + if(countIdentialConvergePointThreads == countActiveThreads) tangle.AddMergePoint(newConvergeInstruction); - } + if(countFunctionReturnThreads) { // all the active threads should have a function return point if any have one