From 9f68c9a8d889b9fa51a4cb1cca345831e95b4bf9 Mon Sep 17 00:00:00 2001 From: hgn Date: Wed, 25 Sep 2024 12:28:52 +0100 Subject: [PATCH] add basic memory viewer --- vg_engine.c | 13 +++- vg_mem.c | 22 +++++- vg_mem_view.c | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++ vg_mem_view.h | 5 ++ 4 files changed, 232 insertions(+), 4 deletions(-) create mode 100644 vg_mem_view.c create mode 100644 vg_mem_view.h diff --git a/vg_engine.c b/vg_engine.c index 37293b0..db025c8 100644 --- a/vg_engine.c +++ b/vg_engine.c @@ -50,6 +50,7 @@ static void _vg_opengl_sync_init(void) #include "vg_console.h" #include "vg_profiler.h" +#include "vg_mem_view.h" #ifndef VG_NO_AUDIO #include "vg_audio.h" #endif @@ -128,6 +129,7 @@ vg_info(" ' ' '--' [] '----- '----- ' ' '---' " vg_loader_step( vg_audio_init, vg_audio_free ); #endif vg_loader_step( vg_profiler_init, NULL ); + vg_loader_step( vg_mem_view_init, NULL ); /* client */ #ifdef VG_CUSTOM_SHADERS @@ -314,7 +316,7 @@ static void _vg_gameloop_render(void) audio_debug_ui( &vg_ui.ctx, vg.pv ); #endif - /* profiling */ + /* profiling TODO MOVE TO OWN FILE */ if( vg_profiler ){ int frame_target = vg.display_refresh_rate; if( vg.fps_limit > 0 ) frame_target = vg.fps_limit; @@ -346,6 +348,14 @@ static void _vg_gameloop_render(void) ui_text( &vg_ui.ctx, (ui_rect){258,4,900,900},perf,1,0,k_ui_align_left); } + + if( vg_mem_view && vg_loader_availible() ) + { + vg_mem_view_ui( &vg_ui.ctx, (ui_rect){400,32, + vg.window_x-400,vg.window_y-64}, + vg_mem.rtmemory, 0, "rtmemory" ); + } + ui_postrender( &vg_ui.ctx, vg.time_frame_delta ); vg_ui_post_update(); } @@ -1336,6 +1346,7 @@ __attribute__((used)) int AmdPowerXpressRequestHighPerformance = 1; #include "vg_framebuffer.c" #include "vg_render.c" #include "vg_opengl.c" +#include "vg_mem_view.c" #ifdef VG_CUSTOM_SHADERS #include "shaders/impl.c" diff --git a/vg_mem.c b/vg_mem.c index 1b55b09..0e07918 100644 --- a/vg_mem.c +++ b/vg_mem.c @@ -126,6 +126,22 @@ void *vg_linear_resize( void *buffer, void *data, u32 newsize ) else return data; } +void vg_libc_del_recursive( void *buffer ) +{ + vg_linear_allocator *alloc = vg_linear_header( buffer ); + for( u32 i=0; iallocation_count; i ++ ) + { + vg_allocation_meta *meta = &alloc->alloc_table[i]; + if( meta->type == k_allocation_type_linear ) + vg_libc_del_recursive( meta->data ); + else + free( meta->data ); + } + + free( alloc->alloc_table ); + free( alloc ); +} + /* its possible to delete just the last item */ void vg_linear_del( void *buffer, void *data ) { @@ -139,9 +155,9 @@ void vg_linear_del( void *buffer, void *data ) { vg_allocation_meta *meta = &alloc->alloc_table[alloc->allocation_count-1]; if( meta->type == k_allocation_type_linear ) - vg_fatal_error( "Cannot free a linear allocator in this conext" ); - - free( data ); + vg_libc_del_recursive( meta->data ); + else + free( data ); } alloc->allocation_count --; diff --git a/vg_mem_view.c b/vg_mem_view.c new file mode 100644 index 0000000..92af16d --- /dev/null +++ b/vg_mem_view.c @@ -0,0 +1,196 @@ +#include "vg_ui/imgui.h" + +int vg_mem_view = 0; + +void squarey_layout( ui_rect rect, f32 *areas, u32 area_count, + void (*cb)( u32, ui_rect, void* ), void *cb_user ) +{ + f32 area_total = 0.0f; + for( u32 i=0; iindices[idx]; + vg_allocation_meta *meta = &inf->alloc->alloc_table[idx]; + + if( meta->type == k_allocation_type_block ) + { + ui_fill( inf->ui_ctx, tmp, 0x80000000 | (~0xff000000&(idx*0x45d9f3b)) ); + + if( tmp[2] > 20 && tmp[3] > 16 ) + ui_text( inf->ui_ctx, tmp, meta->name, 1, k_ui_align_left, 0 ); + } + else + { + vg_mem_view_ui( inf->ui_ctx, tmp, meta->data, 0, meta->name ); + } + + return; + + + char buf[32]; + vg_mem_print_size( meta->size, buf ); + ui_text( inf->ui_ctx, tmp, buf, 1, k_ui_align_middle_center, 0 ); +} + +vg_linear_allocator *_CB_values; +int _CB_vg_mem_sort( const void *a, const void *b ) +{ + i32 ia = *((const i32 *)a), ib = *((const i32 *)b); + f32 fa = _CB_values->alloc_table[ ia ].size, + fb = _CB_values->alloc_table[ ib ].size; + return (fa < fb) - (fa > fb); +} + +void vg_mem_view_ui( ui_context *ctx, ui_rect rect, + void *lin_alloc, int depth, const char *name ) +{ + f32 sizes[ VG_MAX_ALLOCATIONS ]; + i32 indices[ VG_MAX_ALLOCATIONS ]; + + if( vg_mem.use_libc_malloc ) + { + vg_linear_allocator *alloc = vg_linear_header( lin_alloc ); + struct vg_mem_draw_inf inf = + { + .ui_ctx = ctx, + .alloc = alloc, + .indices = indices, + }; + + if( alloc->allocation_count ) + { + if( alloc->cur < alloc->size ) + { + u32 short_side = rect[3] < rect[2]? 1: 0; + f32 p = 1.0f-((f32)alloc->cur / (f32)alloc->size); + ui_px h = (f32)rect[2+short_side^0x1] * p*p; + ui_rect out_box = {rect[0], rect[1]}; + out_box[ 2+short_side^0x1 ] = h; + out_box[ 2+short_side ] = rect[ 2+short_side ]; + + ui_fill( ctx, out_box, 0x80303030 ); + + rect[ short_side^0x1 ] += h; + rect[ 2+short_side^0x1 ] -= h; + } + + if( alloc->flags & VG_MEMORY_SYSTEM ) + { + for( i32 i=0; iallocation_count; i ++ ) + indices[i] = i; + + u32 count = alloc->allocation_count; + _CB_values = alloc; + qsort( indices, count, sizeof(i32), _CB_vg_mem_sort ); + + for( u32 i=0; iallocation_count; i++ ) + { + i32 indice = indices[i]; + + vg_allocation_meta *meta = &alloc->alloc_table[indice]; + sizes[i] = sqrtf(meta->size); + } + + squarey_layout( rect, sizes, count, vg_mem_draw_cb, &inf ); + } + else + { + //printf( " (UNTRACKED)\n" ); + } + } + else + { + ui_fill( ctx, rect, 0x80101010 ); + ui_text( ctx, rect, name, 1, k_ui_align_left, 0 ); + } + } + else + { + //vg_error( "allocations are not tracked (turn on libc mode)\n" ); + } +} + +void vg_mem_view_init(void) +{ + VG_VAR_I32( vg_mem_view, flags=VG_VAR_PERSISTENT ); +} diff --git a/vg_mem_view.h b/vg_mem_view.h new file mode 100644 index 0000000..8792257 --- /dev/null +++ b/vg_mem_view.h @@ -0,0 +1,5 @@ +#pragma once +#include "vg_ui/imgui.h" +extern int vg_mem_view; +void vg_mem_view_init(void); +void vg_mem_view_ui( ui_context *ctx, ui_rect rect, void *lin_alloc, int depth, const char *name ); -- 2.25.1