From 4f20a2016594dc739ab74ba5f6346e2f61e4c766 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 10 Oct 2020 21:08:24 +0300 Subject: [PATCH] Performance stats --- src/CMakeLists.txt | 2 + src/Makefile | 1 + src/d_clisrv.c | 5 +- src/d_main.c | 95 +---- src/d_netcmd.c | 6 + src/d_netcmd.h | 2 + src/hardware/hw_batching.c | 28 +- src/hardware/hw_main.c | 68 ++-- src/hardware/hw_main.h | 27 +- src/lua_hooklib.c | 42 +++ src/m_perfstats.c | 541 +++++++++++++++++++++++++++ src/m_perfstats.h | 42 +++ src/p_map.c | 4 + src/p_tick.c | 13 + src/r_bsp.c | 4 +- src/r_main.c | 48 +-- src/r_main.h | 28 +- src/r_things.c | 2 +- src/sdl/Srb2SDL-vc10.vcxproj | 2 + src/sdl/Srb2SDL-vc10.vcxproj.filters | 6 + 20 files changed, 778 insertions(+), 188 deletions(-) create mode 100644 src/m_perfstats.c create mode 100644 src/m_perfstats.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 962f8f87a..48c2b4eaa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,6 +32,7 @@ set(SRB2_CORE_SOURCES m_fixed.c m_menu.c m_misc.c + m_perfstats.c m_queue.c m_random.c md5.c @@ -97,6 +98,7 @@ set(SRB2_CORE_HEADERS m_fixed.h m_menu.h m_misc.h + m_perfstats.h m_queue.h m_random.h m_swap.h diff --git a/src/Makefile b/src/Makefile index ee0d50625..e365dcc95 100644 --- a/src/Makefile +++ b/src/Makefile @@ -486,6 +486,7 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/m_fixed.o \ $(OBJDIR)/m_menu.o \ $(OBJDIR)/m_misc.o \ + $(OBJDIR)/m_perfstats.o \ $(OBJDIR)/m_random.o \ $(OBJDIR)/m_queue.o \ $(OBJDIR)/info.o \ diff --git a/src/d_clisrv.c b/src/d_clisrv.c index c9490410b..a6f7cc1c8 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -44,6 +44,7 @@ #include "lua_script.h" #include "lua_hook.h" #include "md5.h" +#include "m_perfstats.h" #ifndef NONET // cl loading screen @@ -5443,14 +5444,14 @@ void TryRunTics(tic_t realtics) { DEBFILE(va("============ Running tic %d (local %d)\n", gametic, localgametic)); - rs_tictime = I_GetTimeMicros(); + ps_tictime = I_GetTimeMicros(); G_Ticker((gametic % NEWTICRATERATIO) == 0); ExtraDataTicker(); gametic++; consistancy[gametic%BACKUPTICS] = Consistancy(); - rs_tictime = I_GetTimeMicros() - rs_tictime; + ps_tictime = I_GetTimeMicros() - ps_tictime; // Leave a certain amount of tics present in the net buffer as long as we've ran at least one tic this frame. if (client && gamestate == GS_LEVEL && leveltime > 3 && neededtic <= gametic + cv_netticbuffer.value) diff --git a/src/d_main.c b/src/d_main.c index d1a414018..41eb59ca7 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -67,6 +67,7 @@ #include "keys.h" #include "filesrch.h" // refreshdirmenu, mainwadstally #include "g_input.h" // tutorial mode control scheming +#include "m_perfstats.h" #ifdef CMAKECONFIG #include "config.h" @@ -435,7 +436,7 @@ static void D_Display(void) if (!automapactive && !dedicated && cv_renderview.value) { - rs_rendercalltime = I_GetTimeMicros(); + ps_rendercalltime = I_GetTimeMicros(); if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) { topleft = screens[0] + viewwindowy*vid.width + viewwindowx; @@ -482,7 +483,7 @@ static void D_Display(void) if (postimgtype2) V_DoPostProcessor(1, postimgtype2, postimgparam2); } - rs_rendercalltime = I_GetTimeMicros() - rs_rendercalltime; + ps_rendercalltime = I_GetTimeMicros() - ps_rendercalltime; } if (lastdraw) @@ -496,7 +497,7 @@ static void D_Display(void) lastdraw = false; } - rs_uitime = I_GetTimeMicros(); + ps_uitime = I_GetTimeMicros(); if (gamestate == GS_LEVEL) { @@ -509,7 +510,7 @@ static void D_Display(void) } else { - rs_uitime = I_GetTimeMicros(); + ps_uitime = I_GetTimeMicros(); } } @@ -551,7 +552,7 @@ static void D_Display(void) CON_Drawer(); - rs_uitime = I_GetTimeMicros() - rs_uitime; + ps_uitime = I_GetTimeMicros() - ps_uitime; // // wipe update @@ -632,90 +633,14 @@ static void D_Display(void) V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-10, V_YELLOWMAP, s); } - if (cv_renderstats.value) + if (cv_perfstats.value) { - char s[50]; - int frametime = I_GetTimeMicros() - rs_prevframetime; - int divisor = 1; - rs_prevframetime = I_GetTimeMicros(); - - if (rs_rendercalltime > 10000) divisor = 1000; - - snprintf(s, sizeof s - 1, "ft %d", frametime / divisor); - V_DrawThinString(30, 10, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "rtot %d", rs_rendercalltime / divisor); - V_DrawThinString(30, 20, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "bsp %d", rs_bsptime / divisor); - V_DrawThinString(30, 30, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "nbsp %d", rs_numbspcalls); - V_DrawThinString(80, 10, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "nspr %d", rs_numsprites); - V_DrawThinString(80, 20, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "nnod %d", rs_numdrawnodes); - V_DrawThinString(80, 30, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "npob %d", rs_numpolyobjects); - V_DrawThinString(80, 40, V_MONOSPACE | V_BLUEMAP, s); - if (rendermode == render_opengl) // OpenGL specific stats - { -#ifdef HWRENDER - snprintf(s, sizeof s - 1, "nsrt %d", rs_hw_nodesorttime / divisor); - V_DrawThinString(30, 40, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "ndrw %d", rs_hw_nodedrawtime / divisor); - V_DrawThinString(30, 50, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "ssrt %d", rs_hw_spritesorttime / divisor); - V_DrawThinString(30, 60, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "sdrw %d", rs_hw_spritedrawtime / divisor); - V_DrawThinString(30, 70, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "ui %d", rs_uitime / divisor); - V_DrawThinString(30, 80, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "fin %d", rs_swaptime / divisor); - V_DrawThinString(30, 90, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "tic %d", rs_tictime / divisor); - V_DrawThinString(30, 105, V_MONOSPACE | V_GRAYMAP, s); - if (cv_glbatching.value) - { - snprintf(s, sizeof s - 1, "bsrt %d", rs_hw_batchsorttime / divisor); - V_DrawThinString(80, 55, V_MONOSPACE | V_REDMAP, s); - snprintf(s, sizeof s - 1, "bdrw %d", rs_hw_batchdrawtime / divisor); - V_DrawThinString(80, 65, V_MONOSPACE | V_REDMAP, s); - - snprintf(s, sizeof s - 1, "npol %d", rs_hw_numpolys); - V_DrawThinString(130, 10, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "ndc %d", rs_hw_numcalls); - V_DrawThinString(130, 20, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "nshd %d", rs_hw_numshaders); - V_DrawThinString(130, 30, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "nvrt %d", rs_hw_numverts); - V_DrawThinString(130, 40, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "ntex %d", rs_hw_numtextures); - V_DrawThinString(185, 10, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "npf %d", rs_hw_numpolyflags); - V_DrawThinString(185, 20, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "ncol %d", rs_hw_numcolors); - V_DrawThinString(185, 30, V_MONOSPACE | V_PURPLEMAP, s); - } -#endif - } - else // software specific stats - { - snprintf(s, sizeof s - 1, "prtl %d", rs_sw_portaltime / divisor); - V_DrawThinString(30, 40, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "plns %d", rs_sw_planetime / divisor); - V_DrawThinString(30, 50, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "mskd %d", rs_sw_maskedtime / divisor); - V_DrawThinString(30, 60, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "ui %d", rs_uitime / divisor); - V_DrawThinString(30, 70, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "fin %d", rs_swaptime / divisor); - V_DrawThinString(30, 80, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "tic %d", rs_tictime / divisor); - V_DrawThinString(30, 95, V_MONOSPACE | V_GRAYMAP, s); - } + M_DrawPerfStats(); } - rs_swaptime = I_GetTimeMicros(); + ps_swaptime = I_GetTimeMicros(); I_FinishUpdate(); // page flip or blit buffer - rs_swaptime = I_GetTimeMicros() - rs_swaptime; + ps_swaptime = I_GetTimeMicros() - ps_swaptime; } needpatchflush = false; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 6f4bcdb1d..80bf11552 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -371,6 +371,10 @@ consvar_t cv_mute = CVAR_INIT ("mute", "Off", CV_NETVAR|CV_CALL, CV_OnOff, Mute_ consvar_t cv_sleep = CVAR_INIT ("cpusleep", "1", CV_SAVE, sleeping_cons_t, NULL); +static CV_PossibleValue_t perfstats_cons_t[] = { + {0, "Off"}, {1, "Rendering"}, {2, "Logic"}, {3, "ThinkFrame"}, {0, NULL}}; +consvar_t cv_perfstats = CVAR_INIT ("perfstats", "Off", 0, perfstats_cons_t, NULL); + char timedemo_name[256]; boolean timedemo_csv; char timedemo_csv_id[256]; @@ -864,6 +868,8 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_soundtest); + CV_RegisterVar(&cv_perfstats); + // ingame object placing COM_AddCommand("objectplace", Command_ObjectPlace_f); COM_AddCommand("writethings", Command_Writethings_f); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 897c28968..841f71acd 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -114,6 +114,8 @@ extern consvar_t cv_skipmapcheck; extern consvar_t cv_sleep; +extern consvar_t cv_perfstats; + extern char timedemo_name[256]; extern boolean timedemo_csv; extern char timedemo_csv_id[256]; diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index 492cea5fa..a63be3a72 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -235,13 +235,13 @@ void HWR_RenderBatches(void) currently_batching = false;// no longer collecting batches if (!polygonArraySize) { - rs_hw_numpolys = rs_hw_numcalls = rs_hw_numshaders = rs_hw_numtextures = rs_hw_numpolyflags = rs_hw_numcolors = 0; + ps_hw_numpolys = ps_hw_numcalls = ps_hw_numshaders = ps_hw_numtextures = ps_hw_numpolyflags = ps_hw_numcolors = 0; return;// nothing to draw } // init stats vars - rs_hw_numpolys = polygonArraySize; - rs_hw_numcalls = rs_hw_numverts = 0; - rs_hw_numshaders = rs_hw_numtextures = rs_hw_numpolyflags = rs_hw_numcolors = 1; + ps_hw_numpolys = polygonArraySize; + ps_hw_numcalls = ps_hw_numverts = 0; + ps_hw_numshaders = ps_hw_numtextures = ps_hw_numpolyflags = ps_hw_numcolors = 1; // init polygonIndexArray for (i = 0; i < polygonArraySize; i++) { @@ -249,12 +249,12 @@ void HWR_RenderBatches(void) } // sort polygons - rs_hw_batchsorttime = I_GetTimeMicros(); + ps_hw_batchsorttime = I_GetTimeMicros(); if (cv_glshaders.value && gl_shadersavailable) qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons); else qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygonsNoShaders); - rs_hw_batchsorttime = I_GetTimeMicros() - rs_hw_batchsorttime; + ps_hw_batchsorttime = I_GetTimeMicros() - ps_hw_batchsorttime; // sort order // 1. shader // 2. texture @@ -262,7 +262,7 @@ void HWR_RenderBatches(void) // 4. colors + light level // not sure about what order of the last 2 should be, or if it even matters - rs_hw_batchdrawtime = I_GetTimeMicros(); + ps_hw_batchdrawtime = I_GetTimeMicros(); currentShader = polygonArray[polygonIndexArray[0]].shader; currentTexture = polygonArray[polygonIndexArray[0]].texture; @@ -398,8 +398,8 @@ void HWR_RenderBatches(void) // execute draw call HWD.pfnDrawIndexedTriangles(¤tSurfaceInfo, finalVertexArray, finalIndexWritePos, currentPolyFlags, finalVertexIndexArray); // update stats - rs_hw_numcalls++; - rs_hw_numverts += finalIndexWritePos; + ps_hw_numcalls++; + ps_hw_numverts += finalIndexWritePos; // reset write positions finalVertexWritePos = 0; finalIndexWritePos = 0; @@ -416,7 +416,7 @@ void HWR_RenderBatches(void) currentShader = nextShader; changeShader = false; - rs_hw_numshaders++; + ps_hw_numshaders++; } if (changeTexture) { @@ -425,21 +425,21 @@ void HWR_RenderBatches(void) currentTexture = nextTexture; changeTexture = false; - rs_hw_numtextures++; + ps_hw_numtextures++; } if (changePolyFlags) { currentPolyFlags = nextPolyFlags; changePolyFlags = false; - rs_hw_numpolyflags++; + ps_hw_numpolyflags++; } if (changeSurfaceInfo) { currentSurfaceInfo = nextSurfaceInfo; changeSurfaceInfo = false; - rs_hw_numcolors++; + ps_hw_numcolors++; } // and that should be it? } @@ -447,7 +447,7 @@ void HWR_RenderBatches(void) polygonArraySize = 0; unsortedVertexArraySize = 0; - rs_hw_batchdrawtime = I_GetTimeMicros() - rs_hw_batchdrawtime; + ps_hw_batchdrawtime = I_GetTimeMicros() - ps_hw_batchdrawtime; } diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 991b51aee..e564c3869 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -146,21 +146,22 @@ static angle_t gl_aimingangle; static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox); // Render stats -int rs_hw_nodesorttime = 0; -int rs_hw_nodedrawtime = 0; -int rs_hw_spritesorttime = 0; -int rs_hw_spritedrawtime = 0; +int ps_hw_skyboxtime = 0; +int ps_hw_nodesorttime = 0; +int ps_hw_nodedrawtime = 0; +int ps_hw_spritesorttime = 0; +int ps_hw_spritedrawtime = 0; // Render stats for batching -int rs_hw_numpolys = 0; -int rs_hw_numverts = 0; -int rs_hw_numcalls = 0; -int rs_hw_numshaders = 0; -int rs_hw_numtextures = 0; -int rs_hw_numpolyflags = 0; -int rs_hw_numcolors = 0; -int rs_hw_batchsorttime = 0; -int rs_hw_batchdrawtime = 0; +int ps_hw_numpolys = 0; +int ps_hw_numverts = 0; +int ps_hw_numcalls = 0; +int ps_hw_numshaders = 0; +int ps_hw_numtextures = 0; +int ps_hw_numpolyflags = 0; +int ps_hw_numcolors = 0; +int ps_hw_batchsorttime = 0; +int ps_hw_batchdrawtime = 0; boolean gl_shadersavailable = true; @@ -3188,7 +3189,7 @@ static void HWR_Subsector(size_t num) } // for render stats - rs_numpolyobjects += numpolys; + ps_numpolyobjects += numpolys; // Sort polyobjects R_SortPolyObjects(sub); @@ -3296,7 +3297,7 @@ static void HWR_RenderBSPNode(INT32 bspnum) // Decide which side the view point is on INT32 side; - rs_numbspcalls++; + ps_numbspcalls++; // Found a subsector? if (bspnum & NF_SUBSECTOR) @@ -4502,7 +4503,7 @@ static void HWR_CreateDrawNodes(void) // that is already lying around. This should all be in some sort of linked list or lists. sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numpolyplanes + numwalls), PU_STATIC, NULL); - rs_hw_nodesorttime = I_GetTimeMicros(); + ps_hw_nodesorttime = I_GetTimeMicros(); for (i = 0; i < numplanes; i++, p++) { @@ -4522,7 +4523,7 @@ static void HWR_CreateDrawNodes(void) sortindex[p] = p; } - rs_numdrawnodes = p; + ps_numdrawnodes = p; // p is the number of stuff to sort @@ -4557,9 +4558,9 @@ static void HWR_CreateDrawNodes(void) } } - rs_hw_nodesorttime = I_GetTimeMicros() - rs_hw_nodesorttime; + ps_hw_nodesorttime = I_GetTimeMicros() - ps_hw_nodesorttime; - rs_hw_nodedrawtime = I_GetTimeMicros(); + ps_hw_nodedrawtime = I_GetTimeMicros(); // Okay! Let's draw it all! Woo! HWD.pfnSetTransform(&atransform); @@ -4596,7 +4597,7 @@ static void HWR_CreateDrawNodes(void) } } - rs_hw_nodedrawtime = I_GetTimeMicros() - rs_hw_nodedrawtime; + ps_hw_nodedrawtime = I_GetTimeMicros() - ps_hw_nodedrawtime; numwalls = 0; numplanes = 0; @@ -5777,8 +5778,10 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) if (viewnumber == 0) // Only do it if it's the first screen being rendered HWD.pfnClearBuffer(true, false, &ClearColor); // Clear the Color Buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs. + ps_hw_skyboxtime = I_GetTimeMicros(); if (skybox && drawsky) // If there's a skybox and we should be drawing the sky, draw the skybox HWR_RenderSkyboxView(viewnumber, player); // This is drawn before everything else so it is placed behind + ps_hw_skyboxtime = I_GetTimeMicros() - ps_hw_skyboxtime; { // do we really need to save player (is it not the same)? @@ -5889,9 +5892,9 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) HWD.pfnSetSpecialState(HWD_SET_SHADERS, cv_glshaders.value); HWD.pfnSetShader(0); - rs_numbspcalls = 0; - rs_numpolyobjects = 0; - rs_bsptime = I_GetTimeMicros(); + ps_numbspcalls = 0; + ps_numpolyobjects = 0; + ps_bsptime = I_GetTimeMicros(); validcount++; @@ -5929,7 +5932,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) } #endif - rs_bsptime = I_GetTimeMicros() - rs_bsptime; + ps_bsptime = I_GetTimeMicros() - ps_bsptime; if (cv_glbatching.value) HWR_RenderBatches(); @@ -5944,22 +5947,22 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) #endif // Draw MD2 and sprites - rs_numsprites = gl_visspritecount; - rs_hw_spritesorttime = I_GetTimeMicros(); + ps_numsprites = gl_visspritecount; + ps_hw_spritesorttime = I_GetTimeMicros(); HWR_SortVisSprites(); - rs_hw_spritesorttime = I_GetTimeMicros() - rs_hw_spritesorttime; - rs_hw_spritedrawtime = I_GetTimeMicros(); + ps_hw_spritesorttime = I_GetTimeMicros() - ps_hw_spritesorttime; + ps_hw_spritedrawtime = I_GetTimeMicros(); HWR_DrawSprites(); - rs_hw_spritedrawtime = I_GetTimeMicros() - rs_hw_spritedrawtime; + ps_hw_spritedrawtime = I_GetTimeMicros() - ps_hw_spritedrawtime; #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? HWR_DrawCoronas(); #endif - rs_numdrawnodes = 0; - rs_hw_nodesorttime = 0; - rs_hw_nodedrawtime = 0; + ps_numdrawnodes = 0; + ps_hw_nodesorttime = 0; + ps_hw_nodedrawtime = 0; if (numplanes || numpolyplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything { HWR_CreateDrawNodes(); @@ -6061,7 +6064,6 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_glfiltermode); CV_RegisterVar(&cv_glsolvetjoin); - CV_RegisterVar(&cv_renderstats); CV_RegisterVar(&cv_glbatching); #ifndef NEWCLIP diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index d70bb6d72..4bf197d7f 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -108,21 +108,22 @@ extern FTransform atransform; // Render stats -extern int rs_hw_nodesorttime; -extern int rs_hw_nodedrawtime; -extern int rs_hw_spritesorttime; -extern int rs_hw_spritedrawtime; +extern int ps_hw_skyboxtime; +extern int ps_hw_nodesorttime; +extern int ps_hw_nodedrawtime; +extern int ps_hw_spritesorttime; +extern int ps_hw_spritedrawtime; // Render stats for batching -extern int rs_hw_numpolys; -extern int rs_hw_numverts; -extern int rs_hw_numcalls; -extern int rs_hw_numshaders; -extern int rs_hw_numtextures; -extern int rs_hw_numpolyflags; -extern int rs_hw_numcolors; -extern int rs_hw_batchsorttime; -extern int rs_hw_batchdrawtime; +extern int ps_hw_numpolys; +extern int ps_hw_numverts; +extern int ps_hw_numcalls; +extern int ps_hw_numshaders; +extern int ps_hw_numtextures; +extern int ps_hw_numpolyflags; +extern int ps_hw_numcolors; +extern int ps_hw_batchsorttime; +extern int ps_hw_batchdrawtime; extern boolean gl_shadersavailable; diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 8840c81a0..a5d4af412 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -23,6 +23,10 @@ #include "lua_hook.h" #include "lua_hud.h" // hud_running errors +#include "m_perfstats.h" +#include "d_netcmd.h" // for cv_perfstats +#include "i_system.h" // I_GetTimeMicros + static UINT8 hooksAvailable[(hook_MAX/8)+1]; const char *const hookNames[hook_MAX+1] = { @@ -269,6 +273,7 @@ boolean LUAh_MobjHook(mobj_t *mo, enum hook which) if (hookp->type != which) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) LUA_PushUserdata(gL, mo, META_MOBJ); PushHook(gL, hookp); @@ -290,6 +295,7 @@ boolean LUAh_MobjHook(mobj_t *mo, enum hook which) if (hookp->type != which) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) LUA_PushUserdata(gL, mo, META_MOBJ); PushHook(gL, hookp); @@ -325,6 +331,7 @@ boolean LUAh_PlayerHook(player_t *plr, enum hook which) if (hookp->type != which) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) LUA_PushUserdata(gL, plr, META_PLAYER); PushHook(gL, hookp); @@ -456,6 +463,9 @@ void LUAh_PreThinkFrame(void) void LUAh_ThinkFrame(void) { hook_p hookp; + // variables used by perf stats + int hook_index = 0; + int time_taken = 0; if (!gL || !(hooksAvailable[hook_ThinkFrame/8] & (1<<(hook_ThinkFrame%8)))) return; @@ -466,6 +476,8 @@ void LUAh_ThinkFrame(void) if (hookp->type != hook_ThinkFrame) continue; + if (cv_perfstats.value == 3) + time_taken = I_GetTimeMicros(); PushHook(gL, hookp); if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) @@ -473,6 +485,16 @@ void LUAh_ThinkFrame(void) lua_pop(gL, 1); hookp->error = true; } + if (cv_perfstats.value == 3) + { + lua_Debug ar; + time_taken = I_GetTimeMicros() - time_taken; + // we need the function, let's just retrieve it again + PushHook(gL, hookp); + lua_getinfo(gL, ">S", &ar); + PS_SetThinkFrameHookInfo(hook_index, time_taken, ar.short_src); + hook_index++; + } } lua_pop(gL, 1); // Pop error handler @@ -523,6 +545,7 @@ UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) if (hookp->type != which) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, thing1, META_MOBJ); @@ -553,6 +576,7 @@ UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) if (hookp->type != which) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, thing1, META_MOBJ); @@ -600,6 +624,7 @@ UINT8 LUAh_MobjLineCollideHook(mobj_t *thing, line_t *line, enum hook which) if (hookp->type != which) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, thing, META_MOBJ); @@ -630,6 +655,7 @@ UINT8 LUAh_MobjLineCollideHook(mobj_t *thing, line_t *line, enum hook which) if (hookp->type != which) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, thing, META_MOBJ); @@ -675,6 +701,7 @@ boolean LUAh_MobjThinker(mobj_t *mo) // Look for all generic mobj thinker hooks for (hookp = mobjthinkerhooks[MT_NULL]; hookp; hookp = hookp->next) { + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) LUA_PushUserdata(gL, mo, META_MOBJ); PushHook(gL, hookp); @@ -693,6 +720,7 @@ boolean LUAh_MobjThinker(mobj_t *mo) for (hookp = mobjthinkerhooks[mo->type]; hookp; hookp = hookp->next) { + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) LUA_PushUserdata(gL, mo, META_MOBJ); PushHook(gL, hookp); @@ -732,6 +760,7 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) if (hookp->type != hook_TouchSpecial) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, special, META_MOBJ); @@ -757,6 +786,7 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) if (hookp->type != hook_TouchSpecial) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, special, META_MOBJ); @@ -800,6 +830,7 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 if (hookp->type != hook_ShouldDamage) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, target, META_MOBJ); @@ -835,6 +866,7 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 { if (hookp->type != hook_ShouldDamage) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, target, META_MOBJ); @@ -889,6 +921,7 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 if (hookp->type != hook_MobjDamage) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, target, META_MOBJ); @@ -920,6 +953,7 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 if (hookp->type != hook_MobjDamage) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, target, META_MOBJ); @@ -969,6 +1003,7 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 if (hookp->type != hook_MobjDeath) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, target, META_MOBJ); @@ -998,6 +1033,7 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 if (hookp->type != hook_MobjDeath) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, target, META_MOBJ); @@ -1190,6 +1226,7 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) if (strcmp(hookp->s.str, line->stringargs[0])) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, line, META_LINE); @@ -1364,6 +1401,7 @@ boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing) if (hookp->type != hook_MapThingSpawn) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, mo, META_MOBJ); @@ -1389,6 +1427,7 @@ boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing) if (hookp->type != hook_MapThingSpawn) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, mo, META_MOBJ); @@ -1430,6 +1469,7 @@ boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj) if (hookp->type != hook_FollowMobj) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, player, META_PLAYER); @@ -1455,6 +1495,7 @@ boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj) if (hookp->type != hook_FollowMobj) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, player, META_PLAYER); @@ -1495,6 +1536,7 @@ UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj) if (hookp->type != hook_PlayerCanDamage) continue; + ps_lua_mobjhooks++; if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, player, META_PLAYER); diff --git a/src/m_perfstats.c b/src/m_perfstats.c new file mode 100644 index 000000000..df1e31b5e --- /dev/null +++ b/src/m_perfstats.c @@ -0,0 +1,541 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file m_perfstats.c +/// \brief Performance measurement tools. + +#include "m_perfstats.h" +#include "v_video.h" +#include "i_video.h" +#include "d_netcmd.h" +#include "r_main.h" +#include "i_system.h" +#include "z_zone.h" +#include "p_local.h" + +#ifdef HWRENDER +#include "hardware/hw_main.h" +#endif + +int ps_tictime = 0; + +int ps_playerthink_time = 0; +int ps_thinkertime = 0; + +int ps_thlist_times[NUM_THINKERLISTS]; +static const char* thlist_names[] = { + "Polyobjects: %d", + "Main: %d", + "Mobjs: %d", + "Dynamic slopes: %d", + "Precipitation: %d", + NULL +}; +static const char* thlist_shortnames[] = { + "plyobjs %d", + "main %d", + "mobjs %d", + "dynslop %d", + "precip %d", + NULL +}; + +int ps_checkposition_calls = 0; + +int ps_lua_thinkframe_time = 0; +int ps_lua_mobjhooks = 0; + +// dynamically allocated resizeable array for thinkframe hook stats +ps_hookinfo_t *thinkframe_hooks = NULL; +int thinkframe_hooks_length = 0; +int thinkframe_hooks_capacity = 16; + +void PS_SetThinkFrameHookInfo(int index, UINT32 time_taken, char* short_src) +{ + if (!thinkframe_hooks) + { + // array needs to be initialized + thinkframe_hooks = Z_Malloc(sizeof(ps_hookinfo_t) * thinkframe_hooks_capacity, PU_STATIC, NULL); + } + if (index >= thinkframe_hooks_capacity) + { + // array needs more space, realloc with double size + thinkframe_hooks_capacity *= 2; + thinkframe_hooks = Z_Realloc(thinkframe_hooks, + sizeof(ps_hookinfo_t) * thinkframe_hooks_capacity, PU_STATIC, NULL); + } + thinkframe_hooks[index].time_taken = time_taken; + memcpy(thinkframe_hooks[index].short_src, short_src, LUA_IDSIZE * sizeof(char)); + // since the values are set sequentially from begin to end, the last call should leave + // the correct value to this variable + thinkframe_hooks_length = index + 1; +} + +void M_DrawPerfStats(void) +{ + char s[100]; + int currenttime = I_GetTimeMicros(); + int frametime = currenttime - ps_prevframetime; + ps_prevframetime = currenttime; + + if (cv_perfstats.value == 1) // rendering + { + if (vid.width < 640 || vid.height < 400) // low resolution + { + snprintf(s, sizeof s - 1, "frmtime %d", frametime); + V_DrawThinString(20, 10, V_MONOSPACE | V_YELLOWMAP, s); + if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) + { + snprintf(s, sizeof s - 1, "ui %d", ps_uitime); + V_DrawThinString(20, 18, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "finupdt %d", ps_swaptime); + V_DrawThinString(20, 26, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "logic %d", ps_tictime); + V_DrawThinString(20, 38, V_MONOSPACE | V_GRAYMAP, s); + return; + } + snprintf(s, sizeof s - 1, "drwtime %d", ps_rendercalltime); + V_DrawThinString(20, 18, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "bspcall %d", ps_numbspcalls); + V_DrawThinString(90, 10, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "sprites %d", ps_numsprites); + V_DrawThinString(90, 18, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "drwnode %d", ps_numdrawnodes); + V_DrawThinString(90, 26, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "plyobjs %d", ps_numpolyobjects); + V_DrawThinString(90, 34, V_MONOSPACE | V_BLUEMAP, s); +#ifdef HWRENDER + if (rendermode == render_opengl) // OpenGL specific stats + { + snprintf(s, sizeof s - 1, "skybox %d", ps_hw_skyboxtime); + V_DrawThinString(24, 26, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "bsptime %d", ps_bsptime); + V_DrawThinString(24, 34, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "nodesrt %d", ps_hw_nodesorttime); + V_DrawThinString(24, 42, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "nodedrw %d", ps_hw_nodedrawtime); + V_DrawThinString(24, 50, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "sprsort %d", ps_hw_spritesorttime); + V_DrawThinString(24, 58, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "sprdraw %d", ps_hw_spritedrawtime); + V_DrawThinString(24, 66, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "other %d", + ps_rendercalltime - ps_hw_skyboxtime - ps_bsptime - ps_hw_nodesorttime + - ps_hw_nodedrawtime - ps_hw_spritesorttime - ps_hw_spritedrawtime + - ps_hw_batchsorttime - ps_hw_batchdrawtime); + V_DrawThinString(24, 74, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "ui %d", ps_uitime); + V_DrawThinString(20, 82, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "finupdt %d", ps_swaptime); + V_DrawThinString(20, 90, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "logic %d", ps_tictime); + V_DrawThinString(20, 102, V_MONOSPACE | V_GRAYMAP, s); + if (cv_glbatching.value) + { + snprintf(s, sizeof s - 1, "batsort %d", ps_hw_batchsorttime); + V_DrawThinString(90, 46, V_MONOSPACE | V_REDMAP, s); + snprintf(s, sizeof s - 1, "batdraw %d", ps_hw_batchdrawtime); + V_DrawThinString(90, 54, V_MONOSPACE | V_REDMAP, s); + + snprintf(s, sizeof s - 1, "polygon %d", ps_hw_numpolys); + V_DrawThinString(155, 10, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "drwcall %d", ps_hw_numcalls); + V_DrawThinString(155, 18, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "shaders %d", ps_hw_numshaders); + V_DrawThinString(155, 26, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "vertex %d", ps_hw_numverts); + V_DrawThinString(155, 34, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "texture %d", ps_hw_numtextures); + V_DrawThinString(220, 10, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "polyflg %d", ps_hw_numpolyflags); + V_DrawThinString(220, 18, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "colors %d", ps_hw_numcolors); + V_DrawThinString(220, 26, V_MONOSPACE | V_PURPLEMAP, s); + } + else + { + // reset these vars so the "other" measurement isn't off + ps_hw_batchsorttime = 0; + ps_hw_batchdrawtime = 0; + } + } + else // software specific stats +#endif + { + snprintf(s, sizeof s - 1, "bsptime %d", ps_bsptime); + V_DrawThinString(24, 26, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "sprclip %d", ps_sw_spritecliptime); + V_DrawThinString(24, 34, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "portals %d", ps_sw_portaltime); + V_DrawThinString(24, 42, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "planes %d", ps_sw_planetime); + V_DrawThinString(24, 50, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "masked %d", ps_sw_maskedtime); + V_DrawThinString(24, 58, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "other %d", + ps_rendercalltime - ps_bsptime - ps_sw_spritecliptime + - ps_sw_portaltime - ps_sw_planetime - ps_sw_maskedtime); + V_DrawThinString(24, 66, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "ui %d", ps_uitime); + V_DrawThinString(20, 74, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "finupdt %d", ps_swaptime); + V_DrawThinString(20, 82, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "logic %d", ps_tictime); + V_DrawThinString(20, 94, V_MONOSPACE | V_GRAYMAP, s); + } + } + else // high resolution + { + snprintf(s, sizeof s - 1, "Frame time: %d", frametime); + V_DrawSmallString(20, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) + { + snprintf(s, sizeof s - 1, "UI render: %d", ps_uitime); + V_DrawSmallString(20, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "I_FinishUpdate: %d", ps_swaptime); + V_DrawSmallString(20, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "Game logic: %d", ps_tictime); + V_DrawSmallString(20, 30, V_MONOSPACE | V_ALLOWLOWERCASE | V_GRAYMAP, s); + return; + } + snprintf(s, sizeof s - 1, "3d rendering: %d", ps_rendercalltime); + V_DrawSmallString(20, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "BSP calls: %d", ps_numbspcalls); + V_DrawSmallString(115, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "Sprites: %d", ps_numsprites); + V_DrawSmallString(115, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "Drawnodes: %d", ps_numdrawnodes); + V_DrawSmallString(115, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "Polyobjects: %d", ps_numpolyobjects); + V_DrawSmallString(115, 25, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); +#ifdef HWRENDER + if (rendermode == render_opengl) // OpenGL specific stats + { + snprintf(s, sizeof s - 1, "Skybox render: %d", ps_hw_skyboxtime); + V_DrawSmallString(24, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "RenderBSPNode: %d", ps_bsptime); + V_DrawSmallString(24, 25, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "Drwnode sort: %d", ps_hw_nodesorttime); + V_DrawSmallString(24, 30, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "Drwnode render: %d", ps_hw_nodedrawtime); + V_DrawSmallString(24, 35, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "Sprite sort: %d", ps_hw_spritesorttime); + V_DrawSmallString(24, 40, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "Sprite render: %d", ps_hw_spritedrawtime); + V_DrawSmallString(24, 45, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + // Remember to update this calculation when adding more 3d rendering stats! + snprintf(s, sizeof s - 1, "Other: %d", + ps_rendercalltime - ps_hw_skyboxtime - ps_bsptime - ps_hw_nodesorttime + - ps_hw_nodedrawtime - ps_hw_spritesorttime - ps_hw_spritedrawtime + - ps_hw_batchsorttime - ps_hw_batchdrawtime); + V_DrawSmallString(24, 50, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "UI render: %d", ps_uitime); + V_DrawSmallString(20, 55, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "I_FinishUpdate: %d", ps_swaptime); + V_DrawSmallString(20, 60, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "Game logic: %d", ps_tictime); + V_DrawSmallString(20, 70, V_MONOSPACE | V_ALLOWLOWERCASE | V_GRAYMAP, s); + if (cv_glbatching.value) + { + snprintf(s, sizeof s - 1, "Batch sort: %d", ps_hw_batchsorttime); + V_DrawSmallString(115, 35, V_MONOSPACE | V_ALLOWLOWERCASE | V_REDMAP, s); + snprintf(s, sizeof s - 1, "Batch render: %d", ps_hw_batchdrawtime); + V_DrawSmallString(115, 40, V_MONOSPACE | V_ALLOWLOWERCASE | V_REDMAP, s); + + snprintf(s, sizeof s - 1, "Polygons: %d", ps_hw_numpolys); + V_DrawSmallString(200, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "Vertices: %d", ps_hw_numverts); + V_DrawSmallString(200, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "Draw calls: %d", ps_hw_numcalls); + V_DrawSmallString(200, 25, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "Shaders: %d", ps_hw_numshaders); + V_DrawSmallString(200, 30, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "Textures: %d", ps_hw_numtextures); + V_DrawSmallString(200, 35, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "Polyflags: %d", ps_hw_numpolyflags); + V_DrawSmallString(200, 40, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "Colors: %d", ps_hw_numcolors); + V_DrawSmallString(200, 45, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); + } + else + { + // reset these vars so the "other" measurement isn't off + ps_hw_batchsorttime = 0; + ps_hw_batchdrawtime = 0; + } + } + else // software specific stats +#endif + { + snprintf(s, sizeof s - 1, "RenderBSPNode: %d", ps_bsptime); + V_DrawSmallString(24, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "R_ClipSprites: %d", ps_sw_spritecliptime); + V_DrawSmallString(24, 25, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "Portals+Skybox: %d", ps_sw_portaltime); + V_DrawSmallString(24, 30, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "R_DrawPlanes: %d", ps_sw_planetime); + V_DrawSmallString(24, 35, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "R_DrawMasked: %d", ps_sw_maskedtime); + V_DrawSmallString(24, 40, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + // Remember to update this calculation when adding more 3d rendering stats! + snprintf(s, sizeof s - 1, "Other: %d", + ps_rendercalltime - ps_bsptime - ps_sw_spritecliptime + - ps_sw_portaltime - ps_sw_planetime - ps_sw_maskedtime); + V_DrawSmallString(24, 45, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "UI render: %d", ps_uitime); + V_DrawSmallString(20, 50, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "I_FinishUpdate: %d", ps_swaptime); + V_DrawSmallString(20, 55, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "Game logic: %d", ps_tictime); + V_DrawSmallString(20, 65, V_MONOSPACE | V_ALLOWLOWERCASE | V_GRAYMAP, s); + } + } + } + else if (cv_perfstats.value == 2) // logic + { + int i = 0; + thinker_t *thinker; + int thinkercount = 0; + int polythcount = 0; + int mainthcount = 0; + int mobjcount = 0; + int nothinkcount = 0; + int scenerycount = 0; + int dynslopethcount = 0; + int precipcount = 0; + int removecount = 0; + // y offset for drawing columns + int yoffset1 = 0; + int yoffset2 = 0; + + for (i = 0; i < NUM_THINKERLISTS; i++) + { + for (thinker = thlist[i].next; thinker != &thlist[i]; thinker = thinker->next) + { + thinkercount++; + if (thinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + removecount++; + else if (i == THINK_POLYOBJ) + polythcount++; + else if (i == THINK_MAIN) + mainthcount++; + else if (i == THINK_MOBJ) + { + if (thinker->function.acp1 == (actionf_p1)P_MobjThinker) + { + mobj_t *mobj = (mobj_t*)thinker; + mobjcount++; + if (mobj->flags & MF_NOTHINK) + nothinkcount++; + else if (mobj->flags & MF_SCENERY) + scenerycount++; + } + } + else if (i == THINK_DYNSLOPE) + dynslopethcount++; + else if (i == THINK_PRECIP) + precipcount++; + } + } + + if (vid.width < 640 || vid.height < 400) // low resolution + { + snprintf(s, sizeof s - 1, "logic %d", ps_tictime); + V_DrawThinString(20, 10, V_MONOSPACE | V_YELLOWMAP, s); + if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) + return; + snprintf(s, sizeof s - 1, "plrthnk %d", ps_playerthink_time); + V_DrawThinString(24, 18, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "thnkers %d", ps_thinkertime); + V_DrawThinString(24, 26, V_MONOSPACE | V_YELLOWMAP, s); + for (i = 0; i < NUM_THINKERLISTS; i++) + { + yoffset1 += 8; + snprintf(s, sizeof s - 1, thlist_shortnames[i], ps_thlist_times[i]); + V_DrawThinString(28, 26+yoffset1, V_MONOSPACE | V_YELLOWMAP, s); + } + snprintf(s, sizeof s - 1, "lthinkf %d", ps_lua_thinkframe_time); + V_DrawThinString(24, 34+yoffset1, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "other %d", + ps_tictime - ps_playerthink_time - ps_thinkertime - ps_lua_thinkframe_time); + V_DrawThinString(24, 42+yoffset1, V_MONOSPACE | V_YELLOWMAP, s); + + snprintf(s, sizeof s - 1, "thnkers %d", thinkercount); + V_DrawThinString(90, 10, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "plyobjs %d", polythcount); + V_DrawThinString(94, 18, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "main %d", mainthcount); + V_DrawThinString(94, 26, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "mobjs %d", mobjcount); + V_DrawThinString(94, 34, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "regular %d", mobjcount - scenerycount - nothinkcount); + V_DrawThinString(98, 42, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "scenery %d", scenerycount); + V_DrawThinString(98, 50, V_MONOSPACE | V_BLUEMAP, s); + if (nothinkcount) + { + snprintf(s, sizeof s - 1, "nothink %d", nothinkcount); + V_DrawThinString(98, 58, V_MONOSPACE | V_BLUEMAP, s); + yoffset2 += 8; + } + snprintf(s, sizeof s - 1, "dynslop %d", dynslopethcount); + V_DrawThinString(94, 58+yoffset2, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "precip %d", precipcount); + V_DrawThinString(94, 66+yoffset2, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "remove %d", removecount); + V_DrawThinString(94, 74+yoffset2, V_MONOSPACE | V_BLUEMAP, s); + + snprintf(s, sizeof s - 1, "lmhooks %d", ps_lua_mobjhooks); + V_DrawThinString(170, 10, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "chkpos %d", ps_checkposition_calls); + V_DrawThinString(170, 18, V_MONOSPACE | V_PURPLEMAP, s); + } + else // high resolution + { + snprintf(s, sizeof s - 1, "Game logic: %d", ps_tictime); + V_DrawSmallString(20, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) + return; + snprintf(s, sizeof s - 1, "P_PlayerThink: %d", ps_playerthink_time); + V_DrawSmallString(24, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "P_RunThinkers: %d", ps_thinkertime); + V_DrawSmallString(24, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + for (i = 0; i < NUM_THINKERLISTS; i++) + { + yoffset1 += 5; + snprintf(s, sizeof s - 1, thlist_names[i], ps_thlist_times[i]); + V_DrawSmallString(28, 20+yoffset1, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + } + snprintf(s, sizeof s - 1, "LUAh_ThinkFrame: %d", ps_lua_thinkframe_time); + V_DrawSmallString(24, 25+yoffset1, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "Other: %d", + ps_tictime - ps_playerthink_time - ps_thinkertime - ps_lua_thinkframe_time); + V_DrawSmallString(24, 30+yoffset1, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); + + snprintf(s, sizeof s - 1, "Thinkers: %d", thinkercount); + V_DrawSmallString(115, 10+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "Polyobjects: %d", polythcount); + V_DrawSmallString(119, 15+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "Main: %d", mainthcount); + V_DrawSmallString(119, 20+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "Mobjs: %d", mobjcount); + V_DrawSmallString(119, 25+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "Regular: %d", mobjcount - scenerycount - nothinkcount); + V_DrawSmallString(123, 30+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "Scenery: %d", scenerycount); + V_DrawSmallString(123, 35+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); + if (nothinkcount) + { + snprintf(s, sizeof s - 1, "Nothink: %d", nothinkcount); + V_DrawSmallString(123, 40+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); + yoffset2 += 5; + } + snprintf(s, sizeof s - 1, "Dynamic slopes: %d", dynslopethcount); + V_DrawSmallString(119, 40+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "Precipitation: %d", precipcount); + V_DrawSmallString(119, 45+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "Pending removal: %d", removecount); + V_DrawSmallString(119, 50+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); + + snprintf(s, sizeof s - 1, "Calls:"); + V_DrawSmallString(212, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "Lua mobj hooks: %d", ps_lua_mobjhooks); + V_DrawSmallString(216, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "P_CheckPosition: %d", ps_checkposition_calls); + V_DrawSmallString(216, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); + } + } + else if (cv_perfstats.value == 3) // lua thinkframe + { + if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) + return; + if (vid.width < 640 || vid.height < 400) // low resolution + { + // it's not gonna fit very well.. + V_DrawThinString(30, 30, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, "Not available for resolutions below 640x400"); + } + else // high resolution + { + int i; + // text writing position + int x = 2; + int y = 4; + UINT32 text_color; + char tempbuffer[LUA_IDSIZE]; + char last_mod_name[LUA_IDSIZE]; + last_mod_name[0] = '\0'; + for (i = 0; i < thinkframe_hooks_length; i++) + { + char* str = thinkframe_hooks[i].short_src; + char* tempstr = tempbuffer; + int len = (int)strlen(str); + char* str_ptr; + if (strcmp(".lua", str + len - 4) == 0) + { + str[len-4] = '\0'; // remove .lua at end + len -= 4; + } + // we locate the wad/pk3 name in the string and compare it to + // what we found on the previous iteration. + // if the name has changed, print it out on the screen + strcpy(tempstr, str); + str_ptr = strrchr(tempstr, '|'); + if (str_ptr) + { + *str_ptr = '\0'; + str = str_ptr + 1; // this is the name of the hook without the mod file name + str_ptr = strrchr(tempstr, PATHSEP[0]); + if (str_ptr) + tempstr = str_ptr + 1; + // tempstr should now point to the mod name, (wad/pk3) possibly truncated + if (strcmp(tempstr, last_mod_name) != 0) + { + strcpy(last_mod_name, tempstr); + len = (int)strlen(tempstr); + if (len > 25) + tempstr += len - 25; + snprintf(s, sizeof s - 1, "%s", tempstr); + V_DrawSmallString(x, y, V_MONOSPACE | V_ALLOWLOWERCASE | V_GRAYMAP, s); + y += 4; // repeated code! + if (y > 192) + { + y = 4; + x += 106; + if (x > 214) + break; + } + } + text_color = V_YELLOWMAP; + } + else + { + // probably a standalone lua file + // cut off the folder if it's there + str_ptr = strrchr(tempstr, PATHSEP[0]); + if (str_ptr) + str = str_ptr + 1; + text_color = 0; // white + } + len = (int)strlen(str); + if (len > 20) + str += len - 20; + snprintf(s, sizeof s - 1, "%20s: %u", str, thinkframe_hooks[i].time_taken); + V_DrawSmallString(x, y, V_MONOSPACE | V_ALLOWLOWERCASE | text_color, s); + y += 4; // repeated code! + if (y > 192) + { + y = 4; + x += 106; + if (x > 214) + break; + } + } + } + } +} diff --git a/src/m_perfstats.h b/src/m_perfstats.h new file mode 100644 index 000000000..4fc45597d --- /dev/null +++ b/src/m_perfstats.h @@ -0,0 +1,42 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file m_perfstats.h +/// \brief Performance measurement tools. + +#ifndef __M_PERFSTATS_H__ +#define __M_PERFSTATS_H__ + +#include "doomdef.h" +#include "lua_script.h" +#include "p_local.h" + +extern int ps_tictime; + +extern int ps_playerthink_time; +extern int ps_thinkertime; + +extern int ps_thlist_times[]; + +extern int ps_checkposition_calls; + +extern int ps_lua_thinkframe_time; +extern int ps_lua_mobjhooks; + +typedef struct +{ + UINT32 time_taken; + char short_src[LUA_IDSIZE]; +} ps_hookinfo_t; + +void PS_SetThinkFrameHookInfo(int index, UINT32 time_taken, char* short_src); + +void M_DrawPerfStats(void); + +#endif \ No newline at end of file diff --git a/src/p_map.c b/src/p_map.c index 74c2790f7..ddf17a0d8 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -33,6 +33,8 @@ #include "lua_hook.h" +#include "m_perfstats.h" // ps_checkposition_calls + fixed_t tmbbox[4]; mobj_t *tmthing; static INT32 tmflags; @@ -2019,6 +2021,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) subsector_t *newsubsec; boolean blockval = true; + ps_checkposition_calls++; + I_Assert(thing != NULL); #ifdef PARANOIA if (P_MobjWasRemoved(thing)) diff --git a/src/p_tick.c b/src/p_tick.c index f84ae96c0..451e5e626 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -21,6 +21,8 @@ #include "m_random.h" #include "lua_script.h" #include "lua_hook.h" +#include "m_perfstats.h" +#include "i_system.h" // I_GetTimeMicros // Object place #include "m_cheat.h" @@ -321,6 +323,7 @@ static inline void P_RunThinkers(void) size_t i; for (i = 0; i < NUM_THINKERLISTS; i++) { + ps_thlist_times[i] = I_GetTimeMicros(); for (currentthinker = thlist[i].next; currentthinker != &thlist[i]; currentthinker = currentthinker->next) { #ifdef PARANOIA @@ -328,6 +331,7 @@ static inline void P_RunThinkers(void) #endif currentthinker->function.acp1(currentthinker); } + ps_thlist_times[i] = I_GetTimeMicros() - ps_thlist_times[i]; } } @@ -641,11 +645,16 @@ void P_Ticker(boolean run) if (demoplayback) G_ReadDemoTiccmd(&players[consoleplayer].cmd, 0); + ps_lua_mobjhooks = 0; + ps_checkposition_calls = 0; + LUAh_PreThinkFrame(); + ps_playerthink_time = I_GetTimeMicros(); for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerThink(&players[i]); + ps_playerthink_time = I_GetTimeMicros() - ps_playerthink_time; } // Keep track of how long they've been playing! @@ -660,14 +669,18 @@ void P_Ticker(boolean run) if (run) { + ps_thinkertime = I_GetTimeMicros(); P_RunThinkers(); + ps_thinkertime = I_GetTimeMicros() - ps_thinkertime; // Run any "after all the other thinkers" stuff for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerAfterThink(&players[i]); + ps_lua_thinkframe_time = I_GetTimeMicros(); LUAh_ThinkFrame(); + ps_lua_thinkframe_time = I_GetTimeMicros() - ps_lua_thinkframe_time; } // Run shield positioning diff --git a/src/r_bsp.c b/src/r_bsp.c index a430ef040..56d038b44 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -799,7 +799,7 @@ static void R_AddPolyObjects(subsector_t *sub) } // for render stats - rs_numpolyobjects += numpolys; + ps_numpolyobjects += numpolys; // sort polyobjects R_SortPolyObjects(sub); @@ -1239,7 +1239,7 @@ void R_RenderBSPNode(INT32 bspnum) node_t *bsp; INT32 side; - rs_numbspcalls++; + ps_numbspcalls++; while (!(bspnum & NF_SUBSECTOR)) // Found a subsector? { diff --git a/src/r_main.c b/src/r_main.c index 9613e2ac1..4138df5b6 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -100,22 +100,22 @@ lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; extracolormap_t *extra_colormaps = NULL; // Render stats -int rs_prevframetime = 0; -int rs_rendercalltime = 0; -int rs_uitime = 0; -int rs_swaptime = 0; -int rs_tictime = 0; +int ps_prevframetime = 0; +int ps_rendercalltime = 0; +int ps_uitime = 0; +int ps_swaptime = 0; -int rs_bsptime = 0; +int ps_bsptime = 0; -int rs_sw_portaltime = 0; -int rs_sw_planetime = 0; -int rs_sw_maskedtime = 0; +int ps_sw_spritecliptime = 0; +int ps_sw_portaltime = 0; +int ps_sw_planetime = 0; +int ps_sw_maskedtime = 0; -int rs_numbspcalls = 0; -int rs_numsprites = 0; -int rs_numdrawnodes = 0; -int rs_numpolyobjects = 0; +int ps_numbspcalls = 0; +int ps_numsprites = 0; +int ps_numdrawnodes = 0; +int ps_numpolyobjects = 0; static CV_PossibleValue_t drawdist_cons_t[] = { {256, "256"}, {512, "512"}, {768, "768"}, @@ -1489,11 +1489,11 @@ void R_RenderPlayerView(player_t *player) mytotal = 0; ProfZeroTimer(); #endif - rs_numbspcalls = rs_numpolyobjects = rs_numdrawnodes = 0; - rs_bsptime = I_GetTimeMicros(); + ps_numbspcalls = ps_numpolyobjects = ps_numdrawnodes = 0; + ps_bsptime = I_GetTimeMicros(); R_RenderBSPNode((INT32)numnodes - 1); - rs_bsptime = I_GetTimeMicros() - rs_bsptime; - rs_numsprites = visspritecount; + ps_bsptime = I_GetTimeMicros() - ps_bsptime; + ps_numsprites = visspritecount; #ifdef TIMING RDMSR(0x10, &mycount); mytotal += mycount; // 64bit add @@ -1503,7 +1503,9 @@ void R_RenderPlayerView(player_t *player) //profile stuff --------------------------------------------------------- Mask_Post(&masks[nummasks - 1]); + ps_sw_spritecliptime = I_GetTimeMicros(); R_ClipSprites(drawsegs, NULL); + ps_sw_spritecliptime = I_GetTimeMicros() - ps_sw_spritecliptime; // Add skybox portals caused by sky visplanes. @@ -1511,7 +1513,7 @@ void R_RenderPlayerView(player_t *player) Portal_AddSkyboxPortals(); // Portal rendering. Hijacks the BSP traversal. - rs_sw_portaltime = I_GetTimeMicros(); + ps_sw_portaltime = I_GetTimeMicros(); if (portal_base) { portal_t *portal; @@ -1551,20 +1553,20 @@ void R_RenderPlayerView(player_t *player) Portal_Remove(portal); } } - rs_sw_portaltime = I_GetTimeMicros() - rs_sw_portaltime; + ps_sw_portaltime = I_GetTimeMicros() - ps_sw_portaltime; - rs_sw_planetime = I_GetTimeMicros(); + ps_sw_planetime = I_GetTimeMicros(); R_DrawPlanes(); #ifdef FLOORSPLATS R_DrawVisibleFloorSplats(); #endif - rs_sw_planetime = I_GetTimeMicros() - rs_sw_planetime; + ps_sw_planetime = I_GetTimeMicros() - ps_sw_planetime; // draw mid texture and sprite // And now 3D floors/sides! - rs_sw_maskedtime = I_GetTimeMicros(); + ps_sw_maskedtime = I_GetTimeMicros(); R_DrawMasked(masks, nummasks); - rs_sw_maskedtime = I_GetTimeMicros() - rs_sw_maskedtime; + ps_sw_maskedtime = I_GetTimeMicros() - ps_sw_maskedtime; free(masks); } diff --git a/src/r_main.h b/src/r_main.h index 89b359c55..383055f9a 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -78,24 +78,22 @@ boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixe // Render stats -extern consvar_t cv_renderstats; +extern int ps_prevframetime;// time when previous frame was rendered +extern int ps_rendercalltime; +extern int ps_uitime; +extern int ps_swaptime; -extern int rs_prevframetime;// time when previous frame was rendered -extern int rs_rendercalltime; -extern int rs_uitime; -extern int rs_swaptime; -extern int rs_tictime; +extern int ps_bsptime; -extern int rs_bsptime; +extern int ps_sw_spritecliptime; +extern int ps_sw_portaltime; +extern int ps_sw_planetime; +extern int ps_sw_maskedtime; -extern int rs_sw_portaltime; -extern int rs_sw_planetime; -extern int rs_sw_maskedtime; - -extern int rs_numbspcalls; -extern int rs_numsprites; -extern int rs_numdrawnodes; -extern int rs_numpolyobjects; +extern int ps_numbspcalls; +extern int ps_numsprites; +extern int ps_numdrawnodes; +extern int ps_numpolyobjects; // // REFRESH - the actual rendering functions. diff --git a/src/r_things.c b/src/r_things.c index 382eed560..cc205f9ea 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2531,7 +2531,7 @@ static drawnode_t *R_CreateDrawNode(drawnode_t *link) node->ffloor = NULL; node->sprite = NULL; - rs_numdrawnodes++; + ps_numdrawnodes++; return node; } diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index 755fa68e6..ef1941c19 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -262,6 +262,7 @@ + @@ -417,6 +418,7 @@ + diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters index 3bbcd9cb5..3b285b869 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj.filters +++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters @@ -348,6 +348,9 @@ M_Misc + + M_Misc + M_Misc @@ -762,6 +765,9 @@ M_Misc + + M_Misc + M_Misc