Merge branch 'renderstats' into 'sal-oglshaderport'

Render stats

See merge request STJr/SRB2!914
This commit is contained in:
SteelT 2020-06-07 12:29:58 -04:00
commit db32b01222
10 changed files with 191 additions and 8 deletions

View file

@ -411,6 +411,7 @@ static void D_Display(void)
if (!automapactive && !dedicated && cv_renderview.value) if (!automapactive && !dedicated && cv_renderview.value)
{ {
rs_rendercalltime = I_GetTimeMicros();
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
{ {
topleft = screens[0] + viewwindowy*vid.width + viewwindowx; topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
@ -457,6 +458,7 @@ static void D_Display(void)
if (postimgtype2) if (postimgtype2)
V_DoPostProcessor(1, postimgtype2, postimgparam2); V_DoPostProcessor(1, postimgtype2, postimgparam2);
} }
rs_rendercalltime = I_GetTimeMicros() - rs_rendercalltime;
} }
if (lastdraw) if (lastdraw)
@ -592,7 +594,58 @@ static void D_Display(void)
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-10, V_YELLOWMAP, s); 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);
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, "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, "fin %d", rs_swaptime / divisor);
V_DrawThinString(30, 80, V_MONOSPACE | V_YELLOWMAP, s);
}
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, 70, V_MONOSPACE | V_YELLOWMAP, s);
}
}
rs_swaptime = I_GetTimeMicros();
I_FinishUpdate(); // page flip or blit buffer I_FinishUpdate(); // page flip or blit buffer
rs_swaptime = I_GetTimeMicros() - rs_swaptime;
} }
needpatchflush = false; needpatchflush = false;

View file

@ -16,6 +16,11 @@ tic_t I_GetTime(void)
return 0; return 0;
} }
int I_GetTimeMicros(void)
{
return 0;
}
void I_Sleep(void){} void I_Sleep(void){}
void I_GetEvent(void){} void I_GetEvent(void){}

View file

