From 62466b41b77bf0337b126b517a93303c42cc6e9b Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Sun, 29 Mar 2020 17:12:11 +0200 Subject: [PATCH] Use ImGui to draw renderer stats for com_showFPS 1 --- neo/framework/Common.cpp | 4 +- neo/framework/Common_local.h | 12 +++ neo/framework/Console.cpp | 110 +++++++++++++++++++++++-- neo/framework/common_frame.cpp | 8 +- neo/imgui/BFGimguiImpl.cpp | 27 +++++- neo/imgui/ImGui_Hooks.h | 3 + neo/libs/imgui/imgui.cpp | 3 +- neo/renderer/RenderBackend.h | 19 ----- neo/renderer/RenderCommon.h | 34 +------- neo/renderer/RenderProgs_embedded.h | 46 +++++++---- neo/renderer/RenderSystem.cpp | 31 +++++-- neo/renderer/RenderSystem.h | 53 +++++++++++- neo/renderer/RenderSystem_init.cpp | 12 +-- neo/renderer/tr_frontend_addmodels.cpp | 7 ++ 14 files changed, 272 insertions(+), 97 deletions(-) diff --git a/neo/framework/Common.cpp b/neo/framework/Common.cpp index 58781b2d..28d47a3a 100644 --- a/neo/framework/Common.cpp +++ b/neo/framework/Common.cpp @@ -903,7 +903,7 @@ void idCommonLocal::RenderSplash() renderSystem->SetColor4( 1, 1, 1, 1 ); renderSystem->DrawStretchPic( barWidth, barHeight, renderSystem->GetVirtualWidth() - barWidth * 2.0f, renderSystem->GetVirtualHeight() - barHeight * 2.0f, 0, 0, 1, 1, splashScreen ); - const emptyCommand_t* cmd = renderSystem->SwapCommandBuffers( &time_frontend, &time_backend, &time_shadows, &time_gpu ); + const emptyCommand_t* cmd = renderSystem->SwapCommandBuffers( &time_frontend, &time_backend, &time_shadows, &time_gpu, &stats_backend, &stats_frontend ); renderSystem->RenderCommandBuffers( cmd ); // RB: this is the same as Doom 3 renderSystem->EndFrame() @@ -939,7 +939,7 @@ void idCommonLocal::RenderBink( const char* path ) while( ( Sys_Milliseconds() <= ( material->GetCinematicStartTime() + cinematicLength ) ) && material->CinematicIsPlaying() ) { renderSystem->DrawStretchPic( chop, 0, imageWidth, renderSystem->GetVirtualHeight(), 0, 0, 1, 1, material ); - const emptyCommand_t* cmd = renderSystem->SwapCommandBuffers( &time_frontend, &time_backend, &time_shadows, &time_gpu ); + const emptyCommand_t* cmd = renderSystem->SwapCommandBuffers( &time_frontend, &time_backend, &time_shadows, &time_gpu, &stats_backend, &stats_frontend ); renderSystem->RenderCommandBuffers( cmd ); Sys_GenerateEvents(); diff --git a/neo/framework/Common_local.h b/neo/framework/Common_local.h index 7859f7d2..7e05d538 100644 --- a/neo/framework/Common_local.h +++ b/neo/framework/Common_local.h @@ -140,6 +140,8 @@ struct frameTiming_t class idCommonLocal : public idCommon { + friend class idConsoleLocal; + public: idCommonLocal(); @@ -297,26 +299,32 @@ public: { return gameThread.GetThreadTotalTime(); } + int GetGameThreadGameTime() const { return gameThread.GetThreadGameTime(); } + int GetGameThreadRenderTime() const { return gameThread.GetThreadRenderTime(); } + int GetRendererBackEndMicroseconds() const { return time_backend; } + int GetRendererShadowsMicroseconds() const { return time_shadows; } + int GetRendererIdleMicroseconds() const { return mainFrameTiming.startRenderTime - mainFrameTiming.finishSyncTime; } + int GetRendererGPUMicroseconds() const { return time_gpu; @@ -535,6 +543,10 @@ private: uint64 time_shadows; // renderer backend waiting for shadow volumes to be created uint64 time_gpu; // total gpu time, at least for PC + // RB: r_speeds counters + backEndCounters_t stats_backend; + performanceCounters_t stats_frontend; + // Used during loading screens int lastPacifierSessionTime; int lastPacifierGuiTime; diff --git a/neo/framework/Console.cpp b/neo/framework/Console.cpp index d8e2ff1d..04dd19d6 100644 --- a/neo/framework/Console.cpp +++ b/neo/framework/Console.cpp @@ -31,6 +31,7 @@ If you have questions concerning this license or the applicable additional terms #include "ConsoleHistory.h" #include "../renderer/ResolutionScale.h" #include "Common_local.h" +#include "../imgui/BFGimgui.h" #define CON_TEXTSIZE 0x30000 #define NUM_CON_TIMES 4 @@ -215,12 +216,18 @@ float idConsoleLocal::DrawFPS( float y ) static int index; static int previous; +#if !defined( USE_VULKAN ) + bool renderImGuiPerfWindow = ImGuiHook::IsReadyToRender() && ( com_showFPS.GetInteger() == 1 ); +#endif + // don't use serverTime, because that will be drifting to // correct for internet lag changes, timescales, timedemos, etc int t = Sys_Milliseconds(); int frameTime = t - previous; previous = t; + int fps = 0; + previousTimes[index % FPS_FRAMES] = frameTime; index++; if( index > FPS_FRAMES ) @@ -235,13 +242,20 @@ float idConsoleLocal::DrawFPS( float y ) { total = 1; } - int fps = 1000000 * FPS_FRAMES / total; + fps = 1000000 * FPS_FRAMES / total; fps = ( fps + 500 ) / 1000; const char* s = va( "%ifps", fps ); int w = strlen( s ) * BIGCHAR_WIDTH; +#if defined( USE_VULKAN ) renderSystem->DrawBigStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, s, colorWhite, true ); +#else + if( com_showFPS.GetInteger() == 2 ) + { + renderSystem->DrawBigStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, s, colorWhite, true ); + } +#endif } y += BIGCHAR_HEIGHT + 4; @@ -253,12 +267,6 @@ float idConsoleLocal::DrawFPS( float y ) } // DG end - // print the resolution scale so we can tell when we are at reduced resolution - idStr resolutionText; - resolutionScale.GetConsoleText( resolutionText ); - int w = resolutionText.Length() * BIGCHAR_WIDTH; - renderSystem->DrawBigStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, resolutionText.c_str(), colorWhite, true ); - const int gameThreadTotalTime = commonLocal.GetGameThreadTotalTime(); const int gameThreadGameTime = commonLocal.GetGameThreadGameTime(); const int gameThreadRenderTime = commonLocal.GetGameThreadRenderTime(); @@ -268,6 +276,91 @@ float idConsoleLocal::DrawFPS( float y ) const int rendererGPUTime = commonLocal.GetRendererGPUMicroseconds(); const int maxTime = 16; +#if !defined( USE_VULKAN ) + +#if 1 + // RB: use ImGui to show more detailed stats about the scene loads + if( ImGuiHook::IsReadyToRender() ) + { + int32 statsWindowWidth = 550; + int32 statsWindowHeight = 290; + + ImVec2 pos; + pos.x = renderSystem->GetWidth() - statsWindowWidth; + pos.y = 0; + + ImGui::SetNextWindowPos( pos ); + ImGui::SetNextWindowSize( ImVec2( statsWindowWidth, statsWindowHeight ) ); + + ImGui::Begin( "Performance Stats" ); + + //ImGui::Text( "Render API: OpenGL" ); + + ImGui::TextColored( ImVec4( 0.00f, 1.00f, 0.00f, 1.00f ), "GENERAL: views:%i draws:%i tris:%i (shdw:%i)", + commonLocal.stats_frontend.c_numViews, + commonLocal.stats_backend.c_drawElements + commonLocal.stats_backend.c_shadowElements, + ( commonLocal.stats_backend.c_drawIndexes + commonLocal.stats_backend.c_shadowIndexes ) / 3, + commonLocal.stats_backend.c_shadowIndexes / 3 ); + + ImGui::Text( "DYNAMIC: callback:%i md5:%i dfrmVerts:%i dfrmTris:%i tangTris:%i guis:%i", + commonLocal.stats_frontend.c_entityDefCallbacks, + commonLocal.stats_frontend.c_generateMd5, + commonLocal.stats_frontend.c_deformedVerts, + commonLocal.stats_frontend.c_deformedIndexes / 3, + commonLocal.stats_frontend.c_tangentIndexes / 3, + commonLocal.stats_frontend.c_guiSurfs + ); + + //ImGui::Text( "Cull: %i box in %i box out\n", + // commonLocal.stats_frontend.c_box_cull_in, commonLocal.stats_frontend.c_box_cull_out ); + + ImGui::Text( "ADDMODEL: callback:%i createInteractions:%i createShadowVolumes:%i", + commonLocal.stats_frontend.c_entityDefCallbacks, + commonLocal.stats_frontend.c_createInteractions, + commonLocal.stats_frontend.c_createShadowVolumes ); + + ImGui::Text( "viewEntities:%i shadowEntities:%i viewLights:%i\n", commonLocal.stats_frontend.c_visibleViewEntities, + commonLocal.stats_frontend.c_shadowViewEntities, + commonLocal.stats_frontend.c_viewLights ); + + ImGui::Text( "UPDATES: entityUpdates:%i entityRefs:%i lightUpdates:%i lightRefs:%i\n", + commonLocal.stats_frontend.c_entityUpdates, commonLocal.stats_frontend.c_entityReferences, + commonLocal.stats_frontend.c_lightUpdates, commonLocal.stats_frontend.c_lightReferences ); + + //ImGui::Text( "frameData: %i (%i)\n", frameData->frameMemoryAllocated.GetValue(), frameData->highWaterAllocated ); + + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Spacing(); + + ImGui::TextColored( ImVec4( 0.00f, 1.00f, 1.00f, 1.00f ), "Average FPS %i", fps ); + + ImGui::Spacing(); + + ImVec4 colorWhite( 1.0f, 1.0f, 1.0f, 1.0f ); + ImVec4 colorRed( 1.0f, 0.0f, 0.0f, 1.0f ); + + ImGui::TextColored( gameThreadTotalTime > maxTime ? colorRed : colorWhite, "G+RF: %4d ms", gameThreadTotalTime ); + ImGui::TextColored( gameThreadGameTime > maxTime ? colorRed : colorWhite, "G: %4d ms", gameThreadGameTime ); + ImGui::TextColored( gameThreadRenderTime > maxTime ? colorRed : colorWhite, "RF: %4d ms", gameThreadRenderTime ); + ImGui::TextColored( rendererBackEndTime > maxTime * 1000 ? colorRed : colorWhite, "RB: %4d ms", int( rendererBackEndTime ) ); + ImGui::TextColored( rendererShadowsTime > maxTime * 1000 ? colorRed : colorWhite, "SHADOWS: %4d ms", int( rendererShadowsTime ) ); + ImGui::TextColored( rendererGPUIdleTime > maxTime * 1000 ? colorRed : colorWhite, "IDLE: %4d ms", int( rendererGPUIdleTime ) ); + ImGui::TextColored( rendererGPUTime > maxTime * 1000 ? colorRed : colorWhite, "GPU: %4d ms", int( rendererGPUTime ) ); + + ImGui::End(); + } +#endif + + return y; +#else + + // print the resolution scale so we can tell when we are at reduced resolution + idStr resolutionText; + resolutionScale.GetConsoleText( resolutionText ); + int w = resolutionText.Length() * BIGCHAR_WIDTH; + renderSystem->DrawBigStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, resolutionText.c_str(), colorWhite, true ); + y += SMALLCHAR_HEIGHT + 4; idStr timeStr; timeStr.Format( "%sG+RF: %4d", gameThreadTotalTime > maxTime ? S_COLOR_RED : "", gameThreadTotalTime ); @@ -305,6 +398,7 @@ float idConsoleLocal::DrawFPS( float y ) renderSystem->DrawSmallStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, timeStr.c_str(), colorWhite, false ); return y + BIGCHAR_HEIGHT + 4; +#endif } /* @@ -1322,6 +1416,7 @@ void idConsoleLocal::Draw( bool forceFullScreen ) float lefty = LOCALSAFE_TOP; float righty = LOCALSAFE_TOP; float centery = LOCALSAFE_TOP; + if( com_showFPS.GetBool() ) { righty = DrawFPS( righty ); @@ -1330,6 +1425,7 @@ void idConsoleLocal::Draw( bool forceFullScreen ) { righty = DrawMemoryUsage( righty ); } + DrawOverlayText( lefty, righty, centery ); DrawDebugGraphs(); } diff --git a/neo/framework/common_frame.cpp b/neo/framework/common_frame.cpp index 0e0c9f21..3777d5bc 100644 --- a/neo/framework/common_frame.cpp +++ b/neo/framework/common_frame.cpp @@ -434,7 +434,7 @@ void idCommonLocal::UpdateScreen( bool captureToImage, bool releaseMouse ) } // this should exit right after vsync, with the GPU idle and ready to draw - const emptyCommand_t* cmd = renderSystem->SwapCommandBuffers( &time_frontend, &time_backend, &time_shadows, &time_gpu ); + const emptyCommand_t* cmd = renderSystem->SwapCommandBuffers( &time_frontend, &time_backend, &time_shadows, &time_gpu, &stats_backend, &stats_frontend ); // get the GPU busy with new commands renderSystem->RenderCommandBuffers( cmd ); @@ -620,7 +620,7 @@ void idCommonLocal::Frame() // foresthale 2014-05-12: also check com_editors as many of them are not particularly thread-safe (editLights for example) if( com_smp.GetInteger() > 0 && com_editors == 0 ) { - renderCommands = renderSystem->SwapCommandBuffers( &time_frontend, &time_backend, &time_shadows, &time_gpu ); + renderCommands = renderSystem->SwapCommandBuffers( &time_frontend, &time_backend, &time_shadows, &time_gpu, &stats_backend, &stats_frontend ); } else if( com_smp.GetInteger() < 0 ) { @@ -631,7 +631,7 @@ void idCommonLocal::Frame() { // the GPU will stay idle through command generation for minimal // input latency - renderSystem->SwapCommandBuffers_FinishRendering( &time_frontend, &time_backend, &time_shadows, &time_gpu ); + renderSystem->SwapCommandBuffers_FinishRendering( &time_frontend, &time_backend, &time_shadows, &time_gpu, &stats_backend, &stats_frontend ); } frameTiming.finishSyncTime = Sys_Microseconds(); @@ -853,7 +853,7 @@ void idCommonLocal::Frame() if( !com_smp.GetInteger() < 0 ) { // RB: this is the same as Doom 3 renderSystem->EndFrame() - renderSystem->SwapCommandBuffers_FinishRendering( &time_frontend, &time_backend, &time_shadows, &time_gpu ); + renderSystem->SwapCommandBuffers_FinishRendering( &time_frontend, &time_backend, &time_shadows, &time_gpu, &stats_backend, &stats_frontend ); } else if( com_smp.GetInteger() == 0 || com_editors != 0 ) { diff --git a/neo/imgui/BFGimguiImpl.cpp b/neo/imgui/BFGimguiImpl.cpp index ae8d9b72..ab2c7e69 100644 --- a/neo/imgui/BFGimguiImpl.cpp +++ b/neo/imgui/BFGimguiImpl.cpp @@ -206,7 +206,7 @@ void SetClipboardText( void*, const char* text ) bool ShowWindows() { - return ( ImGuiTools::AreEditorsActive() || imgui_showDemoWindow.GetBool() ); + return ( ImGuiTools::AreEditorsActive() || imgui_showDemoWindow.GetBool() || com_showFPS.GetInteger() > 0 ); } bool UseInput() @@ -340,7 +340,7 @@ bool InjectMouseWheel( int delta ) void NewFrame() { - if( IsInitialized() && ShowWindows() ) + if( !g_haveNewFrame && IsInitialized() && ShowWindows() ) { ImGuiIO& io = ImGui::GetIO(); @@ -351,6 +351,12 @@ void NewFrame() int time = Sys_Milliseconds(); double current_time = time * 0.001; io.DeltaTime = g_Time > 0.0 ? ( float )( current_time - g_Time ) : ( float )( 1.0f / 60.0f ); + + if( io.DeltaTime <= 0.0F ) + { + io.DeltaTime = ( 1.0f / 60.0f ); + } + g_Time = current_time; // Setup inputs @@ -383,6 +389,23 @@ void NewFrame() } } +bool IsReadyToRender() +{ + if( IsInitialized() && ShowWindows() ) + { + if( !g_haveNewFrame ) + { + // for screenshots etc, where we didn't go through idCommonLocal::Frame() + // before idRenderSystemLocal::SwapCommandBuffers_FinishRendering() + NewFrame(); + } + + return true; + } + + return false; +} + void Render() { if( IsInitialized() && ShowWindows() ) diff --git a/neo/imgui/ImGui_Hooks.h b/neo/imgui/ImGui_Hooks.h index 9d5befaa..7095863d 100644 --- a/neo/imgui/ImGui_Hooks.h +++ b/neo/imgui/ImGui_Hooks.h @@ -25,6 +25,9 @@ bool InjectMouseWheel( int delta ); // (but ideally after getting all new events) void NewFrame(); +// call this to enable custom ImGui windows which are not editors +bool IsReadyToRender(); + // call this once per frame (at the end) - it'll render all ImGui::* commands // since NewFrame() void Render(); diff --git a/neo/libs/imgui/imgui.cpp b/neo/libs/imgui/imgui.cpp index cc9265b1..46ac7cd9 100644 --- a/neo/libs/imgui/imgui.cpp +++ b/neo/libs/imgui/imgui.cpp @@ -6991,7 +6991,8 @@ void ImGui::End() if( g.CurrentWindowStack.Size <= 1 && g.FrameScopePushedImplicitWindow ) { - IM_ASSERT( g.CurrentWindowStack.Size > 1 && "Calling End() too many times!" ); + // RB: disabled assert + //IM_ASSERT( g.CurrentWindowStack.Size > 1 && "Calling End() too many times!" ); return; // FIXME-ERRORHANDLING } IM_ASSERT( g.CurrentWindowStack.Size > 0 ); diff --git a/neo/renderer/RenderBackend.h b/neo/renderer/RenderBackend.h index 3e08ddf2..73132d04 100644 --- a/neo/renderer/RenderBackend.h +++ b/neo/renderer/RenderBackend.h @@ -57,25 +57,6 @@ enum stencilFace_t STENCIL_FACE_NUM }; -struct backEndCounters_t -{ - int c_surfaces; - int c_shaders; - - int c_drawElements; - int c_drawIndexes; - - int c_shadowElements; - int c_shadowIndexes; - - int c_copyFrameBuffer; - - float c_overDraw; - - int totalMicroSec; // total microseconds for backend run - int shadowMicroSec; -}; - struct gfxImpParms_t { int x; // ignored in fullscreen diff --git a/neo/renderer/RenderCommon.h b/neo/renderer/RenderCommon.h index 9b45241f..16d6c6f5 100644 --- a/neo/renderer/RenderCommon.h +++ b/neo/renderer/RenderCommon.h @@ -695,35 +695,7 @@ const idMaterial* R_RemapShaderBySkin( const idMaterial* shader, const idDeclSki //==================================================== -/* -** performanceCounters_t -*/ -struct performanceCounters_t -{ - int c_box_cull_in; - int c_box_cull_out; - int c_createInteractions; // number of calls to idInteraction::CreateInteraction - int c_createShadowVolumes; - int c_generateMd5; - int c_entityDefCallbacks; - int c_alloc; // counts for R_StaticAllc/R_StaticFree - int c_free; - int c_visibleViewEntities; - int c_shadowViewEntities; - int c_viewLights; - int c_numViews; // number of total views rendered - int c_deformedSurfaces; // idMD5Mesh::GenerateSurface - int c_deformedVerts; // idMD5Mesh::GenerateSurface - int c_deformedIndexes; // idMD5Mesh::GenerateSurface - int c_tangentIndexes; // R_DeriveTangents() - int c_entityUpdates; - int c_lightUpdates; - int c_envprobeUpdates; - int c_entityReferences; - int c_lightReferences; - int c_guiSurfs; - int frontEndMicroSec; // sum of time in all RE_RenderScene's in a frame -}; + enum vertexLayoutType_t { @@ -806,9 +778,9 @@ public: virtual void WriteDemoPics(); virtual void WriteEndFrame(); virtual void DrawDemoPics(); - virtual const emptyCommand_t* SwapCommandBuffers( uint64* frontEndMicroSec, uint64* backEndMicroSec, uint64* shadowMicroSec, uint64* gpuMicroSec ); + virtual const emptyCommand_t* SwapCommandBuffers( uint64* frontEndMicroSec, uint64* backEndMicroSec, uint64* shadowMicroSec, uint64* gpuMicroSec, backEndCounters_t* bc, performanceCounters_t* pc ); - virtual void SwapCommandBuffers_FinishRendering( uint64* frontEndMicroSec, uint64* backEndMicroSec, uint64* shadowMicroSec, uint64* gpuMicroSec ); + virtual void SwapCommandBuffers_FinishRendering( uint64* frontEndMicroSec, uint64* backEndMicroSec, uint64* shadowMicroSec, uint64* gpuMicroSec, backEndCounters_t* bc, performanceCounters_t* pc ); virtual const emptyCommand_t* SwapCommandBuffers_FinishCommandBuffers(); virtual void RenderCommandBuffers( const emptyCommand_t* commandBuffers ); diff --git a/neo/renderer/RenderProgs_embedded.h b/neo/renderer/RenderProgs_embedded.h index cd346617..b1953f20 100644 --- a/neo/renderer/RenderProgs_embedded.h +++ b/neo/renderer/RenderProgs_embedded.h @@ -2197,7 +2197,7 @@ static const cgShaderDef_t cg_renderprogs[] = "\n" "Doom 3 BFG Edition GPL Source Code\n" "Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. \n" - "Copyright (C) 2013-2019 Robert Beckebans\n" + "Copyright (C) 2013-2020 Robert Beckebans\n" "\n" "This file is part of the Doom 3 BFG Edition GPL Source Code (\"Doom 3 BFG Edition Source Code\"). \n" "\n" @@ -2254,7 +2254,8 @@ static const cgShaderDef_t cg_renderprogs[] = "// half4 lightFalloff = idtex2Dproj( samp1, fragment.texcoord2 );\n" "// half4 lightProj = idtex2Dproj( samp2, fragment.texcoord3 );\n" " half4 YCoCG = tex2D( samp2, fragment.texcoord1.xy );\n" - " half4 specMap = tex2D( samp1, fragment.texcoord2.xy );\n" + " half4 specMapSRGB = tex2D( samp1, fragment.texcoord2.xy );\n" + " half4 specMap = sRGBAToLinearRGBA( specMapSRGB );\n" "\n" " //half3 lightVector = normalize( fragment.texcoord0.xyz );\n" " half3 diffuseMap = sRGBToLinearRGB( ConvertYCoCgToRGB( YCoCG ) );\n" @@ -2293,10 +2294,11 @@ static const cgShaderDef_t cg_renderprogs[] = " float3 reflectionVector = globalNormal * dot3( globalEye, globalNormal );\n" " reflectionVector = ( reflectionVector * 2.0f ) - globalEye;\n" " \n" - "#if defined(USE_PBR)\n" + "#if 1 //defined(USE_PBR)\n" " \n" - " const half metallic = specMap.g;\n" - " const half roughness = specMap.r;\n" + "#if 1 //defined(USE_METALNESS)\n" + " const half metallic = specMapSRGB.g;\n" + " const half roughness = specMapSRGB.r;\n" " const half glossiness = 1.0 - roughness;\n" "\n" " // the vast majority of real-world materials (anything not metal or gems) have F(0°)\n" @@ -2310,11 +2312,21 @@ static const cgShaderDef_t cg_renderprogs[] = " \n" " half3 diffuseColor = baseColor * ( 1.0 - metallic );\n" " half3 specularColor = lerp( dielectricColor, baseColor, metallic );\n" + "#else\n" + " // HACK calculate roughness from D3 gloss maps\n" + " float Y = dot( LUMINANCE_SRGB.rgb, specMapSRGB.rgb );\n" " \n" - " //diffuseColor = half3( 1.0 );\n" - " float3 diffuseLight = ( texCUBE( samp7, globalNormal ).rgb ) * diffuseColor * ( rpDiffuseModifier.xyz ) * 1.5f;\n" + " //const float glossiness = clamp( 1.0 - specMapSRGB.r, 0.0, 0.98 );\n" + " const float glossiness = clamp( pow( Y, 1.0 / 2.0 ), 0.0, 0.98 );\n" " \n" - " //specularColor = half3( 0.0 );\n" + " const float roughness = 1.0 - glossiness;\n" + " \n" + " half3 diffuseColor = diffuseMap;\n" + " half3 specularColor = specMap.rgb;\n" + "\n" + "#endif\n" + " \n" + " float3 diffuseLight = ( texCUBE( samp7, globalNormal ).rgb ) * diffuseColor * ( rpDiffuseModifier.xyz ) * 3.5f;\n" " \n" " float mip = clamp( ( roughness * 7.0 ) + 3.0, 0.0, 10.0 );\n" " float3 envColor = ( textureLod( samp8, reflectionVector, mip ).rgb ) * ( rpSpecularModifier.xyz ) * 1.0f;\n" @@ -2323,11 +2335,9 @@ static const cgShaderDef_t cg_renderprogs[] = " \n" "#else\n" " \n" - " half4 specMapSRGB = specMap;\n" - " specMap = sRGBAToLinearRGBA( specMap );\n" - " \n" - " //float3 diffuseLight = sRGBToLinearRGB( texCUBE( samp7, globalNormal ).rgb ) * diffuseMap.rgb * ( rpDiffuseModifier.xyz ) * 3.5f;\n" - " float3 diffuseLight = ( texCUBE( samp7, globalNormal ).rgb ) * diffuseMap.rgb * ( rpDiffuseModifier.xyz ) * 3.5f;\n" + " // non PBR path\n" + "\n" + " float3 diffuseLight = ( texCUBE( samp7, globalNormal ).rgb ) * diffuseMap.rgb * ( rpDiffuseModifier.xyz ) * 3.5f;\n" " //float3 diffuseLight = diffuseMap.rgb * ( rpDiffuseModifier.xyz ) * 1.5f;\n" "\n" " // HACK calculate roughness from D3 gloss maps\n" @@ -8662,7 +8672,7 @@ static const cgShaderDef_t cg_renderprogs[] = "\n" "#if 1 //defined(USE_PBR)\n" " \n" - "#if 0 //defined(USE_METALNESS)\n" + "#if 1 //defined(USE_METALNESS)\n" " const half metallic = specMapSRGB.g;\n" " const half roughness = specMapSRGB.r;\n" " const half glossiness = 1.0 - roughness;\n" @@ -8703,7 +8713,7 @@ static const cgShaderDef_t cg_renderprogs[] = " half ldotH = clamp( dot3( lightVector, halfAngleVector ), 0.0, 1.0 );\n" " \n" " // compensate r_lightScale 3 * 2\n" - " half3 reflectColor = specMap.rgb * rpSpecularModifier.rgb * 1.0;// * 0.5;\n" + " half3 reflectColor = specularColor * rpSpecularModifier.rgb * 1.0;// * 0.5;\n" " \n" " // cheap approximation by ARM with only one division\n" " // http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf\n" @@ -9472,7 +9482,7 @@ static const cgShaderDef_t cg_renderprogs[] = "\n" "Doom 3 BFG Edition GPL Source Code\n" "Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. \n" - "Copyright (C) 2013-2014 Robert Beckebans\n" + "Copyright (C) 2013-2020 Robert Beckebans\n" "\n" "This file is part of the Doom 3 BFG Edition GPL Source Code (\"Doom 3 BFG Edition Source Code\"). \n" "\n" @@ -9749,7 +9759,7 @@ static const cgShaderDef_t cg_renderprogs[] = "\n" "#if 1 //defined(USE_PBR)\n" " \n" - "#if 0 //defined(USE_METALNESS)\n" + "#if 1 //defined(USE_METALNESS)\n" " const half metallic = specMapSRGB.g;\n" " const half roughness = specMapSRGB.r;\n" " const half glossiness = 1.0 - roughness;\n" @@ -9790,7 +9800,7 @@ static const cgShaderDef_t cg_renderprogs[] = " half ldotH = clamp( dot3( lightVector, halfAngleVector ), 0.0, 1.0 );\n" " \n" " // compensate r_lightScale 3 * 2\n" - " half3 reflectColor = specMap.rgb * rpSpecularModifier.rgb * 1.0;// * 0.5;\n" + " half3 reflectColor = specularColor * rpSpecularModifier.rgb * 1.0;// * 0.5;\n" " \n" " // cheap approximation by ARM with only one division\n" " // http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf\n" diff --git a/neo/renderer/RenderSystem.cpp b/neo/renderer/RenderSystem.cpp index e8c46c6d..cf66baa1 100644 --- a/neo/renderer/RenderSystem.cpp +++ b/neo/renderer/RenderSystem.cpp @@ -32,6 +32,8 @@ If you have questions concerning this license or the applicable additional terms #include "precompiled.h" #include "RenderCommon.h" +#include "../framework/Common_local.h" +#include "../imgui/BFGimgui.h" idRenderSystemLocal tr; idRenderSystem* renderSystem = &tr; @@ -610,10 +612,13 @@ const emptyCommand_t* idRenderSystemLocal::SwapCommandBuffers( uint64* frontEndMicroSec, uint64* backEndMicroSec, uint64* shadowMicroSec, - uint64* gpuMicroSec ) + uint64* gpuMicroSec, + backEndCounters_t* bc, + performanceCounters_t* pc +) { - SwapCommandBuffers_FinishRendering( frontEndMicroSec, backEndMicroSec, shadowMicroSec, gpuMicroSec ); + SwapCommandBuffers_FinishRendering( frontEndMicroSec, backEndMicroSec, shadowMicroSec, gpuMicroSec, bc, pc ); return SwapCommandBuffers_FinishCommandBuffers(); } @@ -623,11 +628,15 @@ const emptyCommand_t* idRenderSystemLocal::SwapCommandBuffers( idRenderSystemLocal::SwapCommandBuffers_FinishRendering ===================== */ +#define FPS_FRAMES 6 void idRenderSystemLocal::SwapCommandBuffers_FinishRendering( uint64* frontEndMicroSec, uint64* backEndMicroSec, uint64* shadowMicroSec, - uint64* gpuMicroSec ) + uint64* gpuMicroSec, + backEndCounters_t* bc, + performanceCounters_t* pc +) { SCOPED_PROFILE_EVENT( "SwapCommandBuffers" ); @@ -641,7 +650,6 @@ void idRenderSystemLocal::SwapCommandBuffers_FinishRendering( return; } - // After coming back from an autoswap, we won't have anything to render //if( frameData && frameData->cmdHead->next != NULL ) { @@ -677,17 +685,30 @@ void idRenderSystemLocal::SwapCommandBuffers_FinishRendering( // save out timing information if( frontEndMicroSec != NULL ) { - *frontEndMicroSec = pc.frontEndMicroSec; + *frontEndMicroSec = this->pc.frontEndMicroSec; } + if( backEndMicroSec != NULL ) { *backEndMicroSec = backend.pc.totalMicroSec; } + if( shadowMicroSec != NULL ) { *shadowMicroSec = backend.pc.shadowMicroSec; } + // RB: TODO clean up the above and just pass entire backend and performance stats before they get cleared + if( bc != NULL ) + { + *bc = backend.pc; + } + + if( pc != NULL ) + { + *pc = this->pc; + } + // print any other statistics and clear all of them PrintPerformanceCounters(); diff --git a/neo/renderer/RenderSystem.h b/neo/renderer/RenderSystem.h index 07a2f48e..257add68 100644 --- a/neo/renderer/RenderSystem.h +++ b/neo/renderer/RenderSystem.h @@ -108,6 +108,55 @@ enum antiAliasingMode_t ANTI_ALIASING_MSAA_4X, ANTI_ALIASING_MSAA_8X }; + +/* +** performanceCounters_t +*/ +struct performanceCounters_t +{ + int c_box_cull_in; + int c_box_cull_out; + int c_createInteractions; // number of calls to idInteraction::CreateInteraction + int c_createShadowVolumes; + int c_generateMd5; + int c_entityDefCallbacks; + int c_alloc; // counts for R_StaticAllc/R_StaticFree + int c_free; + int c_visibleViewEntities; + int c_shadowViewEntities; + int c_viewLights; + int c_numViews; // number of total views rendered + int c_deformedSurfaces; // idMD5Mesh::GenerateSurface + int c_deformedVerts; // idMD5Mesh::GenerateSurface + int c_deformedIndexes; // idMD5Mesh::GenerateSurface + int c_tangentIndexes; // R_DeriveTangents() + int c_entityUpdates; + int c_lightUpdates; + int c_envprobeUpdates; + int c_entityReferences; + int c_lightReferences; + int c_guiSurfs; + int frontEndMicroSec; // sum of time in all RE_RenderScene's in a frame +}; + +struct backEndCounters_t +{ + int c_surfaces; + int c_shaders; + + int c_drawElements; + int c_drawIndexes; + + int c_shadowElements; + int c_shadowIndexes; + + int c_copyFrameBuffer; + + float c_overDraw; + + int totalMicroSec; // total microseconds for backend run + int shadowMicroSec; +}; // RB end // Contains variables specific to the OpenGL configuration being run right now. @@ -326,11 +375,11 @@ public: // // After this is called, new command buffers can be built up in parallel // with the rendering of the closed off command buffers by RenderCommandBuffers() - virtual const emptyCommand_t* SwapCommandBuffers( uint64* frontEndMicroSec, uint64* backEndMicroSec, uint64* shadowMicroSec, uint64* gpuMicroSec ) = 0; + virtual const emptyCommand_t* SwapCommandBuffers( uint64* frontEndMicroSec, uint64* backEndMicroSec, uint64* shadowMicroSec, uint64* gpuMicroSec, backEndCounters_t* bc, performanceCounters_t* pc ) = 0; // SwapCommandBuffers operation can be split in two parts for non-smp rendering // where the GPU is idled intentionally for minimal latency. - virtual void SwapCommandBuffers_FinishRendering( uint64* frontEndMicroSec, uint64* backEndMicroSec, uint64* shadowMicroSec, uint64* gpuMicroSec ) = 0; + virtual void SwapCommandBuffers_FinishRendering( uint64* frontEndMicroSec, uint64* backEndMicroSec, uint64* shadowMicroSec, uint64* gpuMicroSec, backEndCounters_t* bc, performanceCounters_t* pc ) = 0; virtual const emptyCommand_t* SwapCommandBuffers_FinishCommandBuffers() = 0; // issues GPU commands to render a built up list of command buffers returned diff --git a/neo/renderer/RenderSystem_init.cpp b/neo/renderer/RenderSystem_init.cpp index 21d89c39..033eaf6d 100644 --- a/neo/renderer/RenderSystem_init.cpp +++ b/neo/renderer/RenderSystem_init.cpp @@ -747,7 +747,7 @@ void R_ReadTiledPixels( int width, int height, byte* buffer, renderView_t* ref = //commonLocal.WaitGameThread(); // discard anything currently on the list - tr.SwapCommandBuffers( NULL, NULL, NULL, NULL ); + tr.SwapCommandBuffers( NULL, NULL, NULL, NULL, NULL, NULL ); int originalNativeWidth = glConfig.nativeScreenWidth; int originalNativeHeight = glConfig.nativeScreenHeight; @@ -765,7 +765,7 @@ void R_ReadTiledPixels( int width, int height, byte* buffer, renderView_t* ref = // foresthale 2014-03-01: fixed custom screenshot resolution by doing a more direct render path #ifdef BUGFIXEDSCREENSHOTRESOLUTION // discard anything currently on the list - tr.SwapCommandBuffers( NULL, NULL, NULL, NULL ); + tr.SwapCommandBuffers( NULL, NULL, NULL, NULL, NULL, NULL ); if( ref ) { // ref is only used by envShot, Event_camShot, etc to grab screenshots of things in the world, @@ -778,13 +778,13 @@ void R_ReadTiledPixels( int width, int height, byte* buffer, renderView_t* ref = commonLocal.Draw(); } // this should exit right after vsync, with the GPU idle and ready to draw - const emptyCommand_t* cmd = tr.SwapCommandBuffers( NULL, NULL, NULL, NULL ); + const emptyCommand_t* cmd = tr.SwapCommandBuffers( NULL, NULL, NULL, NULL, NULL, NULL ); // get the GPU busy with new commands tr.RenderCommandBuffers( cmd ); // discard anything currently on the list (this triggers SwapBuffers) - tr.SwapCommandBuffers( NULL, NULL, NULL, NULL ); + tr.SwapCommandBuffers( NULL, NULL, NULL, NULL, NULL, NULL ); #else // foresthale 2014-03-01: note: ref is always NULL in every call path to this function if( ref ) @@ -835,7 +835,7 @@ void R_ReadTiledPixels( int width, int height, byte* buffer, renderView_t* ref = // foresthale 2014-03-01: fixed custom screenshot resolution by doing a more direct render path #ifdef BUGFIXEDSCREENSHOTRESOLUTION // discard anything currently on the list - tr.SwapCommandBuffers( NULL, NULL, NULL, NULL ); + tr.SwapCommandBuffers( NULL, NULL, NULL, NULL, NULL, NULL ); glConfig.nativeScreenWidth = originalNativeWidth; glConfig.nativeScreenHeight = originalNativeHeight; @@ -2302,7 +2302,7 @@ void idRenderSystemLocal::Init() bInitialized = true; // make sure the command buffers are ready to accept the first screen update - SwapCommandBuffers( NULL, NULL, NULL, NULL ); + SwapCommandBuffers( NULL, NULL, NULL, NULL, NULL, NULL ); common->Printf( "renderSystem initialized.\n" ); common->Printf( "--------------------------------------\n" ); diff --git a/neo/renderer/tr_frontend_addmodels.cpp b/neo/renderer/tr_frontend_addmodels.cpp index 64e86bf2..627ff9cc 100644 --- a/neo/renderer/tr_frontend_addmodels.cpp +++ b/neo/renderer/tr_frontend_addmodels.cpp @@ -1420,6 +1420,12 @@ void R_AddModels() for( viewEntity_t* vEntity = tr.viewDef->viewEntitys; vEntity != NULL; vEntity = vEntity->next ) { + // RB + if( vEntity->drawSurfs != NULL ) + { + tr.pc.c_visibleViewEntities++; + } + for( drawSurf_t* ds = vEntity->drawSurfs; ds != NULL; ) { drawSurf_t* next = ds->nextOnLight; @@ -1434,6 +1440,7 @@ void R_AddModels() } ds = next; } + vEntity->drawSurfs = NULL; } }