vk: profiler: metrics: print filenames instead of filepaths

Reduces enormous amount of space used by absolute filepaths in
metrics print.  This does not mean we cannot locate the files now.
Pretty much all of the vk files have such prefix in their name.
This commit is contained in:
nilsoncore 2023-09-17 17:06:49 +03:00
parent 6659c83c6d
commit b4aa0fcaf1
3 changed files with 59 additions and 10 deletions

View File

@ -4,16 +4,20 @@
#include <assert.h>
#include <string.h>
#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++;
}

View File

@ -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;
}

View File

@ -1,5 +1,6 @@
#pragma once
#include "xash3d_types.h"
#include "profiler.h" // APROF_FILENAME
#include <stdint.h>
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__)