ogl_beamforming

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

Commit: ed9bf0168561fe96954448f55656c5710bb324c1
Parent: 2e8f1b8faee89705c651fedbf29b983dbcda87df
Author: Randy Palamar
Date:   Tue, 20 Aug 2024 11:51:36 -0600

replace cuda lib "vtable" with global function pointers

This also includes stubs for when they are not found. Doing so is
more robust, less error prone, and requires less code.

Diffstat:
Mbeamformer.c | 22+++++++---------------
Mbeamformer.h | 30++++++++++--------------------
Mmain.c | 21++++++++++++++-------
Mos_unix.c | 2++
Mos_win32.c | 2++
5 files changed, 35 insertions(+), 42 deletions(-)

diff --git a/beamformer.c b/beamformer.c @@ -77,14 +77,10 @@ alloc_shader_storage(BeamformerCtx *ctx, Arena a) break; case GL_VENDOR_NVIDIA: cs->raw_data_arena = os_alloc_arena(cs->raw_data_arena, full_rf_buf_size); - if (g_cuda_lib_functions[CLF_REGISTER_BUFFERS] && g_cuda_lib_functions[CLF_INIT_CONFIG]) { - register_cuda_buffers *fn = g_cuda_lib_functions[CLF_REGISTER_BUFFERS]; - fn(cs->rf_data_ssbos, ARRAY_COUNT(cs->rf_data_ssbos), cs->raw_data_ssbo); - - init_cuda_configuration *init_fn = g_cuda_lib_functions[CLF_INIT_CONFIG]; - init_fn(bp->rf_raw_dim.E, bp->dec_data_dim.E, bp->channel_mapping, - bp->channel_offset > 0); - } + register_cuda_buffers(cs->rf_data_ssbos, ARRAY_COUNT(cs->rf_data_ssbos), + cs->raw_data_ssbo); + init_cuda_configuration(bp->rf_raw_dim.E, bp->dec_data_dim.E, bp->channel_mapping, + bp->channel_offset > 0); break; } @@ -129,13 +125,9 @@ do_compute_shader(BeamformerCtx *ctx, enum compute_shaders shader) csctx->last_output_ssbo_index = !csctx->last_output_ssbo_index; break; case CS_CUDA_DECODE_AND_DEMOD: - if (g_cuda_lib_functions[CLF_DECODE_AND_DEMOD]) { - decode_and_hilbert*fn = g_cuda_lib_functions[CLF_DECODE_AND_DEMOD]; - - fn(csctx->raw_data_index * rf_raw_size, output_ssbo_idx); - csctx->raw_data_fences[csctx->raw_data_index] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - csctx->last_output_ssbo_index = !csctx->last_output_ssbo_index; - } + decode_and_hilbert(csctx->raw_data_index * rf_raw_size, output_ssbo_idx); + csctx->raw_data_fences[csctx->raw_data_index] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + csctx->last_output_ssbo_index = !csctx->last_output_ssbo_index; break; case CS_LPF: glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, csctx->rf_data_ssbos[input_ssbo_idx]); diff --git a/beamformer.h b/beamformer.h @@ -160,27 +160,17 @@ typedef struct { BeamformerParametersFull *params; } BeamformerCtx; -enum cuda_lib_functions { - CLF_INIT_CONFIG, - CLF_REGISTER_BUFFERS, - CLF_DECODE_AND_DEMOD, - CLF_LAST -}; +#define CUDA_LIB_NAME "cuda_toolkit.dll" -static char *cuda_lib_function_names[CLF_LAST] = { - [CLF_INIT_CONFIG] = "init_cuda_configuration", - [CLF_REGISTER_BUFFERS] = "register_cuda_buffers", - [CLF_DECODE_AND_DEMOD] = "decode_and_hilbert", -}; +#define INIT_CUDA_CONFIGURATION_FN(name) void name(u32 *, u32 *, u32 *, b32) +typedef INIT_CUDA_CONFIGURATION_FN(init_cuda_configuration_fn); +#define REGISTER_CUDA_BUFFERS_FN(name) void name(u32 *, u32, u32) +typedef REGISTER_CUDA_BUFFERS_FN(register_cuda_buffers_fn); +#define DECODE_AND_HILBERT_FN(name) void name(size_t, u32) +typedef DECODE_AND_HILBERT_FN(decode_and_hilbert_fn); -#define CUDA_LIB_NAME "cuda_toolkit.dll" -typedef void init_cuda_configuration(const u32*, const u32*, const u32*, b32); -typedef void register_cuda_buffers(u32*, u32, u32); -typedef void decode_and_hilbert(size_t, u32); - -/* NOTE: Array of Function Pointers used for accessing cuda lib functions */ -/* TODO: robustness: replace with function stubs when not found */ -static void *g_cuda_lib_functions[CLF_LAST]; -static os_library_handle g_cuda_lib_handle; +static init_cuda_configuration_fn *init_cuda_configuration; +static register_cuda_buffers_fn *register_cuda_buffers; +static decode_and_hilbert_fn *decode_and_hilbert; #endif /*_BEAMFORMER_H_ */ diff --git a/main.c b/main.c @@ -1,6 +1,8 @@ /* See LICENSE for license details. */ #include "beamformer.h" +static os_library_handle g_cuda_lib_handle; + static char *compute_shader_paths[CS_LAST] = { [CS_HADAMARD] = "shaders/hadamard.glsl", [CS_HERCULES] = "shaders/2d_hercules.glsl", @@ -53,6 +55,11 @@ do_debug(void) #endif /* _DEBUG */ +/* NOTE: cuda lib stubs */ +INIT_CUDA_CONFIGURATION_FN(init_cuda_configuration_stub) {} +REGISTER_CUDA_BUFFERS_FN(register_cuda_buffers_stub) {} +DECODE_AND_HILBERT_FN(decode_and_hilbert_stub) {} + static void gl_debug_logger(u32 src, u32 type, u32 id, u32 lvl, i32 len, const char *msg, const void *userctx) { @@ -199,13 +206,13 @@ main(void) break; case GL_VENDOR_NVIDIA: g_cuda_lib_handle = os_load_library(CUDA_LIB_NAME); - if (!g_cuda_lib_handle) - break; - for (u32 i = 0; i < CLF_LAST; i++) { - void *fn = os_lookup_dynamic_symbol(g_cuda_lib_handle, - cuda_lib_function_names[i]); - g_cuda_lib_functions[i] = fn; - } + #define LOOKUP_CUDA_FN(f) \ + f = os_lookup_dynamic_symbol(g_cuda_lib_handle, #f); \ + if (!f) f = f##_stub + LOOKUP_CUDA_FN(init_cuda_configuration); + LOOKUP_CUDA_FN(register_cuda_buffers); + LOOKUP_CUDA_FN(decode_and_hilbert); + break; } /* NOTE: set up OpenGL debug logging */ diff --git a/os_unix.c b/os_unix.c @@ -150,6 +150,8 @@ os_load_library(char *name) static void * os_lookup_dynamic_symbol(os_library_handle h, char *name) { + if (!h) + return 0; void *res = dlsym(h, name); if (!res) TraceLog(LOG_WARNING, "os_lookup_dynamic_symbol(%s): %s\n", name, dlerror()); diff --git a/os_win32.c b/os_win32.c @@ -156,6 +156,8 @@ os_load_library(char *name) static void * os_lookup_dynamic_symbol(os_library_handle h, char *name) { + if (!h) + return 0; void *res = GetProcAddress(h, name); if (!res) TraceLog(LOG_WARNING, "os_lookup_dynamic_symbol(%s): %s\n", name, GetLastError());