profiler wip

This commit is contained in:
jacob 2026-03-30 16:34:28 -05:00
parent 5ef6a770cb
commit 10acb10782
13 changed files with 364 additions and 431 deletions

View File

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

View File

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

View File

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

View File

@ -23,6 +23,11 @@
////////////////////////////////////////////////////////////
//~ Settings
#define PROFILING_ENABLED 1
// TODO: Move these to user-configurable settings
#define AUDIO_ENABLED 0

View File

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

View File

@ -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)

View File

@ -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,
// &params,
// .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);
}
//////////////////////////////
//- Commit GPU command list
ProfZoneDF("Publish GPU cmds")
{
G_CommitCommandList(cl);
}
//////////////////////////////
//- End frame
G_CommitCommandList(cl);
i32 vsync = !!TweakBool("Vsync", 1);
vsync = 1;

View File

@ -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 ), ) \

View File

@ -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<BlaParams>)[0];
// RWTexture2D<Vec4> bla = G_Deref(params.bla_tex, RWTexture2D<Vec4>);
// i64 samples_count = params.bla_samples_count;
// StructuredBuffer<BlaSample> samples = G_Deref(params.bla_samples, StructuredBuffer<BlaSample>);
// 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<V_SharedFrame>)[0];
RWTexture2D<Vec4> graph = G_Deref(frame.profiler_graph, RWTexture2D<Vec4>);

View File

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

View File

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

View File

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

View File

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