@ -146,6 +146,13 @@ static float gr_fovlud;
static angle_t gr_aimingangle; static angle_t gr_aimingangle;
static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox); 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;
// ========================================================================== // ==========================================================================
// Lighting // Lighting
// ========================================================================== // ==========================================================================
@ -3463,6 +3470,9 @@ static void HWR_Subsector(size_t num)
po = (polyobj_t *)(po->link.next); po = (polyobj_t *)(po->link.next);
} }
// for render stats
rs_numpolyobjects += numpolys;
// Sort polyobjects // Sort polyobjects
R_SortPolyObjects(sub); R_SortPolyObjects(sub);
@ -3578,6 +3588,8 @@ static void HWR_RenderBSPNode(INT32 bspnum)
// Decide which side the view point is on // Decide which side the view point is on
INT32 side; INT32 side;
rs_numbspcalls++;
// Found a subsector? // Found a subsector?
if (bspnum & NF_SUBSECTOR) if (bspnum & NF_SUBSECTOR)
{ {
@ -4752,6 +4764,8 @@ static void HWR_CreateDrawNodes(void)
// If true, swap the draw order. // If true, swap the draw order.
boolean shift = false; boolean shift = false;
rs_hw_nodesorttime = I_GetTimeMicros();
for (i = 0; i < numplanes; i++, p++) for (i = 0; i < numplanes; i++, p++)
{ {
sortnode[p].plane = &planeinfo[i]; sortnode[p].plane = &planeinfo[i];
@ -4770,6 +4784,8 @@ static void HWR_CreateDrawNodes(void)
sortindex[p] = p; sortindex[p] = p;
} }
rs_numdrawnodes = p;
// p is the number of stuff to sort // p is the number of stuff to sort
// Add the 3D floors, thicksides, and masked textures... // Add the 3D floors, thicksides, and masked textures...
@ -4871,6 +4887,10 @@ static void HWR_CreateDrawNodes(void)
} //i++ } //i++
} // loop++ } // loop++
rs_hw_nodesorttime = I_GetTimeMicros() - rs_hw_nodesorttime;
rs_hw_nodedrawtime = I_GetTimeMicros();
// Okay! Let's draw it all! Woo! // Okay! Let's draw it all! Woo!
HWD.pfnSetTransform(&atransform); HWD.pfnSetTransform(&atransform);
HWD.pfnSetShader(0); HWD.pfnSetShader(0);
@ -4906,6 +4926,8 @@ static void HWR_CreateDrawNodes(void)
} }
} }
rs_hw_nodedrawtime = I_GetTimeMicros() - rs_hw_nodedrawtime;
numwalls = 0; numwalls = 0;
numplanes = 0; numplanes = 0;
numpolyplanes = 0; numpolyplanes = 0;
@ -5981,6 +6003,10 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
HWD.pfnSetSpecialState(HWD_SET_SHADERS, cv_grshaders.value); HWD.pfnSetSpecialState(HWD_SET_SHADERS, cv_grshaders.value);
HWD.pfnSetShader(0); HWD.pfnSetShader(0);
rs_numbspcalls = 0;
rs_numpolyobjects = 0;
rs_bsptime = I_GetTimeMicros();
validcount++; validcount++;
HWR_RenderBSPNode((INT32)numnodes-1); HWR_RenderBSPNode((INT32)numnodes-1);
@ -6014,6 +6040,8 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
} }
#endif #endif
rs_bsptime = I_GetTimeMicros() - rs_bsptime;
// Check for new console commands. // Check for new console commands.
NetUpdate(); NetUpdate();
@ -6024,14 +6052,22 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
#endif #endif
// Draw MD2 and sprites // Draw MD2 and sprites
rs_numsprites = gr_visspritecount;
rs_hw_spritesorttime = I_GetTimeMicros();
HWR_SortVisSprites(); HWR_SortVisSprites();
rs_hw_spritesorttime = I_GetTimeMicros() - rs_hw_spritesorttime;
rs_hw_spritedrawtime = I_GetTimeMicros();
HWR_DrawSprites(); HWR_DrawSprites();
rs_hw_spritedrawtime = I_GetTimeMicros() - rs_hw_spritedrawtime;
#ifdef NEWCORONAS #ifdef NEWCORONAS
//Hurdler: they must be drawn before translucent planes, what about gl fog? //Hurdler: they must be drawn before translucent planes, what about gl fog?
HWR_DrawCoronas(); HWR_DrawCoronas();
#endif #endif
rs_numdrawnodes = 0;
rs_hw_nodesorttime = 0;
rs_hw_nodedrawtime = 0;
if (numplanes || numpolyplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything if (numplanes || numpolyplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything
{ {
HWR_CreateDrawNodes(); HWR_CreateDrawNodes();
@ -6135,6 +6171,8 @@ void HWR_AddCommands(void)
CV_RegisterVar(&cv_grcorrecttricks); CV_RegisterVar(&cv_grcorrecttricks);
CV_RegisterVar(&cv_grsolvetjoin); CV_RegisterVar(&cv_grsolvetjoin);
CV_RegisterVar(&cv_renderstats);
#ifndef NEWCLIP #ifndef NEWCLIP
CV_RegisterVar(&cv_grclipwalls); CV_RegisterVar(&cv_grclipwalls);
#endif #endif

View file

@ -104,4 +104,11 @@ extern float gr_viewwindowx, gr_basewindowcentery;
extern fixed_t *hwbbox; extern fixed_t *hwbbox;
extern FTransform atransform; 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;
#endif #endif

View file

@ -46,6 +46,8 @@ UINT32 I_GetFreeMem(UINT32 *total);
*/ */
tic_t I_GetTime(void); tic_t I_GetTime(void);
int I_GetTimeMicros(void);// provides microsecond counter for render stats
/** \brief The I_Sleep function /** \brief The I_Sleep function
\return void \return void

View file

@ -812,6 +812,9 @@ static void R_AddPolyObjects(subsector_t *sub)
po = (polyobj_t *)(po->link.next); po = (polyobj_t *)(po->link.next);
} }
// for render stats
rs_numpolyobjects += numpolys;
// sort polyobjects // sort polyobjects
R_SortPolyObjects(sub); R_SortPolyObjects(sub);
@ -1363,6 +1366,9 @@ void R_RenderBSPNode(INT32 bspnum)
{ {
node_t *bsp; node_t *bsp;
INT32 side; INT32 side;
rs_numbspcalls++;
while (!(bspnum & NF_SUBSECTOR)) // Found a subsector? while (!(bspnum & NF_SUBSECTOR)) // Found a subsector?
{ {
bsp = &nodes[bspnum]; bsp = &nodes[bspnum];

View file

@ -34,6 +34,7 @@
#include "m_random.h" // quake camera shake #include "m_random.h" // quake camera shake
#include "r_portal.h" #include "r_portal.h"
#include "r_main.h" #include "r_main.h"
#include "i_system.h" // I_GetTimeMicros
#ifdef HWRENDER #ifdef HWRENDER
#include "hardware/hw_main.h" #include "hardware/hw_main.h"
@ -98,6 +99,22 @@ lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
// Hack to support extra boom colormaps. // Hack to support extra boom colormaps.
extracolormap_t *extra_colormaps = NULL; extracolormap_t *extra_colormaps = NULL;
// Render stats
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[] = { static CV_PossibleValue_t drawdist_cons_t[] = {
{256, "256"}, {512, "512"}, {768, "768"}, {256, "256"}, {512, "512"}, {768, "768"},
{1024, "1024"}, {1536, "1536"}, {2048, "2048"}, {1024, "1024"}, {1536, "1536"}, {2048, "2048"},
@ -148,6 +165,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_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) void SplitScreen_OnChange(void)
{ {
if (!cv_debug && netgame) if (!cv_debug && netgame)
@ -1445,7 +1464,11 @@ void R_RenderPlayerView(player_t *player)
mytotal = 0; mytotal = 0;
ProfZeroTimer(); ProfZeroTimer();
#endif #endif
rs_numbspcalls = rs_numpolyobjects = rs_numdrawnodes = 0;
rs_bsptime = I_GetTimeMicros();
R_RenderBSPNode((INT32)numnodes - 1); R_RenderBSPNode((INT32)numnodes - 1);
rs_bsptime = I_GetTimeMicros() - rs_bsptime;
rs_numsprites = visspritecount;
#ifdef TIMING #ifdef TIMING
RDMSR(0x10, &mycount); RDMSR(0x10, &mycount);
mytotal += mycount; // 64bit add mytotal += mycount; // 64bit add
@ -1463,6 +1486,7 @@ void R_RenderPlayerView(player_t *player)
Portal_AddSkyboxPortals(); Portal_AddSkyboxPortals();
// Portal rendering. Hijacks the BSP traversal. // Portal rendering. Hijacks the BSP traversal.
rs_sw_portaltime = I_GetTimeMicros();
if (portal_base) if (portal_base)
{ {
portal_t *portal; portal_t *portal;
@ -1502,15 +1526,20 @@ void R_RenderPlayerView(player_t *player)
Portal_Remove(portal); Portal_Remove(portal);
} }
} }
rs_sw_portaltime = I_GetTimeMicros() - rs_sw_portaltime;
rs_sw_planetime = I_GetTimeMicros();
R_DrawPlanes(); R_DrawPlanes();
#ifdef FLOORSPLATS #ifdef FLOORSPLATS
R_DrawVisibleFloorSplats(); R_DrawVisibleFloorSplats();
#endif #endif
rs_sw_planetime = I_GetTimeMicros() - rs_sw_planetime;
// draw mid texture and sprite // draw mid texture and sprite
// And now 3D floors/sides! // And now 3D floors/sides!
rs_sw_maskedtime = I_GetTimeMicros();
R_DrawMasked(masks, nummasks); R_DrawMasked(masks, nummasks);
rs_sw_maskedtime = I_GetTimeMicros() - rs_sw_maskedtime;
free(masks); free(masks);
} }

View file

@ -74,6 +74,25 @@ 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); 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;
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. // REFRESH - the actual rendering functions.
// //

View file

@ -2552,6 +2552,8 @@ static drawnode_t *R_CreateDrawNode(drawnode_t *link)
node->thickseg = NULL; node->thickseg = NULL;
node->ffloor = NULL; node->ffloor = NULL;
node->sprite = NULL; node->sprite = NULL;
rs_numdrawnodes++;
return node; return node;
} }

View file

@ -2060,9 +2060,11 @@ static p_timeGetTime pfntimeGetTime = NULL;
// but lower precision on Windows NT // but lower precision on Windows NT
// --------- // ---------
tic_t I_GetTime(void) DWORD TimeFunction(int requested_frequency)
{ {
tic_t newtics = 0; DWORD newtics = 0;
// 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 if (!starttickcount) // high precision timer
{ {
@ -2082,7 +2084,7 @@ tic_t I_GetTime(void)
if (frequency.LowPart && QueryPerformanceCounter(&currtime)) if (frequency.LowPart && QueryPerformanceCounter(&currtime))
{ {
newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * NEWTICRATE newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * requested_frequency
/ frequency.QuadPart); / frequency.QuadPart);
} }
else if (pfntimeGetTime) else if (pfntimeGetTime)
@ -2090,11 +2092,19 @@ tic_t I_GetTime(void)
currtime.LowPart = pfntimeGetTime(); currtime.LowPart = pfntimeGetTime();
if (!basetime.LowPart) if (!basetime.LowPart)
basetime.LowPart = currtime.LowPart; basetime.LowPart = currtime.LowPart;
newtics = ((currtime.LowPart - basetime.LowPart)/(1000/NEWTICRATE)); if (requested_frequency > 1000)
newtics = currtime.LowPart - basetime.LowPart * excess_frequency;
else
newtics = (currtime.LowPart - basetime.LowPart)/(1000/requested_frequency);
} }
} }
else else
newtics = (GetTickCount() - starttickcount)/(1000/NEWTICRATE); {
if (requested_frequency > 1000)
newtics = (GetTickCount() - starttickcount) * excess_frequency;
else
newtics = (GetTickCount() - starttickcount)/(1000/requested_frequency);
}
return newtics; return newtics;
} }
@ -2116,7 +2126,9 @@ static void I_ShutdownTimer(void)
// I_GetTime // I_GetTime
// returns time in 1/TICRATE second tics // returns time in 1/TICRATE second tics
// //
tic_t I_GetTime (void)
// millisecond precision only
int TimeFunction(int requested_frequency)
{ {
static Uint64 basetime = 0; static Uint64 basetime = 0;
Uint64 ticks = SDL_GetTicks(); Uint64 ticks = SDL_GetTicks();
@ -2126,14 +2138,24 @@ tic_t I_GetTime (void)
ticks -= basetime; ticks -= basetime;
ticks = (ticks*TICRATE); ticks = (ticks*requested_frequency);
ticks = (ticks/1000); ticks = (ticks/1000);
return (tic_t)ticks; return ticks;
} }
#endif #endif
tic_t I_GetTime(void)
{
return TimeFunction(NEWTICRATE);
}
int I_GetTimeMicros(void)
{
return TimeFunction(1000000);
}
// //
//I_StartupTimer //I_StartupTimer
// //