diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6446ff109..6c0e20e8e 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 2fe0b26cd..8ad7ecf5a 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 b6974b6cd..51a3bb24b 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
@@ -5444,14 +5445,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 c4cde87a3..ce1331fe3 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 9082a818a..87abd596a 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 e7a0ac3ff..4268556e3 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(SHADER_DEFAULT);
- 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 9bce49b25..85072dfd9 100644
--- a/src/hardware/hw_main.h
+++ b/src/hardware/hw_main.h
@@ -113,21 +113,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..1db46025e
--- /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
diff --git a/src/p_map.c b/src/p_map.c
index f2faf29b6..544df66d7 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 0c13e3423..5165b3c87 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"},
@@ -1490,11 +1490,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
@@ -1504,7 +1504,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.
@@ -1512,7 +1514,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;
@@ -1552,20 +1554,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 5466d2a25..379b5b8df 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 5b0ff7425..c2d6456e4 100644
--- a/src/sdl/Srb2SDL-vc10.vcxproj
+++ b/src/sdl/Srb2SDL-vc10.vcxproj
@@ -262,6 +262,7 @@
+
@@ -418,6 +419,7 @@
+
diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters
index 505384313..438746ac7 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
@@ -765,6 +768,9 @@
M_Misc
+
+ M_Misc
+
M_Misc