This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

141 lines
4.6 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Real-Time Hierarchical Telemetry Profiling
//
// $NoKeywords: $
//=============================================================================//
#ifndef VPROF_TELEMETRY_H
#define VPROF_TELEMETRY_H
#if !defined(MAKE_VPC)
#if !defined(RAD_TELEMETRY_DISABLED) && \
(defined(IS_WINDOWS_PC) || defined(_LINUX))
// Rad Telemetry profiling is enabled on Win32 and Win64.
#define RAD_TELEMETRY_ENABLED
#endif
#endif // !MAKE_VPC
#if !defined(RAD_TELEMETRY_ENABLED)
//
// Kill all tmZone() macros, etc.
//
#include "tmapi_dummy.h"
inline void TelemetryTick() {}
inline void TelemetrySetLevel(unsigned int Level) {}
#define TelemetrySetLockName(_ctx, _location, _description)
class CTelemetryLock {
public:
CTelemetryLock(void *plocation, const char *description) {}
~CTelemetryLock() {}
void Locked() {}
void Unlocked() {}
};
class CTelemetrySpikeDetector {
public:
CTelemetrySpikeDetector(const char *msg, uint32 threshold = 50) {}
~CTelemetrySpikeDetector() {}
};
#else
//
// Telemetry is enabled. Include the telemetry header.
//
#include "../../thirdparty/telemetry/include/telemetry.h"
// Different versions of radbase.h define RADCOPYRIGHT to different values. So
// undef that here.
#undef RADCOPYRIGHT
struct TelemetryData {
HTELEMETRY tmContext[32];
float flRDTSCToMilliSeconds; // Conversion from tmFastTime() (rdtsc) to
// milliseconds.
uint32 FrameCount; // Count of frames to capture before turning off.
char ServerAddress[128]; // Server name to connect to.
int playbacktick; // GetPlaybackTick() value from demo file (or 0 if not
// playing a demo).
uint32 DemoTickStart; // Start telemetry on demo tick #
uint32 DemoTickEnd; // End telemetry on demo tick #
uint32 Level; // Current Telemetry level (Use TelemetrySetLevel to modify)
};
PLATFORM_INTERFACE TelemetryData g_Telemetry;
PLATFORM_INTERFACE void TelemetryTick();
PLATFORM_INTERFACE void TelemetrySetLevel(unsigned int Level);
#define TELEMETRY_LEVEL0 g_Telemetry.tmContext[0] // high level tmZone()
#define TELEMETRY_LEVEL1 \
g_Telemetry.tmContext[1] // lower level tmZone(), tmZoneFiltered()
#define TELEMETRY_LEVEL2 g_Telemetry.tmContext[2] // VPROF_0
#define TELEMETRY_LEVEL3 g_Telemetry.tmContext[3] // VPROF_1
#define TELEMETRY_LEVEL4 g_Telemetry.tmContext[4] // VPROF_2
#define TELEMETRY_LEVEL5 g_Telemetry.tmContext[5] // VPROF_3
#define TELEMETRY_LEVEL6 g_Telemetry.tmContext[6] // VPROF_4
#define TelemetrySetLockName(_ctx, _location, _description) \
do { \
static bool s_bNameSet = false; \
if (_ctx && !s_bNameSet) { \
tmLockName(_ctx, _location, _description); \
s_bNameSet = true; \
} \
} while (0)
class CTelemetryLock {
public:
CTelemetryLock(void *plocation, const char *description) {
m_plocation = (const char *)plocation;
m_description = description;
TelemetrySetLockName(TELEMETRY_LEVEL1, m_plocation, m_description);
tmTryLock(TELEMETRY_LEVEL1, m_plocation, "%s", m_description);
}
~CTelemetryLock() { Unlocked(); }
void Locked() {
tmEndTryLock(TELEMETRY_LEVEL1, m_plocation, TMLR_SUCCESS);
tmSetLockState(TELEMETRY_LEVEL1, m_plocation, TMLS_LOCKED, "%s Locked",
m_description);
}
void Unlocked() {
if (m_plocation) {
tmSetLockState(TELEMETRY_LEVEL1, m_plocation, TMLS_RELEASED,
"%s Released", m_description);
m_plocation = NULL;
}
}
public:
const char *m_plocation;
const char *m_description;
};
class CTelemetrySpikeDetector {
public:
// Spews Telemetry message when threshold hit (in milliseconds.)
CTelemetrySpikeDetector(const char *msg, float threshold = 5)
: m_message(msg), m_threshold(threshold), time0(tmFastTime()) {}
~CTelemetrySpikeDetector() {
float time = (tmFastTime() - time0) * g_Telemetry.flRDTSCToMilliSeconds;
if (time >= m_threshold) {
tmMessage(TELEMETRY_LEVEL0, TMMF_ICON_NOTE | TMMF_SEVERITY_WARNING,
"(source/spike)%s %.2fms %t", m_message, time,
tmSendCallStack(TELEMETRY_LEVEL0, 0));
}
}
private:
TmU64 time0;
float m_threshold;
const char *m_message;
};
#endif // RAD_TELEMETRY_ENABLED
#endif // VPROF_TELEMETRY_H