extend profiler

This commit is contained in:
John Alanbrook 2024-09-25 12:46:59 -05:00
parent ad1bcd45c7
commit dad588639e
6 changed files with 157 additions and 27 deletions

View file

@ -41,6 +41,24 @@ globalThis.class_use = function(script, config, base, callback)
return padawan; return padawan;
} }
globalThis.rmactor = function(e)
{
if (!actor_spawns[e._file]) return;
actor_spawns[e._file].remove(e);
}
actor.__stats = function()
{
var total = 0;
var stats = {};
for (var i in actor_spawns) {
stats[i] = actor_spawns[i].length;
total += stats[i];
}
stats.total = total;
return stats;
}
actor.hotreload = function() actor.hotreload = function()
{ {
profile.cache("hotreload", "check"); profile.cache("hotreload", "check");

View file

@ -1,4 +1,3 @@
globalThis.entityreport = {}; globalThis.entityreport = {};
var timer_update = function(dt) var timer_update = function(dt)
@ -383,6 +382,8 @@ dup(diff) {
if (typeof this.then === 'function') this.then(); if (typeof this.then === 'function') this.then();
game.tag_clear_guid(this.guid); game.tag_clear_guid(this.guid);
rmactor(this);
for (var i in this) { for (var i in this) {
if (this[i] instanceof Object || this[i] instanceof Function) delete this[i]; if (this[i] instanceof Object || this[i] instanceof Function) delete this[i];

View file

@ -349,24 +349,31 @@ profile.data.gpu = {};
profile.data.physics = {}; profile.data.physics = {};
profile.data.script = {}; profile.data.script = {};
profile.data.memory = {}; profile.data.memory = {};
var frame = 0; profile.data.gfx = {};
profile.data.actors = {};
profile.curframe = 0;
function prof_add_stats(obj, stat)
{
for (var i in stat) {
obj[i] ??= [];
if (obj[i].last() !== stat[i])
obj[i][profile.curframe] = stat[i];
}
}
profile.pushdata = function(arr, val) profile.pushdata = function(arr, val)
{ {
if (arr.last() !== val) if (arr.last() !== val)
arr[frame] = val; arr[profile.curframe] = val;
} }
profile.capture_data = function() profile.capture_data = function()
{ {
var mem = os.mem(); prof_add_stats(profile.data.memory, os.mem());
var memo = profile.data.memory; prof_add_stats(profile.data.gfx, imgui.framestats());
for (var i in mem) { prof_add_stats(profile.data.actors, actor.__stats());
memo[i] ??= []; profile.curframe++;
if (memo[i].last() !== mem[i])
memo[i][frame] = mem[i];
}
frame++;
} }
profile.best_mem = function(bytes) profile.best_mem = function(bytes)
@ -385,7 +392,7 @@ profile.print_gc = function()
var gc = os.check_gc(); var gc = os.check_gc();
if (!gc) return; if (!gc) return;
profile.data.gc ??= []; profile.data.gc ??= [];
profile.data.gc[frame] = gc; profile.data.gc[profile.curframe] = gc;
} }
return {profile}; return {profile};

View file

@ -22,6 +22,33 @@ static sgimgui_t sgimgui;
static int wantkeys = 0; static int wantkeys = 0;
static int wantmouse = 0; static int wantmouse = 0;
int num_to_yaxis(int y)
{
switch(y) {
case 0:
return ImAxis_Y1;
case 1:
return ImAxis_Y2;
case 2:
return ImAxis_Y3;
}
return ImAxis_Y1;
}
int num_to_xaxis(int x)
{
switch(x) {
case 0:
return ImAxis_X1;
case 1:
return ImAxis_X2;
case 2:
return ImAxis_X3;
}
return ImAxis_X1;
}
JSC_SCALL(imgui_window, JSC_SCALL(imgui_window,
bool active = true; bool active = true;
ImGui::Begin(str, &active); ImGui::Begin(str, &active);
@ -71,7 +98,7 @@ JSC_SCALL(imgui_plot,
) )
#define PLOT_FN(NAME, FN, ADD, SHADED) JSC_SCALL(imgui_##NAME, \ #define PLOT_FN(NAME, FN, ADD, SHADED) JSC_SCALL(imgui_##NAME, \
fill_plotdata(argv[1]); \ fill_plotdata(argv[1], argv[3]); \
bool shaded = js2boolean(argv[2]);\ bool shaded = js2boolean(argv[2]);\
int flag = 0; \ int flag = 0; \
if (shaded) flag = SHADED; \ if (shaded) flag = SHADED; \
@ -80,7 +107,7 @@ JSC_SCALL(imgui_plot,
static HMM_Vec2 *plotdata = NULL; static HMM_Vec2 *plotdata = NULL;
void fill_plotdata(JSValue v) void fill_plotdata(JSValue v, JSValue last)
{ {
arrsetlen(plotdata, 0); arrsetlen(plotdata, 0);
@ -96,6 +123,12 @@ void fill_plotdata(JSValue v)
arrput(plotdata, c); arrput(plotdata, c);
} }
} }
if (!JS_IsUndefined(last)) {
int frame = js2number(last);
HMM_Vec2 c = (HMM_Vec2){frame, arrlast(plotdata).y};
arrput(plotdata, c);
}
} }
PLOT_FN(lineplot, PlotLine,,ImPlotLineFlags_Shaded) PLOT_FN(lineplot, PlotLine,,ImPlotLineFlags_Shaded)
@ -117,7 +150,7 @@ JSC_SCALL(imgui_shadedplot,
) )
JSC_SCALL(imgui_barplot, JSC_SCALL(imgui_barplot,
fill_plotdata(argv[1]); fill_plotdata(argv[1], JS_UNDEFINED);
ImPlot::PlotBars(str, &plotdata[0].x, &plotdata[0].y, js_arrlen(argv[1]), js2number(argv[2]), 0, 0, sizeof(HMM_Vec2)); ImPlot::PlotBars(str, &plotdata[0].x, &plotdata[0].y, js_arrlen(argv[1]), js2number(argv[2]), 0, 0, sizeof(HMM_Vec2));
) )
@ -739,21 +772,58 @@ JSC_CCALL(imgui_plotlimits,
static JSValue axis_formatter = JS_UNDEFINED; static JSValue axis_formatter = JS_UNDEFINED;
void jsformatter(double value, char *buff, int size, void *usr_data) static JSValue axis_fmts[10];
void jsformatter(double value, char *buff, int size, JSValue *fmt)
{ {
JSValue v = number2js(value); JSValue v = number2js(value);
char *str = js2str(script_call_sym_ret(axis_formatter, 1, &v)); char *str = js2str(script_call_sym_ret(*fmt, 1, &v));
strncpy(buff,str, size); strncpy(buff,str, size);
JS_FreeCString(js, str); JS_FreeCString(js, str);
} }
JSC_CCALL(imgui_axisfmt, JSC_CCALL(imgui_axisfmt,
if (!JS_IsUndefined(axis_formatter)) { int y = num_to_yaxis(js2number(argv[0]));
JS_FreeValue(js, axis_formatter);
axis_formatter = JS_UNDEFINED; if (!JS_IsUndefined(axis_fmts[y])) {
JS_FreeValue(js, axis_fmts[y]);
axis_fmts[y] = JS_UNDEFINED;
} }
axis_formatter = JS_DupValue(js,argv[1]);
ImPlot::SetupAxisFormat(js2boolean(argv[0]) ? ImAxis_Y1 : ImAxis_X1, jsformatter); axis_fmts[y] = JS_DupValue(js,argv[1]);
ImPlot::SetupAxisFormat(y, jsformatter, axis_fmts+y);
)
#define FSTAT(KEY) js_setpropstr(v, #KEY, number2js(stats.KEY));
JSC_CCALL(imgui_framestats,
JSValue v = JS_NewObject(js);
sg_frame_stats stats = sg_query_frame_stats();
FSTAT(num_passes)
FSTAT(num_apply_viewport)
FSTAT(num_apply_scissor_rect)
FSTAT(num_apply_pipeline)
FSTAT(num_apply_bindings)
FSTAT(num_apply_uniforms)
FSTAT(num_draw)
FSTAT(num_update_buffer)
FSTAT(num_append_buffer)
FSTAT(num_update_image)
FSTAT(size_apply_uniforms)
FSTAT(size_update_buffer)
FSTAT(size_append_buffer)
FSTAT(size_update_image)
return v;
)
JSC_CCALL(imgui_setaxes,
int x = num_to_xaxis(js2number(argv[0]));
int y = num_to_yaxis(js2number(argv[1]));
ImPlot::SetAxes(x,y);
)
JSC_CCALL(imgui_setupaxis,
ImPlot::SetupAxis(num_to_yaxis(js2number(argv[0])));
) )
static const JSCFunctionListEntry js_imgui_funcs[] = { static const JSCFunctionListEntry js_imgui_funcs[] = {
@ -761,6 +831,9 @@ static const JSCFunctionListEntry js_imgui_funcs[] = {
MIST_FUNC_DEF(imgui, plot2pixels, 1), MIST_FUNC_DEF(imgui, plot2pixels, 1),
MIST_FUNC_DEF(imgui, plotpos, 0), MIST_FUNC_DEF(imgui, plotpos, 0),
MIST_FUNC_DEF(imgui, plotlimits, 0), MIST_FUNC_DEF(imgui, plotlimits, 0),
MIST_FUNC_DEF(imgui, setaxes, 2),
MIST_FUNC_DEF(imgui, setupaxis, 1),
MIST_FUNC_DEF(imgui, framestats, 0),
MIST_FUNC_DEF(imgui, inplot, 1), MIST_FUNC_DEF(imgui, inplot, 1),
MIST_FUNC_DEF(imgui, window, 2), MIST_FUNC_DEF(imgui, window, 2),
MIST_FUNC_DEF(imgui, menu, 2), MIST_FUNC_DEF(imgui, menu, 2),
@ -782,11 +855,11 @@ static const JSCFunctionListEntry js_imgui_funcs[] = {
MIST_FUNC_DEF(imgui, checkbox, 2), MIST_FUNC_DEF(imgui, checkbox, 2),
MIST_FUNC_DEF(imgui, text, 1), MIST_FUNC_DEF(imgui, text, 1),
MIST_FUNC_DEF(imgui, plot, 1), MIST_FUNC_DEF(imgui, plot, 1),
MIST_FUNC_DEF(imgui, lineplot, 3), MIST_FUNC_DEF(imgui, lineplot, 4),
MIST_FUNC_DEF(imgui, scatterplot, 3), MIST_FUNC_DEF(imgui, scatterplot, 4),
MIST_FUNC_DEF(imgui, stairplot, 3), MIST_FUNC_DEF(imgui, stairplot, 4),
MIST_FUNC_DEF(imgui, digitalplot, 3), MIST_FUNC_DEF(imgui, digitalplot, 4),
MIST_FUNC_DEF(imgui, shadedplot, 3), MIST_FUNC_DEF(imgui, shadedplot, 4),
MIST_FUNC_DEF(imgui, barplot, 3), MIST_FUNC_DEF(imgui, barplot, 3),
MIST_FUNC_DEF(imgui, pieplot, 5), MIST_FUNC_DEF(imgui, pieplot, 5),
MIST_FUNC_DEF(imgui, textplot, 2), MIST_FUNC_DEF(imgui, textplot, 2),
@ -857,12 +930,17 @@ JSValue gui_init(JSContext *js)
sgimgui_desc_t desc = {0}; sgimgui_desc_t desc = {0};
sgimgui_init(&sgimgui, &desc); sgimgui_init(&sgimgui, &desc);
sgimgui.frame_stats_window.disable_sokol_imgui_stats = true;
ImPlot::CreateContext(); ImPlot::CreateContext();
ImNodes::CreateContext(); ImNodes::CreateContext();
JSValue imgui = JS_NewObject(js); JSValue imgui = JS_NewObject(js);
JS_SetPropertyFunctionList(js, imgui, js_imgui_funcs, countof(js_imgui_funcs)); JS_SetPropertyFunctionList(js, imgui, js_imgui_funcs, countof(js_imgui_funcs));
started = 1; started = 1;
sg_enable_frame_stats();
return imgui; return imgui;
} }

View file

@ -43,6 +43,28 @@ sg_pass_action off_action = {0};
sg_image screencolor = {0}; sg_image screencolor = {0};
sg_image screendepth = {0}; sg_image screendepth = {0};
struct rfd {
int num_passes;
int num_apply_viewport;
int num_apply_scissor_rect;
int num_apply_pipeline;
int num_apply_uniforms;
int size_uniforms;
};
static struct rfd rfd = {0};
void trace_apply_uniforms(sg_shader_stage stage, int ub_index, const sg_range *data, void *user_data)
{
rfd.num_apply_uniforms++;
rfd.size_uniforms += data->size;
}
void trace_draw(int base_e, int num_e, int num_inst, void *data)
{
}
void trace_apply_pipeline(sg_pipeline pip, void *data) void trace_apply_pipeline(sg_pipeline pip, void *data)
{ {
// YughSpam("Applying pipeline %u %s.", pip, sg_query_pipeline_desc(pip).label); // YughSpam("Applying pipeline %u %s.", pip, sg_query_pipeline_desc(pip).label);

View file

@ -3508,6 +3508,9 @@ typedef struct sg_frame_stats {
uint32_t size_append_buffer; uint32_t size_append_buffer;
uint32_t size_update_image; uint32_t size_update_image;
uint32_t num_tris;
uint32_t num_verts;
sg_frame_stats_gl gl; sg_frame_stats_gl gl;
sg_frame_stats_d3d11 d3d11; sg_frame_stats_d3d11 d3d11;
sg_frame_stats_metal metal; sg_frame_stats_metal metal;
@ -18615,6 +18618,7 @@ SOKOL_API_IMPL void sg_draw(int base_element, int num_elements, int num_instance
SOKOL_ASSERT(num_elements >= 0); SOKOL_ASSERT(num_elements >= 0);
SOKOL_ASSERT(num_instances >= 0); SOKOL_ASSERT(num_instances >= 0);
_sg_stats_add(num_draw, 1); _sg_stats_add(num_draw, 1);
_sg_stats_add(num_verts, num_elements*num_instances);
if (!_sg.cur_pass.valid) { if (!_sg.cur_pass.valid) {
return; return;
} }