From 10acb1078207e8122874d793f5ffba0eda9b5b77 Mon Sep 17 00:00:00 2001 From: jacob Date: Mon, 30 Mar 2026 16:34:28 -0500 Subject: [PATCH] profiler wip --- src/base/base.cgh | 58 ++-- src/base/base_controller.c | 17 +- src/base/base_controller.h | 9 +- src/config.h | 5 + src/gpu/gpu_core.h | 2 +- src/pp/pp_vis/pp_vis.lay | 2 +- src/pp/pp_vis/pp_vis_core.c | 392 +++++++++---------------- src/pp/pp_vis/pp_vis_core.h | 149 +++++++++- src/pp/pp_vis/pp_vis_gpu.g | 131 +-------- src/pp/pp_vis/pp_vis_gpu.gh | 2 +- src/ui/ui_core.c | 24 +- src/ui/ui_core.h | 2 + src/window/window_win32/window_win32.c | 2 +- 13 files changed, 364 insertions(+), 431 deletions(-) diff --git a/src/base/base.cgh b/src/base/base.cgh index 97c339a8..502b0d0d 100644 --- a/src/base/base.cgh +++ b/src/base/base.cgh @@ -544,10 +544,10 @@ Inline b32 MatchU128(u128 a, u128 b) { return a.lo == b.lo && a.hi == b.hi; } #if IsCpu //- Atomic types - Struct(Atomic8) { volatile i8 _v; }; - Struct(Atomic16) { volatile i16 _v; }; - Struct(Atomic32) { volatile i32 _v; }; - Struct(Atomic64) { volatile i64 _v; }; + Struct(Atomic8) { volatile i8 _atom; }; + Struct(Atomic16) { volatile i16 _atom; }; + Struct(Atomic32) { volatile i32 _atom; }; + Struct(Atomic64) { volatile i64 _atom; }; //- Cache-line isolated aligned atomic types AlignedStruct(IsolatedAtomic8, IsolationSize) { Atomic8 v; }; @@ -555,35 +555,37 @@ Inline b32 MatchU128(u128 a, u128 b) { return a.lo == b.lo && a.hi == b.hi; } AlignedStruct(IsolatedAtomic32, IsolationSize) { Atomic32 v; }; AlignedStruct(IsolatedAtomic64, IsolationSize) { Atomic64 v; }; + #define Unatomic(atomic) (&(atomic)->_atom) + #if IsPlatformWindows && IsArchX64 //- 8 bit atomic ops - ForceInline i8 Atomic8Fetch (Atomic8 *x) { CompilerBarrier(); i8 result = x->_v; CompilerBarrier(); return result; } - ForceInline void Atomic8Set (Atomic8 *x, i8 e) { CompilerBarrier(); x->_v = e; CompilerBarrier(); } - ForceInline i8 Atomic8FetchSet (Atomic8 *x, i8 e) { return (i8)_InterlockedExchange8((volatile char *)&x->_v, e); } - ForceInline i8 Atomic8FetchTestSet (Atomic8 *x, i8 c, i8 e) { return (i8)_InterlockedCompareExchange8((volatile char *)&x->_v, e, c); } - ForceInline i8 Atomic8FetchXor (Atomic8 *x, i8 c) { return (i8)_InterlockedXor8((volatile char *)&x->_v, c); } - ForceInline i8 Atomic8FetchAdd (Atomic8 *x, i8 a) { return (i8)_InterlockedExchangeAdd8((volatile char *)&x->_v, a); } + ForceInline i8 Atomic8Fetch (Atomic8 *x) { CompilerBarrier(); i8 result = x->_atom; CompilerBarrier(); return result; } + ForceInline void Atomic8Set (Atomic8 *x, i8 e) { CompilerBarrier(); x->_atom = e; CompilerBarrier(); } + ForceInline i8 Atomic8FetchSet (Atomic8 *x, i8 e) { return (i8)_InterlockedExchange8((volatile char *)&x->_atom, e); } + ForceInline i8 Atomic8FetchTestSet (Atomic8 *x, i8 c, i8 e) { return (i8)_InterlockedCompareExchange8((volatile char *)&x->_atom, e, c); } + ForceInline i8 Atomic8FetchXor (Atomic8 *x, i8 c) { return (i8)_InterlockedXor8((volatile char *)&x->_atom, c); } + ForceInline i8 Atomic8FetchAdd (Atomic8 *x, i8 a) { return (i8)_InterlockedExchangeAdd8((volatile char *)&x->_atom, a); } //- 16 bit atomic ops - ForceInline i16 Atomic16Fetch (Atomic16 *x) { CompilerBarrier(); i16 result = x->_v; CompilerBarrier(); return result; } - ForceInline void Atomic16Set (Atomic16 *x, i16 e) { CompilerBarrier(); x->_v = e; CompilerBarrier(); } - ForceInline i16 Atomic16FetchSet (Atomic16 *x, i16 e) { return (i16)_InterlockedExchange16(&x->_v, e); } - ForceInline i16 Atomic16FetchTestSet (Atomic16 *x, i16 c, i16 e) { return (i16)_InterlockedCompareExchange16(&x->_v, e, c); } - ForceInline i16 Atomic16FetchXor (Atomic16 *x, i16 c) { return (i16)_InterlockedXor16(&x->_v, c); } - ForceInline i16 Atomic16FetchAdd (Atomic16 *x, i16 a) { return (i16)_InterlockedExchangeAdd16(&x->_v, a); } + ForceInline i16 Atomic16Fetch (Atomic16 *x) { CompilerBarrier(); i16 result = x->_atom; CompilerBarrier(); return result; } + ForceInline void Atomic16Set (Atomic16 *x, i16 e) { CompilerBarrier(); x->_atom = e; CompilerBarrier(); } + ForceInline i16 Atomic16FetchSet (Atomic16 *x, i16 e) { return (i16)_InterlockedExchange16(&x->_atom, e); } + ForceInline i16 Atomic16FetchTestSet (Atomic16 *x, i16 c, i16 e) { return (i16)_InterlockedCompareExchange16(&x->_atom, e, c); } + ForceInline i16 Atomic16FetchXor (Atomic16 *x, i16 c) { return (i16)_InterlockedXor16(&x->_atom, c); } + ForceInline i16 Atomic16FetchAdd (Atomic16 *x, i16 a) { return (i16)_InterlockedExchangeAdd16(&x->_atom, a); } //- 32 bit atomic ops - ForceInline i32 Atomic32Fetch (Atomic32 *x) { CompilerBarrier(); i32 result = x->_v; CompilerBarrier(); return result; } - ForceInline void Atomic32Set (Atomic32 *x, i32 e) { CompilerBarrier(); x->_v = e; CompilerBarrier(); } - ForceInline i32 Atomic32FetchSet (Atomic32 *x, i32 e) { return (i32)_InterlockedExchange((volatile long *)&x->_v, e); } - ForceInline i32 Atomic32FetchTestSet (Atomic32 *x, i32 c, i32 e) { return (i32)_InterlockedCompareExchange((volatile long *)&x->_v, e, c); } - ForceInline i32 Atomic32FetchXor (Atomic32 *x, i32 c) { return (i32)_InterlockedXor((volatile long *)&x->_v, c); } - ForceInline i32 Atomic32FetchAdd (Atomic32 *x, i32 a) { return (i32)_InterlockedExchangeAdd((volatile long *)&x->_v, a); } + ForceInline i32 Atomic32Fetch (Atomic32 *x) { CompilerBarrier(); i32 result = x->_atom; CompilerBarrier(); return result; } + ForceInline void Atomic32Set (Atomic32 *x, i32 e) { CompilerBarrier(); x->_atom = e; CompilerBarrier(); } + ForceInline i32 Atomic32FetchSet (Atomic32 *x, i32 e) { return (i32)_InterlockedExchange((volatile long *)&x->_atom, e); } + ForceInline i32 Atomic32FetchTestSet (Atomic32 *x, i32 c, i32 e) { return (i32)_InterlockedCompareExchange((volatile long *)&x->_atom, e, c); } + ForceInline i32 Atomic32FetchXor (Atomic32 *x, i32 c) { return (i32)_InterlockedXor((volatile long *)&x->_atom, c); } + ForceInline i32 Atomic32FetchAdd (Atomic32 *x, i32 a) { return (i32)_InterlockedExchangeAdd((volatile long *)&x->_atom, a); } //- 64 bit atomic ops - ForceInline i64 Atomic64Fetch (Atomic64 *x) { CompilerBarrier(); i64 result = x->_v; CompilerBarrier(); return result; } - ForceInline void Atomic64Set (Atomic64 *x, i64 e) { CompilerBarrier(); x->_v = e; CompilerBarrier(); } - ForceInline i64 Atomic64FetchSet (Atomic64 *x, i64 e) { return (i64)_InterlockedExchange64(&x->_v, e); } - ForceInline i64 Atomic64FetchTestSet (Atomic64 *x, i64 c, i64 e) { return (i64)_InterlockedCompareExchange64(&x->_v, e, c); } - ForceInline i64 Atomic64FetchXor (Atomic64 *x, i64 c) { return (i64)_InterlockedXor64(&x->_v, c); } - ForceInline i64 Atomic64FetchAdd (Atomic64 *x, i64 a) { return (i64)_InterlockedExchangeAdd64(&x->_v, a); } + ForceInline i64 Atomic64Fetch (Atomic64 *x) { CompilerBarrier(); i64 result = x->_atom; CompilerBarrier(); return result; } + ForceInline void Atomic64Set (Atomic64 *x, i64 e) { CompilerBarrier(); x->_atom = e; CompilerBarrier(); } + ForceInline i64 Atomic64FetchSet (Atomic64 *x, i64 e) { return (i64)_InterlockedExchange64(&x->_atom, e); } + ForceInline i64 Atomic64FetchTestSet (Atomic64 *x, i64 c, i64 e) { return (i64)_InterlockedCompareExchange64(&x->_atom, e, c); } + ForceInline i64 Atomic64FetchXor (Atomic64 *x, i64 c) { return (i64)_InterlockedXor64(&x->_atom, c); } + ForceInline i64 Atomic64FetchAdd (Atomic64 *x, i64 a) { return (i64)_InterlockedExchangeAdd64(&x->_atom, a); } #endif #endif diff --git a/src/base/base_controller.c b/src/base/base_controller.c index 213f5822..5f2c6a8e 100644 --- a/src/base/base_controller.c +++ b/src/base/base_controller.c @@ -9,8 +9,8 @@ String StringFromButton(Button button) [Button_M3] = CompLit("Mouse 3"), [Button_M4] = CompLit("Mouse 4"), [Button_M5] = CompLit("Mouse 5"), - [Button_MWheelUp] = CompLit("Wheel Up"), - [Button_MWheelDown] = CompLit("Wheel Down"), + [Button_WheelUp] = CompLit("Wheel Up"), + [Button_WheelDown] = CompLit("Wheel Down"), [Button_Escape] = CompLit("Escape"), [Button_F1] = CompLit("F1"), [Button_F2] = CompLit("F2"), @@ -108,12 +108,17 @@ String StringFromButton(Button button) return name; } -b32 IsMouseClickButton(Button button) +b32 IsClickButton(Button button) { - return button >= Button_M1 && button <= Button_M3; + return button >= Button_M1 && button <= Button_M5; } -b32 IsAnyMouseButton(Button button) +b32 IsWheelButton(Button button) { - return button >= Button_M1 && button <= Button_MWheelDown; + return button == Button_WheelUp || button == Button_WheelDown; +} + +b32 IsMouseButton(Button button) +{ + return button >= Button_M1 && button <= Button_WheelDown; } diff --git a/src/base/base_controller.h b/src/base/base_controller.h index 65e41da5..f4c27d82 100644 --- a/src/base/base_controller.h +++ b/src/base/base_controller.h @@ -13,8 +13,8 @@ Enum(Button) Button_M5, //- Mouse wheel - Button_MWheelUp, - Button_MWheelDown, + Button_WheelUp, + Button_WheelDown, //- Keyboard buttons Button_Escape, @@ -160,5 +160,6 @@ Struct(ControllerEventsArray) //~ Button helpers String StringFromButton(Button button); -b32 IsMouseClickButton(Button button); -b32 IsAnyMouseButton(Button button); +b32 IsClickButton(Button button); +b32 IsWheelButton(Button button); +b32 IsouseButton(Button button); diff --git a/src/config.h b/src/config.h index 18ecb807..176a202d 100644 --- a/src/config.h +++ b/src/config.h @@ -23,6 +23,11 @@ //////////////////////////////////////////////////////////// //~ Settings + +#define PROFILING_ENABLED 1 + + + // TODO: Move these to user-configurable settings #define AUDIO_ENABLED 0 diff --git a/src/gpu/gpu_core.h b/src/gpu/gpu_core.h index 32763226..4f500892 100644 --- a/src/gpu/gpu_core.h +++ b/src/gpu/gpu_core.h @@ -560,7 +560,7 @@ void G_PopZoneEx(G_CommandListHandle cl); #define G_PushZone(cl, name_lit) G_PushZoneEx((cl), Lit(name_lit"\0")) #define G_PopZone(cl) G_PopZoneEx(cl) -#define G_ZoneDF(cl, name_lit) DeferFor(G_PushZone((cl), name_lit), G_PopZone(cl)) +#define G_ProfZoneDF(cl, name_lit) DeferFor(G_PushZone((cl), name_lit), G_PopZone(cl)) //- Cpu -> Gpu staged copy diff --git a/src/pp/pp_vis/pp_vis.lay b/src/pp/pp_vis/pp_vis.lay index 551d99cf..c504116a 100644 --- a/src/pp/pp_vis/pp_vis.lay +++ b/src/pp/pp_vis/pp_vis.lay @@ -15,7 +15,7 @@ ////////////////////////////// //- Resources -@Shader V_BuildProfilerGraphCS (1, 128) // Vertical group shape so that profiler-sample access is uniform +@Shader V_BuildProfilerGraphCS (1, 128) // Vertical group dims so that profiler-sample access is uniform @Shader V_PrepareShadeCS (16, 16) @Shader V_PrepareCellsCS (16, 16) @Shader V_BackdropDownCS (16, 16) diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index d0e62810..df42b14a 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -1,5 +1,28 @@ V_Ctx V = Zi; + + + + + + + + + + + + +// FIXME: Remove this + +ProfCtx Prof = Zi; +ThreadLocal ProfThreadLocalCtx Prof_tl = Zi; + + + + + + + //////////////////////////////////////////////////////////// //~ Bootstrap @@ -1143,11 +1166,11 @@ void V_TickForever(WaveLaneCtx *lane) { b32 clear = 0; { - if (IsMouseClickButton(btn) && !frame->has_mouse_focus) + if ((IsClickButton(btn) || IsWheelButton(btn)) && !frame->has_mouse_focus) { clear = 1; } - if (!IsAnyMouseButton(btn) && !frame->has_keyboard_focus) + if (!IsMouseButton(btn) && !frame->has_keyboard_focus) { clear = 1; } @@ -1161,11 +1184,11 @@ void V_TickForever(WaveLaneCtx *lane) { b32 clear = 0; { - if (IsMouseClickButton(btn) && !frame->has_mouse_focus) + if ((IsClickButton(btn) || IsWheelButton(btn)) && !frame->has_mouse_focus) { clear = 1; } - if (!IsAnyMouseButton(btn) && (!frame->has_keyboard_focus || is_typing)) + if (!IsMouseButton(btn) && (!frame->has_keyboard_focus || is_typing)) { clear = 1; } @@ -1296,7 +1319,7 @@ void V_TickForever(WaveLaneCtx *lane) } } frame->real_held_buttons[hotkey.button] = down; - if (IsMouseClickButton(hotkey.button) || !is_typing) + if (IsClickButton(hotkey.button) || !is_typing) { frame->held_buttons[hotkey.button] = down; } @@ -2070,6 +2093,7 @@ void V_TickForever(WaveLaneCtx *lane) // Predict P_Frame *predict_frame = predict_world->last_frame; + ProfZoneDF("Predict simulation") { if (predict_world->tiles_hash != sim_world->tiles_hash) { @@ -2196,6 +2220,7 @@ void V_TickForever(WaveLaneCtx *lane) P_Frame *prev_local_frame = prev_frame->local_world->last_frame; P_Frame *local_frame = &P_NilFrame; + ProfZoneDF("Blend worlds") { if (frame->local_world->tiles_hash != predict_world->tiles_hash) { @@ -2314,6 +2339,7 @@ void V_TickForever(WaveLaneCtx *lane) + ProfZoneDF("Observe Entities") for (P_Ent *ent = P_FirstEnt(local_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent)) { P_EntKey key = ent->key; @@ -4616,12 +4642,12 @@ void V_TickForever(WaveLaneCtx *lane) display_text = Lit(" Search..."); } - // Vec4 raah_color = Color_Black; - Vec4 raah_color = Zi; + // Vec4 search_color = Color_Black; + Vec4 search_color = Zi; UI_SetNext(Width, UI_GROW(1, 0)); UI_SetNext(Height, search_height); - UI_SetNext(BackgroundColor, raah_color); + UI_SetNext(BackgroundColor, search_color); // UI_SetNext(BorderColor, item_border_color); UI_SetNext(BorderSize, 0); // UI_SetNext(Rounding, UI_RPIX(5)); @@ -5469,18 +5495,36 @@ void V_TickForever(WaveLaneCtx *lane) UI_PushDF(Tag, profiler_box.v) UI_PushDF(Parent, profiler_box) { - UI_Size profiler_height = UI_FNT(20, 1); + UI_Key main_box = UI_KeyF("main"); + + UI_Size profiler_height = UI_FNT(40, 1); UI_Size header_height = UI_FNT(2, 1); UI_Size window_padding = UI_FNT(0.5, 1); + UI_Size graph_height = UI_GROW(0.25, 0); + UI_Size main_height = UI_GROW(1, 0); + UI_Size zone_height = UI_FNT(0.75, 0); + + UI_BoxReport main_rep = UI_ReportsFromKey(main_box).draw; + + Vec2 last_main_dims = DimsFromRng2(main_rep.screen_rect); + last_main_dims.x = MaxF32(last_main_dims.x, 1); + last_main_dims.y = MaxF32(last_main_dims.y, 1); + + i64 view_start_ns = NsFromSeconds(0); + i64 view_end_ns = NsFromSeconds(10); + + f64 ns_per_px = MaxF64((view_end_ns - view_start_ns) / last_main_dims.x, 1); Vec4 profiler_color = theme.col.window_bg; - profiler_color.a = 0.75; + profiler_color.a = 1; UI_SetNext(Parent, vis_ui_box); + UI_SetNext(BorderColor, theme.col.window_bd); + UI_SetNext(BorderSize, 2); UI_SetNext(BackgroundColor, profiler_color); - UI_SetNext(Rounding, UI_RPIX(5 * theme.rounding)); + UI_SetNext(Rounding, UI_RPIX(10 * theme.rounding)); + UI_SetNext(Height, profiler_height); UI_PushDF(Width, UI_GROW(1, 0)) - UI_PushDF(Height, profiler_height) UI_PushDF(Parent, UI_BuildColumnEx(profiler_box)) UI_PushDF(Parent, UI_BuildRow()) { @@ -5502,237 +5546,78 @@ void V_TickForever(WaveLaneCtx *lane) //- Graph // UI_SetNext(BackgroundColor, Color_Cyan); + UI_SetNext(Height, graph_height); UI_PushDF(Parent, UI_BuildBoxEx(profiler_graph_box)) { } + UI_BuildDivider(UI_PIX(1, 1), theme.col.divider, Axis_Y); + + //- Main + UI_SetNext(Height, main_height); + UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + UI_PushDF(Parent, UI_BuildRowEx(main_box)) + { + + // FIXME: Remove this + + Struct(V_ZoneDesc) + { + Vec4 color; + i64 start_ns; + i64 end_ns; + }; + + u64 zones_count = 64; + V_ZoneDesc *zones = PushStructs(frame->arena, V_ZoneDesc, zones_count); + for (u64 zone_idx = 0; zone_idx < zones_count; ++zone_idx) + { + V_ZoneDesc *zone = &zones[zone_idx]; + zone->color = VEC4(0.5, 0.2, 0.2, 0.5); + zone->start_ns = NsFromSeconds(zone_idx * 2); + zone->end_ns = NsFromSeconds(zone_idx * 2 + 1); + }; + + //- Zones + for (u64 zone_idx = 0; zone_idx < zones_count; ++zone_idx) + { + V_ZoneDesc *zone = &zones[zone_idx]; + + UI_Key zone_box = UI_KeyF("Zone %F", FmtUint(zone_idx)); + // UI_BoxReport zone_rep = UI_ReportFromKey(zone_box).draw; + + Vec4 zone_color = zone->color; + + // Vec4 zone_color_bd = Zi; + // zone_color_bd + + i64 zone_len_ns = zone->end_ns - zone->start_ns; + f32 zone_len_px = zone_len_ns / ns_per_px; + // i6 + + f32 zone_offset_px = (zone->start_ns - view_start_ns) / ns_per_px; + Vec2 zone_pos = VEC2(zone_offset_px, 0); + UI_Size zone_width = UI_PIX(zone_len_px, 1); + + // UI_Report + + + UI_SetNext(Width, zone_width); + UI_SetNext(Height, zone_height); + UI_SetNext(BackgroundColor, zone_color); + UI_SetNext(FloatingPos, zone_pos); + UI_SetNext(Flags, UI_BoxFlag_Floating | UI_BoxFlag_NoFloatingClampX | UI_BoxFlag_NoFloatingClampY); + UI_PushDF(Parent, UI_BuildBoxEx(zone_box)) + { + } + } + } + } UI_BuildSpacer(window_padding, Axis_X); } } } - - - - - - - - - - - - - - - - - - - - - - - - - - - ////////////////////////////// - //- Build test profiler - - - - - - // TODO: Remove this - - // FIXME: remove this (samples testing) - - - - - - // { - // BlaParams params = Zi; - // params.cursor = frame->screen_cursor; - - // //- Sample GPU work - // G_ZoneDF(cl, "BLAAAAAAAAA") - // { - // params.bla_dims = VEC2(1000, 200); - // // params.bla_samples_count = Mebi(1); - // params.bla_samples_count = 1000; - // BlaSample *bla_samples = PushStructsNoZero(frame->arena, BlaSample, params.bla_samples_count); - // { - // for (i64 sample_idx = 0; sample_idx < params.bla_samples_count; ++sample_idx) - // { - // BlaSample *sample = &bla_samples[sample_idx]; - // // sample->bla0 = sample_idx; - // // sample->bla1 = params.bla_samples_count - sample_idx; - - - - - // // sample->r0 = Norm24(MixU64(sample_idx)); - // sample->r0 = 0.5 + ((Norm24(MixU64(sample_idx + frame->tick)) - 0.5) * 0.01); - // // sample->r0 += SinF32(SecondsFromNs(frame->time_ns)) * 0.1; - - // // sample->r0 += SinF32(SecondsFromNs(frame->time_ns)) * 0.1; - - // sample->r1 = (1.0 - sample->r0) * 0.5; - // } - // } - - - - // params.bla_samples = G_PushStructsFromCpu( - // cl, gpu_frame_arena, - // bla_samples, params.bla_samples_count, - // .name = StringF(frame->arena, "bla samples [%F]", FmtSint(frame->tick)) - // ); - // params.bla_tex = G_PushTexture2D( - // cl, gpu_frame_arena, - // G_TextureLayout_Family, - // G_Format_R16G16B16A16_Float, - // params.bla_dims, - // .flags = G_MemoryFlag_AllowTextureRW, - // .name = StringF(frame->arena, "Shade target [%F]", FmtSint(frame->tick)) - // ); - - - - - - - - - - // G_BufferRef gpu_bla_params = G_PushStructFromCpu( - // cl, gpu_frame_arena, - // ¶ms, - // .name = StringF(frame->arena, "Bla params [%F]", FmtSint(frame->tick)) - // ); - - // // Set initial constants - // // FIXME: Don't use frame slot - // G_SetConstant(cl, V_GpuConst_Frame, gpu_bla_params); - - - // // Compute - // { - // G_Sync(cl); - // G_Compute2D(cl, V_BlaCS, params.bla_dims); - // G_Sync(cl); - // } - // } - - // //- Sample UI - // { - // UI_Key bla_box = UI_KeyF("blaaaa samples"); - // UI_Key bla_tex_box = UI_KeyF("blaaaa samples tex"); - // b32 is_showing = 1; - - // { - // Rng2 uv = RNG2(VEC2(0, 0), VEC2(1, 1)); - // UI_SetRawTexture(bla_tex_box, params.bla_tex, uv); - // } - - - // UI_Push(Tag, HashF("BLAAA")); - // { - - - // Vec4 bg = Color_Black; - // Vec4 bd = Color_White; - // UI_Size width = UI_PIX(params.bla_dims.x, 1); - // UI_Size height = UI_PIX(params.bla_dims.y, 1); - // Vec2 pos = VEC2(frame->screen_dims.x / 2, 100); - - - // UI_SetNext(Tint, Color_White); - // // UI_SetNext(BackgroundColor, bg); - // // UI_SetNext(BorderColor, bd); - // // UI_SetNext(BorderSize, 1); - // UI_SetNext(Rounding, UI_RPIX(20)); - // // UI_SetNext(BorderColor, window_border_color); - // // // UI_SetNext(BorderSize, theme.window_bd_sz); - // // UI_SetNext(BorderSize, 1); - // // UI_SetNext(Rounding, UI_RGROW(0.06 * theme.rounding)); - // UI_SetNext(Width, width); - // UI_SetNext(Height, height); - // // UI_SetNext(ChildLayoutAxis, Axis_Y); - // UI_SetNext(FloatingPos, pos); - // UI_SetNext(Anchor, UI_Region_Top); - // // UI_SetNext(Flags, UI_BoxFlag_Floating | (UI_BoxFlag_CaptureMouse * !!is_showing)); - // UI_SetNext(Flags, UI_BoxFlag_Floating); - // UI_PushCp(UI_BuildBoxEx(bla_box)); - // { - // UI_PushCp(UI_BuildBoxEx(bla_tex_box)); - // { - // } - // UI_PopCp(UI_TopCp()); - // } - // UI_PopCp(UI_TopCp()); - // } - // UI_Pop(Tag); - - - - - - // // f32 item_size_px = UI_FNT(1.5, 1).v; - // // f32 tweak_size_px = UI_FNT(1.25, 1).v; - - // // palette->key = UI_KeyF("command palette"); - // // UI_Checkpoint palette_cp = UI_PushCp(UI_NilKey); - // // { - // // UI_Push(Tag, palette->key.v); - // // UI_Key titlebar_key = UI_KeyF("title bar"); - // // UI_BoxReports titlebar_reps = UI_ReportsFromKey(titlebar_key); - // // UI_BoxReports palette_reps = UI_ReportsFromKey(palette->key); - - // // Vec4 window_background_color = theme.col.window_bg; - // // Vec4 window_border_color = theme.col.window_bd; - // // Vec4 titlebar_color = Zi; - // // Vec4 titlebar_border_color = Zi; - // // Vec4 divider_color = theme.col.divider; - // // if (titlebar_reps.draw.m1.held) - // // { - // // Vec2 drag_offset = SubVec2(ui_frame->drag_cursor_pos, palette_reps.drag.screen_anchor); - // // palette->pos = SubVec2(frame->screen_cursor, drag_offset); - // // } - // // window_border_color = LerpSrgb(window_border_color, theme.col.button_active, titlebar_reps.draw.hot); - - // // f32 scale = LerpF32(0.85, 1, palette->show); - // // UI_Push(Tint, VEC4(1, 1, 1, palette->show)); - // // UI_SetNext(Scale, VEC2(scale, scale)); - - // // UI_Push(BackgroundColor, window_background_color); - // // UI_Push(BorderColor, window_border_color); - // // // UI_Push(BorderSize, theme.window_bd_sz); - // // UI_Push(BorderSize, 1); - // // UI_Push(Rounding, UI_RGROW(0.06 * theme.rounding)); - // // UI_Push(Width, UI_FNT(40, 0)); - // // UI_Push(Height, UI_SHRINK(0, 0)); - // // UI_Push(ChildLayoutAxis, Axis_Y); - // // UI_Push(FloatingPos, palette->pos); - // // UI_SetNext(Anchor, UI_Region_Center); - // // UI_SetNext(Flags, UI_BoxFlag_Floating | (UI_BoxFlag_CaptureMouse * !!palette->is_showing)); - // // UI_PushCp(UI_BuildBoxEx(palette->key)); - // // } - // } - // } - - - - - - - - - - - ////////////////////////////// //- Build notifications @@ -5854,8 +5739,6 @@ void V_TickForever(WaveLaneCtx *lane) UI_PopCp(UI_TopCp()); } - - } @@ -6495,6 +6378,7 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Process vis commands + ProfZoneDF("Process vis cmds") for (V_CmdNode *cmd_node = frame->first_cmd_node; cmd_node; cmd_node = cmd_node->next) { String cmd_name = cmd_node->cmd.name; @@ -6696,11 +6580,12 @@ void V_TickForever(WaveLaneCtx *lane) Rng3 screen_viewport = RNG3(VEC3(0, 0, 0), VEC3(frame->screen_dims.x, frame->screen_dims.y, 1)); Rng2 screen_scissor = RNG2(VEC2(screen_viewport.p0.x, screen_viewport.p0.y), VEC2(screen_viewport.p1.x, screen_viewport.p1.y)); b32 should_draw_profiler_graph = profiler->is_showing && profiler->graph_dims.x > 0 && profiler->graph_dims.y > 0; + ProfZoneDF("Build GPU cmds") { ////////////////////////////// //- GPU upload pass - G_ZoneDF(cl, "Setup") + G_ProfZoneDF(cl, "Setup") { // Backdrop frame->backdrop_parallax = TweakFloat("Backdrop parallax", 4, 0, 20); @@ -6883,12 +6768,12 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Initialization pass - G_ZoneDF(cl, "Init") + G_ProfZoneDF(cl, "Init") { // Build profiler graph if (should_draw_profiler_graph) { - G_Compute2D(cl, V_ProfilerGraphCS, frame->profiler_graph_dims); + G_Compute2D(cl, V_BuildProfilerGraphCS, frame->profiler_graph_dims); } // Prepare shade @@ -6938,7 +6823,7 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Quads & emitters pass - G_ZoneDF(cl, "Quads & emitters") + G_ProfZoneDF(cl, "Quads & emitters") { // Draw quads G_ClearRenderTarget(cl, frame->albedo, VEC4(0, 0, 0, 0), 0); @@ -6960,7 +6845,7 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Particle simulation pass - G_ZoneDF(cl, "Particle sim") + G_ProfZoneDF(cl, "Particle sim") { // Simulate particles G_Compute(cl, V_SimParticlesCS, V_ParticlesCap); @@ -6973,7 +6858,7 @@ void V_TickForever(WaveLaneCtx *lane) // TODO: Remove this - G_ZoneDF(cl, "Shade") + G_ProfZoneDF(cl, "Shade") if (0) { G_Compute2D(cl, V_ShadeCS, frame->shade_dims); @@ -6984,7 +6869,7 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Composite pass - G_ZoneDF(cl, "Composite") + G_ProfZoneDF(cl, "Composite") { G_Compute2D(cl, V_CompositeCS, frame->screen_dims); } @@ -7003,7 +6888,7 @@ void V_TickForever(WaveLaneCtx *lane) // the first mip index in the bloom mip chain //- Downsample - G_ZoneDF(cl, "Bloom down") + G_ProfZoneDF(cl, "Bloom down") for (i32 mip_idx = 1; mip_idx < mips_count; ++mip_idx) { Vec2I32 down_dims = G_DimsFromMip2D(G_Count2D(frame->screen), mip_idx); @@ -7015,7 +6900,7 @@ void V_TickForever(WaveLaneCtx *lane) } //- Upsample - G_ZoneDF(cl, "Bloom up") + G_ProfZoneDF(cl, "Bloom up") for (i32 mip_idx = mips_count - 2; mip_idx >= 0; --mip_idx) { Vec2I32 up_dims = G_DimsFromMip2D(G_Count2D(frame->screen), mip_idx); @@ -7030,7 +6915,7 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Finalization pass - G_ZoneDF(cl, "Finalize") + G_ProfZoneDF(cl, "Finalize") { G_Compute2D(cl, V_FinalizeCS, frame->screen_dims); } @@ -7040,7 +6925,7 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Debug shapes pass - G_ZoneDF(cl, "Debug shapes") + G_ProfZoneDF(cl, "Debug shapes") { G_Draw( cl, @@ -7115,6 +7000,7 @@ void V_TickForever(WaveLaneCtx *lane) // NET_Send(net_pipe, frame->sim_key, packed, NET_SendFlag_None); // } + ProfZoneDF("Publish net msgs") { if (P_tl.out_msgs.count > 0) { @@ -7122,15 +7008,21 @@ void V_TickForever(WaveLaneCtx *lane) String packed = P_PackMessages(&packer_bbw, P_tl.out_msgs); NET_Send(net_pipe, frame->sim_key, packed, NET_SendFlag_None); } + ResetArena(P_tl.out_msgs_arena); + ZeroStruct(&P_tl.out_msgs); } - ResetArena(P_tl.out_msgs_arena); - ZeroStruct(&P_tl.out_msgs); + ////////////////////////////// + //- Commit GPU command list + + ProfZoneDF("Publish GPU cmds") + { + G_CommitCommandList(cl); + } ////////////////////////////// //- End frame - G_CommitCommandList(cl); i32 vsync = !!TweakBool("Vsync", 1); vsync = 1; diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index 2c97d7ac..fac2cb91 100644 --- a/src/pp/pp_vis/pp_vis_core.h +++ b/src/pp/pp_vis/pp_vis_core.h @@ -1,3 +1,148 @@ + + + + + + + + + + + + + + +// FIXME: Remove this + + +// // Enum(ProfFamilyKind) +// // { +// // ProfFamilyKind_Unknown, +// // ProfFamilyKind_Async, +// // ProfFamilyKind_Vis, +// // ProfFamilyKind_Sim, + +// // ProfFamilyKind_COUNT +// // }; + + + + + +// // // Struct( + + + + + + + +#define ProfTrackSamplesCap Kibi(256) +#define MaxRegisteredProfTracks Kibi(32) + + + + + + + +Struct(ProfSample) +{ + // Bit 63: zone-end, Bits 62-0: timestamp + u64 stamp; +}; + +Struct(ProfTrack) +{ + u64 top_sample_seq; + ProfSample samples[ProfTrackSamplesCap]; +}; + +Struct(ProfCtx) +{ + TicketMutex register_track_tm; + + Atomic32 tracks_count; + ProfTrack *tracks[MaxRegisteredProfTracks]; +}; + +Struct(ProfThreadLocalCtx) +{ + b32 initialized; + u32 track_idx; + ProfTrack thread_track; +}; + +extern ProfCtx Prof; +extern ThreadLocal ProfThreadLocalCtx Prof_tl; + + +Inline void PushProfZoneEx(b32 end_zone) +{ + ProfTrack *track = &Prof_tl.thread_track; + if (!Prof_tl.initialized) + { + LockTicketMutex(&Prof.register_track_tm); + { + Prof_tl.track_idx = Atomic32Fetch(&Prof.tracks_count); + Prof.tracks[Prof_tl.track_idx] = track; + Atomic32FetchAdd(&Prof.tracks_count, 1); + } + UnlockTicketMutex(&Prof.register_track_tm); + Prof_tl.initialized = 1; + } + + u64 sample_seq = track->top_sample_seq; + ProfSample *sample = &track->samples[sample_seq % ProfTrackSamplesCap]; + { + // TODO: Wrap rdtsc for cpu-relative <-> program-relative timestamp conversion + // sample->stamp = __rdtsc() | ((u64)end_zone << 63); + sample->stamp = TimeNs() | ((u64)end_zone << 63); + } + track->top_sample_seq = sample_seq + 1; +} + + + + + + +#if PROFILING_ENABLED + #define ProfZoneDF(...) DeferFor(PushProfZoneEx(0), PushProfZoneEx(1)) +#else + #define ProfZoneDF(...) +#endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //////////////////////////////////////////////////////////// //~ Command table @@ -5,8 +150,8 @@ X(nop, NOP, V_CmdDescFlag_HideFromPalette, V_HOTKEY(0), ) \ X(exit_program, Exit Program, V_CmdDescFlag_HideFromPalette, V_HOTKEY( Button_Escape ) ) \ X(toggle_palette, Toggle Command Palette, V_CmdDescFlag_HideFromPalette, V_HOTKEY( Button_E, .ctrl = 1 ), V_HOTKEY( Button_P, .ctrl = 1, .shift = 1 ), ) \ - X(zoom_in, Zoom In, V_CmdDescFlag_HideFromPalette, V_HOTKEY( Button_MWheelUp ), ) \ - X(zoom_out, Zoom Out, V_CmdDescFlag_HideFromPalette, V_HOTKEY( Button_MWheelDown ), ) \ + X(zoom_in, Zoom In, V_CmdDescFlag_HideFromPalette, V_HOTKEY( Button_WheelUp ), ) \ + X(zoom_out, Zoom Out, V_CmdDescFlag_HideFromPalette, V_HOTKEY( Button_WheelDown ), ) \ X(toggle_editor, Toggle Editor, V_CmdDescFlag_None, V_HOTKEY( Button_F1 ), ) \ X(save_level, Save level, V_CmdDescFlag_None, V_HOTKEY( Button_S, .ctrl = 1 ), ) \ X(toggle_ui_debug, Toggle UI Debug, V_CmdDescFlag_None, V_HOTKEY( Button_F5 ), ) \ diff --git a/src/pp/pp_vis/pp_vis_gpu.g b/src/pp/pp_vis/pp_vis_gpu.g index 3da32348..db1910f3 100644 --- a/src/pp/pp_vis/pp_vis_gpu.g +++ b/src/pp/pp_vis/pp_vis_gpu.g @@ -1,132 +1,3 @@ - -//////////////////////////////////////////////////////////// -//~ Bla samples test - - - -// FIXME: Remove this - - - - - - - -// FIXME: Header - - - - - - - -// TODO: Make use of the fact that x is always scalar? - - - - - - - - -// ComputeShader(V_BlaCS) -// { -// // FIXME: Don't use frame slot -// BlaParams params = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; -// RWTexture2D bla = G_Deref(params.bla_tex, RWTexture2D); - -// i64 samples_count = params.bla_samples_count; -// StructuredBuffer samples = G_Deref(params.bla_samples, StructuredBuffer); - - - -// Vec2 bla_pos = SV_DispatchThreadID + 0.5; - -// Vec2 dims = params.bla_dims; - - -// // f32 samp_width = 10 * G_TweakFloat; -// f32 samp_width = 3; - -// i64 sample_idx = bla_pos.x / samp_width; - - - - -// if (all(bla_pos < dims) && sample_idx < samples_count) -// { -// // // Vec4 color = Color_Red; -// // Vec4 color = Color_Black; -// // color.b = bla_pos.x / dims.x; -// // if (MatchFloor(bla_pos, params.cursor)) -// // { -// // G_PrintF("bla_pos: %F, dims: %F, color: %F", G_Fmt(bla_pos), G_Fmt(dims), G_Fmt(color)); -// // } -// // bla[bla_pos] = color; - - - -// BlaSample sample = samples[sample_idx]; -// // f32 ratio0 = (f32)sample.bla0 / (f32)samples_count; -// // f32 ratio1 = (f32)sample.bla1 / (f32)samples_count; - -// f32 ratio0 = sample.r0; -// f32 ratio1 = sample.r1; - - - - -// f32 ratio_y = 1.0 - (bla_pos.y / dims.y); - - - -// Vec4 color = 0; -// if (ratio_y < ratio0) -// { -// color = LinearFromSrgb(Vec4(0.82, 0, 0.933, 1)); -// } -// else if (ratio_y < ratio0 + ratio1) -// { -// color = LinearFromSrgb(Vec4(0.953, 0.467, 0.208, 1)); -// } -// else -// { -// color = 0; -// } - -// bla[bla_pos] = color; - -// } -// } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //////////////////////////////////////////////////////////// //~ Helpers @@ -183,7 +54,7 @@ Vec4 V_ColorFromParticle(V_ParticleDesc desc, u32 particle_idx, u32 density) //////////////////////////////////////////////////////////// //~ Build profiler graph -ComputeShader(V_ProfilerGraphCS) +ComputeShader(V_BuildProfilerGraphCS) { V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; RWTexture2D graph = G_Deref(frame.profiler_graph, RWTexture2D); diff --git a/src/pp/pp_vis/pp_vis_gpu.gh b/src/pp/pp_vis/pp_vis_gpu.gh index 25c263a2..6e949162 100644 --- a/src/pp/pp_vis/pp_vis_gpu.gh +++ b/src/pp/pp_vis/pp_vis_gpu.gh @@ -51,7 +51,7 @@ Vec4 V_ColorFromParticle(V_ParticleDesc desc, u32 particle_idx, u32 density); //~ Shaders //- Build profiler graph -ComputeShader(V_ProfilerGraphCS); +ComputeShader(V_BuildProfilerGraphCS); //- Prepare frame ComputeShader(V_PrepareShadeCS); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 99c9c755..85855109 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -695,7 +695,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags) case ControllerEventKind_ButtonDown: { - if (cev.button == Button_M1 || cev.button == Button_M2 || cev.button == Button_M3) + if (IsClickButton(cev.button) || IsWheelButton(cev.button)) { mouse_downs += 1; if (top_hovered_box && active_box == 0) @@ -704,25 +704,35 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags) { ++top_hovered_box->reports.draw.m1.downs; top_hovered_box->reports.draw.m1.held = 1; + active_box = top_hovered_box; } else if (cev.button == Button_M2) { ++top_hovered_box->reports.draw.m2.downs; top_hovered_box->reports.draw.m2.held = 1; + active_box = top_hovered_box; } else if (cev.button == Button_M3) { ++top_hovered_box->reports.draw.m3.downs; top_hovered_box->reports.draw.m3.held = 1; + active_box = top_hovered_box; + } + else if (cev.button == Button_WheelUp) + { + ++top_hovered_box->reports.draw.wheel_up; + } + else if (cev.button == Button_WheelUp) + { + ++top_hovered_box->reports.draw.wheel_down; } - active_box = top_hovered_box; } } } break; case ControllerEventKind_ButtonUp: { - if (cev.button == Button_M1 || cev.button == Button_M2 || cev.button == Button_M3) + if (IsClickButton(cev.button)) { if (active_box) { @@ -1747,7 +1757,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync) ////////////////////////////// //- Upload data to GPU - G_ZoneDF(UI.cl, "UI upload") + G_ProfZoneDF(UI.cl, "UI upload") { // Target gpu_frame.target_size = draw_size; @@ -1790,14 +1800,14 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync) //- Clear pass - G_ZoneDF(UI.cl, "UI clear") + G_ProfZoneDF(UI.cl, "UI clear") { G_ClearRenderTarget(UI.cl, gpu_frame.target, VEC4(0, 0, 0, 0), 0); } //- Rects pass - G_ZoneDF(UI.cl, "UI rects") + G_ProfZoneDF(UI.cl, "UI rects") { G_Draw( UI.cl, @@ -1813,7 +1823,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync) if (AnyBit(frame->frame_flags, UI_FrameFlag_Debug)) { - G_ZoneDF(UI.cl, "UI debug rects") + G_ProfZoneDF(UI.cl, "UI debug rects") { G_SetConstant(UI.cl, UI_GpuConst_DebugDraw, 1); G_Draw( diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 81b6759c..76c36797 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -231,6 +231,8 @@ Struct(UI_BoxReport) UI_MouseReport m1; UI_MouseReport m2; UI_MouseReport m3; + i32 wheel_up; + i32 wheel_down; Rng2 screen_rect; Vec2 screen_anchor; diff --git a/src/window/window_win32/window_win32.c b/src/window/window_win32/window_win32.c index fb95935e..61cba921 100644 --- a/src/window/window_win32/window_win32.c +++ b/src/window/window_win32/window_win32.c @@ -394,7 +394,7 @@ LRESULT CALLBACK WND_W32_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM l { int delta = GET_WHEEL_DELTA_WPARAM(wparam); i32 dir = delta >= 0 ? 1 : -1; - Button btn = dir >= 0 ? Button_MWheelUp : Button_MWheelDown; + Button btn = dir >= 0 ? Button_WheelUp : Button_WheelDown; for (i32 i = 0; i < (dir * delta); i += WHEEL_DELTA) { // Send a button down & button up event simultaneously