141 lines
4.6 KiB
C++
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
|