ogl_beamforming

Ultrasound Beamforming Implemented with OpenGL
git clone anongit@rnpnr.xyz:ogl_beamforming.git
Log | Files | Refs | Feed | Submodules | README | LICENSE

Commit: cca918133a1f5442b1547904c892623fe75eaf66
Parent: 2a909e8c80e322344dc36fa682cb8a6dc4d99de5
Author: Randy Palamar
Date:   Wed,  7 Jan 2026 22:03:47 -0700

beamformer.h: use standard c types for BeamformerInput

Diffstat:
Mbeamformer.c | 3++-
Mbeamformer.h | 28+++++++++++++++++++++-------
Mbeamformer_internal.h | 5+----
Mmain_linux.c | 18+++++++++++-------
Mmain_w32.c | 18+++++++++++-------
Mstatic.c | 4++--
Mui.c | 35+++++++++++++++++++----------------
Mutil.c | 21++++++++++++++++++---
8 files changed, 85 insertions(+), 47 deletions(-)

diff --git a/beamformer.c b/beamformer.c @@ -1474,7 +1474,8 @@ DEBUG_EXPORT BEAMFORMER_RF_UPLOAD_FN(beamformer_rf_upload) DEBUG_EXPORT BEAMFORMER_FRAME_STEP_FN(beamformer_frame_step) { BeamformerCtx *ctx = BeamformerContextMemory(input->memory); - dt_for_frame = input->dt; + + dt_for_frame = (f64)(input->timer_ticks) / input->timer_frequency; if (IsWindowResized()) { ctx->window_size.h = GetScreenHeight(); diff --git a/beamformer.h b/beamformer.h @@ -2,6 +2,10 @@ #ifndef BEAMFORMER_H #define BEAMFORMER_H +#include <stdint.h> + +#define BEAMFORMER_NAME_STRING "OGL Beamformer" + /////////////////// // REQUIRED OS API function void os_barrier_wait(Barrier); @@ -13,17 +17,27 @@ function OS_SHARED_MEMORY_UNLOCK_REGION_FN(os_shared_memory_region_unlock); function OS_WAKE_WAITERS_FN(os_wake_waiters); function OS_WRITE_FILE_FN(os_write_file); -#define BEAMFORMER_NAME_STRING "OGL Beamformer" - typedef struct { - Arena memory; - f64 dt; - v2 mouse; - v2 last_mouse; - b32 executable_reloaded; + void * memory; + uint64_t memory_size; + + uint64_t timer_ticks; + uint64_t timer_frequency; + + float mouse_x; + float mouse_y; + float last_mouse_x; + float last_mouse_y; + + uint32_t executable_reloaded; } BeamformerInput; #define BEAMFORMER_FRAME_STEP_FN(name) void name(BeamformerInput *input) typedef BEAMFORMER_FRAME_STEP_FN(beamformer_frame_step_fn); +#define BEAMFORMER_DEBUG_UI_DEINIT_FN(name) void name(void *memory) +typedef BEAMFORMER_DEBUG_UI_DEINIT_FN(beamformer_debug_ui_deinit_fn); + +function void beamformer_invalidate_shared_memory(void *memory); + #endif /*BEAMFORMER_H */ diff --git a/beamformer_internal.h b/beamformer_internal.h @@ -316,7 +316,7 @@ typedef struct { DEBUG_DECL(renderdoc_start_frame_capture_fn *start_frame_capture;) DEBUG_DECL(renderdoc_end_frame_capture_fn *end_frame_capture;) } BeamformerCtx; -#define BeamformerContextMemory(a) (BeamformerCtx *)arena_aligned_start(a, alignof(BeamformerCtx)) +#define BeamformerContextMemory(m) (BeamformerCtx *)align_pointer_up((m), alignof(BeamformerCtx)); typedef struct ShaderReloadContext ShaderReloadContext; struct ShaderReloadContext { @@ -337,7 +337,4 @@ typedef BEAMFORMER_RF_UPLOAD_FN(beamformer_rf_upload_fn); Arena arena, s8 shader_name) typedef BEAMFORMER_RELOAD_SHADER_FN(beamformer_reload_shader_fn); -#define BEAMFORMER_DEBUG_UI_DEINIT_FN(name) void name(Arena memory) -typedef BEAMFORMER_DEBUG_UI_DEINIT_FN(beamformer_debug_ui_deinit_fn); - #endif /* BEAMFORMER_INTERNAL_H */ diff --git a/main_linux.c b/main_linux.c @@ -83,7 +83,9 @@ main(void) BeamformerInput *input = push_struct(&program_memory, BeamformerInput); - input->memory = program_memory; + input->memory = program_memory.beg; + input->memory_size = program_memory.end - program_memory.beg; + input->timer_frequency = os_get_timer_frequency(); input->executable_reloaded = 1; beamformer_init(input); @@ -99,18 +101,20 @@ main(void) Vector2 new_mouse = GetMousePosition(); u64 now = os_get_timer_counter(); - input->last_mouse = input->mouse; - input->mouse = (v2){{new_mouse.x, new_mouse.y}}; - input->dt = (f64)(now - last_time) / (f64)os_get_timer_frequency(); - last_time = now; + input->last_mouse_x = input->mouse_x; + input->last_mouse_y = input->mouse_y; + input->mouse_x = new_mouse.x; + input->mouse_y = new_mouse.y; + input->timer_ticks = now - last_time; + last_time = now; beamformer_frame_step(input); input->executable_reloaded = 0; } - beamformer_invalidate_shared_memory(program_memory); - beamformer_debug_ui_deinit(program_memory); + beamformer_invalidate_shared_memory(program_memory.beg); + beamformer_debug_ui_deinit(program_memory.beg); /* NOTE: make sure this will get cleaned up after external * programs release their references */ diff --git a/main_w32.c b/main_w32.c @@ -122,7 +122,9 @@ main(void) os_w32_context.io_completion_handle = CreateIoCompletionPort(INVALID_FILE, 0, 0, 0); BeamformerInput *input = push_struct(&program_memory, BeamformerInput); - input->memory = program_memory; + input->memory = program_memory.beg; + input->memory_size = program_memory.end - program_memory.beg; + input->timer_frequency = os_w32_context.timer_frequency; input->executable_reloaded = 1; beamformer_init(input); @@ -136,16 +138,18 @@ main(void) Vector2 new_mouse = GetMousePosition(); u64 now = os_get_timer_counter(); - input->last_mouse = input->mouse; - input->mouse = (v2){{new_mouse.x, new_mouse.y}}; - input->dt = (f64)(now - last_time) / (f64)os_w32_context.timer_frequency; - last_time = now; + input->last_mouse_x = input->mouse_x; + input->last_mouse_y = input->mouse_y; + input->mouse_x = new_mouse.x; + input->mouse_y = new_mouse.y; + input->timer_ticks = now - last_time; + last_time = now; beamformer_frame_step(input); input->executable_reloaded = 0; } - beamformer_invalidate_shared_memory(program_memory); - beamformer_debug_ui_deinit(program_memory); + beamformer_invalidate_shared_memory(program_memory.beg); + beamformer_debug_ui_deinit(program_memory.beg); } diff --git a/static.c b/static.c @@ -333,7 +333,7 @@ function OS_THREAD_ENTRY_POINT_FN(beamformer_upload_entry_point) function void beamformer_init(BeamformerInput *input) { - Arena memory = input->memory; + Arena memory = arena_from_memory(input->memory, input->memory_size); Arena compute_arena = sub_arena_end(&memory, MB(2), KB(4)); Arena upload_arena = sub_arena_end(&memory, KB(4), KB(4)); Arena ui_arena = sub_arena_end(&memory, MB(2), KB(4)); @@ -582,7 +582,7 @@ beamformer_init(BeamformerInput *input) } function void -beamformer_invalidate_shared_memory(Arena memory) +beamformer_invalidate_shared_memory(void *memory) { /* NOTE(rnp): work around pebkac when the beamformer is closed while we are doing live * imaging. if the verasonics is blocked in an external function (calling the library diff --git a/ui.c b/ui.c @@ -3542,7 +3542,7 @@ ui_button_interaction(BeamformerUI *ui, Variable *button) } function void -ui_begin_interact(BeamformerUI *ui, BeamformerInput *input, b32 scroll) +ui_begin_interact(BeamformerUI *ui, v2 mouse, b32 scroll) { Interaction hot = ui->hot_interaction; if (hot.kind != InteractionKind_None) { @@ -3560,7 +3560,7 @@ ui_begin_interact(BeamformerUI *ui, BeamformerInput *input, b32 scroll) hot.kind = InteractionKind_Drag; } else { hot.kind = InteractionKind_Text; - begin_text_input(&ui->text_input_state, hot.rect, hot.var, input->mouse); + begin_text_input(&ui->text_input_state, hot.rect, hot.var, mouse); } ui_widget_bring_to_front(&ui->floating_widget_sentinal, hot.var); }break; @@ -3597,7 +3597,7 @@ ui_begin_interact(BeamformerUI *ui, BeamformerInput *input, b32 scroll) case RulerState_Start:{ hot.kind = InteractionKind_Ruler; v2 r_max = v2_add(hot.rect.pos, hot.rect.size); - v2 p = screen_point_to_world_2d(input->mouse, hot.rect.pos, r_max, + v2 p = screen_point_to_world_2d(mouse, hot.rect.pos, r_max, XZ(bv->min_coordinate), XZ(bv->max_coordinate)); bv->ruler.start = p; @@ -3625,7 +3625,7 @@ ui_begin_interact(BeamformerUI *ui, BeamformerInput *input, b32 scroll) Variable *w = add_floating_view(ui, &ui->arena, VT_UI_TEXT_BOX, hot.rect.pos, hot.var, 0); w->view.rect = hot.rect; - begin_text_input(&ui->text_input_state, hot.rect, w, input->mouse); + begin_text_input(&ui->text_input_state, hot.rect, w, mouse); } else { hot.kind = InteractionKind_Drag; } @@ -3646,7 +3646,7 @@ ui_begin_interact(BeamformerUI *ui, BeamformerInput *input, b32 scroll) HideCursor(); DisableCursor(); /* wtf raylib */ - SetMousePosition((i32)input->mouse.x, (i32)input->mouse.y); + SetMousePosition((i32)mouse.x, (i32)mouse.y); } } else { ui->interaction.kind = InteractionKind_Nop; @@ -3813,6 +3813,8 @@ ui_sticky_interaction_check_end(BeamformerUI *ui, v2 mouse) function void ui_interact(BeamformerUI *ui, BeamformerInput *input, Rect window_rect) { + v2 input_mouse = {{input->mouse_x, input->mouse_y}}; + v2 last_mouse = {{input->last_mouse_x, input->last_mouse_y}}; Interaction *it = &ui->interaction; if (it->kind == InteractionKind_None || interaction_is_sticky(*it)) { ui->hot_interaction = ui->next_interaction; @@ -3822,8 +3824,8 @@ ui_interact(BeamformerUI *ui, BeamformerInput *input, Rect window_rect) b32 wheel_moved = GetMouseWheelMoveV().y != 0; if (mouse_right_pressed || mouse_left_pressed || wheel_moved) { if (it->kind != InteractionKind_None) - ui_sticky_interaction_check_end(ui, input->mouse); - ui_begin_interact(ui, input, wheel_moved); + ui_sticky_interaction_check_end(ui, input_mouse); + ui_begin_interact(ui, input_mouse, wheel_moved); } } @@ -3832,34 +3834,34 @@ ui_interact(BeamformerUI *ui, BeamformerInput *input, Rect window_rect) case InteractionKind_None:{}break; case InteractionKind_Text:{ if (update_text_input(&ui->text_input_state, it->var)) - ui_end_interact(ui, input->mouse); + ui_end_interact(ui, input_mouse); }break; case InteractionKind_Ruler:{ assert(it->var->type == VT_BEAMFORMER_FRAME_VIEW); BeamformerFrameView *bv = it->var->generic; v2 r_max = v2_add(it->rect.pos, it->rect.size); - v2 mouse = clamp_v2_rect(input->mouse, it->rect); + v2 mouse = clamp_v2_rect(input_mouse, it->rect); bv->ruler.end = screen_point_to_world_2d(mouse, it->rect.pos, r_max, XZ(bv->min_coordinate), XZ(bv->max_coordinate)); }break; case InteractionKind_Drag:{ if (!IsMouseButtonDown(MOUSE_BUTTON_LEFT) && !IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) { - ui_end_interact(ui, input->mouse); + ui_end_interact(ui, input_mouse); } else { v2 ws = window_rect.size; - v2 dMouse = v2_sub(input->mouse, input->last_mouse); + v2 dMouse = v2_sub(input_mouse, last_mouse); switch (it->var->type) { case VT_BEAMFORMER_VARIABLE:{ BeamformerVariable *bv = &it->var->beamformer_variable; /* TODO(rnp): vertical sliders? */ - f32 mouse_frac = CLAMP01((input->mouse.x - it->rect.pos.x) / it->rect.size.w); + f32 mouse_frac = CLAMP01((input_mouse.x - it->rect.pos.x) / it->rect.size.w); *bv->store = bv->limits.x + mouse_frac * (bv->limits.y - bv->limits.x); }break; case VT_X_PLANE_SHIFT:{ assert(it->var->parent && it->var->parent->type == VT_BEAMFORMER_FRAME_VIEW); - v2 mouse = clamp_v2_rect(input->mouse, it->rect); + v2 mouse = clamp_v2_rect(input_mouse, it->rect); XPlaneShift *xp = &it->var->x_plane_shift; ray mouse_ray = ray_for_x_plane_view(ui, it->var->parent->generic, normalized_p_in_rect(it->rect, mouse, 0)); @@ -3906,7 +3908,7 @@ ui_interact(BeamformerUI *ui, BeamformerInput *input, Rect window_rect) ui_live_control_update(ui, it->var->parent); } } break; - default:{ ui_end_interact(ui, input->mouse); }break; + default:{ ui_end_interact(ui, input_mouse); }break; } ui->next_interaction = (Interaction){.kind = InteractionKind_None}; @@ -4037,10 +4039,11 @@ draw_ui(BeamformerCtx *ctx, BeamformerInput *input, BeamformerFrame *frame_to_dr update_frame_views(ui, window_rect); BeginDrawing(); + v2 mouse = {{input->mouse_x, input->mouse_y}}; glClearNamedFramebufferfv(0, GL_COLOR, 0, BG_COLOUR.E); glClearNamedFramebufferfv(0, GL_DEPTH, 0, (f32 []){1}); - draw_ui_regions(ui, window_rect, input->mouse); - draw_floating_widgets(ui, window_rect, input->mouse); + draw_ui_regions(ui, window_rect, mouse); + draw_floating_widgets(ui, window_rect, mouse); EndDrawing(); } diff --git a/util.c b/util.c @@ -85,14 +85,29 @@ memory_scan_backwards(void *memory, u8 byte, iz n) return result; } +function Arena +arena_from_memory(void *memory, u64 size) +{ + Arena result; + result.beg = memory; + result.end = result.beg + size; + return result; +} + function void * -arena_aligned_start(Arena a, uz alignment) +align_pointer_up(void *p, uz alignment) { - uz padding = -(uintptr_t)a.beg & (alignment - 1); - u8 *result = a.beg + padding; + uz padding = -(uintptr_t)p & (alignment - 1); + void *result = (u8 *)p + padding; return result; } +function void * +arena_aligned_start(Arena a, uz alignment) +{ + return align_pointer_up(a.beg, alignment); +} + #define arena_capacity(a, t) arena_capacity_(a, sizeof(t), alignof(t)) function iz arena_capacity_(Arena *a, iz size, uz alignment)