From 7f130077da0e23c68be61373449d20c5c8b027f6 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 23 Feb 2021 12:12:46 +0000 Subject: [PATCH] When source debugging, skip non-mapped instructions * We entirely skip over any instructions that don't have a source mapping. These are assumed to be filler instructions or others that don't correspond usefully to anything in the source. --- qrenderdoc/Windows/ShaderViewer.cpp | 67 ++++++++++++++++++++++++++--- qrenderdoc/Windows/ShaderViewer.h | 1 + 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/qrenderdoc/Windows/ShaderViewer.cpp b/qrenderdoc/Windows/ShaderViewer.cpp index 3bb94259e..bc11f1873 100644 --- a/qrenderdoc/Windows/ShaderViewer.cpp +++ b/qrenderdoc/Windows/ShaderViewer.cpp @@ -890,8 +890,41 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR // source file, the second time jumps to it. if(preferSourceDebug) { - gotoSourceDebugging(); - updateDebugState(); + // if we're not on a source line, move forward to the first source line + while(!m_CurInstructionScintilla) + { + do + { + applyForwardsChange(); + + if(m_Trace->lineInfo[GetCurrentState().nextInstruction].fileIndex >= 0) + break; + + if(IsLastState()) + break; + + } while(true); + + updateDebugState(); + + if(IsLastState()) + break; + } + + // if we got to the last state something's wrong - we're preferring source debug but we + // didn't ever reach an instruction mapped to source lines? just reverse course and don't + // switch to source debugging + if(IsLastState()) + { + m_FirstSourceStateIdx = ~0U; + runTo({}, false); + } + else + { + m_FirstSourceStateIdx = m_CurrentStateIdx; + gotoSourceDebugging(); + updateDebugState(); + } } m_DeferredInit = false; @@ -1930,6 +1963,10 @@ bool ShaderViewer::step(bool forward, StepMode mode) if((forward && IsLastState()) || (!forward && IsFirstState())) return false; + // also stop if we reach the first real source-mapped instruction, while source debugging + if(!forward && isSourceDebugging() && m_CurrentStateIdx == m_FirstSourceStateIdx) + return false; + if(isSourceDebugging()) { LineColumnInfo oldLine = m_Trace->lineInfo[GetCurrentState().nextInstruction]; @@ -1951,13 +1988,17 @@ bool ShaderViewer::step(bool forward, StepMode mode) if((forward && IsLastState()) || (!forward && IsFirstState())) break; + // also stop if we reach the first real source-mapped instruction, while source debugging + if(!forward && isSourceDebugging() && m_CurrentStateIdx == m_FirstSourceStateIdx) + break; + // keep going if we're still on the same source line as we started LineColumnInfo curLine = m_Trace->lineInfo[GetCurrentState().nextInstruction]; if(curLine.SourceEqual(oldLine)) continue; - // if we're stepping into, break now as soon as we hit a different line - if(mode == StepInto) + // if we're in an invalid file, skip it as unmapped instructions + if(curLine.fileIndex == -1) break; // we're on a different line but that might not be enough for Step Out or Step Over @@ -2162,6 +2203,9 @@ void ShaderViewer::runTo(QVector runToInstruction, bool forward, ShaderE { if(IsFirstState()) break; + // also stop if we reach the first real source-mapped instruction, while source debugging + if(isSourceDebugging() && m_CurrentStateIdx == m_FirstSourceStateIdx) + break; applyBackwardsChange(); } } @@ -2987,7 +3031,7 @@ void ShaderViewer::updateDebugState() if(state.nextInstruction < m_Trace->lineInfo.size()) { - LineColumnInfo &lineInfo = m_Trace->lineInfo[state.nextInstruction]; + LineColumnInfo lineInfo = m_Trace->lineInfo[state.nextInstruction]; // highlight the current line { @@ -3002,6 +3046,19 @@ void ShaderViewer::updateDebugState() ensureLineScrolled(m_DisassemblyView, lineInfo.disassemblyLine - 1); } + if(IsLastState() && (lineInfo.fileIndex < 0 || lineInfo.fileIndex >= m_FileScintillas.count())) + { + // if the last state doesn't have source mapping information, display the line info for the + // last state which did. + for(int stateLookbackIdx = (int)m_CurrentStateIdx; stateLookbackIdx > 0; stateLookbackIdx--) + { + lineInfo = m_Trace->lineInfo[m_States[stateLookbackIdx].nextInstruction]; + + if(lineInfo.fileIndex >= 0 && lineInfo.fileIndex < m_FileScintillas.count()) + break; + } + } + if(lineInfo.fileIndex >= 0 && lineInfo.fileIndex < m_FileScintillas.count()) { m_CurInstructionScintilla = m_FileScintillas[lineInfo.fileIndex]; diff --git a/qrenderdoc/Windows/ShaderViewer.h b/qrenderdoc/Windows/ShaderViewer.h index b8b8eea10..78a097574 100644 --- a/qrenderdoc/Windows/ShaderViewer.h +++ b/qrenderdoc/Windows/ShaderViewer.h @@ -266,6 +266,7 @@ private: bool m_Saved = false; ShaderDebugTrace *m_Trace = NULL; + size_t m_FirstSourceStateIdx = ~0U; rdcarray m_States; size_t m_CurrentStateIdx = 0; rdcarray m_Variables;