ogl_beamforming

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

Commit: afbe09a30c48e46ce2c5f6aac3768234afd5320a
Parent: b320ad663f99c17ad943af888f008a0b43a4c302
Author: Randy Palamar
Date:   Sat, 12 Jul 2025 19:36:13 -0600

core: replace os function table with static definitions

these will be duplicated in debug build (copy in both static and
dynamic portion) but will allow inlining in release build.

Diffstat:
Mbeamformer.c | 29+++++++++++++++++------------
Mbeamformer.h | 9+++++++++
Mbeamformer_work_queue.c | 5++---
Mhelpers/ogl_beamformer_lib.c | 11++++++-----
Mmain_w32.c | 2+-
Mos_linux.c | 4----
Mos_win32.c | 4----
Mui.c | 9++++-----
Mutil.h | 12------------
Mutil_gl.c | 6+++---
10 files changed, 42 insertions(+), 49 deletions(-)

diff --git a/beamformer.c b/beamformer.c @@ -21,6 +21,14 @@ #include "beamformer.h" #include "beamformer_work_queue.c" +#if _DEBUG + #if OS_LINUX + #include "os_linux.c" + #elif OS_WINDOWS + #include "os_win32.c" + #endif +#endif + global f32 dt_for_frame; global u32 cycle_t; @@ -458,7 +466,7 @@ shader_text_with_header(ShaderReloadContext *ctx, OS *os, Arena *arena) s8 result = arena_stream_commit(arena, &sb); if (ctx->path.len) { - s8 file = os->read_whole_file(arena, (c8 *)ctx->path.data); + s8 file = os_read_whole_file(arena, (c8 *)ctx->path.data); assert(file.data == result.data + result.len); result.len += file.len; } @@ -540,9 +548,8 @@ complete_queue(BeamformerCtx *ctx, BeamformWorkQueue *q, Arena arena, iptr gl_co }break; case BeamformerWorkKind_ExportBuffer:{ /* TODO(rnp): better way of handling DispatchCompute barrier */ - post_sync_barrier(&ctx->shared_memory, BeamformerSharedMemoryLockKind_DispatchCompute, - sm->locks, ctx->os.shared_memory_region_unlock); - ctx->os.shared_memory_region_lock(&ctx->shared_memory, sm->locks, (i32)work->lock, (u32)-1); + post_sync_barrier(&ctx->shared_memory, BeamformerSharedMemoryLockKind_DispatchCompute, sm->locks); + os_shared_memory_region_lock(&ctx->shared_memory, sm->locks, (i32)work->lock, (u32)-1); BeamformerExportContext *ec = &work->export_context; switch (ec->kind) { case BeamformerExportKind_BeamformedData:{ @@ -566,12 +573,11 @@ complete_queue(BeamformerCtx *ctx, BeamformWorkQueue *q, Arena arena, iptr gl_co }break; InvalidDefaultCase; } - ctx->os.shared_memory_region_unlock(&ctx->shared_memory, sm->locks, (i32)work->lock); - post_sync_barrier(&ctx->shared_memory, BeamformerSharedMemoryLockKind_ExportSync, sm->locks, - ctx->os.shared_memory_region_unlock); + os_shared_memory_region_unlock(&ctx->shared_memory, sm->locks, (i32)work->lock); + post_sync_barrier(&ctx->shared_memory, BeamformerSharedMemoryLockKind_ExportSync, sm->locks); }break; case BeamformerWorkKind_UploadBuffer:{ - ctx->os.shared_memory_region_lock(&ctx->shared_memory, sm->locks, (i32)work->lock, (u32)-1); + os_shared_memory_region_lock(&ctx->shared_memory, sm->locks, (i32)work->lock, (u32)-1); BeamformerUploadContext *uc = &work->upload_context; u32 tex_type, tex_format, tex_1d = 0, buffer = 0; i32 tex_element_count; @@ -628,15 +634,14 @@ complete_queue(BeamformerCtx *ctx, BeamformWorkQueue *q, Arena arena, iptr gl_co } atomic_and_u32(&sm->dirty_regions, ~(sm->dirty_regions & 1 << (work->lock - 1))); - ctx->os.shared_memory_region_unlock(&ctx->shared_memory, sm->locks, (i32)work->lock); + os_shared_memory_region_unlock(&ctx->shared_memory, sm->locks, (i32)work->lock); }break; case BeamformerWorkKind_ComputeIndirect:{ fill_frame_compute_work(ctx, work, work->compute_indirect_plane); DEBUG_DECL(work->kind = BeamformerWorkKind_ComputeIndirect;) } /* FALLTHROUGH */ case BeamformerWorkKind_Compute:{ - post_sync_barrier(&ctx->shared_memory, work->lock, sm->locks, - ctx->os.shared_memory_region_unlock); + post_sync_barrier(&ctx->shared_memory, work->lock, sm->locks); push_compute_timing_info(ctx->compute_timing_table, (ComputeTimingInfo){.kind = ComputeTimingInfoKind_ComputeFrameBegin}); @@ -842,7 +847,7 @@ DEBUG_EXPORT BEAMFORMER_FRAME_STEP_FN(beamformer_frame_step) beamform_work_queue_push_commit(ctx->beamform_work_queue); atomic_store_u32(&sm->start_compute_from_main, 0); } - ctx->os.wake_waiters(&ctx->os.compute_worker.sync_variable); + os_wake_waiters(&ctx->os.compute_worker.sync_variable); } draw_ui(ctx, input, ctx->latest_frame->ready_to_present ? &ctx->latest_frame->frame : 0, diff --git a/beamformer.h b/beamformer.h @@ -6,6 +6,15 @@ #include <rlgl.h> #include "util.h" + +/////////////////// +// REQUIRED OS API +function OS_READ_WHOLE_FILE_FN(os_read_whole_file); +function OS_SHARED_MEMORY_LOCK_REGION_FN(os_shared_memory_region_lock); +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); + #include "opengl.h" #include "util_gl.c" diff --git a/beamformer_work_queue.c b/beamformer_work_queue.c @@ -52,12 +52,11 @@ DEBUG_EXPORT BEAMFORM_WORK_QUEUE_PUSH_COMMIT_FN(beamform_work_queue_push_commit) } function void -post_sync_barrier(SharedMemoryRegion *sm, BeamformerSharedMemoryLockKind lock, i32 *locks, - os_shared_memory_region_unlock_fn *shared_memory_region_unlock) +post_sync_barrier(SharedMemoryRegion *sm, BeamformerSharedMemoryLockKind lock, i32 *locks) { /* NOTE(rnp): debug: here it is not a bug to release the lock if it * isn't held but elswhere it is */ DEBUG_DECL(if (locks[lock])) { - shared_memory_region_unlock(sm, locks, (i32)lock); + os_shared_memory_region_unlock(sm, locks, (i32)lock); } } diff --git a/helpers/ogl_beamformer_lib.c b/helpers/ogl_beamformer_lib.c @@ -4,11 +4,6 @@ #include "../util.h" #include "../beamformer_parameters.h" #include "ogl_beamformer_lib_base.h" -#include "../beamformer_work_queue.c" - -global SharedMemoryRegion g_shared_memory; -global BeamformerSharedMemory *g_bp; -global BeamformerLibErrorKind g_lib_last_error; #if OS_LINUX #include "../os_linux.c" @@ -21,6 +16,12 @@ W32(iptr) OpenFileMappingA(u32, b32, c8 *); #error Unsupported Platform #endif +#include "../beamformer_work_queue.c" + +global SharedMemoryRegion g_shared_memory; +global BeamformerSharedMemory *g_bp; +global BeamformerLibErrorKind g_lib_last_error; + #if OS_LINUX function SharedMemoryRegion diff --git a/main_w32.c b/main_w32.c @@ -48,7 +48,7 @@ dispatch_file_watch(OS *os, FileWatchDirectory *fw_dir, u8 *buf, Arena arena) stream_append_s8(&path, s8("unknown file watch event: ")); stream_append_u64(&path, fni->action); stream_append_byte(&path, '\n'); - os->write_file(os->error_handle, stream_to_s8(&path)); + os_write_file(os->error_handle, stream_to_s8(&path)); stream_reset(&path, 0); } diff --git a/os_linux.c b/os_linux.c @@ -299,10 +299,6 @@ function OS_SHARED_MEMORY_UNLOCK_REGION_FN(os_shared_memory_region_unlock) function void os_init(OS *os, Arena *program_memory) { - #define X(name) os->name = os_ ## name; - OS_FNS - #undef X - os->file_watch_context.handle = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); os->error_handle = STDERR_FILENO; } diff --git a/os_win32.c b/os_win32.c @@ -407,10 +407,6 @@ function OS_SHARED_MEMORY_UNLOCK_REGION_FN(os_shared_memory_region_unlock) function void os_init(OS *os, Arena *program_memory) { - #define X(name) os->name = os_ ## name; - OS_FNS - #undef X - w32_context *ctx = push_struct(program_memory, typeof(*ctx)); ctx->io_completion_handle = CreateIoCompletionPort(INVALID_FILE, 0, 0, 0); ctx->timer_frequency = os_get_timer_frequency(); diff --git a/ui.c b/ui.c @@ -3849,15 +3849,14 @@ draw_ui(BeamformerCtx *ctx, BeamformerInput *input, BeamformerFrame *frame_to_dr if (ui->flush_params) { i32 lock = BeamformerSharedMemoryLockKind_Parameters; validate_ui_parameters(&ui->params); - if (ctx->os.shared_memory_region_lock(&ctx->shared_memory, sm->locks, lock, 0)) { + if (os_shared_memory_region_lock(&ctx->shared_memory, sm->locks, lock, 0)) { mem_copy(&sm->parameters_ui, &ui->params, sizeof(ui->params)); ui->flush_params = 0; atomic_or_u32(&sm->dirty_regions, (1 << (lock - 1))); - b32 dispatch = ctx->os.shared_memory_region_lock(&ctx->shared_memory, sm->locks, - BeamformerSharedMemoryLockKind_DispatchCompute, - 0); + b32 dispatch = os_shared_memory_region_lock(&ctx->shared_memory, sm->locks, + BeamformerSharedMemoryLockKind_DispatchCompute, 0); sm->start_compute_from_main |= dispatch & ctx->latest_frame->ready_to_present; - ctx->os.shared_memory_region_unlock(&ctx->shared_memory, sm->locks, lock); + os_shared_memory_region_unlock(&ctx->shared_memory, sm->locks, lock); } } diff --git a/util.h b/util.h @@ -326,15 +326,6 @@ typedef OS_SHARED_MEMORY_LOCK_REGION_FN(os_shared_memory_region_lock_fn); #define OS_SHARED_MEMORY_UNLOCK_REGION_FN(name) void name(SharedMemoryRegion *sm, i32 *locks, i32 lock_index) typedef OS_SHARED_MEMORY_UNLOCK_REGION_FN(os_shared_memory_region_unlock_fn); -#define OS_FNS \ - X(add_file_watch) \ - X(read_whole_file) \ - X(shared_memory_region_lock) \ - X(shared_memory_region_unlock) \ - X(wake_waiters) \ - X(write_new_file) \ - X(write_file) - #define RENDERDOC_GET_API_FN(name) b32 name(u32 version, void **out_api) typedef RENDERDOC_GET_API_FN(renderdoc_get_api_fn); @@ -350,9 +341,6 @@ typedef align_as(16) u8 RenderDocAPI[216]; #define RENDERDOC_END_FRAME_CAPTURE(a) (renderdoc_end_frame_capture_fn *) RENDERDOC_API_FN_ADDR(a, 168) struct OS { -#define X(name) os_ ## name ## _fn *name; - OS_FNS -#undef X FileWatchContext file_watch_context; iptr context; iptr error_handle; diff --git a/util_gl.c b/util_gl.c @@ -18,7 +18,7 @@ compile_shader(OS *os, Arena a, u32 type, s8 shader, s8 name) glGetShaderInfoLog(sid, len, &out_len, (char *)(buf.data + buf.widx)); stream_commit(&buf, out_len); glDeleteShader(sid); - os->write_file(os->error_handle, stream_to_s8(&buf)); + os_write_file(os->error_handle, stream_to_s8(&buf)); sid = 0; } @@ -42,7 +42,7 @@ link_program(OS *os, Arena a, u32 *shader_ids, i32 shader_id_count) glGetProgramInfoLog(result, buf.cap - buf.widx, &len, (c8 *)(buf.data + buf.widx)); stream_reset(&buf, len); stream_append_byte(&buf, '\n'); - os->write_file(os->error_handle, stream_to_s8(&buf)); + os_write_file(os->error_handle, stream_to_s8(&buf)); glDeleteProgram(result); result = 0; } @@ -66,7 +66,7 @@ load_shader(OS *os, Arena arena, s8 *shader_texts, u32 *shader_types, i32 count, if (result) { Stream buf = arena_stream(arena); stream_append_s8s(&buf, s8("loaded: "), name, s8("\n")); - os->write_file(os->error_handle, stream_to_s8(&buf)); + os_write_file(os->error_handle, stream_to_s8(&buf)); LABEL_GL_OBJECT(GL_PROGRAM, result, name); }