From 64a153fdeecd99aa3f984fe144fd36a29f4dbc62 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sun, 19 Apr 2020 01:25:28 +0300 Subject: [PATCH 1/6] Render stats --- src/d_main.c | 73 ++++++++++++++++++++++++++++++++++++++++++ src/hardware/hw_main.c | 55 +++++++++++++++++++++++++++++++ src/hardware/hw_main.h | 21 ++++++++++++ src/i_system.h | 2 ++ src/sdl/i_system.c | 39 +++++++++++++++++++--- 5 files changed, 185 insertions(+), 5 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index c0a8eacec..09aa2d340 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -411,6 +411,7 @@ static void D_Display(void) if (!automapactive && !dedicated && cv_renderview.value) { + rs_rendercalltime = I_GetTimeMicros(); if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) { topleft = screens[0] + viewwindowy*vid.width + viewwindowx; @@ -457,6 +458,7 @@ static void D_Display(void) if (postimgtype2) V_DoPostProcessor(1, postimgtype2, postimgparam2); } + rs_rendercalltime = I_GetTimeMicros() - rs_rendercalltime; } if (lastdraw) @@ -591,6 +593,77 @@ static void D_Display(void) snprintf(s, sizeof s - 1, "SysMiss %.2f%%", lostpercent); V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-10, V_YELLOWMAP, s); } + + if (cv_renderstats.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); + if (rendermode == render_opengl)// dont show unimplemented stats + { + snprintf(s, sizeof s - 1, "bsp %d", rs_bsptime / divisor); + V_DrawThinString(30, 30, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "nsrt %d", rs_nodesorttime / divisor); + V_DrawThinString(30, 40, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "ndrw %d", rs_nodedrawtime / divisor); + V_DrawThinString(30, 50, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "ssrt %d", rs_spritesorttime / divisor); + V_DrawThinString(30, 60, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "sdrw %d", rs_spritedrawtime / divisor); + V_DrawThinString(30, 70, V_MONOSPACE | V_YELLOWMAP, s); + /*snprintf(s, sizeof s - 1, "post %d", rs_posttime / divisor); + V_DrawThinString(30, 80, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "flip %d", rs_swaptime / divisor); + V_DrawThinString(30, 90, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "test %d", rs_test / divisor); + V_DrawThinString(30, 100, 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, "nnod %d", rs_numdrawnodes); + V_DrawThinString(80, 20, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "nspr %d", rs_numsprites); + 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 (cv_enable_batching.value) + { + snprintf(s, sizeof s - 1, "bsrt %d", rs_batchsorttime / divisor); + V_DrawThinString(75, 55, V_MONOSPACE | V_REDMAP, s); + snprintf(s, sizeof s - 1, "bdrw %d", rs_batchdrawtime / divisor); + V_DrawThinString(75, 65, V_MONOSPACE | V_REDMAP, s); + + snprintf(s, sizeof s - 1, "npol %d", rs_numpolys); + V_DrawThinString(130, 10, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "ndc %d", rs_numcalls); + V_DrawThinString(130, 20, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "nshd %d", rs_numshaders); + V_DrawThinString(130, 30, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "nvrt %d", rs_numverts); + V_DrawThinString(130, 40, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "ntex %d", rs_numtextures); + V_DrawThinString(185, 10, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "npf %d", rs_numpolyflags); + V_DrawThinString(185, 20, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "ncol %d", rs_numcolors); + V_DrawThinString(185, 30, V_MONOSPACE | V_PURPLEMAP, s); + }*/ + } +/* else + { + snprintf(s, sizeof s - 1, "flip %d", rs_swaptime / divisor); + V_DrawThinString(30, 30, V_MONOSPACE | V_YELLOWMAP, s); + }*/ + } I_FinishUpdate(); // page flip or blit buffer } diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 6fe0d4078..ed43ec9ae 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -146,6 +146,25 @@ static float gr_fovlud; static angle_t gr_aimingangle; static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox); +// render stats +int rs_prevframetime = 0; +int rs_rendercalltime = 0; +int rs_bsptime = 0; +int rs_nodetime = 0; +int rs_nodesorttime = 0; +int rs_nodedrawtime = 0; +int rs_spritesorttime = 0; +int rs_spritedrawtime = 0; + +int rs_numdrawnodes = 0; +int rs_numbspcalls = 0; +int rs_numsprites = 0; +int rs_numpolyobjects = 0; + +//int rs_posttime = 0; +//int rs_swaptime = 0; + + // ========================================================================== // Lighting // ========================================================================== @@ -3484,6 +3503,9 @@ static void HWR_Subsector(size_t num) po = (polyobj_t *)(po->link.next); } + // for render stats + rs_numpolyobjects += numpolys; + // Sort polyobjects R_SortPolyObjects(sub); @@ -3598,6 +3620,8 @@ static void HWR_RenderBSPNode(INT32 bspnum) // Decide which side the view point is on INT32 side; + + rs_numbspcalls++; // Found a subsector? if (bspnum & NF_SUBSECTOR) @@ -4772,6 +4796,8 @@ static void HWR_CreateDrawNodes(void) // If true, swap the draw order. boolean shift = false; + + rs_nodesorttime = I_GetTimeMicros(); for (i = 0; i < numplanes; i++, p++) { @@ -4790,6 +4816,8 @@ static void HWR_CreateDrawNodes(void) sortnode[p].wall = &wallinfo[i]; sortindex[p] = p; } + + rs_numdrawnodes = p; // p is the number of stuff to sort @@ -4892,6 +4920,10 @@ static void HWR_CreateDrawNodes(void) } //i++ } // loop++ + rs_nodesorttime = I_GetTimeMicros() - rs_nodesorttime; + + rs_nodedrawtime = I_GetTimeMicros(); + // Okay! Let's draw it all! Woo! HWD.pfnSetTransform(&atransform); HWD.pfnSetShader(0); @@ -4926,6 +4958,8 @@ static void HWR_CreateDrawNodes(void) sortnode[sortindex[i]].wall->lightlevel, sortnode[sortindex[i]].wall->wallcolormap); } } + + rs_nodedrawtime = I_GetTimeMicros() - rs_nodedrawtime; numwalls = 0; numplanes = 0; @@ -6002,6 +6036,10 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) HWD.pfnSetSpecialState(HWD_SET_SHADERS, cv_grshaders.value); HWD.pfnSetShader(0); + rs_numbspcalls = 0; + rs_numpolyobjects = 0; + rs_bsptime = I_GetTimeMicros(); + validcount++; HWR_RenderBSPNode((INT32)numnodes-1); @@ -6035,6 +6073,8 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) } #endif + rs_bsptime = I_GetTimeMicros() - rs_bsptime; + // Check for new console commands. NetUpdate(); @@ -6045,14 +6085,22 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) #endif // Draw MD2 and sprites + rs_numsprites = gr_visspritecount; + rs_spritesorttime = I_GetTimeMicros(); HWR_SortVisSprites(); + rs_spritesorttime = I_GetTimeMicros() - rs_spritesorttime; + rs_spritedrawtime = I_GetTimeMicros(); HWR_DrawSprites(); + rs_spritedrawtime = I_GetTimeMicros() - rs_spritedrawtime; #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? HWR_DrawCoronas(); #endif + rs_numdrawnodes = 0; + rs_nodesorttime = 0; + rs_nodedrawtime = 0; if (numplanes || numpolyplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything { HWR_CreateDrawNodes(); @@ -6118,6 +6166,11 @@ consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotro consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +// render stats +// for now have it in here in the hw code +// could have it somewhere else since renderstats could also be a software rendering thing +consvar_t cv_renderstats = {"renderstats", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + static void CV_grfiltermode_OnChange(void) { if (rendermode == render_opengl) @@ -6155,6 +6208,8 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_grfiltermode); CV_RegisterVar(&cv_grcorrecttricks); CV_RegisterVar(&cv_grsolvetjoin); + + CV_RegisterVar(&cv_renderstats); #ifndef NEWCLIP CV_RegisterVar(&cv_grclipwalls); diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index aedfa9cd6..8aaa335fb 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -104,4 +104,25 @@ extern float gr_viewwindowx, gr_basewindowcentery; extern fixed_t *hwbbox; extern FTransform atransform; + +// render stats console toggle +extern consvar_t cv_renderstats; +// render stats time counter variables +extern int rs_prevframetime;// time when previous frame was rendered +extern int rs_rendercalltime; +extern int rs_bsptime; +extern int rs_nodetime; +extern int rs_nodesorttime; +extern int rs_nodedrawtime; +extern int rs_spritesorttime; +extern int rs_spritedrawtime; + +//extern int rs_posttime; +//extern int rs_swaptime; + +extern int rs_numdrawnodes; +extern int rs_numbspcalls; +extern int rs_numsprites; +extern int rs_numpolyobjects; + #endif diff --git a/src/i_system.h b/src/i_system.h index b38748244..dd0b65f6d 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -46,6 +46,8 @@ UINT32 I_GetFreeMem(UINT32 *total); */ tic_t I_GetTime(void); +int I_GetTimeMicros(void);// provides microsecond counter for render stats + /** \brief The I_Sleep function \return void diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index a86af316e..9d63225cb 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2060,9 +2060,12 @@ static p_timeGetTime pfntimeGetTime = NULL; // but lower precision on Windows NT // --------- -tic_t I_GetTime(void) +DWORD TimeFunction(boolean microseconds) { - tic_t newtics = 0; + DWORD newtics = 0; + int multiplier = 1; + + if (microseconds) multiplier = 1000; if (!starttickcount) // high precision timer { @@ -2082,7 +2085,7 @@ tic_t I_GetTime(void) if (frequency.LowPart && QueryPerformanceCounter(&currtime)) { - newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * NEWTICRATE + newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * 1000 * multiplier / frequency.QuadPart); } else if (pfntimeGetTime) @@ -2090,11 +2093,11 @@ tic_t I_GetTime(void) currtime.LowPart = pfntimeGetTime(); if (!basetime.LowPart) basetime.LowPart = currtime.LowPart; - newtics = ((currtime.LowPart - basetime.LowPart)/(1000/NEWTICRATE)); + newtics = currtime.LowPart - basetime.LowPart; } } else - newtics = (GetTickCount() - starttickcount)/(1000/NEWTICRATE); + newtics = (GetTickCount() - starttickcount) * multiplier; return newtics; } @@ -2116,6 +2119,7 @@ static void I_ShutdownTimer(void) // I_GetTime // returns time in 1/TICRATE second tics // +/* tic_t I_GetTime (void) { static Uint64 basetime = 0; @@ -2132,8 +2136,33 @@ tic_t I_GetTime (void) return (tic_t)ticks; } +*/ +int TimeFunction(boolean microseconds)// this cant actually do microseconds so it fakes it +{ + static Uint64 basetime = 0; + Uint64 ticks = SDL_GetTicks(); + + if (!basetime) + basetime = ticks; + + ticks -= basetime; + + return microseconds ? ticks * 1000 : ticks; +} #endif +tic_t I_GetTime(void) +{ + //return TimeFunction(false) / (1000/NEWTICRATE); + // how about this + return (TimeFunction(false) * NEWTICRATE) / 1000; +} + +int I_GetTimeMicros(void) +{ + return TimeFunction(true); +} + // //I_StartupTimer // From 8dcc2fe20da0cebdbf31ffb0c69a34337a401cd3 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Fri, 1 May 2020 20:57:48 +0300 Subject: [PATCH 2/6] Move some render stats variables to better locations, add I_FinishUpdate timing --- src/d_main.c | 14 ++++++++------ src/hardware/hw_main.c | 10 +--------- src/hardware/hw_main.h | 6 ------ src/r_main.c | 7 +++++++ src/r_main.h | 8 ++++++++ 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 09aa2d340..28e134d65 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -620,10 +620,10 @@ static void D_Display(void) snprintf(s, sizeof s - 1, "sdrw %d", rs_spritedrawtime / divisor); V_DrawThinString(30, 70, V_MONOSPACE | V_YELLOWMAP, s); /*snprintf(s, sizeof s - 1, "post %d", rs_posttime / divisor); + V_DrawThinString(30, 80, 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, "flip %d", rs_swaptime / divisor); - V_DrawThinString(30, 90, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "test %d", rs_test / divisor); + /*snprintf(s, sizeof s - 1, "test %d", rs_test / divisor); V_DrawThinString(30, 100, V_MONOSPACE | V_YELLOWMAP, s);*/ snprintf(s, sizeof s - 1, "nbsp %d", rs_numbspcalls); @@ -658,14 +658,16 @@ static void D_Display(void) V_DrawThinString(185, 30, V_MONOSPACE | V_PURPLEMAP, s); }*/ } -/* else + else { - snprintf(s, sizeof s - 1, "flip %d", rs_swaptime / divisor); + snprintf(s, sizeof s - 1, "fin %d", rs_swaptime / divisor); V_DrawThinString(30, 30, V_MONOSPACE | V_YELLOWMAP, s); - }*/ + } } + rs_swaptime = I_GetTimeMicros(); I_FinishUpdate(); // page flip or blit buffer + rs_swaptime = I_GetTimeMicros() - rs_swaptime; } needpatchflush = false; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index ed43ec9ae..79cc83bba 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -146,9 +146,7 @@ static float gr_fovlud; static angle_t gr_aimingangle; static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox); -// render stats -int rs_prevframetime = 0; -int rs_rendercalltime = 0; +// Render stats int rs_bsptime = 0; int rs_nodetime = 0; int rs_nodesorttime = 0; @@ -162,7 +160,6 @@ int rs_numsprites = 0; int rs_numpolyobjects = 0; //int rs_posttime = 0; -//int rs_swaptime = 0; // ========================================================================== @@ -6166,11 +6163,6 @@ consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotro consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -// render stats -// for now have it in here in the hw code -// could have it somewhere else since renderstats could also be a software rendering thing -consvar_t cv_renderstats = {"renderstats", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - static void CV_grfiltermode_OnChange(void) { if (rendermode == render_opengl) diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 8aaa335fb..f89809cc7 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -105,11 +105,6 @@ extern fixed_t *hwbbox; extern FTransform atransform; -// render stats console toggle -extern consvar_t cv_renderstats; -// render stats time counter variables -extern int rs_prevframetime;// time when previous frame was rendered -extern int rs_rendercalltime; extern int rs_bsptime; extern int rs_nodetime; extern int rs_nodesorttime; @@ -118,7 +113,6 @@ extern int rs_spritesorttime; extern int rs_spritedrawtime; //extern int rs_posttime; -//extern int rs_swaptime; extern int rs_numdrawnodes; extern int rs_numbspcalls; diff --git a/src/r_main.c b/src/r_main.c index a881e046d..17eae9495 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -98,6 +98,11 @@ lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; // Hack to support extra boom colormaps. extracolormap_t *extra_colormaps = NULL; +// Render stats +int rs_prevframetime = 0; +int rs_rendercalltime = 0; +int rs_swaptime = 0; + static CV_PossibleValue_t drawdist_cons_t[] = { {256, "256"}, {512, "512"}, {768, "768"}, {1024, "1024"}, {1536, "1536"}, {2048, "2048"}, @@ -148,6 +153,8 @@ consvar_t cv_homremoval = {"homremoval", "No", CV_SAVE, homremoval_cons_t, NULL, consvar_t cv_maxportals = {"maxportals", "2", CV_SAVE, maxportals_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_renderstats = {"renderstats", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + void SplitScreen_OnChange(void) { if (!cv_debug && netgame) diff --git a/src/r_main.h b/src/r_main.h index 578eb3d54..72d340bd9 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -74,6 +74,14 @@ subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y); boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph); +// Render stats + +extern consvar_t cv_renderstats; + +extern int rs_prevframetime;// time when previous frame was rendered +extern int rs_rendercalltime; +extern int rs_swaptime; + // // REFRESH - the actual rendering functions. // From 7e8543a408c35e590ac023a88af7e902761d85d5 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 2 May 2020 20:43:53 +0300 Subject: [PATCH 3/6] More render stats for software mode, renamed and relocated some render stats variables --- src/d_main.c | 40 +++++++++++++++++++++++----------------- src/hardware/hw_main.c | 35 ++++++++++++++--------------------- src/hardware/hw_main.h | 16 +++++----------- src/r_bsp.c | 6 ++++++ src/r_main.c | 22 ++++++++++++++++++++++ src/r_main.h | 11 +++++++++++ src/r_things.c | 2 ++ 7 files changed, 83 insertions(+), 49 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 28e134d65..2e1badc69 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -607,17 +607,25 @@ static void D_Display(void) 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); - if (rendermode == render_opengl)// dont show unimplemented stats + 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 { - snprintf(s, sizeof s - 1, "bsp %d", rs_bsptime / divisor); - V_DrawThinString(30, 30, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "nsrt %d", rs_nodesorttime / divisor); + 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_nodedrawtime / divisor); + 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_spritesorttime / divisor); + 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_spritedrawtime / divisor); + 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, "post %d", rs_posttime / divisor); V_DrawThinString(30, 80, V_MONOSPACE | V_YELLOWMAP, s);*/ @@ -626,14 +634,6 @@ static void D_Display(void) /*snprintf(s, sizeof s - 1, "test %d", rs_test / divisor); V_DrawThinString(30, 100, 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, "nnod %d", rs_numdrawnodes); - V_DrawThinString(80, 20, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "nspr %d", rs_numsprites); - 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 (cv_enable_batching.value) { @@ -658,10 +658,16 @@ static void D_Display(void) V_DrawThinString(185, 30, V_MONOSPACE | V_PURPLEMAP, s); }*/ } - else + 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, "fin %d", rs_swaptime / divisor); - V_DrawThinString(30, 30, V_MONOSPACE | V_YELLOWMAP, s); + V_DrawThinString(30, 70, V_MONOSPACE | V_YELLOWMAP, s); } } diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 79cc83bba..bd2c5c9f4 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -147,17 +147,10 @@ static angle_t gr_aimingangle; static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox); // Render stats -int rs_bsptime = 0; -int rs_nodetime = 0; -int rs_nodesorttime = 0; -int rs_nodedrawtime = 0; -int rs_spritesorttime = 0; -int rs_spritedrawtime = 0; - -int rs_numdrawnodes = 0; -int rs_numbspcalls = 0; -int rs_numsprites = 0; -int rs_numpolyobjects = 0; +int rs_hw_nodesorttime = 0; +int rs_hw_nodedrawtime = 0; +int rs_hw_spritesorttime = 0; +int rs_hw_spritedrawtime = 0; //int rs_posttime = 0; @@ -4794,7 +4787,7 @@ static void HWR_CreateDrawNodes(void) // If true, swap the draw order. boolean shift = false; - rs_nodesorttime = I_GetTimeMicros(); + rs_hw_nodesorttime = I_GetTimeMicros(); for (i = 0; i < numplanes; i++, p++) { @@ -4917,9 +4910,9 @@ static void HWR_CreateDrawNodes(void) } //i++ } // loop++ - rs_nodesorttime = I_GetTimeMicros() - rs_nodesorttime; + rs_hw_nodesorttime = I_GetTimeMicros() - rs_hw_nodesorttime; - rs_nodedrawtime = I_GetTimeMicros(); + rs_hw_nodedrawtime = I_GetTimeMicros(); // Okay! Let's draw it all! Woo! HWD.pfnSetTransform(&atransform); @@ -4956,7 +4949,7 @@ static void HWR_CreateDrawNodes(void) } } - rs_nodedrawtime = I_GetTimeMicros() - rs_nodedrawtime; + rs_hw_nodedrawtime = I_GetTimeMicros() - rs_hw_nodedrawtime; numwalls = 0; numplanes = 0; @@ -6083,12 +6076,12 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) // Draw MD2 and sprites rs_numsprites = gr_visspritecount; - rs_spritesorttime = I_GetTimeMicros(); + rs_hw_spritesorttime = I_GetTimeMicros(); HWR_SortVisSprites(); - rs_spritesorttime = I_GetTimeMicros() - rs_spritesorttime; - rs_spritedrawtime = I_GetTimeMicros(); + rs_hw_spritesorttime = I_GetTimeMicros() - rs_hw_spritesorttime; + rs_hw_spritedrawtime = I_GetTimeMicros(); HWR_DrawSprites(); - rs_spritedrawtime = I_GetTimeMicros() - rs_spritedrawtime; + rs_hw_spritedrawtime = I_GetTimeMicros() - rs_hw_spritedrawtime; #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? @@ -6096,8 +6089,8 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) #endif rs_numdrawnodes = 0; - rs_nodesorttime = 0; - rs_nodedrawtime = 0; + rs_hw_nodesorttime = 0; + rs_hw_nodedrawtime = 0; if (numplanes || numpolyplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything { HWR_CreateDrawNodes(); diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index f89809cc7..631593d6f 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -105,18 +105,12 @@ extern fixed_t *hwbbox; extern FTransform atransform; -extern int rs_bsptime; -extern int rs_nodetime; -extern int rs_nodesorttime; -extern int rs_nodedrawtime; -extern int rs_spritesorttime; -extern int rs_spritedrawtime; +// Render stats +extern int rs_hw_nodesorttime; +extern int rs_hw_nodedrawtime; +extern int rs_hw_spritesorttime; +extern int rs_hw_spritedrawtime; //extern int rs_posttime; -extern int rs_numdrawnodes; -extern int rs_numbspcalls; -extern int rs_numsprites; -extern int rs_numpolyobjects; - #endif diff --git a/src/r_bsp.c b/src/r_bsp.c index c0011f4b9..355d55bc6 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -812,6 +812,9 @@ static void R_AddPolyObjects(subsector_t *sub) po = (polyobj_t *)(po->link.next); } + // for render stats + rs_numpolyobjects += numpolys; + // sort polyobjects R_SortPolyObjects(sub); @@ -1363,6 +1366,9 @@ void R_RenderBSPNode(INT32 bspnum) { node_t *bsp; INT32 side; + + rs_numbspcalls++; + while (!(bspnum & NF_SUBSECTOR)) // Found a subsector? { bsp = &nodes[bspnum]; diff --git a/src/r_main.c b/src/r_main.c index 17eae9495..4d1be4b14 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -34,6 +34,7 @@ #include "m_random.h" // quake camera shake #include "r_portal.h" #include "r_main.h" +#include "i_system.h" // I_GetTimeMicros #ifdef HWRENDER #include "hardware/hw_main.h" @@ -103,6 +104,17 @@ int rs_prevframetime = 0; int rs_rendercalltime = 0; int rs_swaptime = 0; +int rs_bsptime = 0; + +int rs_sw_portaltime = 0; +int rs_sw_planetime = 0; +int rs_sw_maskedtime = 0; + +int rs_numbspcalls = 0; +int rs_numsprites = 0; +int rs_numdrawnodes = 0; +int rs_numpolyobjects = 0; + static CV_PossibleValue_t drawdist_cons_t[] = { {256, "256"}, {512, "512"}, {768, "768"}, {1024, "1024"}, {1536, "1536"}, {2048, "2048"}, @@ -1452,7 +1464,11 @@ void R_RenderPlayerView(player_t *player) mytotal = 0; ProfZeroTimer(); #endif + rs_numbspcalls = rs_numpolyobjects = rs_numdrawnodes = 0; + rs_bsptime = I_GetTimeMicros(); R_RenderBSPNode((INT32)numnodes - 1); + rs_bsptime = I_GetTimeMicros() - rs_bsptime; + rs_numsprites = visspritecount; #ifdef TIMING RDMSR(0x10, &mycount); mytotal += mycount; // 64bit add @@ -1470,6 +1486,7 @@ void R_RenderPlayerView(player_t *player) Portal_AddSkyboxPortals(); // Portal rendering. Hijacks the BSP traversal. + rs_sw_portaltime = I_GetTimeMicros(); if (portal_base) { portal_t *portal; @@ -1509,15 +1526,20 @@ void R_RenderPlayerView(player_t *player) Portal_Remove(portal); } } + rs_sw_portaltime = I_GetTimeMicros() - rs_sw_portaltime; + rs_sw_planetime = I_GetTimeMicros(); R_DrawPlanes(); #ifdef FLOORSPLATS R_DrawVisibleFloorSplats(); #endif + rs_sw_planetime = I_GetTimeMicros() - rs_sw_planetime; // draw mid texture and sprite // And now 3D floors/sides! + rs_sw_maskedtime = I_GetTimeMicros(); R_DrawMasked(masks, nummasks); + rs_sw_maskedtime = I_GetTimeMicros() - rs_sw_maskedtime; free(masks); } diff --git a/src/r_main.h b/src/r_main.h index 72d340bd9..99a25d86e 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -82,6 +82,17 @@ extern int rs_prevframetime;// time when previous frame was rendered extern int rs_rendercalltime; extern int rs_swaptime; +extern int rs_bsptime; + +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; + // // REFRESH - the actual rendering functions. // diff --git a/src/r_things.c b/src/r_things.c index d2f3b4902..02c347929 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2552,6 +2552,8 @@ static drawnode_t *R_CreateDrawNode(drawnode_t *link) node->thickseg = NULL; node->ffloor = NULL; node->sprite = NULL; + + rs_numdrawnodes++; return node; } From 724e093ce8f8dd679a5fff9cf6040fc99c313a3a Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 2 May 2020 20:45:33 +0300 Subject: [PATCH 4/6] Render stats cleanup --- src/d_main.c | 28 ---------------------------- src/hardware/hw_main.c | 2 -- src/hardware/hw_main.h | 2 -- 3 files changed, 32 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 2e1badc69..5631cb939 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -627,36 +627,8 @@ static void D_Display(void) 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, "post %d", rs_posttime / divisor); - V_DrawThinString(30, 80, 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, "test %d", rs_test / divisor); - V_DrawThinString(30, 100, V_MONOSPACE | V_YELLOWMAP, s);*/ - -/* - if (cv_enable_batching.value) - { - snprintf(s, sizeof s - 1, "bsrt %d", rs_batchsorttime / divisor); - V_DrawThinString(75, 55, V_MONOSPACE | V_REDMAP, s); - snprintf(s, sizeof s - 1, "bdrw %d", rs_batchdrawtime / divisor); - V_DrawThinString(75, 65, V_MONOSPACE | V_REDMAP, s); - - snprintf(s, sizeof s - 1, "npol %d", rs_numpolys); - V_DrawThinString(130, 10, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "ndc %d", rs_numcalls); - V_DrawThinString(130, 20, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "nshd %d", rs_numshaders); - V_DrawThinString(130, 30, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "nvrt %d", rs_numverts); - V_DrawThinString(130, 40, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "ntex %d", rs_numtextures); - V_DrawThinString(185, 10, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "npf %d", rs_numpolyflags); - V_DrawThinString(185, 20, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "ncol %d", rs_numcolors); - V_DrawThinString(185, 30, V_MONOSPACE | V_PURPLEMAP, s); - }*/ } else // software specific stats { diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index bd2c5c9f4..88c4a7808 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -152,8 +152,6 @@ int rs_hw_nodedrawtime = 0; int rs_hw_spritesorttime = 0; int rs_hw_spritedrawtime = 0; -//int rs_posttime = 0; - // ========================================================================== // Lighting diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 631593d6f..fc49364da 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -111,6 +111,4 @@ extern int rs_hw_nodedrawtime; extern int rs_hw_spritesorttime; extern int rs_hw_spritedrawtime; -//extern int rs_posttime; - #endif From 1b6e65b91c17ee622a995a6e0cb4b40eecb0462d Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 2 May 2020 23:06:01 +0300 Subject: [PATCH 5/6] Implement I_GetTimeMicros without affecting I_GetTime behaviour details --- src/sdl/i_system.c | 49 ++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 9d63225cb..426904c63 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2060,12 +2060,11 @@ static p_timeGetTime pfntimeGetTime = NULL; // but lower precision on Windows NT // --------- -DWORD TimeFunction(boolean microseconds) +DWORD TimeFunction(int requested_frequency) { DWORD newtics = 0; - int multiplier = 1; - - if (microseconds) multiplier = 1000; + // this var acts as a multiplier if sub-millisecond precision is asked but is not available + int excess_frequency = requested_frequency / 1000; if (!starttickcount) // high precision timer { @@ -2085,7 +2084,7 @@ DWORD TimeFunction(boolean microseconds) if (frequency.LowPart && QueryPerformanceCounter(&currtime)) { - newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * 1000 * multiplier + newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * requested_frequency / frequency.QuadPart); } else if (pfntimeGetTime) @@ -2093,11 +2092,19 @@ DWORD TimeFunction(boolean microseconds) currtime.LowPart = pfntimeGetTime(); if (!basetime.LowPart) basetime.LowPart = currtime.LowPart; - newtics = currtime.LowPart - basetime.LowPart; + if (requested_frequency > 1000) + newtics = currtime.LowPart - basetime.LowPart * excess_frequency; + else + newtics = (currtime.LowPart - basetime.LowPart)/(1000/requested_frequency); } } else - newtics = (GetTickCount() - starttickcount) * multiplier; + { + if (requested_frequency > 1000) + newtics = (GetTickCount() - starttickcount) * excess_frequency; + else + newtics = (GetTickCount() - starttickcount)/(1000/requested_frequency); + } return newtics; } @@ -2119,8 +2126,9 @@ static void I_ShutdownTimer(void) // I_GetTime // returns time in 1/TICRATE second tics // -/* -tic_t I_GetTime (void) + +// millisecond precision only +int TimeFunction(int requested_frequency) { static Uint64 basetime = 0; Uint64 ticks = SDL_GetTicks(); @@ -2130,37 +2138,22 @@ tic_t I_GetTime (void) ticks -= basetime; - ticks = (ticks*TICRATE); + ticks = (ticks*requested_frequency); ticks = (ticks/1000); - return (tic_t)ticks; -} -*/ -int TimeFunction(boolean microseconds)// this cant actually do microseconds so it fakes it -{ - static Uint64 basetime = 0; - Uint64 ticks = SDL_GetTicks(); - - if (!basetime) - basetime = ticks; - - ticks -= basetime; - - return microseconds ? ticks * 1000 : ticks; + return ticks; } #endif tic_t I_GetTime(void) { - //return TimeFunction(false) / (1000/NEWTICRATE); - // how about this - return (TimeFunction(false) * NEWTICRATE) / 1000; + return TimeFunction(NEWTICRATE); } int I_GetTimeMicros(void) { - return TimeFunction(true); + return TimeFunction(1000000); } // From c9114867cc0b3d47a30eeab096042300531df920 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 2 May 2020 23:22:58 +0300 Subject: [PATCH 6/6] Dummy I_GetTimeMicros --- src/dummy/i_system.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c index 5c0f7eb99..4a657ed19 100644 --- a/src/dummy/i_system.c +++ b/src/dummy/i_system.c @@ -16,6 +16,11 @@ tic_t I_GetTime(void) return 0; } +int I_GetTimeMicros(void) +{ + return 0; +} + void I_Sleep(void){} void I_GetEvent(void){}