mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-07 22:38:41 +00:00
adjust top-level rd_frame structure to allow N cycles (rather than 1) of [rd cmds], [d tick] per frame; fix a few ctrl thread driving issues in dbg engine
This commit is contained in:
@@ -1939,8 +1939,12 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
|
||||
for(CTRL_EntityNode *n = threads.first; n != 0; n = n->next)
|
||||
{
|
||||
CTRL_Entity *thread = n->v;
|
||||
if(thread->is_frozen)
|
||||
{
|
||||
str8_list_push(scratch.arena, &strings, str8_struct(&thread->id));
|
||||
str8_list_push(scratch.arena, &strings, str8_struct(&thread->is_frozen));
|
||||
}
|
||||
}
|
||||
for(U64 idx = 0; idx < breakpoints->count; idx += 1)
|
||||
{
|
||||
D_Breakpoint *bp = &breakpoints->v[idx];
|
||||
|
||||
+77
-62
@@ -9928,6 +9928,11 @@ rd_frame(void)
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: loop - consume events in core, tick engine, and repeat
|
||||
//
|
||||
for(U64 cmd_process_loop_idx = 0; cmd_process_loop_idx < 3; cmd_process_loop_idx += 1)
|
||||
{
|
||||
////////////////////////////
|
||||
//- rjf: unpack eval-dependent info
|
||||
//
|
||||
CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process);
|
||||
@@ -9982,7 +9987,7 @@ rd_frame(void)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
////////////////////////////
|
||||
//- rjf: build eval type context
|
||||
//
|
||||
E_TypeCtx *type_ctx = push_array(scratch.arena, E_TypeCtx, 1);
|
||||
@@ -9996,7 +10001,7 @@ rd_frame(void)
|
||||
}
|
||||
e_select_type_ctx(type_ctx);
|
||||
|
||||
//////////////////////////////
|
||||
////////////////////////////
|
||||
//- rjf: build eval parse context
|
||||
//
|
||||
E_ParseCtx *parse_ctx = push_array(scratch.arena, E_ParseCtx, 1);
|
||||
@@ -10016,7 +10021,7 @@ rd_frame(void)
|
||||
}
|
||||
e_select_parse_ctx(parse_ctx);
|
||||
|
||||
//////////////////////////////
|
||||
////////////////////////////
|
||||
//- rjf: build eval IR context
|
||||
//
|
||||
E_IRCtx *ir_ctx = push_array(scratch.arena, E_IRCtx, 1);
|
||||
@@ -10101,7 +10106,7 @@ rd_frame(void)
|
||||
}
|
||||
e_select_ir_ctx(ir_ctx);
|
||||
|
||||
//////////////////////////////
|
||||
////////////////////////////
|
||||
//- rjf: build eval interpretation context
|
||||
//
|
||||
E_InterpretCtx *interpret_ctx = push_array(scratch.arena, E_InterpretCtx, 1);
|
||||
@@ -10120,7 +10125,7 @@ rd_frame(void)
|
||||
}
|
||||
e_select_interpret_ctx(interpret_ctx);
|
||||
|
||||
//////////////////////////////
|
||||
////////////////////////////
|
||||
//- rjf: build eval visualization view rule table
|
||||
//
|
||||
EV_ViewRuleInfoTable *view_rule_info_table = push_array(scratch.arena, EV_ViewRuleInfoTable, 1);
|
||||
@@ -10129,7 +10134,7 @@ rd_frame(void)
|
||||
}
|
||||
ev_select_view_rule_info_table(view_rule_info_table);
|
||||
|
||||
//////////////////////////////
|
||||
////////////////////////////
|
||||
//- rjf: autosave if needed
|
||||
//
|
||||
{
|
||||
@@ -10142,7 +10147,7 @@ rd_frame(void)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
////////////////////////////
|
||||
//- rjf: process top-level graphical commands
|
||||
//
|
||||
B32 panel_reset_done = 0;
|
||||
@@ -14068,55 +14073,7 @@ rd_frame(void)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: rotate command slots, bump command gen counter
|
||||
//
|
||||
// in this step, we rotate the ring buffer of command batches (command
|
||||
// arenas & lists). when the cmds_gen (the position of the ring buffer)
|
||||
// is even, the command queue is in a "read/write" mode, and this is uniquely
|
||||
// usable by the core - this is done so that commands in the core can push
|
||||
// other commands, and have those other commands processed on the same frame.
|
||||
//
|
||||
// in view code, however, they can only use the current command queue in a
|
||||
// "read only" mode, because new commands pushed by those views must be
|
||||
// processed first by the core. so, before calling into view code, the
|
||||
// cmds_gen is incremented to be *odd*. this way, the views will *write*
|
||||
// commands into the 0 slot, but *read* from the 1 slot (which will contain
|
||||
// this frame's commands).
|
||||
//
|
||||
// after view code runs, the generation number is incremented back to even.
|
||||
// the commands pushed by the view will be in the queue, and the core can
|
||||
// treat that queue as r/w again.
|
||||
//
|
||||
if(depth == 0)
|
||||
{
|
||||
// rjf: rotate
|
||||
{
|
||||
Arena *first_arena = rd_state->cmds_arenas[0];
|
||||
RD_CmdList first_cmds = rd_state->cmds[0];
|
||||
MemoryCopy(rd_state->cmds_arenas,
|
||||
rd_state->cmds_arenas+1,
|
||||
sizeof(rd_state->cmds_arenas[0])*(ArrayCount(rd_state->cmds_arenas)-1));
|
||||
MemoryCopy(rd_state->cmds,
|
||||
rd_state->cmds+1,
|
||||
sizeof(rd_state->cmds[0])*(ArrayCount(rd_state->cmds)-1));
|
||||
rd_state->cmds_arenas[ArrayCount(rd_state->cmds_arenas)-1] = first_arena;
|
||||
rd_state->cmds[ArrayCount(rd_state->cmds_arenas)-1] = first_cmds;
|
||||
}
|
||||
|
||||
// rjf: clear next batch
|
||||
{
|
||||
arena_clear(rd_state->cmds_arenas[0]);
|
||||
MemoryZeroStruct(&rd_state->cmds[0]);
|
||||
}
|
||||
|
||||
// rjf: bump
|
||||
{
|
||||
rd_state->cmds_gen += 1;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
////////////////////////////
|
||||
//- rjf: gather targets
|
||||
//
|
||||
D_TargetArray targets = {0};
|
||||
@@ -14140,7 +14097,7 @@ rd_frame(void)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
////////////////////////////
|
||||
//- rjf: gather breakpoints
|
||||
//
|
||||
D_BreakpointArray breakpoints = {0};
|
||||
@@ -14169,7 +14126,7 @@ rd_frame(void)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
////////////////////////////
|
||||
//- rjf: gather path maps
|
||||
//
|
||||
D_PathMapArray path_maps = {0};
|
||||
@@ -14177,7 +14134,7 @@ rd_frame(void)
|
||||
// TODO(rjf): @msgs
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
////////////////////////////
|
||||
//- rjf: gather exception code filters
|
||||
//
|
||||
U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64] = {0};
|
||||
@@ -14185,12 +14142,13 @@ rd_frame(void)
|
||||
// TODO(rjf): @msgs
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
////////////////////////////
|
||||
//- rjf: tick debug engine
|
||||
//
|
||||
U64 cmd_count_pre_tick = rd_state->cmds[0].count;
|
||||
D_EventList engine_events = d_tick(scratch.arena, &targets, &breakpoints, &path_maps, exception_code_filters);
|
||||
|
||||
//////////////////////////////
|
||||
////////////////////////////
|
||||
//- rjf: no selected thread? -> try to snap to any existing thread
|
||||
//
|
||||
if(ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread) == &ctrl_entity_nil)
|
||||
@@ -14211,7 +14169,7 @@ rd_frame(void)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
////////////////////////////
|
||||
//- rjf: process debug engine events
|
||||
//
|
||||
for(D_EventNode *n = engine_events.first; n != 0; n = n->next)
|
||||
@@ -14281,6 +14239,15 @@ rd_frame(void)
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
//- rjf: early-out if no new commands
|
||||
//
|
||||
if(rd_state->cmds[0].count == cmd_count_pre_tick)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: animate confirmation
|
||||
//
|
||||
@@ -14365,6 +14332,54 @@ rd_frame(void)
|
||||
rd_queue_drag_drop();
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
//- rjf: rotate command slots, bump command gen counter
|
||||
//
|
||||
// in this step, we rotate the ring buffer of command batches (command
|
||||
// arenas & lists). when the cmds_gen (the position of the ring buffer)
|
||||
// is even, the command queue is in a "read/write" mode, and this is uniquely
|
||||
// usable by the core - this is done so that commands in the core can push
|
||||
// other commands, and have those other commands processed on the same frame.
|
||||
//
|
||||
// in view code, however, they can only use the current command queue in a
|
||||
// "read only" mode, because new commands pushed by those views must be
|
||||
// processed first by the core. so, before calling into view code, the
|
||||
// cmds_gen is incremented to be *odd*. this way, the views will *write*
|
||||
// commands into the 0 slot, but *read* from the 1 slot (which will contain
|
||||
// this frame's commands).
|
||||
//
|
||||
// after view code runs, the generation number is incremented back to even.
|
||||
// the commands pushed by the view will be in the queue, and the core can
|
||||
// treat that queue as r/w again.
|
||||
//
|
||||
if(depth == 0)
|
||||
{
|
||||
// rjf: rotate
|
||||
{
|
||||
Arena *first_arena = rd_state->cmds_arenas[0];
|
||||
RD_CmdList first_cmds = rd_state->cmds[0];
|
||||
MemoryCopy(rd_state->cmds_arenas,
|
||||
rd_state->cmds_arenas+1,
|
||||
sizeof(rd_state->cmds_arenas[0])*(ArrayCount(rd_state->cmds_arenas)-1));
|
||||
MemoryCopy(rd_state->cmds,
|
||||
rd_state->cmds+1,
|
||||
sizeof(rd_state->cmds[0])*(ArrayCount(rd_state->cmds)-1));
|
||||
rd_state->cmds_arenas[ArrayCount(rd_state->cmds_arenas)-1] = first_arena;
|
||||
rd_state->cmds[ArrayCount(rd_state->cmds_arenas)-1] = first_cmds;
|
||||
}
|
||||
|
||||
// rjf: clear next batch
|
||||
{
|
||||
arena_clear(rd_state->cmds_arenas[0]);
|
||||
MemoryZeroStruct(&rd_state->cmds[0]);
|
||||
}
|
||||
|
||||
// rjf: bump
|
||||
{
|
||||
rd_state->cmds_gen += 1;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: update/render all windows
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user