Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7dc2952b8d |
|
@ -3,6 +3,7 @@
|
|||
#include "../include/gl.h"
|
||||
#include "../include/glext.h"
|
||||
#include "private.h"
|
||||
#include "profile.h"
|
||||
|
||||
typedef struct {
|
||||
const void* ptr;
|
||||
|
@ -192,6 +193,8 @@ inline void transformNormalToEyeSpace(GLfloat* normal) {
|
|||
|
||||
|
||||
static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum type, const GLvoid* indices) {
|
||||
TRACE_START();
|
||||
|
||||
static GLfloat normal[3] = {0.0f, 0.0f, -1.0f};
|
||||
static GLfloat eye_P[3];
|
||||
static GLfloat eye_N[3];
|
||||
|
|
68
GL/profile.c
Normal file
68
GL/profile.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
#include "profile.h"
|
||||
|
||||
Profiler __profiler;
|
||||
|
||||
void profiler_init() {
|
||||
__profiler.trace_count = 0;
|
||||
}
|
||||
|
||||
static uint32_t time_now_in_ms() {
|
||||
return timer_us_gettime64() / 1000;
|
||||
}
|
||||
|
||||
static int compare(const void* trace1, const void* trace2) {
|
||||
Trace* t1 = (Trace*) trace1;
|
||||
Trace* t2 = (Trace*) trace2;
|
||||
return (t1->total_time < t2->total_time) ? -1 : (t2->total_time < t1->total_time) ? 1 : 0;
|
||||
}
|
||||
|
||||
void profiler_dump(uint32_t ms) {
|
||||
static uint32_t time_since_last = time_now_in_ms();
|
||||
|
||||
uint32_t now = time_now_in_ms();
|
||||
|
||||
if((now - time_since_last) >= ms) {
|
||||
qsort(__profiler.traces, __profiler.trace_count, sizeof(Trace), compare);
|
||||
|
||||
fprintf(stderr, "Function\t\t\t\tTotal Time\t\t\t\tBreakdown\n");
|
||||
for(uint8_t i = 0; i < __profiler.trace_count; ++i) {
|
||||
Trace* trace = __profiler.traces + i;
|
||||
fprintf(stderr, "%s\t\t\t\t%dms\n", trace->name, trace->total_time);
|
||||
|
||||
for(uint8_t j = 0; j < trace->max_checkpoints; ++j) {
|
||||
fprintf(stderr, "\t\t\t\t\t\t\t\t%d: %dms\n", trace->checkpoints[j].total_time);
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n\n");
|
||||
}
|
||||
|
||||
time_since_last -= ms;
|
||||
}
|
||||
}
|
||||
|
||||
void profiler_register_trace(Trace* trace, const char* func_name) {
|
||||
__profiler.traces[__profiler.trace_count++] = trace;
|
||||
|
||||
trace->calls = 0;
|
||||
trace->max_checkpoints = 0;
|
||||
trace->total_time = 0;
|
||||
trace->start = 0;
|
||||
|
||||
strncpy(trace->name, func_name, 128);
|
||||
}
|
||||
|
||||
void profiler_trace_start(Trace* trace) {
|
||||
trace->start = time_now_in_ms();
|
||||
trace->calls++;
|
||||
}
|
||||
|
||||
void profiler_trace_checkpoint(Trace* trace, int counter) {
|
||||
uint32_t now = time_now_in_ms();
|
||||
uint32_t checkpoint_time = (now - trace->start);
|
||||
|
||||
trace->total_time += checkpoint_time;
|
||||
trace->start = now;
|
||||
|
||||
trace->checkpoints[counter].total_time + checkpoint_time;
|
||||
trace->checkpoints[counter].calls++;
|
||||
}
|
74
GL/profile.h
Normal file
74
GL/profile.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
#ifndef PROFILE_H
|
||||
#define PROFILE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../containers/aligned_vector.h"
|
||||
|
||||
/* USAGE:
|
||||
*
|
||||
* profiler_init();
|
||||
*
|
||||
* void my_func() {
|
||||
* TRACE_START();
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* TRACE_CHECKPOINT();
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* TRACE_CHECKPOINT();
|
||||
* }
|
||||
*
|
||||
* profiler_dump(1000);
|
||||
*
|
||||
*
|
||||
* Output:
|
||||
*
|
||||
* Name Total Time Breakdown
|
||||
* -------------------------------------------------
|
||||
my_func 15.33
|
||||
0: 4.23
|
||||
1: 11.10
|
||||
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint32_t total_time;
|
||||
uint32_t calls;
|
||||
} Checkpoint;
|
||||
|
||||
typedef struct {
|
||||
char name[128];
|
||||
uint32_t calls;
|
||||
uint32_t start;
|
||||
uint32_t total_time;
|
||||
Checkpoint checkpoints[16];
|
||||
uint8_t max_checkpoints;
|
||||
} Trace;
|
||||
|
||||
struct Profiler {
|
||||
Trace traces[256];
|
||||
uint8_t trace_count;
|
||||
};
|
||||
|
||||
extern Profiler __profiler;
|
||||
|
||||
void profiler_init();
|
||||
void profiler_dump(uint32_t ms);
|
||||
void profiler_register_trace(Trace* trace, const char* func_name);
|
||||
void profiler_trace_start(Trace* trace);
|
||||
void profiler_trace_checkpoint(Trace* trace, int counter);
|
||||
|
||||
#define TRACE_START() \
|
||||
int __sc = 0; \
|
||||
static char __trace_registered = 0;
|
||||
static Trace __trace; \
|
||||
if(!_trace_registered) {profiler_register_trace(&__trace, __func__); __trace_registered = 1;} \
|
||||
profiler_trace_start(&__trace);
|
||||
|
||||
#define TRACE_CHECKPOINT() \
|
||||
profiler_trace_checkpoint(&__trace, __sc++);
|
||||
|
||||
|
||||
#endif // PROFILE_H
|
Loading…
Reference in New Issue
Block a user