Descent3/rtperformance/rtperformance.h
Azamat H. Hackimov 7ba009b811 Isolate rtperformance module
Update rtperformance module, minor cleanups.
2024-07-28 16:50:42 +03:00

339 lines
16 KiB
C++

/*
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef RUN_TIME_PROFILING_
#define RUN_TIME_PROFILING_
#include <cstdint>
// uncomment the following if you want to enable Run-time Profiling
#ifndef RELEASE
#define USE_RTP
#endif
#if defined(POSIX)
// #if defined(POSIX)
#ifdef USE_RTP
#undef USE_RTP // no rtp for now
#endif
#endif
// use INT64 for 64bit integers
#ifdef USE_RTP
#if defined(POSIX)
#define INT64 int64_t
#else
#define INT64 signed __int64
#endif
#else
#define INT64 uint8_t
#endif
// struct of information to be saved per frame (note: use INT64 for timer info)
// -----------------------------------------------------------------------------------
struct tRTFrameInfo {
INT64 frame_num; // the frame number, used internally
INT64 renderframe_time;
INT64 multiframe_time;
INT64 musicframe_time;
INT64 ambsound_frame_time;
INT64 weatherframe_time;
INT64 playerframe_time;
INT64 doorframe_time;
INT64 levelgoal_time;
INT64 matcenframe_time;
INT64 objframe_time;
INT64 aiframeall_time;
INT64 processkeys_time;
INT64 normalevent_time;
INT64 ct_flying_time;
INT64 ct_aidoframe_time;
INT64 ct_weaponframe_time;
INT64 ct_explosionframe_time;
INT64 ct_debrisframe_time;
INT64 ct_splinterframe_time;
INT64 mt_physicsframe_time;
INT64 mt_walkingframe_time;
INT64 mt_shockwave_time;
INT64 obj_doeffect_time;
INT64 obj_move_player_time;
INT64 obj_d3xint_time;
INT64 obj_objlight_time;
INT64 cycle_anim;
INT64 vis_eff_move;
INT64 phys_link;
INT64 obj_do_frm;
INT64 fvi_time;
int texture_uploads;
int polys_drawn;
int fvi_calls;
float frame_time; // how long the frame took. A float because it's already calc'd so we might as well save it
};
// Flags for Runtime Performance Counters (these are 64 bit)
// --------------------------------------------------------------------
#define RTI_FRAMETIME 0x00000001
#define RTI_RENDERFRAMETIME 0x00000002
#define RTI_MULTIFRAMETIME 0x00000004
#define RTI_MUSICFRAMETIME 0x00000008
#define RTI_AMBSOUNDFRAMETIME 0x00000010
#define RTI_WEATHERFRAMETIME 0x00000020
#define RTI_PLAYERFRAMETIME 0x00000040
#define RTI_DOORFRAMETIME 0x00000080
#define RTI_LEVELGOALTIME 0x00000100
#define RTI_MATCENFRAMETIME 0x00000200
#define RTI_OBJFRAMETIME 0x00000400
#define RTI_AIFRAMETIME 0x00000800
#define RTI_PROCESSKEYTIME 0x00001000
#define RTI_TEXTUREUPLOADS 0x00002000
#define RTI_POLYSDRAWN 0x00004000
// Macros to be used internally and externally
// --------------------------------------------------
#ifndef USE_RTP
#define RTP_CLOCKTOSECONDS(c1, c2, t)
#define RTP_CLOCKSECONDS(c, t)
#define RTP_RECORDVALUE(member, value)
#define RTP_INCRVALUE(member, amount)
#define RTP_DECRVALUE(member, amount)
#define RTP_GETVALUE(member, value)
#define RTP_STARTTIME(member)
#define RTP_tSTARTTIME(member, time)
#define RTP_ENDTIME(member)
#define RTP_tENDTIME(member, time)
#define RTP_GETCLOCK(time)
#define RTP_STARTINCTIME(member)
#define RTP_ENDINCTIME(member)
#define RTP_ENABLEFLAGS(flags)
#define RTP_DISABLEFLAGS(flags)
#else
#define RTP_ENABLEFLAGS(flags) rtp_EnableFlags(flags)
#define RTP_DISABLEFLAGS(flags) rtp_EnableFlags(flags)
// given 2 clocks (INT64's) it will return the time in seconds between them (double)
// (internal use)
// c1 = start time
// c2 = end time
// t = time in seconds
#define RTP_CLOCKTOSECONDS(c1, c2, t) \
do { \
if (Runtime_performance_enabled) { \
INT64 diff = (c2) - (c1); \
t = ((double)diff) / ((double)Runtime_performance_clockfreq); \
} \
} while (0)
// given a clock time, it will convert it to seconds
#define RTP_CLOCKSECONDS(c, t) \
do { \
if (Runtime_performance_enabled) { \
t = ((double)c) / ((double)Runtime_performance_clockfreq); \
} \
} while (0)
// sets a value of a member of the current tRTFrameInfo frame
// (external use)
// member = the member of the tRTFrameInfo to set
// value = the value to set it to
#define RTP_RECORDVALUE(member, value) \
do { \
if (Runtime_performance_enabled) { \
RTP_SingleFrame.member = (value); \
} \
} while (0)
// increments a value of a member of the current tRTFrameInfo frame
// (external use)
// member = the member of the tRTFrameInfo to increment
// amount = how much to increment it
#define RTP_INCRVALUE(member, amount) \
do { \
if (Runtime_performance_enabled) { \
RTP_SingleFrame.member += (amount); \
} \
} while (0)
// decrements a value of a member of the current tRTFrameInfo frame
// (external use)
// member = the member of the tRTFrameInfo to decrement
// amount = how much to decrement it
#define RTP_DECRVALUE(member, amount) \
do { \
if (Runtime_performance_enabled) { \
RTP_SingleFrame.member -= (amount); \
} \
} while (0)
// returns the value of a member of the current tRTFrameInfo frame
// (external use)
// member = the member to retrieve
// value = where to store the value
#define RTP_GETVALUE(member, value) \
do { \
if (Runtime_performance_enabled) { \
value = RTP_SingleFrame.member; \
} \
} while (0)
// starts a frame time calculation for a time member of the tRTFrameInfo frame
// this version calls the clock to get the current time
// member = member to start recording time on
#define RTP_STARTTIME(member) \
do { \
if (Runtime_performance_enabled) { \
RTP_SingleFrame.member = rtp_GetClock(); \
} \
} while (0)
// starts a frame time calculation given a time to start it with (similar to the above
// except you give it the starting time). This should be used (along with
// RTP_tENDTIME(member,time)) in places where you do a bunch of frame times in a row
// to reduce the number of calls to rtp_GetClock(), however, this way will give
// a few cycles off, compared to the RTP_STARTTIME(member)/RTP_ENDTIME(member) way
// member = member to start recording time on
#define RTP_tSTARTTIME(member, time) \
do { \
if (Runtime_performance_enabled) { \
RTP_SingleFrame.member = time; \
} \
} while (0)
// ends a frame time calculation for a member of tRTFrameInfo frame
// member = member to stop recording time for
#define RTP_ENDTIME(member) \
do { \
if (Runtime_performance_enabled) { \
RTP_SingleFrame.member = rtp_GetClock() - RTP_SingleFrame.member; \
} \
} while (0)
// same as above, but will return the time that it stopped the recording time
#define RTP_tENDTIME(member, time) \
do { \
if (Runtime_performance_enabled) { \
time = rtp_GetClock(); \
RTP_SingleFrame.member = time - RTP_SingleFrame.member; \
} \
} while (0)
// returns the current clock time
#define RTP_GETCLOCK(time) \
do { \
if (Runtime_performance_enabled) { \
time = rtp_GetClock(); \
} \
} while (0)
// Starts a frame time calculation, but when ending the frame, it will increment the time by
// the difference instead of just setting it
// RTP_STARTINCTIME and RTP_ENDINCTIME must be in the same scope
#define RTP_STARTINCTIME(member) \
INT64 __start_time_; \
do { \
if (Runtime_performance_enabled) { \
__start_time_ = rtp_GetClock(); \
} \
} while (0)
// Ends a frame time calculation and increments the member by the time for that frame
#define RTP_ENDINCTIME(member) \
do { \
if (Runtime_performance_enabled) { \
RTP_SingleFrame.member += (rtp_GetClock() - __start_time_); \
} \
} while (0)
#endif
// Internal Global Vars
// ------------------------------
extern tRTFrameInfo RTP_SingleFrame;
extern INT64 Runtime_performance_clockfreq;
extern uint8_t Runtime_performance_enabled;
/*
void rtp_Init
This function initilizes the runtime performance system so it's ready to be used
*/
void rtp_Init();
/*
void rtp_EnableFlags
This function enables the performance profiling of whatever flags you pass in
*/
void rtp_EnableFlags(INT64 flags);
/*
void rtp_DisableFlags
This function disables the performance profiling of whatever flags you pass in
*/
void rtp_DisableFlags(INT64 flags);
/*
void rtp_StartLog
Calling this function will reset the log and start a new log, recording immediatly
*/
void rtp_StartLog();
/*
void rtp_StopLog
Calling this function will stop the currently processing log and write it out to
file.
*/
void rtp_StopLog();
/*
void rtp_PauseLog
Calling this function will pause the log recording until rtp_ResumeLog is called
*/
void rtp_PauseLog();
/*
void rtp_ResumeLog
Calling this will resume a paused log, starting at where it left off
*/
void rtp_ResumeLog();
/*
void rtp_RecordFrame
Calling this will record the data of the frame into the internal log, and prepare for
the next frame
*/
void rtp_RecordFrame();
/*
INT64 rtp_GetClock
Returns the current hi-resolution clock value...no checking for overflow
*/
INT64 rtp_GetClock();
/*
void rtp_WriteBufferLog
Writes the buffer of frames to file...
*/
void rtp_WriteBufferLog();
#endif