ogl_beamforming

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

Commit: f36c234cb479149684a81c52f870cf7b80b1d440
Parent: 5a4ffd9e9003be95adddf615a1567b3b3bc6ca33
Author: Randy Palamar
Date:   Sat, 26 Jul 2025 19:27:07 -0600

lib: remove timeout argument from most functions

these now use a global timeout which can be set via a single
function if necessary. In most case no timeout is probably
correct.

Diffstat:
Mhelpers/ogl_beamformer_lib.c | 36++++++++++++++++++------------------
Mhelpers/ogl_beamformer_lib_base.h | 35++++++++++++++++++++++-------------
Mtests/throughput.c | 12++++++------
3 files changed, 46 insertions(+), 37 deletions(-)

diff --git a/helpers/ogl_beamformer_lib.c b/helpers/ogl_beamformer_lib.c @@ -18,6 +18,7 @@ W32(iptr) OpenFileMappingA(u32, b32, c8 *); #include "../beamformer_work_queue.c" +global int32_t g_timeout_ms; global SharedMemoryRegion g_shared_memory; global BeamformerSharedMemory *g_bp; global BeamformerLibErrorKind g_lib_last_error; @@ -170,11 +171,11 @@ validate_pipeline(i32 *shaders, i32 shader_count, BeamformerDataKind data_kind) } b32 -beamformer_set_pipeline_stage_parameters(i32 stage_index, i32 parameter, i32 timeout_ms) +beamformer_set_pipeline_stage_parameters(i32 stage_index, i32 parameter) { b32 result = 0; BeamformerSharedMemoryLockKind lock = BeamformerSharedMemoryLockKind_ComputePipeline; - if (check_shared_memory() && g_bp->shader_count != 0 && lib_try_lock(lock, timeout_ms)) { + if (check_shared_memory() && g_bp->shader_count != 0 && lib_try_lock(lock, g_timeout_ms)) { stage_index %= (i32)g_bp->shader_count; g_bp->shader_parameters[stage_index].filter_slot = (u8)parameter; atomic_or_u32(&g_bp->dirty_regions, 1 << (lock - 1)); @@ -184,12 +185,12 @@ beamformer_set_pipeline_stage_parameters(i32 stage_index, i32 parameter, i32 tim } b32 -beamformer_push_pipeline(i32 *shaders, i32 shader_count, BeamformerDataKind data_kind, i32 timeout_ms) +beamformer_push_pipeline(i32 *shaders, i32 shader_count, BeamformerDataKind data_kind) { b32 result = 0; if (validate_pipeline(shaders, shader_count, data_kind) && check_shared_memory()) { BeamformerSharedMemoryLockKind lock = BeamformerSharedMemoryLockKind_ComputePipeline; - if (lib_try_lock(lock, timeout_ms)) { + if (lib_try_lock(lock, g_timeout_ms)) { g_bp->shader_count = shader_count; g_bp->data_kind = data_kind; for (i32 i = 0; i < shader_count; i++) @@ -283,13 +284,13 @@ beamformer_upload_buffer(void *data, u32 size, i32 store_offset, BeamformerUploa X(focal_vectors, f32, 2, FocalVectors) #define X(name, dtype, elements, lock_name) \ -b32 beamformer_push_##name (dtype *data, u32 count, i32 timeout_ms) { \ +b32 beamformer_push_##name (dtype *data, u32 count) { \ b32 result = 0; \ if (count <= countof(g_bp->name)) { \ result = beamformer_upload_buffer(data, count * elements * sizeof(dtype), \ offsetof(BeamformerSharedMemory, name), \ BeamformerUploadKind_##lock_name, \ - BeamformerSharedMemoryLockKind_##lock_name, timeout_ms); \ + BeamformerSharedMemoryLockKind_##lock_name, g_timeout_ms); \ } else { \ g_lib_last_error = BF_LIB_ERR_KIND_BUFFER_OVERFLOW; \ } \ @@ -314,15 +315,15 @@ beamformer_push_data_base(void *data, u32 data_size, i32 timeout_ms, b32 start_f } b32 -beamformer_push_data(void *data, u32 data_size, i32 timeout_ms) +beamformer_push_data(void *data, u32 data_size) { - return beamformer_push_data_base(data, data_size, timeout_ms, 1); + return beamformer_push_data_base(data, data_size, g_timeout_ms, 1); } b32 -beamformer_push_data_with_compute(void *data, u32 data_size, u32 image_plane_tag, i32 timeout_ms) +beamformer_push_data_with_compute(void *data, u32 data_size, u32 image_plane_tag) { - b32 result = beamformer_push_data_base(data, data_size, timeout_ms, 0); + b32 result = beamformer_push_data_base(data, data_size, g_timeout_ms, 0); if (result) { result = image_plane_tag < BeamformerViewPlaneTag_Count; if (result) { @@ -341,29 +342,29 @@ beamformer_push_data_with_compute(void *data, u32 data_size, u32 image_plane_tag } b32 -beamformer_push_parameters(BeamformerParameters *bp, i32 timeout_ms) +beamformer_push_parameters(BeamformerParameters *bp) { b32 result = locked_region_upload((u8 *)g_bp + offsetof(BeamformerSharedMemory, parameters), bp, sizeof(*bp), BeamformerSharedMemoryLockKind_Parameters, - 0, timeout_ms); + 0, g_timeout_ms); return result; } b32 -beamformer_push_parameters_ui(BeamformerUIParameters *bp, i32 timeout_ms) +beamformer_push_parameters_ui(BeamformerUIParameters *bp) { b32 result = locked_region_upload((u8 *)g_bp + offsetof(BeamformerSharedMemory, parameters_ui), bp, sizeof(*bp), BeamformerSharedMemoryLockKind_Parameters, - 0, timeout_ms); + 0, g_timeout_ms); return result; } b32 -beamformer_push_parameters_head(BeamformerParametersHead *bp, i32 timeout_ms) +beamformer_push_parameters_head(BeamformerParametersHead *bp) { b32 result = locked_region_upload((u8 *)g_bp + offsetof(BeamformerSharedMemory, parameters_head), bp, sizeof(*bp), BeamformerSharedMemoryLockKind_Parameters, - 0, timeout_ms); + 0, g_timeout_ms); return result; } @@ -410,8 +411,7 @@ beamform_data_synchronized(void *data, u32 data_size, i32 output_points[3], f32 g_bp->parameters.output_points[2] = output_points[2]; uz output_size = (u32)output_points[0] * (u32)output_points[1] * (u32)output_points[2] * sizeof(f32) * 2; - if (output_size <= BEAMFORMER_SCRATCH_SIZE && - beamformer_push_data_with_compute(data, data_size, 0, 0)) + if (output_size <= BEAMFORMER_SCRATCH_SIZE && beamformer_push_data_with_compute(data, data_size, 0)) { BeamformerExportContext export; export.kind = BeamformerExportKind_BeamformedData; diff --git a/helpers/ogl_beamformer_lib_base.h b/helpers/ogl_beamformer_lib_base.h @@ -20,7 +20,8 @@ X(WORK_QUEUE_FULL, 9, "work queue full") \ X(EXPORT_SPACE_OVERFLOW, 10, "not enough space for data export") \ X(SHARED_MEMORY, 11, "failed to open shared memory region") \ - X(SYNC_VARIABLE, 12, "failed to acquire lock within timeout period") + X(SYNC_VARIABLE, 12, "failed to acquire lock within timeout period") \ + X(INVALID_TIMEOUT, 13, "invalid timeout value") #define X(type, num, string) BF_LIB_ERR_KIND_ ##type = num, typedef enum {BEAMFORMER_LIB_ERRORS} BeamformerLibErrorKind; @@ -32,7 +33,15 @@ LIB_FN BeamformerLibErrorKind beamformer_get_last_error(void); LIB_FN const char *beamformer_get_last_error_string(void); LIB_FN const char *beamformer_error_string(BeamformerLibErrorKind kind); -/* IMPORTANT: timeout of -1 will block forever */ +/* NOTE: sets timeout for all functions which may timeout but don't + * take a timeout argument. The majority of such functions will not + * timeout in the normal case and so passing a timeout parameter around + * every where is cumbersome. + * + * timeout_ms: milliseconds in the range [-1, ...) (Default: 0) + * + * IMPORTANT: timeout of -1 will block forever */ +LIB_FN uint32_t beamformer_set_global_timeout(int32_t timeout_ms); /* NOTE: sends data and waits for (complex) beamformed data to be returned. * out_data: must be allocated by the caller as 2 floats per output point. */ @@ -48,18 +57,18 @@ LIB_FN uint32_t beamformer_start_compute(int32_t timeout_ms); /* NOTE: waits for previously queued beamform to start or for timeout_ms */ LIB_FN uint32_t beamformer_wait_for_compute_dispatch(int32_t timeout_ms); -/* NOTE: these functions only queue an upload; you must flush (old data functions or start_compute) */ -LIB_FN uint32_t beamformer_push_data(void *data, uint32_t size, int32_t timeout_ms); -LIB_FN uint32_t beamformer_push_data_with_compute(void *data, uint32_t size, uint32_t image_plane_tag, int32_t timeout_ms); -LIB_FN uint32_t beamformer_push_channel_mapping(int16_t *mapping, uint32_t count, int32_t timeout_ms); -LIB_FN uint32_t beamformer_push_sparse_elements(int16_t *elements, uint32_t count, int32_t timeout_ms); -LIB_FN uint32_t beamformer_push_focal_vectors(float *vectors, uint32_t count, int32_t timeout_ms); +LIB_FN uint32_t beamformer_push_data_with_compute(void *data, uint32_t size, uint32_t image_plane_tag); +/* NOTE: these functions only queue an upload; you must flush (start_compute) */ +LIB_FN uint32_t beamformer_push_data(void *data, uint32_t size); +LIB_FN uint32_t beamformer_push_channel_mapping(int16_t *mapping, uint32_t count); +LIB_FN uint32_t beamformer_push_sparse_elements(int16_t *elements, uint32_t count); +LIB_FN uint32_t beamformer_push_focal_vectors(float *vectors, uint32_t count); -LIB_FN uint32_t beamformer_set_pipeline_stage_parameters(int32_t stage_index, int32_t parameter, int32_t timeout_ms); -LIB_FN uint32_t beamformer_push_pipeline(int32_t *shaders, int32_t shader_count, BeamformerDataKind data_kind, int32_t timeout_ms); -LIB_FN uint32_t beamformer_push_parameters(BeamformerParameters *, int32_t timeout_ms); -LIB_FN uint32_t beamformer_push_parameters_ui(BeamformerUIParameters *, int32_t timeout_ms); -LIB_FN uint32_t beamformer_push_parameters_head(BeamformerParametersHead *, int32_t timeout_ms); +LIB_FN uint32_t beamformer_set_pipeline_stage_parameters(int32_t stage_index, int32_t parameter); +LIB_FN uint32_t beamformer_push_pipeline(int32_t *shaders, int32_t shader_count, BeamformerDataKind data_kind); +LIB_FN uint32_t beamformer_push_parameters(BeamformerParameters *); +LIB_FN uint32_t beamformer_push_parameters_ui(BeamformerUIParameters *); +LIB_FN uint32_t beamformer_push_parameters_head(BeamformerParametersHead *); //////////////////// // Filter Creation diff --git a/tests/throughput.c b/tests/throughput.c @@ -293,7 +293,7 @@ send_frame(i16 *restrict i16_data, BeamformerParameters *restrict bp) b32 result = 0; u32 data_size = bp->rf_raw_dim[0] * bp->rf_raw_dim[1] * sizeof(i16); if (beamformer_wait_for_compute_dispatch(10000)) - result = beamformer_push_data_with_compute(i16_data, data_size, BeamformerViewPlaneTag_XZ, 100); + result = beamformer_push_data_with_compute(i16_data, data_size, BeamformerViewPlaneTag_XZ); if (!result && !g_should_exit) printf("lib error: %s\n", beamformer_get_last_error_string()); return result; @@ -344,12 +344,12 @@ execute_study(s8 study, Arena arena, Stream path, Options *options) align_as(64) v2 focal_vectors[countof(zbp->focal_depths)]; for (u32 i = 0; i < countof(zbp->focal_depths); i++) focal_vectors[i] = (v2){{zbp->transmit_angles[i], zbp->focal_depths[i]}}; - beamformer_push_focal_vectors((f32 *)focal_vectors, countof(focal_vectors), 0); + beamformer_push_focal_vectors((f32 *)focal_vectors, countof(focal_vectors)); } - beamformer_push_channel_mapping(zbp->channel_mapping, countof(zbp->channel_mapping), 0); - beamformer_push_sparse_elements(zbp->sparse_elements, countof(zbp->sparse_elements), 0); - beamformer_push_parameters(&bp, 0); + beamformer_push_channel_mapping(zbp->channel_mapping, countof(zbp->channel_mapping)); + beamformer_push_sparse_elements(zbp->sparse_elements, countof(zbp->sparse_elements)); + beamformer_push_parameters(&bp); free(zbp); @@ -359,7 +359,7 @@ execute_study(s8 study, Arena arena, Stream path, Options *options) else shader_stages[shader_stage_count++] = BeamformerShaderKind_Decode; shader_stages[shader_stage_count++] = BeamformerShaderKind_DAS; - set_beamformer_pipeline(shader_stages, shader_stage_count); + beamformer_push_pipeline(shader_stages, shader_stage_count, BeamformerDataKind_Int16); stream_reset(&path, path_work_index); i16 *data = decompress_data_at_work_index(&path, options->frame_number);