diff --git a/ref/vk/profiler.h b/ref/vk/profiler.h index fc6e2df5..72d92081 100644 --- a/ref/vk/profiler.h +++ b/ref/vk/profiler.h @@ -4,16 +4,20 @@ #include #include +#include "crtlib.h" // Q_strlen + // Note: this module initializes itself on the first scope initialization. // I.e. it is invalid to call any of the functions before the first of aprof_scope_init/APROF_SCOPE_INIT/APROF_SCOPE_DECLARE_BEGIN is called. // TODO: explicit initialization function +#define APROF_FILENAME(filepath) aprof_get_filename_from_filepath( filepath, Q_strlen( filepath ) ) + #define APROF_SCOPE_DECLARE(scope) \ static aprof_scope_id_t _aprof_scope_id_##scope = -1 // scope_name is expected to be static and alive for the entire duration of the program #define APROF_SCOPE_INIT_EX(scope, scope_name, flags) \ - _aprof_scope_id_##scope = aprof_scope_init(scope_name, flags, __FILE__, __LINE__) + _aprof_scope_id_##scope = aprof_scope_init(scope_name, flags, APROF_FILENAME( __FILE__ ), __LINE__) #define APROF_SCOPE_INIT(scope, scope_name) APROF_SCOPE_INIT_EX(scope, scope_name, 0) @@ -23,7 +27,7 @@ #define APROF_SCOPE_DECLARE_BEGIN_EX(scope, scope_name, flags) \ static aprof_scope_id_t _aprof_scope_id_##scope = -1; \ if (_aprof_scope_id_##scope == -1) { \ - _aprof_scope_id_##scope = aprof_scope_init(scope_name, flags, __FILE__, __LINE__); \ + _aprof_scope_id_##scope = aprof_scope_init(scope_name, flags, APROF_FILENAME( __FILE__ ), __LINE__); \ } \ aprof_scope_event(_aprof_scope_id_##scope, 1) @@ -41,8 +45,14 @@ typedef int aprof_scope_id_t; +// Returns pointer to filename in filepath string. +// Ideally, this function should be static and visible only inside file scope, +// but then the `APROF_FILENAME` macro would not work. +// Also, maybe this function should be inside filesystem or something like that. +const char *aprof_get_filename_from_filepath( const char *filepath, size_t filepath_length ); + // scope_name should be static const, and not on stack -aprof_scope_id_t aprof_scope_init(const char *scope_name, uint32_t flags, const char *source_file, int source_line); +aprof_scope_id_t aprof_scope_init(const char *scope_name, uint32_t flags, const char *source_filename, int source_line); void aprof_scope_event(aprof_scope_id_t, int begin); // Returns event index for previous frame uint32_t aprof_scope_frame( void ); @@ -67,7 +77,7 @@ enum { typedef struct { const char *name; uint32_t flags; - const char *source_file; + const char *source_filename; int source_line; } aprof_scope_t; @@ -147,7 +157,28 @@ uint64_t aprof_time_platform_to_ns( uint64_t platform_time ) { aprof_state_t g_aprof = {0}; -aprof_scope_id_t aprof_scope_init(const char *scope_name, uint32_t flags, const char *source_file, int source_line) { +// Returns pointer to filename in filepath string. +// Examples: +// on Windows: C:/Users/User/xash3d-fwgs/ref/vk/vk_rtx.c -> vk_rtx.c +// on Linux: /home/user/xash3d-fwgs/ref/vk/vk_rtx.c -> vk.rtx.c (imaginary example, not tested) +const char *aprof_get_filename_from_filepath( const char *filepath, size_t filepath_length ) { + if ( !filepath_length ) + filepath_length = Q_strlen( filepath ); + + int cursor = filepath_length - 1; + while ( cursor > 0 ) { + char c = filepath[cursor]; + if ( c == '/' || c == '\\' ) { + // Advance by 1 char to skip the folder delimiter symbol itself. + return &filepath[cursor + 1]; + } + cursor -= 1; + } + + return NULL; +} + +aprof_scope_id_t aprof_scope_init(const char *scope_name, uint32_t flags, const char *source_filename, int source_line) { #if defined(_WIN32) if (_aprof_frequency.QuadPart == 0) QueryPerformanceFrequency(&_aprof_frequency); @@ -161,7 +192,7 @@ aprof_scope_id_t aprof_scope_init(const char *scope_name, uint32_t flags, const g_aprof.scopes[g_aprof.num_scopes].name = scope_name; g_aprof.scopes[g_aprof.num_scopes].flags = flags; - g_aprof.scopes[g_aprof.num_scopes].source_file = source_file; + g_aprof.scopes[g_aprof.num_scopes].source_filename = source_filename; g_aprof.scopes[g_aprof.num_scopes].source_line = source_line; return g_aprof.num_scopes++; } diff --git a/ref/vk/r_speeds.c b/ref/vk/r_speeds.c index fc83d366..50f5b249 100644 --- a/ref/vk/r_speeds.c +++ b/ref/vk/r_speeds.c @@ -215,7 +215,15 @@ static void drawCPUProfilerScopes(int draw, const aprof_event_t *events, uint64_ const uint64_t delta_ns = timestamp_ns - stack[depth].begin_ns; if (!g_speeds.frame.scopes[scope_id].initialized) { - R_SpeedsRegisterMetric(&g_speeds.frame.scopes[scope_id].time_us, "scope", scope->name, kSpeedsMetricMicroseconds, /*reset*/ true, scope->name, scope->source_file, scope->source_line); + R_SpeedsRegisterMetric( + /* p_value */ &g_speeds.frame.scopes[scope_id].time_us, + /* module */ "scope", + /* name */ scope->name, + /* type */ kSpeedsMetricMicroseconds, + /* reset */ true, + /* var_name */ scope->name, + /* file */ scope->source_filename, + /* line */ scope->source_line); g_speeds.frame.scopes[scope_id].initialized = 1; } @@ -429,7 +437,16 @@ static void drawGPUProfilerScopes(qboolean draw, int y, uint64_t frame_begin_tim const char *name = gpurofl->scopes[scope_index].name; if (!g_speeds.frame.gpu_scopes[scope_index].initialized) { - R_SpeedsRegisterMetric(&g_speeds.frame.gpu_scopes[scope_index].time_us, "gpuscope", name, kSpeedsMetricMicroseconds, /*reset*/ true, name, __FILE__, __LINE__); + R_SpeedsRegisterMetric( + /* p_value */ &g_speeds.frame.gpu_scopes[scope_index].time_us, + /* module */ "gpuscope", + /* name */ name, + /* type */ kSpeedsMetricMicroseconds, + /* reset */ true, + /* var_name */ name, + /* file */ APROF_FILENAME( __FILE__ ), + /* line */ __LINE__); + g_speeds.frame.gpu_scopes[scope_index].initialized = 1; } diff --git a/ref/vk/r_speeds.h b/ref/vk/r_speeds.h index 4c6c671a..0844a9e0 100644 --- a/ref/vk/r_speeds.h +++ b/ref/vk/r_speeds.h @@ -1,5 +1,6 @@ #pragma once #include "xash3d_types.h" +#include "profiler.h" // APROF_FILENAME #include void R_SpeedsInit( void ); @@ -22,9 +23,9 @@ void R_SpeedsRegisterMetric(int* p_value, const char *module, const char *name, // A counter is a value accumulated during a single frame, and reset to zero between frames. // Examples: drawn models count, scope times, etc. #define R_SPEEDS_COUNTER(var, name, type) \ - R_SpeedsRegisterMetric(&(var), MODULE_NAME, name, type, /*reset*/ true, #var, __FILE__, __LINE__) + R_SpeedsRegisterMetric(&(var), MODULE_NAME, name, type, /*reset*/ true, #var, APROF_FILENAME( __FILE__ ), __LINE__) // A metric is computed and preserved across frame boundaries. // Examples: total allocated memory, cache sizes, etc. #define R_SPEEDS_METRIC(var, name, type) \ - R_SpeedsRegisterMetric(&(var), MODULE_NAME, name, type, /*reset*/ false, #var, __FILE__, __LINE__) + R_SpeedsRegisterMetric(&(var), MODULE_NAME, name, type, /*reset*/ false, #var, APROF_FILENAME( __FILE__ ), __LINE__)