From d2ef9209bfc4d25d312a8353166d48ce3b707a05 Mon Sep 17 00:00:00 2001 From: Sylvain Doremus Date: Tue, 23 Jul 2024 14:12:56 +0200 Subject: [PATCH] NonSemanticDebug: Now forwarding parent scope variables to children scopes. It allows for RenderDoc to track those variables through scopes. --- source/CompilerSpirV/SpirVBlock.cpp | 3 + source/CompilerSpirV/SpirVBlock.hpp | 1 + source/CompilerSpirV/SpirVFunction.cpp | 1 + source/CompilerSpirV/SpirVFunction.hpp | 1 + .../CompilerSpirV/SpirVGenerateStatements.cpp | 56 ++++++++++++------- source/CompilerSpirV/SpirVModule.cpp | 15 ++++- source/CompilerSpirV/SpirVModule.hpp | 2 + .../CompilerSpirV/SpirVNonSemanticDebug.cpp | 42 ++++++++++---- .../CompilerSpirV/SpirVNonSemanticDebug.hpp | 10 ++-- 9 files changed, 96 insertions(+), 35 deletions(-) diff --git a/source/CompilerSpirV/SpirVBlock.cpp b/source/CompilerSpirV/SpirVBlock.cpp index fc83f2fb..3020ef2f 100644 --- a/source/CompilerSpirV/SpirVBlock.cpp +++ b/source/CompilerSpirV/SpirVBlock.cpp @@ -34,6 +34,7 @@ namespace spirv , blockEnd{ std::move( rhs.blockEnd ) } , allocator{ rhs.allocator } , variables{ std::move( rhs.variables ) } + , declaredVariables{ std::move( rhs.declaredVariables ) } , accessChains{ std::move( rhs.accessChains ) } , isInterrupted{ rhs.isInterrupted } { @@ -49,6 +50,7 @@ namespace spirv blockEnd = std::move( rhs.blockEnd ); allocator = rhs.allocator; variables = std::move( rhs.variables ); + declaredVariables = std::move( rhs.declaredVariables ); accessChains = std::move( rhs.accessChains ); isInterrupted = rhs.isInterrupted; @@ -65,6 +67,7 @@ namespace spirv , instructions{ alloc } , allocator{ alloc } , variables{ ast::StlMapAllocatorT< DebugId, DebugId >{ alloc } } + , declaredVariables{ ast::StlAllocatorT< DebugId >{ alloc } } , accessChains{ ast::StlPairAllocatorT< DebugIdList, DebugId >{ alloc } } { } diff --git a/source/CompilerSpirV/SpirVBlock.hpp b/source/CompilerSpirV/SpirVBlock.hpp index 3aca7ca8..a5e68e8c 100644 --- a/source/CompilerSpirV/SpirVBlock.hpp +++ b/source/CompilerSpirV/SpirVBlock.hpp @@ -92,6 +92,7 @@ namespace spirv // Used during construction. ast::ShaderAllocatorBlock * allocator; ast::Map< DebugId, DebugId > variables; + ast::Vector< DebugId > declaredVariables; ast::Vector< std::pair< DebugIdList, DebugId > > accessChains; bool isInterrupted{}; }; diff --git a/source/CompilerSpirV/SpirVFunction.cpp b/source/CompilerSpirV/SpirVFunction.cpp index 6bef49e5..2ee2c42a 100644 --- a/source/CompilerSpirV/SpirVFunction.cpp +++ b/source/CompilerSpirV/SpirVFunction.cpp @@ -14,6 +14,7 @@ namespace spirv , debugStart{ ast::StlAllocatorT< InstructionPtr >{ alloc } } , promotedParams{ alloc } , registeredVariables{ ast::StlMapAllocatorT< std::string, VariableInfo >{ alloc } } + , debugParams{ ast::StlAllocatorT< DebugId >{ alloc } } { } diff --git a/source/CompilerSpirV/SpirVFunction.hpp b/source/CompilerSpirV/SpirVFunction.hpp index d31d26d4..b7c6b586 100644 --- a/source/CompilerSpirV/SpirVFunction.hpp +++ b/source/CompilerSpirV/SpirVFunction.hpp @@ -137,6 +137,7 @@ namespace spirv InstructionList debugStart; Block promotedParams; ast::Map< std::string, VariableInfo, std::less<> > registeredVariables; + ast::Vector< DebugId > debugParams; }; using FunctionList = ast::Vector< Function >; diff --git a/source/CompilerSpirV/SpirVGenerateStatements.cpp b/source/CompilerSpirV/SpirVGenerateStatements.cpp index 6d2aa285..be4c3215 100644 --- a/source/CompilerSpirV/SpirVGenerateStatements.cpp +++ b/source/CompilerSpirV/SpirVGenerateStatements.cpp @@ -2349,15 +2349,22 @@ namespace spirv writeLine( instructions, getCurrentDebugStatement() ); } - void beginScope( Block & block ) + void beginScope( Block & block + , ast::Vector< DebugId > const * parentVariables ) { beginScope( block.instructions ); + + if ( parentVariables ) + { + m_result.importParentBlockVars( block, *parentVariables ); + } } glsl::Statement * parseScope( ast::stmt::Compound const * stmt , glsl::StatementType scopeBegin , glsl::StatementType scopeLine - , glsl::StatementType scopeEnd ) + , glsl::StatementType scopeEnd + , ast::Vector< DebugId > const * parentVariables ) { glsl::Statement * result{}; @@ -2369,7 +2376,7 @@ namespace spirv if ( scopeBegin == glsl::StatementType::eLexicalScopeBegin ) { m_debug.makeLexicalBlockInstruction( scopeBeginStmt ); - beginScope( m_currentBlock ); + beginScope( m_currentBlock, parentVariables ); } m_scopeLines.push_back( scopeLine ); @@ -2475,7 +2482,8 @@ namespace spirv parseScope( stmt , glsl::StatementType::eStructureScopeBegin , glsl::StatementType::eStructureMemberDecl - , glsl::StatementType::eStructureScopeEnd ); + , glsl::StatementType::eStructureScopeEnd + , nullptr ); auto variableId = m_result.bindBufferVariable( stmt->getName() , stmt->getBindingPoint() , stmt->getDescriptorSet() @@ -2544,7 +2552,8 @@ namespace spirv parseScope( stmt , glsl::StatementType::eStructureScopeBegin , glsl::StatementType::eStructureMemberDecl - , glsl::StatementType::eStructureScopeEnd ); + , glsl::StatementType::eStructureScopeEnd + , nullptr ); } } @@ -2559,12 +2568,14 @@ namespace spirv parseScope( stmt , glsl::StatementType::eLexicalScopeBegin , glsl::StatementType::eScopeLine - , glsl::StatementType::eLexicalScopeEnd ); + , glsl::StatementType::eLexicalScopeEnd + , nullptr ); } void visitDoWhileStmt( ast::stmt::DoWhile const * stmt )override { TraceFunc; + auto parentBlockVariables = m_currentBlock.declaredVariables; auto loopBlock = m_result.newBlock(); auto ifBlock = m_result.newBlock(); auto mergeBlock = m_result.newBlock(); @@ -2592,7 +2603,8 @@ namespace spirv parseScope( stmt , glsl::StatementType::eLexicalScopeBegin , glsl::StatementType::eScopeLine - , glsl::StatementType::eLexicalScopeEnd ); + , glsl::StatementType::eLexicalScopeEnd + , &parentBlockVariables ); // Branch current block to the continue target block. endBlock( m_currentBlock, ifBlock.label ); @@ -2615,12 +2627,7 @@ namespace spirv void visitElseStmt( ast::stmt::Else const * stmt )override { - TraceFunc; - beginControl( m_currentBlock ); - parseScope( stmt - , glsl::StatementType::eLexicalScopeBegin - , glsl::StatementType::eScopeLine - , glsl::StatementType::eLexicalScopeEnd ); + ast::Logger::logError( "Unexpected Else statement." ); } void visitForStmt( ast::stmt::For const * stmt )override @@ -2807,6 +2814,7 @@ namespace spirv { TraceFunc; ++m_ifStmts; + auto parentBlockVariables = m_currentBlock.declaredVariables; auto contentBlock = m_result.newBlock(); auto mergeBlock = m_result.newBlock(); @@ -2835,17 +2843,23 @@ namespace spirv parseScope( stmt , glsl::StatementType::eLexicalScopeBegin , glsl::StatementType::eScopeLine - , glsl::StatementType::eLexicalScopeEnd ); + , glsl::StatementType::eLexicalScopeEnd + , &parentBlockVariables ); endBlock( m_currentBlock, mergeBlock.label ); if ( stmt->getElse() ) { m_currentBlock = std::move( elseBlock ); - stmt->getElse()->accept( this ); + beginControl( m_currentBlock ); + parseScope( stmt->getElse() + , glsl::StatementType::eLexicalScopeBegin + , glsl::StatementType::eScopeLine + , glsl::StatementType::eLexicalScopeEnd + , &parentBlockVariables ); endBlock( m_currentBlock, mergeBlock.label ); } - beginScope( mergeBlock ); + beginScope( mergeBlock, &parentBlockVariables ); // Current block becomes the merge block. m_currentBlock = std::move( mergeBlock ); @@ -3169,6 +3183,7 @@ namespace spirv void visitSwitchStmt( ast::stmt::Switch const * stmt )override { TraceFunc; + auto parentBlockVariables = m_currentBlock.declaredVariables; ast::Vector< Block > caseBlocks{ m_allocator }; ast::Map< int32_t, spv::Id > caseBlocksIds{ m_allocator }; auto mergeBlock = m_result.newBlock(); @@ -3218,7 +3233,8 @@ namespace spirv parseScope( &caseStmt , glsl::StatementType::eLexicalScopeBegin , glsl::StatementType::eScopeLine - , glsl::StatementType::eLexicalScopeEnd ); + , glsl::StatementType::eLexicalScopeEnd + , &parentBlockVariables ); if ( m_currentBlock.isInterrupted ) { @@ -3258,7 +3274,8 @@ namespace spirv parseScope( defaultStmt , glsl::StatementType::eLexicalScopeBegin , glsl::StatementType::eScopeLine - , glsl::StatementType::eLexicalScopeEnd ); + , glsl::StatementType::eLexicalScopeEnd + , &parentBlockVariables ); } consumeDebugStatement( glsl::StatementType::eLexicalScopeEnd ); @@ -3393,7 +3410,8 @@ namespace spirv parseScope( stmt , glsl::StatementType::eStructureScopeBegin , glsl::StatementType::eStructureMemberDecl - , glsl::StatementType::eStructureScopeEnd ); + , glsl::StatementType::eStructureScopeEnd + , nullptr ); } DebugId submitAndLoad( ast::expr::Expr const & expr ) diff --git a/source/CompilerSpirV/SpirVModule.cpp b/source/CompilerSpirV/SpirVModule.cpp index 2e87fda0..21b5d49f 100644 --- a/source/CompilerSpirV/SpirVModule.cpp +++ b/source/CompilerSpirV/SpirVModule.cpp @@ -1142,7 +1142,7 @@ namespace spirv auto funcTypeId = m_types.registerFunctionType( funcTypes ); m_currentFunction->debugTypeId = funcTypeId.debug; DebugId scopeLineId{}; - m_nonSemanticDebug.declareFunction( *m_currentFunction + m_currentFunction->debugParams = m_nonSemanticDebug.declareFunction( *m_currentFunction , name , params , funcParams @@ -1182,6 +1182,16 @@ namespace spirv return result; } + void Module::importParentBlockVars( Block & block + , ast::Vector< DebugId > const & parentVariables ) + { + for ( auto & debugVarDesc : parentVariables ) + { + m_nonSemanticDebug.declareLocalVariable( block.instructions, debugVarDesc ); + block.declaredVariables.push_back( debugVarDesc ); + } + } + void Module::endFunction() { if ( m_currentFunction @@ -1562,7 +1572,8 @@ namespace spirv } m_registeredVariablesTypes.try_emplace( varId, rawTypeId ); - m_nonSemanticDebug.declareVariable( block.instructions, name, type, varId, initialiser, debugStatement ); + auto debugVarDesc = m_nonSemanticDebug.declareVariable( block.instructions, name, type, varId, initialiser, debugStatement ); + block.declaredVariables.emplace_back( debugVarDesc ); } //************************************************************************* diff --git a/source/CompilerSpirV/SpirVModule.hpp b/source/CompilerSpirV/SpirVModule.hpp index df607ba8..c4c4c97b 100644 --- a/source/CompilerSpirV/SpirVModule.hpp +++ b/source/CompilerSpirV/SpirVModule.hpp @@ -209,6 +209,8 @@ namespace spirv , glsl::Statement const * scopeBeginDebugStatement , glsl::Statement const * firstLineStatement ); SDWSPIRV_API Block newBlock(); + SDWSPIRV_API void importParentBlockVars( Block & block + , ast::Vector< DebugId > const & parentVariables ); SDWSPIRV_API void endFunction(); SDWSPIRV_API spv::Id getNextId(); diff --git a/source/CompilerSpirV/SpirVNonSemanticDebug.cpp b/source/CompilerSpirV/SpirVNonSemanticDebug.cpp index ee3ff21d..ac92ab76 100644 --- a/source/CompilerSpirV/SpirVNonSemanticDebug.cpp +++ b/source/CompilerSpirV/SpirVNonSemanticDebug.cpp @@ -261,7 +261,20 @@ namespace spirv::debug , debug::makeValueIdList( m_allocator, flagsId, funcTypes ) ); } - void NonSemanticDebug::declareVariable( InstructionList & instructions + void NonSemanticDebug::declareLocalVariable( InstructionList & instructions + , DebugId const & variableId ) + { + if ( !m_enabled || !variableId.debug ) + { + return; + } + + makeDebugInstruction( spv::NonSemanticShaderDebugInfo100Instructions::Declare + , instructions + , debug::makeValueIdList( m_allocator, variableId.debug, variableId.id, m_debugExpressionDummy ) ); + } + + DebugId NonSemanticDebug::declareVariable( InstructionList & instructions , std::string const & name , ast::type::TypePtr type , DebugId variableId @@ -271,7 +284,7 @@ namespace spirv::debug { if ( !m_enabled || !debugStatement ) { - return; + return variableId; } auto nameId = m_module.registerString( name ); @@ -300,9 +313,11 @@ namespace spirv::debug , instructions , debug::makeValueIdList( m_allocator, variableId.debug, initialiserId.id, m_debugExpressionDummy ) ); } + + return variableId; } - void NonSemanticDebug::declarePointerParam( InstructionList & instructions + DebugId NonSemanticDebug::declarePointerParam( InstructionList & instructions , std::string const & name , ast::type::TypePtr type , DebugId variableId @@ -311,33 +326,35 @@ namespace spirv::debug { if ( !m_enabled ) { - return; + return variableId; } // if debugStatement exists, the variable will be declared prior to this call if ( !debugStatement ) { - declareVariable( instructions + return declareVariable( instructions , name , std::move( type ) , std::move( variableId ) , std::move( initialiser ) , m_currentFunctionFirstLineStatement ); } + + return variableId; } - void NonSemanticDebug::declareAccessChain( InstructionList & instructions + DebugId NonSemanticDebug::declareAccessChain( InstructionList & instructions , ast::expr::Expr const & expr , glsl::Statement const * debugStatement , DebugId & resultId ) { if ( !m_enabled || !debugStatement || !m_config ) { - return; + return resultId; } resultId.debug = ValueId{ getNextId(), expr.getType() }; - declareVariable( instructions + return declareVariable( instructions , glsl::getExprName( *m_config, expr ) , expr.getType() , resultId @@ -346,7 +363,7 @@ namespace spirv::debug , true ); } - void NonSemanticDebug::declareFunction( Function & function + ast::Vector< DebugId > NonSemanticDebug::declareFunction( Function & function , std::string const & name , ast::var::VariableList const & params , DebugIdList const & funcParams @@ -354,9 +371,11 @@ namespace spirv::debug , glsl::Statement const * scopeBeginDebugStatement , glsl::Statement const * firstLineStatement ) { + ast::Vector< DebugId > result{ m_allocator }; + if ( !m_enabled || !declDebugStatement || !scopeBeginDebugStatement || !firstLineStatement ) { - return; + return result; } m_currentFunctionFirstLineStatement = firstLineStatement; @@ -387,6 +406,7 @@ namespace spirv::debug auto paramTypeId = m_module.registerType( param->getType(), scopeBeginDebugStatement ); auto paramColumnId = m_module.registerLiteral( 0u ); auto paramFlagsId = m_module.registerLiteral( 0u ); + result.emplace_back( *itParam ); makeDebugInstruction( spv::NonSemanticShaderDebugInfo100Instructions::LocalVariable , m_declarations , itParam->debug @@ -395,6 +415,8 @@ namespace spirv::debug ++itParam; } + + return result; } void NonSemanticDebug::makeEntryPointInstruction( DebugId functionId ) diff --git a/source/CompilerSpirV/SpirVNonSemanticDebug.hpp b/source/CompilerSpirV/SpirVNonSemanticDebug.hpp index 723623db..0e1a13ff 100644 --- a/source/CompilerSpirV/SpirVNonSemanticDebug.hpp +++ b/source/CompilerSpirV/SpirVNonSemanticDebug.hpp @@ -74,24 +74,26 @@ namespace spirv::debug // // Variables declarations // - void declareVariable( InstructionList & instructions + void declareLocalVariable( InstructionList & instructions + , DebugId const & variableId ); + DebugId declareVariable( InstructionList & instructions , std::string const & name , ast::type::TypePtr type , DebugId variableId , DebugId initialiser , glsl::Statement const * debugStatement , bool isAccessChain = false ); - void declarePointerParam( InstructionList & instructions + DebugId declarePointerParam( InstructionList & instructions , std::string const & name , ast::type::TypePtr type , DebugId variableId , DebugId initialiser , glsl::Statement const * debugStatement ); - void declareAccessChain( InstructionList & instructions + DebugId declareAccessChain( InstructionList & instructions , ast::expr::Expr const & expr , glsl::Statement const * debugStatement , DebugId & resultId ); - void declareFunction( Function & function + ast::Vector< DebugId > declareFunction( Function & function , std::string const & name , ast::var::VariableList const & params , DebugIdList const & funcParams