ogl_beamforming

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

Commit: cc356b1a9dde0a0f1d5891e734643e93c031716e
Parent: 69079ef7e42114041cc58ac2ee02836ed95230a5
Author: Randy Palamar
Date:   Tue, 13 May 2025 21:13:19 -0600

cleanup remaining usage of static keyword

static is overloaded and means different things in different
contexts. use proper names for each meaning. this is also easier
to search for variables that may cause problems if a function is
called from multiple threads.

Diffstat:
Mbeamformer.c | 24++++++++++++------------
Mbeamformer_work_queue.c | 6+++---
Mintrinsics.c | 6+++---
Mmain_w32.c | 2+-
Mos_linux.c | 24++++++++++++------------
Mos_win32.c | 116++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mstatic.c | 20++++++++++----------
Mui.c | 66++++++++++++++++++++++++++++++++----------------------------------
Mutil.c | 132+++++++++++++++++++++++++++++++++++++++----------------------------------------
Mutil.h | 2+-
10 files changed, 197 insertions(+), 201 deletions(-)

diff --git a/beamformer.c b/beamformer.c @@ -21,8 +21,8 @@ global u32 cycle_t; #define start_renderdoc_capture(...) #define end_renderdoc_capture(...) #else -static renderdoc_start_frame_capture_fn *start_frame_capture; -static renderdoc_end_frame_capture_fn *end_frame_capture; +global renderdoc_start_frame_capture_fn *start_frame_capture; +global renderdoc_end_frame_capture_fn *end_frame_capture; #define start_renderdoc_capture(gl) if (start_frame_capture) start_frame_capture(gl, 0) #define end_renderdoc_capture(gl) if (end_frame_capture) end_frame_capture(gl, 0) #endif @@ -59,7 +59,7 @@ compute_frame_iterator(BeamformerCtx *ctx, u32 start_index, u32 needed_frames) return result; } -static BeamformComputeFrame * +function BeamformComputeFrame * frame_next(ComputeFrameIterator *bfi) { BeamformComputeFrame *result = 0; @@ -70,7 +70,7 @@ frame_next(ComputeFrameIterator *bfi) return result; } -static void +function void alloc_beamform_frame(GLParams *gp, BeamformFrame *out, ComputeShaderStats *out_stats, uv3 out_dim, s8 name, Arena arena) { @@ -170,7 +170,7 @@ fill_frame_compute_work(BeamformerCtx *ctx, BeamformWork *work, ImagePlaneTag pl return result; } -static void +function void export_frame(BeamformerCtx *ctx, iptr handle, BeamformFrame *frame) { uv3 dim = frame->dim; @@ -183,7 +183,7 @@ export_frame(BeamformerCtx *ctx, iptr handle, BeamformFrame *frame) ctx->os.close(handle); } -static void +function void do_sum_shader(ComputeShaderCtx *cs, u32 *in_textures, u32 in_texture_count, f32 in_scale, u32 out_texture, uv3 out_data_dim) { @@ -211,7 +211,7 @@ struct compute_cursor { u32 total_points; }; -static struct compute_cursor +function struct compute_cursor start_compute_cursor(uv3 dim, u32 max_points) { struct compute_cursor result = {0}; @@ -238,7 +238,7 @@ start_compute_cursor(uv3 dim, u32 max_points) return result; } -static iv3 +function iv3 step_compute_cursor(struct compute_cursor *cursor) { cursor->cursor.x += 1; @@ -261,14 +261,14 @@ step_compute_cursor(struct compute_cursor *cursor) return result; } -static b32 +function b32 compute_cursor_finished(struct compute_cursor *cursor) { b32 result = cursor->completed_points >= cursor->total_points; return result; } -static void +function void do_compute_shader(BeamformerCtx *ctx, Arena arena, BeamformComputeFrame *frame, ComputeShaderID shader) { ComputeShaderCtx *csctx = &ctx->csctx; @@ -442,7 +442,7 @@ push_compute_shader_header(Arena *a, b32 parameters, ComputeShaderID shader) return arena_stream_commit(a, &sb); } -static b32 +function b32 reload_compute_shader(BeamformerCtx *ctx, s8 path, s8 extra, ComputeShaderReloadContext *csr, Arena tmp) { ComputeShaderCtx *cs = &ctx->csctx; @@ -475,7 +475,7 @@ reload_compute_shader(BeamformerCtx *ctx, s8 path, s8 extra, ComputeShaderReload return result; } -static void +function void complete_queue(BeamformerCtx *ctx, BeamformWorkQueue *q, Arena arena, iptr gl_context, iz barrier_offset) { ComputeShaderCtx *cs = &ctx->csctx; diff --git a/beamformer_work_queue.c b/beamformer_work_queue.c @@ -1,7 +1,7 @@ /* See LICENSE for license details. */ #include "beamformer_work_queue.h" -static BeamformWork * +function BeamformWork * beamform_work_queue_pop(BeamformWorkQueue *q) { BeamformWork *result = 0; @@ -18,7 +18,7 @@ beamform_work_queue_pop(BeamformWorkQueue *q) return result; } -static void +function void beamform_work_queue_pop_commit(BeamformWorkQueue *q) { atomic_add(&q->queue, 0x100000000ULL); @@ -51,7 +51,7 @@ DEBUG_EXPORT BEAMFORM_WORK_QUEUE_PUSH_COMMIT_FN(beamform_work_queue_push_commit) atomic_add(&q->queue, 1); } -static b32 +function b32 try_wait_sync(i32 *sync, i32 timeout_ms, os_wait_on_value_fn *os_wait_on_value) { b32 result = 0; diff --git a/intrinsics.c b/intrinsics.c @@ -1,4 +1,4 @@ -#define FORCE_INLINE inline __attribute__((always_inline)) +#define force_inline inline __attribute__((always_inline)) /* TODO(rnp): msvc probably won't build this but there are other things preventing that as well */ #define sqrt_f32(a) __builtin_sqrtf(a) @@ -12,7 +12,7 @@ #define atomic_inc(ptr, n) __atomic_fetch_add(ptr, n, __ATOMIC_ACQ_REL) #define atomic_cas(ptr, cptr, n) __atomic_compare_exchange_n(ptr, cptr, n, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) -static FORCE_INLINE u32 +function force_inline u32 clz_u32(u32 a) { u32 result = 32; @@ -20,7 +20,7 @@ clz_u32(u32 a) return result; } -static FORCE_INLINE u32 +function force_inline u32 ctz_u32(u32 a) { u32 result = 32; diff --git a/main_w32.c b/main_w32.c @@ -68,7 +68,7 @@ dispatch_file_watch(OS *os, FileWatchDirectory *fw_dir, u8 *buf, Arena arena) } while (offset); } -static void +function void clear_io_queue(OS *os, BeamformerInput *input, Arena arena) { w32_context *ctx = (w32_context *)os->context; diff --git a/os_linux.c b/os_linux.c @@ -27,7 +27,7 @@ i32 ftruncate(i32, i64); i64 syscall(i64, ...); #ifdef _DEBUG -static void * +function void * os_get_module(char *name, Stream *e) { void *result = dlopen(name, RTLD_NOW|RTLD_LOCAL|RTLD_NOLOAD); @@ -39,7 +39,7 @@ os_get_module(char *name, Stream *e) } #endif -static OS_WRITE_FILE_FN(os_write_file) +function OS_WRITE_FILE_FN(os_write_file) { while (raw.len) { iz r = write(file, raw.data, raw.len); @@ -85,12 +85,12 @@ function OS_ALLOC_ARENA_FN(os_alloc_arena) return result; } -static OS_CLOSE_FN(os_close) +function OS_CLOSE_FN(os_close) { close(file); } -static OS_OPEN_FOR_WRITE_FN(os_open_for_write) +function OS_OPEN_FOR_WRITE_FN(os_open_for_write) { iptr result = open(fname, O_WRONLY|O_TRUNC); if (result == -1) @@ -115,7 +115,7 @@ function OS_READ_WHOLE_FILE_FN(os_read_whole_file) return result; } -static OS_WRITE_NEW_FILE_FN(os_write_new_file) +function OS_WRITE_NEW_FILE_FN(os_write_new_file) { iptr fd = open(fname, O_WRONLY|O_TRUNC|O_CREAT, 0600); if (fd == INVALID_FILE) @@ -125,7 +125,7 @@ static OS_WRITE_NEW_FILE_FN(os_write_new_file) return ret; } -static b32 +function b32 os_file_exists(char *path) { struct stat st; @@ -133,7 +133,7 @@ os_file_exists(char *path) return result; } -static OS_READ_FILE_FN(os_read_file) +function OS_READ_FILE_FN(os_read_file) { iz r = 0, total_read = 0; do { @@ -205,7 +205,7 @@ os_load_library(char *name, char *temp_name, Stream *e) return result; } -static void * +function void * os_lookup_dynamic_symbol(void *h, char *name, Stream *e) { void *result = 0; @@ -219,7 +219,7 @@ os_lookup_dynamic_symbol(void *h, char *name, Stream *e) return result; } -static void +function void os_unload_library(void *h) { /* NOTE: glibc is buggy gnuware so we need to check this */ @@ -227,7 +227,7 @@ os_unload_library(void *h) dlclose(h); } -static OS_ADD_FILE_WATCH_FN(os_add_file_watch) +function OS_ADD_FILE_WATCH_FN(os_add_file_watch) { s8 directory = path; directory.len = s8_scan_backwards(path, '/'); @@ -261,7 +261,7 @@ os_create_thread(Arena arena, iptr user_context, s8 name, os_thread_entry_point_ return (iptr)result; } -static OS_WAIT_ON_VALUE_FN(os_wait_on_value) +function OS_WAIT_ON_VALUE_FN(os_wait_on_value) { struct timespec *timeout = 0, timeout_value; if (timeout_ms != (u32)-1) { @@ -272,7 +272,7 @@ static OS_WAIT_ON_VALUE_FN(os_wait_on_value) return syscall(SYS_futex, value, FUTEX_WAIT, current, timeout, 0, 0) == 0; } -static OS_WAKE_WAITERS_FN(os_wake_waiters) +function OS_WAKE_WAITERS_FN(os_wake_waiters) { if (sync) { atomic_inc(sync, 1); diff --git a/os_win32.c b/os_win32.c @@ -34,20 +34,6 @@ #define THREAD_SET_LIMITED_INFORMATION 0x0400 -typedef struct { - u16 wProcessorArchitecture; - u16 _pad1; - u32 dwPageSize; - iz lpMinimumApplicationAddress; - iz lpMaximumApplicationAddress; - u64 dwActiveProcessorMask; - u32 dwNumberOfProcessors; - u32 dwProcessorType; - u32 dwAllocationGranularity; - u16 wProcessorLevel; - u16 wProcessorRevision; -} w32_sys_info; - /* NOTE: this is packed because the w32 api designers are dumb and ordered the members * incorrectly. They worked around it be making the ft* members a struct {u32, u32} which * is aligned on a 4-byte boundary. Then in their documentation they explicitly tell you not @@ -108,7 +94,7 @@ W32(b32) DeleteFileA(c8 *); W32(void) ExitProcess(i32); W32(b32) FreeLibrary(void *); W32(i32) GetFileAttributesA(c8 *); -W32(b32) GetFileInformationByHandle(iptr, w32_file_info *); +W32(b32) GetFileInformationByHandle(iptr, void *); W32(i32) GetLastError(void); W32(void *) GetModuleHandleA(c8 *); W32(void *) GetProcAddress(void *, c8 *); @@ -128,7 +114,7 @@ W32(void *) VirtualAlloc(u8 *, iz, u32, u32); W32(b32) VirtualFree(u8 *, iz, u32); #ifdef _DEBUG -static void * +function void * os_get_module(char *name, Stream *e) { void *result = GetModuleHandleA(name); @@ -141,10 +127,10 @@ os_get_module(char *name, Stream *e) } #endif -static OS_WRITE_FILE_FN(os_write_file) +function OS_WRITE_FILE_FN(os_write_file) { i32 wlen = 0; - if (raw.len) WriteFile(file, raw.data, raw.len, &wlen, 0); + if (raw.len > 0 && raw.len <= U32_MAX) WriteFile(file, raw.data, raw.len, &wlen, 0); return raw.len == wlen; } @@ -165,33 +151,46 @@ os_fatal(s8 msg) function OS_ALLOC_ARENA_FN(os_alloc_arena) { - Arena result; - w32_sys_info Info; - GetSystemInfo(&Info); - - if (capacity % Info.dwPageSize != 0) - capacity += (Info.dwPageSize - capacity % Info.dwPageSize); - - iz oldsize = old.end - old.beg; - if (oldsize > capacity) - return old; - - if (old.beg) - VirtualFree(old.beg, oldsize, MEM_RELEASE); - - result.beg = VirtualAlloc(0, capacity, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); - if (result.beg == NULL) - os_fatal(s8("os_alloc_arena: couldn't allocate memory\n")); - result.end = result.beg + capacity; + Arena result = old; + + struct { + u16 architecture; + u16 _pad1; + u32 page_size; + iz minimum_application_address; + iz maximum_application_address; + u64 active_processor_mask; + u32 number_of_processors; + u32 processor_type; + u32 allocation_granularity; + u16 processor_level; + u16 processor_revision; + } info; + + GetSystemInfo(&info); + + if (capacity % info.page_size != 0) + capacity += (info.page_size - capacity % info.page_size); + + iz old_size = old.end - old.beg; + if (old_size < capacity) { + if (old.beg) + VirtualFree(old.beg, old_size, MEM_RELEASE); + + result.beg = VirtualAlloc(0, capacity, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); + if (!result.beg) + os_fatal(s8("os_alloc_arena: couldn't allocate memory\n")); + result.end = result.beg + capacity; + } return result; } -static OS_CLOSE_FN(os_close) +function OS_CLOSE_FN(os_close) { CloseHandle(file); } -static OS_OPEN_FOR_WRITE_FN(os_open_for_write) +function OS_OPEN_FOR_WRITE_FN(os_open_for_write) { iptr result = CreateFileA(fname, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); return result; @@ -219,32 +218,33 @@ function OS_READ_WHOLE_FILE_FN(os_read_whole_file) return result; } -static OS_READ_FILE_FN(os_read_file) +function OS_READ_FILE_FN(os_read_file) { i32 total_read = 0; ReadFile(file, buf, size, &total_read, 0); return total_read; } -static OS_WRITE_NEW_FILE_FN(os_write_new_file) +function OS_WRITE_NEW_FILE_FN(os_write_new_file) { - if (raw.len > (iz)U32_MAX) { - os_write_file(GetStdHandle(STD_ERROR_HANDLE), - s8("os_write_file: files >4GB are not yet handled on win32\n")); - return 0; - } + enum { CHUNK_SIZE = GB(2) }; + b32 result = 0; iptr h = CreateFileA(fname, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); - if (h == INVALID_FILE) - return 0; - - b32 ret = os_write_file(h, raw); - CloseHandle(h); - - return ret; + if (h >= 0) { + while (raw.len > 0) { + s8 chunk = raw; + chunk.len = MIN(chunk.len, CHUNK_SIZE); + result = os_write_file(h, chunk); + if (!result) break; + raw = s8_cut_head(raw, chunk.len); + } + CloseHandle(h); + } + return result; } -static b32 +function b32 os_file_exists(char *path) { b32 result = GetFileAttributesA(path) != -1; @@ -286,7 +286,7 @@ os_load_library(char *name, char *temp_name, Stream *e) return result; } -static void * +function void * os_lookup_dynamic_symbol(void *h, char *name, Stream *e) { void *result = 0; @@ -302,13 +302,13 @@ os_lookup_dynamic_symbol(void *h, char *name, Stream *e) return result; } -static void +function void os_unload_library(void *h) { FreeLibrary(h); } -static OS_ADD_FILE_WATCH_FN(os_add_file_watch) +function OS_ADD_FILE_WATCH_FN(os_add_file_watch) { s8 directory = path; directory.len = s8_scan_backwards(path, '\\'); @@ -355,12 +355,12 @@ os_create_thread(Arena arena, iptr user_context, s8 name, os_thread_entry_point_ return result; } -static OS_WAIT_ON_VALUE_FN(os_wait_on_value) +function OS_WAIT_ON_VALUE_FN(os_wait_on_value) { return WaitOnAddress(value, &current, sizeof(*value), timeout_ms); } -static OS_WAKE_WAITERS_FN(os_wake_waiters) +function OS_WAKE_WAITERS_FN(os_wake_waiters) { if (sync) { atomic_inc(sync, 1); diff --git a/static.c b/static.c @@ -5,7 +5,7 @@ #define debug_init(...) #else -static void *debug_lib; +global void *debug_lib; #define DEBUG_ENTRY_POINTS \ X(beamformer_frame_step) \ @@ -14,7 +14,7 @@ static void *debug_lib; X(beamform_work_queue_push) \ X(beamform_work_queue_push_commit) -#define X(name) static name ##_fn *name; +#define X(name) global name ##_fn *name; DEBUG_ENTRY_POINTS #undef X @@ -42,7 +42,7 @@ function FILE_WATCH_CALLBACK_FN(debug_reload) return 1; } -static void +function void debug_init(OS *os, iptr input, Arena *arena) { os->add_file_watch(os, arena, s8(OS_DEBUG_LIB_NAME), debug_reload, input); @@ -74,7 +74,7 @@ struct gl_debug_ctx { OS *os; }; -static void +function void gl_debug_logger(u32 src, u32 type, u32 id, u32 lvl, i32 len, const char *msg, const void *userctx) { (void)src; (void)type; (void)id; @@ -95,7 +95,7 @@ gl_debug_logger(u32 src, u32 type, u32 id, u32 lvl, i32 len, const char *msg, co stream_reset(e, 0); } -static void +function void get_gl_params(GLParams *gl, Stream *err) { char *vendor = (char *)glGetString(GL_VENDOR); @@ -145,7 +145,7 @@ validate_gl_requirements(GLParams *gl, Arena a) if (s.widx) os_fatal(stream_to_s8(&s)); } -static void +function void dump_gl_params(GLParams *gl, Arena a, OS *os) { (void)gl; (void)a; @@ -223,7 +223,7 @@ function FILE_WATCH_CALLBACK_FN(reload_render_shader) } -static FILE_WATCH_CALLBACK_FN(queue_compute_shader_reload) +function FILE_WATCH_CALLBACK_FN(queue_compute_shader_reload) { ComputeShaderReloadContext *csr = (typeof(csr))user_data; BeamformerCtx *ctx = csr->beamformer_ctx; @@ -237,7 +237,7 @@ static FILE_WATCH_CALLBACK_FN(queue_compute_shader_reload) return 1; } -static FILE_WATCH_CALLBACK_FN(load_cuda_lib) +function FILE_WATCH_CALLBACK_FN(load_cuda_lib) { CudaLib *cl = (CudaLib *)user_data; b32 result = os_file_exists((c8 *)path.data); @@ -267,7 +267,7 @@ void glfwWindowHint(i32, i32); iptr glfwCreateWindow(i32, i32, char *, iptr, iptr); void glfwMakeContextCurrent(iptr); -static OS_THREAD_ENTRY_POINT_FN(compute_worker_thread_entry_point) +function OS_THREAD_ENTRY_POINT_FN(compute_worker_thread_entry_point) { GLWorkerThreadContext *ctx = (GLWorkerThreadContext *)_ctx; @@ -294,7 +294,7 @@ static OS_THREAD_ENTRY_POINT_FN(compute_worker_thread_entry_point) return 0; } -static void +function void setup_beamformer(BeamformerCtx *ctx, Arena *memory) { ctx->window_size = (uv2){.w = 1280, .h = 840}; diff --git a/ui.c b/ui.c @@ -726,7 +726,7 @@ resize_frame_view(BeamformerFrameView *view, uv2 dim) LABEL_GL_OBJECT(GL_TEXTURE, view->texture, s8("Frame View Texture")); } -static void +function void ui_variable_free(BeamformerUI *ui, Variable *var) { if (var) { @@ -781,7 +781,7 @@ ui_view_free(BeamformerUI *ui, Variable *view) ui_variable_free(ui, view); } -static Variable * +function Variable * fill_variable(Variable *var, Variable *group, s8 name, u32 flags, VariableType type, Font font) { var->flags = flags; @@ -798,7 +798,7 @@ fill_variable(Variable *var, Variable *group, s8 name, u32 flags, VariableType t return var; } -static Variable * +function Variable * add_variable(BeamformerUI *ui, Variable *group, Arena *arena, s8 name, u32 flags, VariableType type, Font font) { @@ -808,7 +808,7 @@ add_variable(BeamformerUI *ui, Variable *group, Arena *arena, s8 name, u32 flags return fill_variable(result, group, name, flags, type, font); } -static Variable * +function Variable * add_variable_group(BeamformerUI *ui, Variable *group, Arena *arena, s8 name, VariableGroupType type, Font font) { Variable *result = add_variable(ui, group, arena, name, V_INPUT, VT_GROUP, font); @@ -816,7 +816,7 @@ add_variable_group(BeamformerUI *ui, Variable *group, Arena *arena, s8 name, Var return result; } -static Variable * +function Variable * end_variable_group(Variable *group) { ASSERT(group->type == VT_GROUP); @@ -843,7 +843,7 @@ add_button(BeamformerUI *ui, Variable *group, Arena *arena, s8 name, UIButtonID return result; } -static Variable * +function Variable * add_ui_split(BeamformerUI *ui, Variable *parent, Arena *arena, s8 name, f32 fraction, RegionSplitDirection direction, Font font) { @@ -1224,21 +1224,21 @@ frame_view_ready_to_present(BeamformerFrameView *view) return !uv2_equal((uv2){0}, view->texture_dim) && view->frame; } -static Color +function Color colour_from_normalized(v4 rgba) { return (Color){.r = rgba.r * 255.0f, .g = rgba.g * 255.0f, .b = rgba.b * 255.0f, .a = rgba.a * 255.0f}; } -static Color +function Color fade(Color a, f32 visibility) { a.a = (u8)((f32)a.a * visibility); return a; } -static v4 +function v4 lerp_v4(v4 a, v4 b, f32 t) { return (v4){ @@ -1249,28 +1249,26 @@ lerp_v4(v4 a, v4 b, f32 t) }; } -static s8 +function s8 push_das_shader_id(Stream *s, DASShaderID shader, u32 transmit_count) { #define X(type, id, pretty, fixed_tx) s8(pretty), - static s8 pretty_names[] = { DAS_TYPES }; + local_persist s8 pretty_names[DAS_LAST + 1] = {DAS_TYPES s8("Invalid")}; #undef X #define X(type, id, pretty, fixed_tx) fixed_tx, - static u8 fixed_transmits[] = { DAS_TYPES }; + local_persist u8 fixed_transmits[DAS_LAST + 1] = {DAS_TYPES 1}; #undef X - if ((u32)shader < (u32)DAS_LAST) { - stream_append_s8(s, pretty_names[shader]); - if (!fixed_transmits[shader]) { - stream_append_byte(s, '-'); - stream_append_u64(s, transmit_count); - } + stream_append_s8(s, pretty_names[MIN(shader, DAS_LAST)]); + if (!fixed_transmits[MIN(shader, DAS_LAST)]) { + stream_append_byte(s, '-'); + stream_append_u64(s, transmit_count); } return stream_to_s8(s); } -static s8 +function s8 push_custom_view_title(Stream *s, Variable *var) { switch (var->type) { @@ -1310,7 +1308,7 @@ push_custom_view_title(Stream *s, Variable *var) return stream_to_s8(s); } -static v2 +function v2 draw_text_base(Font font, s8 text, v2 pos, Color colour) { v2 off = pos; @@ -1340,7 +1338,7 @@ draw_text_base(Font font, s8 text, v2 pos, Color colour) } /* NOTE(rnp): expensive but of the available options in raylib this gives the best results */ -static v2 +function v2 draw_outlined_text(s8 text, v2 pos, TextSpec *ts) { f32 ow = ts->outline_thick; @@ -1356,7 +1354,7 @@ draw_outlined_text(s8 text, v2 pos, TextSpec *ts) return result; } -static v2 +function v2 draw_text(s8 text, v2 pos, TextSpec *ts) { if (ts->flags & TF_ROTATED) { @@ -1396,7 +1394,7 @@ draw_text(s8 text, v2 pos, TextSpec *ts) return result; } -static Rect +function Rect extend_rect_centered(Rect r, v2 delta) { r.size.w += delta.x; @@ -1406,7 +1404,7 @@ extend_rect_centered(Rect r, v2 delta) return r; } -static Rect +function Rect shrink_rect_centered(Rect r, v2 delta) { delta.x = MIN(delta.x, r.size.w); @@ -1418,7 +1416,7 @@ shrink_rect_centered(Rect r, v2 delta) return r; } -static Rect +function Rect scale_rect_centered(Rect r, v2 scale) { Rect or = r; @@ -1477,7 +1475,7 @@ hover_var(BeamformerUI *ui, v2 mouse, Rect rect, Variable *var) return result; } -static Rect +function Rect draw_title_bar(BeamformerUI *ui, Arena arena, Variable *ui_view, Rect r, v2 mouse) { ASSERT(ui_view->type == VT_UI_VIEW); @@ -1658,7 +1656,7 @@ draw_radio_button(BeamformerUI *ui, Variable *var, v2 at, v2 mouse, v4 base_colo return result; } -static v2 +function v2 draw_variable(BeamformerUI *ui, Arena arena, Variable *var, v2 at, v2 mouse, v4 base_colour, TextSpec text_spec) { v2 result; @@ -1933,7 +1931,7 @@ draw_beamformer_frame_view(BeamformerUI *ui, Arena a, Variable *var, Rect displa draw_table(ui, a, table, table_rect, text_spec, mouse); } -static v2 +function v2 draw_compute_progress_bar(BeamformerUI *ui, Arena arena, ComputeProgressBar *state, Rect r) { if (*state->processing) state->display_t_velocity += 65 * dt_for_frame; @@ -2179,7 +2177,7 @@ draw_active_text_box(BeamformerUI *ui, Variable *var) DrawRectanglePro(cursor.rl, (Vector2){0}, 0, colour_from_normalized(cursor_colour)); } -static void +function void draw_active_menu(BeamformerUI *ui, Arena arena, Variable *menu, v2 mouse, Rect window) { ASSERT(menu->type == VT_GROUP); @@ -2238,7 +2236,7 @@ draw_active_menu(BeamformerUI *ui, Arena arena, Variable *menu, v2 mouse, Rect w } } -static void +function void draw_layout_variable(BeamformerUI *ui, Variable *var, Rect draw_rect, v2 mouse) { if (var->type != VT_UI_REGION_SPLIT) { @@ -2296,7 +2294,7 @@ draw_layout_variable(BeamformerUI *ui, Variable *var, Rect draw_rect, v2 mouse) EndScissorMode(); } -static void +function void draw_ui_regions(BeamformerUI *ui, Rect window, v2 mouse) { struct region_frame { @@ -2524,7 +2522,7 @@ scale_bar_interaction(BeamformerUI *ui, ScaleBar *sb, v2 mouse) } } -static void +function void ui_button_interaction(BeamformerUI *ui, Variable *button) { ASSERT(button->type == VT_UI_BUTTON); @@ -2565,7 +2563,7 @@ ui_button_interaction(BeamformerUI *ui, Variable *button) } } -static void +function void ui_begin_interact(BeamformerUI *ui, BeamformerInput *input, b32 scroll, b32 mouse_left_pressed) { InteractionState *is = &ui->interaction; @@ -2748,7 +2746,7 @@ ui_interact(BeamformerUI *ui, BeamformerInput *input, uv2 window_size) is->hot = 0; } -static void +function void ui_init(BeamformerCtx *ctx, Arena store) { /* NOTE(rnp): store the ui at the base of the passed in arena and use the rest for diff --git a/util.c b/util.c @@ -1,36 +1,21 @@ /* See LICENSE for license details. */ -static i32 hadamard_12_12_transpose[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, - 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, - 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, - 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, - 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, - 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, - 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, - 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, - 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, - 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, - 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -}; - #define zero_struct(s) mem_clear(s, 0, sizeof(*s)) -static void * -mem_clear(void *p_, u8 c, iz size) +function void * +mem_clear(void *restrict p_, u8 c, iz size) { u8 *p = p_; while (size > 0) p[--size] = c; return p; } -static void +function void mem_copy(void *restrict dest, void *restrict src, uz n) { u8 *s = src, *d = dest; for (; n; n--) *d++ = *s++; } -static void +function void mem_move(u8 *dest, u8 *src, iz n) { if (dest < src) mem_copy(dest, src, n); @@ -38,7 +23,7 @@ mem_move(u8 *dest, u8 *src, iz n) } -static u8 * +function u8 * arena_commit(Arena *a, iz size) { ASSERT(a->end - a->beg >= size); @@ -47,7 +32,7 @@ arena_commit(Arena *a, iz size) return result; } -static void +function void arena_pop(Arena *a, iz length) { a->beg -= length; @@ -93,7 +78,7 @@ enum { DA_INITIAL_CAP = 4 }; (s)->data + (s)->count++ \ : (s)->data + (s)->count++) -static void * +function void * da_reserve_(Arena *a, void *data, iz *capacity, iz needed, iz align, iz size) { iz cap = *capacity; @@ -113,7 +98,7 @@ da_reserve_(Arena *a, void *data, iz *capacity, iz needed, iz align, iz size) return data; } -static Arena +function Arena sub_arena(Arena *a, iz len, iz align) { Arena result = {0}; @@ -126,14 +111,14 @@ sub_arena(Arena *a, iz len, iz align) return result; } -static TempArena +function TempArena begin_temp_arena(Arena *a) { TempArena result = {.arena = a, .old_beg = a->beg}; return result; } -static void +function void end_temp_arena(TempArena ta) { Arena *a = ta.arena; @@ -143,7 +128,7 @@ end_temp_arena(TempArena ta) } } -static u32 +function u32 utf8_encode(u8 *out, u32 cp) { u32 result = 1; @@ -170,7 +155,7 @@ utf8_encode(u8 *out, u32 cp) return result; } -static UnicodeDecode +function UnicodeDecode utf16_decode(u16 *data, iz length) { UnicodeDecode result = {.cp = U32_MAX}; @@ -187,7 +172,7 @@ utf16_decode(u16 *data, iz length) return result; } -static u32 +function u32 utf16_encode(u16 *out, u32 cp) { u32 result = 1; @@ -228,7 +213,7 @@ stream_reset(Stream *s, iz index) s->widx = index; } -static void +function void stream_commit(Stream *s, iz count) { s->errors |= !BETWEEN(s->widx + count, 0, s->cap); @@ -236,7 +221,7 @@ stream_commit(Stream *s, iz count) s->widx += count; } -static void +function void stream_append(Stream *s, void *data, iz count) { s->errors |= (s->cap - s->widx) < count; @@ -246,19 +231,19 @@ stream_append(Stream *s, void *data, iz count) } } -static void +function void stream_append_byte(Stream *s, u8 b) { stream_append(s, &b, 1); } -static void +function void stream_pad(Stream *s, u8 b, i32 n) { while (n > 0) stream_append_byte(s, b), n--; } -static void +function void stream_append_s8(Stream *s, s8 str) { stream_append(s, str.data, str.len); @@ -273,7 +258,7 @@ stream_append_s8s_(Stream *s, s8 *strs, iz count) stream_append(s, strs[i].data, strs[i].len); } -static void +function void stream_append_u64(Stream *s, u64 n) { u8 tmp[64]; @@ -283,16 +268,15 @@ stream_append_u64(Stream *s, u64 n) stream_append(s, beg, end - beg); } -static void +function void stream_append_hex_u64(Stream *s, u64 n) { if (!s->errors) { - static u8 hex[16] = {"0123456789abcdef"}; u8 buf[16]; u8 *end = buf + sizeof(buf); u8 *beg = end; while (n) { - *--beg = hex[n & 0x0F]; + *--beg = "0123456789abcdef"[n & 0x0F]; n >>= 4; } while (end - beg < 2) @@ -301,7 +285,7 @@ stream_append_hex_u64(Stream *s, u64 n) } } -static void +function void stream_append_i64(Stream *s, i64 n) { if (n < 0) { @@ -311,7 +295,7 @@ stream_append_i64(Stream *s, i64 n) stream_append_u64(s, n); } -static void +function void stream_append_f64(Stream *s, f64 f, i64 prec) { if (f < 0) { @@ -337,7 +321,7 @@ stream_append_f64(Stream *s, f64 f, i64 prec) } } -static void +function void stream_append_f64_e(Stream *s, f64 f) { /* TODO: there should be a better way of doing this */ @@ -373,7 +357,7 @@ stream_append_f64_e(Stream *s, f64 f) stream_append_u64(s, ABS(scale)); } -static void +function void stream_append_v2(Stream *s, v2 v) { stream_append_byte(s, '{'); @@ -424,7 +408,7 @@ s8_hash(s8 v) return h; } -static s8 +function s8 c_str_to_s8(char *cstr) { s8 result = {.data = (u8 *)cstr}; @@ -433,7 +417,7 @@ c_str_to_s8(char *cstr) } /* NOTE(rnp): returns < 0 if byte is not found */ -static iz +function iz s8_scan_backwards(s8 s, u8 byte) { iz result = s.len; @@ -442,7 +426,7 @@ s8_scan_backwards(s8 s, u8 byte) return result; } -static s8 +function s8 s8_cut_head(s8 s, iz cut) { s8 result = s; @@ -482,7 +466,7 @@ s16_to_s8(Arena *a, s16 in) return result; } -static s16 +function s16 s8_to_s16(Arena *a, s8 in) { s16 result = {0}; @@ -501,7 +485,7 @@ s8_to_s16(Arena *a, s8 in) return result; } -static s8 +function s8 push_s8(Arena *a, s8 str) { s8 result = s8_alloc(a, str.len); @@ -509,7 +493,7 @@ push_s8(Arena *a, s8 str) return result; } -static s8 +function s8 push_s8_zero(Arena *a, s8 str) { s8 result = s8_alloc(a, str.len + 1); @@ -518,26 +502,26 @@ push_s8_zero(Arena *a, s8 str) return result; } -static u32 +function u32 round_down_power_of_2(u32 a) { u32 result = 0x80000000UL >> clz_u32(a); return result; } -static b32 +function b32 uv2_equal(uv2 a, uv2 b) { return a.x == b.x && a.y == b.y; } -static b32 +function b32 uv3_equal(uv3 a, uv3 b) { return a.x == b.x && a.y == b.y && a.z == b.z; } -static v3 +function v3 cross(v3 a, v3 b) { v3 result = { @@ -548,7 +532,7 @@ cross(v3 a, v3 b) return result; } -static v3 +function v3 sub_v3(v3 a, v3 b) { v3 result = { @@ -559,14 +543,14 @@ sub_v3(v3 a, v3 b) return result; } -static f32 +function f32 length_v3(v3 a) { f32 result = a.x * a.x + a.y * a.y + a.z * a.z; return result; } -static v3 +function v3 normalize_v3(v3 a) { f32 length = length_v3(a); @@ -574,7 +558,7 @@ normalize_v3(v3 a) return result; } -static v2 +function v2 clamp_v2_rect(v2 v, Rect r) { v2 result = v; @@ -583,7 +567,7 @@ clamp_v2_rect(v2 v, Rect r) return result; } -static v2 +function v2 add_v2(v2 a, v2 b) { v2 result = { @@ -593,7 +577,7 @@ add_v2(v2 a, v2 b) return result; } -static v2 +function v2 sub_v2(v2 a, v2 b) { v2 result = { @@ -603,7 +587,7 @@ sub_v2(v2 a, v2 b) return result; } -static v2 +function v2 scale_v2(v2 a, f32 scale) { v2 result = { @@ -613,7 +597,7 @@ scale_v2(v2 a, f32 scale) return result; } -static v2 +function v2 mul_v2(v2 a, v2 b) { v2 result = { @@ -633,7 +617,7 @@ div_v2(v2 a, v2 b) } -static v2 +function v2 floor_v2(v2 a) { v2 result; @@ -642,7 +626,7 @@ floor_v2(v2 a) return result; } -static f32 +function f32 magnitude_v2(v2 a) { f32 result = sqrt_f32(a.x * a.x + a.y * a.y); @@ -688,7 +672,7 @@ sub_v4(v4 a, v4 b) return result; } -static void +function void split_rect_horizontal(Rect rect, f32 fraction, Rect *left, Rect *right) { if (left) { @@ -704,7 +688,7 @@ split_rect_horizontal(Rect rect, f32 fraction, Rect *left, Rect *right) } } -static void +function void split_rect_vertical(Rect rect, f32 fraction, Rect *top, Rect *bot) { if (top) { @@ -720,7 +704,7 @@ split_rect_vertical(Rect rect, f32 fraction, Rect *top, Rect *bot) } } -static void +function void cut_rect_horizontal(Rect rect, f32 at, Rect *left, Rect *right) { at = MIN(at, rect.size.w); @@ -735,7 +719,7 @@ cut_rect_horizontal(Rect rect, f32 at, Rect *left, Rect *right) } } -static void +function void cut_rect_vertical(Rect rect, f32 at, Rect *top, Rect *bot) { at = MIN(at, rect.size.h); @@ -750,7 +734,7 @@ cut_rect_vertical(Rect rect, f32 at, Rect *top, Rect *bot) } } -static f64 +function f64 parse_f64(s8 s) { f64 integral = 0, fractional = 0, sign = 1; @@ -807,7 +791,7 @@ fill_kronecker_sub_matrix(i32 *out, i32 out_stride, i32 scale, i32 *b, uv2 b_dim } /* NOTE: this won't check for valid space/etc and assumes row major order */ -static void +function void kronecker_product(i32 *out, i32 *a, uv2 a_dim, i32 *b, uv2 b_dim) { uv2 out_dim = {.x = a_dim.x * b_dim.x, .y = a_dim.y * b_dim.y}; @@ -856,6 +840,20 @@ make_hadamard_transpose(Arena *a, u32 dim) #undef IND if (!power_of_2) { + local_persist i32 hadamard_12_12_transpose[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, + 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, + 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, + 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, + 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, + 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, + 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, + 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, + 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, + 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, + 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, + }; kronecker_product(result, m, (uv2){.x = dim, .y = dim}, hadamard_12_12_transpose, (uv2){.x = 12, .y = 12}); } diff --git a/util.h b/util.h @@ -30,7 +30,7 @@ #define DEBUG_DECL(a) a #define ASSERT(c) do { if (!(c)) debugbreak(); } while (0); #else - #define DEBUG_EXPORT static + #define DEBUG_EXPORT function #define DEBUG_DECL(a) #define ASSERT(c) #endif