debug.h (4458B)
1 /* See LICENSE for copyright details */ 2 3 #define MAX_DEBUG_EVENT_COUNT (16 * 65536) 4 /* TODO: this is way too high and it only seems to be necessary when resizing */ 5 #define MAX_DEBUG_REGION_COUNT 16 * 1024 6 #define MAX_DEBUG_META_COUNT 4096 7 #define MAX_DEBUG_RECORD_COUNT 32 8 9 typedef __attribute__((aligned(16))) struct { 10 u64 clock; 11 u16 metadata_index; 12 u16 type; 13 union { 14 /* TODO: store core + thread id if we make this multithreaded */ 15 struct { u16 core_id, thread_id; }; 16 f32 wall_clock_time; 17 }; 18 } DebugEvent; 19 20 typedef struct { 21 char *file_name; 22 char *block_name; 23 u32 line_number; 24 } DebugMetadata; 25 26 typedef struct { 27 f32 min_t; 28 f32 max_t; 29 DebugMetadata *meta; 30 u16 colour_index; 31 } DebugRegion; 32 33 typedef struct OpenDebugBlock { 34 DebugEvent *opening_event; 35 DebugMetadata *source; 36 struct OpenDebugBlock *parent; 37 struct OpenDebugBlock *next_free; 38 u32 starting_record_index; 39 } OpenDebugBlock; 40 41 typedef struct { 42 u64 start_clock; 43 u64 end_clock; 44 DebugRegion *regions; 45 u32 region_count; 46 f32 wall_time; 47 OpenDebugBlock *first_block; 48 } DebugRecord; 49 50 typedef struct { 51 Arena memory; 52 TempArena temp_memory; 53 b32 initialized; 54 b32 paused; 55 56 f32 bar_thickness; 57 f32 record_bar_scale; 58 f32 frame_target_time; 59 f32 cpu_target_time; 60 f32 gpu_target_time; 61 u32 frame_draw_count; 62 63 DebugMetadata *selected_metadata; 64 65 u32 record_count; 66 u32 record_working_index; 67 DebugRecord *records; 68 DebugRecord *open_record; 69 70 OpenDebugBlock *first_free_block; 71 } DebugState; 72 73 #define INVALID_CODE_PATH ASSERT(0) 74 75 #ifndef _DEBUG 76 77 #define FRAME_MARK(...) 78 79 #define BEGIN_TIMED_BLOCK(...) 80 #define END_TIMED_BLOCK(...) 81 82 #define BEGIN_NAMED_BLOCK(...) 83 #define END_NAMED_BLOCK(...) 84 85 #define debug_frame_end(...) 86 #define draw_debug_overlay(...) 87 88 #else 89 90 enum debug_event_types { 91 DE_INVALID, 92 DE_FRAME_MARK, 93 DE_BEGIN, 94 DE_END, 95 }; 96 97 typedef struct { 98 DebugEvent events[MAX_DEBUG_RECORD_COUNT][MAX_DEBUG_EVENT_COUNT]; 99 u32 events_count[MAX_DEBUG_RECORD_COUNT]; 100 u64 event_array_event_index; 101 DebugMetadata metadata[MAX_DEBUG_META_COUNT]; 102 u32 metadata_count; 103 u32 snapshot_index; 104 } DebugTable; 105 static DebugTable g_debug_table; 106 107 #define RECORD_DEBUG_EVENT_COMMON(counter, event_type) \ 108 u64 event_index = atomic_fetch_add(&g_debug_table.event_array_event_index, 1); \ 109 ASSERT((event_index & 0xFFFFFFFF) < MAX_DEBUG_EVENT_COUNT); \ 110 DebugEvent *event = g_debug_table.events[event_index >> 32] + (event_index & 0xFFFFFFFF); \ 111 event->clock = __rdtsc(); \ 112 event->metadata_index = counter; \ 113 event->type = event_type 114 115 #define RECORD_DEBUG_EVENT(counter, event_type) \ 116 { \ 117 RECORD_DEBUG_EVENT_COMMON(counter, event_type); \ 118 } 119 120 #define FRAME_MARK(wall_seconds_elapsed) \ 121 { \ 122 RECORD_DEBUG_EVENT_COMMON(__COUNTER__, DE_FRAME_MARK); \ 123 event->wall_clock_time = wall_seconds_elapsed; \ 124 } 125 126 #define RECORD_DEBUG_META_COMMON(counter, blockname) \ 127 { \ 128 DebugMetadata *meta = g_debug_table.metadata + counter; \ 129 meta->file_name = __FILE__; \ 130 meta->block_name = (char *)blockname; \ 131 meta->line_number = __LINE__; \ 132 RECORD_DEBUG_EVENT(counter, DE_BEGIN); \ 133 } 134 135 #define BEGIN_TIMED_BLOCK(...) \ 136 u16 __counter = __COUNTER__; \ 137 RECORD_DEBUG_META_COMMON(__counter, __FUNCTION__) 138 #define END_TIMED_BLOCK(...) RECORD_DEBUG_EVENT(__counter, DE_END); 139 140 #define BEGIN_NAMED_BLOCK(name) \ 141 u16 __counter_##name = __COUNTER__; \ 142 RECORD_DEBUG_META_COMMON(__counter_##name, #name) 143 #define END_NAMED_BLOCK(name) RECORD_DEBUG_EVENT(__counter_##name, DE_END) 144 145 static void dump_lines_to_file(Term *t); 146 static void draw_debug_overlay(TerminalMemory *term_memory, TerminalInput *input, RenderCtx *rc); 147 static void debug_frame_end(TerminalMemory *memory, TerminalInput *input); 148 149 #endif