diff --git a/TODO b/TODO index 974b50c..d5e77a7 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,6 @@ Post-processing: * Lens dirt Technical: -* Profiling * GLSL with includes * GLSL constants generator * Common handling for parameters diff --git a/main.cc b/main.cc index e2dbd3a..6926527 100644 --- a/main.cc +++ b/main.cc @@ -85,15 +85,7 @@ void T_Main::mainLoop( ) render( ); T_Profiler::Profiler.end( "Full frame" ); SDL_GL_SwapWindow( window ); - p.endFrame( ); - const auto n( p.sections( ) ); - for ( auto i = 0u ; i < n ; i ++ ) { - printf( "%s: %fms (start %fms)\n" , - p.nameOf( i ).c_str( ) , - p.durationOf( i ) , - p.startOf( i ) ); - } } } } @@ -172,10 +164,13 @@ void T_Main::makeUI( ) ImGui::SetNextWindowPos( ImVec2( ) , ImGuiSetCond_Once ); ImGui::Begin( "Yay! Demo!" ); + ImGui::Checkbox( "Profiler" , &T_Profiler::Profiler.uiEnabled( ) ); raymarcher->makeUI( ); bloomPass->makeUI( ); ImGui::End( ); + + T_Profiler::Profiler.makeUI( ); } void T_Main::render( ) diff --git a/profiling.cc b/profiling.cc index b52d999..e77b156 100644 --- a/profiling.cc +++ b/profiling.cc @@ -109,6 +109,94 @@ void T_Profiler::end( current_ = Invalid; } +void T_Profiler::makeUI( ) +{ + if ( !uiEnabled_ ) { + return; + } + auto const n( sections_.size( ) ); + if ( n != secDurations_.size( ) ) { + return; + } + + auto const& dspSize( ImGui::GetIO( ).DisplaySize ); + ImGui::SetNextWindowSize( ImVec2( dspSize.x , 150 ) , + ImGuiSetCond_Once ); + ImGui::SetNextWindowPos( ImVec2( 0 , dspSize.y - 150 ) , + ImGuiSetCond_Once ); + ImGui::Begin( "Profiler" ); + + ImGui::BeginChild( "left" , ImVec2( 150 , 0 ) , true ); + float angle( 0 ); + for ( auto i = 0u ; i < n ; i ++ ) { + if ( displayed_.size( ) == i ) { + displayed_.push_back( true ); + } + angle = fmod( angle + 137 , 360 ); + ImVec4 color( 0 , 0 , 0 , 1 ); + ImGui::ColorConvertHSVtoRGB( angle / 360. , .5 , 1 , + color.x , color.y , color.z ); + ImGui::PushStyleColor( ImGuiCol_Text , color ); + ImGui::Checkbox( sections_[ i ].c_str( ) , + (bool*) &displayed_[ i ] ); + ImGui::PopStyleColor( ); + } + ImGui::EndChild( ); + ImGui::SameLine( ); + + auto* const dl( ImGui::GetWindowDrawList( ) ); + const ImVec2 wp( ImGui::GetWindowPos( ) ); + const ImVec2 pos( ImGui::GetCursorPos( ) ); + const ImVec2 ws( ImGui::GetWindowContentRegionMax( ) ); + const ImVec2 start( wp.x + pos.x , wp.y + pos.y ); + auto& style( ImGui::GetStyle( ) ); + const ImVec2 end( wp.x + ws.x + 1 - style.FramePadding.x , + wp.y + ws.y + 1 - style.FramePadding.y ); + dl->AddRectFilled( start , end , + ImGui::GetColorU32( ImVec4( .5 , .5 , .5 , .8 ) ) ); + + // Ms marks + static constexpr float msWidth = 20; + float lp( 0 ); + while ( lp < ws.x ) { + dl->AddLine( ImVec2( start.x + lp , start.y ) , + ImVec2( start.x + lp , end.y ) , + ImGui::GetColorU32( ImVec4( 0 , 0 , 0 , .8 ) ) ); + lp += msWidth; + } + + // 60/30FPS line + dl->AddLine( ImVec2( start.x + msWidth * 1000. / 60. , start.y ) , + ImVec2( start.x + msWidth * 1000. / 60. , end.y ) , + ImGui::GetColorU32( ImVec4( 0 , 1 , 0 , 1 ) ) ); + dl->AddLine( ImVec2( start.x + msWidth * 1000. / 30. , start.y ) , + ImVec2( start.x + msWidth * 1000. / 30. , end.y ) , + ImGui::GetColorU32( ImVec4( 1 , 0 , 0 , 1 ) ) ); + + // Plot + static constexpr float plHeight = 5; + float lh( 0 ); + angle = 0; + for ( auto i = 0u ; i < n ; i ++ ) { + angle = fmod( angle + 137 , 360 ); + if ( !displayed_[ i ] ) { + continue; + } + const float lx0 = msWidth * secStarts_[ i ]; + const float lx1 = msWidth * ( secStarts_[ i ] + secDurations_[ i ] ); + const float ly1 = lh + plHeight; + ImVec4 color( 0 , 0 , 0 , 1 ); + ImGui::ColorConvertHSVtoRGB( angle / 360. , .5 , 1 , + color.x , color.y , color.z ); + dl->AddRectFilled( ImVec2( start.x + lx0 , start.y + lh ) , + ImVec2( start.x + lx1 , start.y + ly1 ) , + ImGui::GetColorU32( color ) ); + lh = ly1 + 1; + } + + ImGui::End( ); +} + float T_Profiler::computeDuration( __rd__ const uint32_t section ) const { diff --git a/profiling.hh b/profiling.hh index b4c7e7c..07acad9 100644 --- a/profiling.hh +++ b/profiling.hh @@ -40,6 +40,9 @@ struct T_Profiler float startOf( __rd__ const uint32_t section ) const { return secStarts_[ section ]; } + void makeUI( ); + bool& uiEnabled( ) { return uiEnabled_; } + private: using T_SamplesList_ = std::vector< T_ProfilerSamples >; using T_Data_ = std::vector< T_SamplesList_ >; @@ -59,5 +62,8 @@ struct T_Profiler std::vector< float > secDurations_; std::vector< float > secStarts_; + + bool uiEnabled_ = false; + std::vector< int > displayed_; };