ogl_beamforming

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

Commit: 1b9d11f38cb94fb5b055538b2f6471217fbbc6ad
Parent: 358d80e69b7e1fc2f4e889468dee439e1231a632
Author: Randy Palamar
Date:   Tue,  8 Apr 2025 19:55:31 -0600

lib: support uploading UI parameters separately

Diffstat:
Mbeamformer.c | 8+++++---
Mbeamformer_parameters.h | 5+++--
Mbeamformer_work_queue.h | 39++++++++++++++++++++++++++-------------
Mhelpers/ogl_beamformer_lib.c | 34++++++++++++++++++++++++++++++++++
Mhelpers/ogl_beamformer_lib.h | 2++
5 files changed, 70 insertions(+), 18 deletions(-)

diff --git a/beamformer.c b/beamformer.c @@ -594,11 +594,13 @@ complete_queue(BeamformerCtx *ctx, BeamformWorkQueue *q, Arena arena, iptr gl_co ARRAY_COUNT(sm->focal_vectors), GL_RG, GL_FLOAT, sm->focal_vectors); } break; - case BW_UPLOAD_PARAMETERS: { - ASSERT(!atomic_load(&ctx->shared_memory->parameters_sync)); + case BW_UPLOAD_PARAMETERS: + case BW_UPLOAD_PARAMETERS_HEAD: + case BW_UPLOAD_PARAMETERS_UI: { + ASSERT(!atomic_load((i32 *)((u8 *)ctx->shared_memory + work->completion_barrier))); glNamedBufferSubData(cs->shared_ubo, 0, sizeof(ctx->shared_memory->parameters), &ctx->shared_memory->parameters); - ctx->ui_read_params = !work->generic; + ctx->ui_read_params = work->type != BW_UPLOAD_PARAMETERS_HEAD && !work->generic; } break; case BW_UPLOAD_RF_DATA: { ASSERT(!atomic_load(&ctx->shared_memory->raw_data_sync)); diff --git a/beamformer_parameters.h b/beamformer_parameters.h @@ -97,8 +97,9 @@ typedef enum { X(readi_group_size, u32, , uint, , "/* Size of readi transmit group */") #define X(name, type, size, gltype, glsize, comment) type name size; -typedef struct { BEAMFORMER_UI_PARAMS } BeamformerUIParameters; -typedef struct { BEAMFORMER_PARAMS_HEAD_V0 } BeamformerFixedParametersV0; +typedef struct { BEAMFORMER_UI_PARAMS } BeamformerUIParameters; +typedef struct { BEAMFORMER_PARAMS_HEAD } BeamformerParametersHead; +typedef struct { BEAMFORMER_PARAMS_TAIL } BeamformerParametersTail; typedef struct { BEAMFORMER_PARAMS_HEAD_V0 diff --git a/beamformer_work_queue.h b/beamformer_work_queue.h @@ -13,6 +13,8 @@ typedef enum { BW_UPLOAD_CHANNEL_MAPPING, BW_UPLOAD_FOCAL_VECTORS, BW_UPLOAD_PARAMETERS, + BW_UPLOAD_PARAMETERS_HEAD, + BW_UPLOAD_PARAMETERS_UI, BW_UPLOAD_RF_DATA, BW_UPLOAD_SPARSE_ELEMENTS, } BeamformWorkType; @@ -57,13 +59,34 @@ typedef BEAMFORM_WORK_QUEUE_PUSH_COMMIT_FN(beamform_work_queue_push_commit_fn); #define BEAMFORMER_MAX_RF_DATA_SIZE (BEAMFORMER_SHARED_MEMORY_SIZE - BEAMFORMER_RF_DATA_OFF) typedef struct { - BeamformerParameters parameters; + /* NOTE(rnp): interleaved transmit angle, focal depth pairs */ + _Alignas(64) v2 focal_vectors[256]; + + i16 channel_mapping[256]; + i16 sparse_elements[256]; + + union { + BeamformerParameters parameters; + struct { + BeamformerParametersHead parameters_head; + BeamformerUIParameters parameters_ui; + BeamformerParametersTail parameters_tail; + }; + }; ComputeShaderID compute_stages[16]; u32 compute_stages_count; - i32 raw_data_sync; - u32 raw_data_size; + i32 parameters_sync; + i32 parameters_head_sync; + i32 parameters_ui_sync; + + i32 focal_vectors_sync; + i32 channel_mapping_sync; + i32 sparse_elements_sync; + + i32 raw_data_sync; + u32 raw_data_size; i32 dispatch_compute_sync; ImagePlaneTag current_image_plane; @@ -71,19 +94,9 @@ typedef struct { /* TODO(rnp): these shouldn't be needed */ b32 export_next_frame; - i32 parameters_sync; - i32 channel_mapping_sync; - i32 sparse_elements_sync; - i32 focal_vectors_sync; - /* TODO(rnp): probably remove this */ c8 export_pipe_name[256]; - i16 channel_mapping[256]; - i16 sparse_elements[256]; - /* NOTE(rnp): interleaved transmit angle, focal depth pairs */ - v2 focal_vectors[256]; - BeamformWorkQueue external_work_queue; } BeamformerSharedMemory; diff --git a/helpers/ogl_beamformer_lib.c b/helpers/ogl_beamformer_lib.c @@ -319,6 +319,40 @@ beamformer_push_parameters(char *shm_name, BeamformerParameters *bp, i32 timeout } b32 +beamformer_push_ui_parameters(char *shm_name, BeamformerUIParameters *bp, i32 timeout_ms) +{ + b32 result = check_shared_memory(shm_name); + if (result) { + BeamformWork *work = beamform_work_queue_push(&g_bp->external_work_queue); + result = work && try_wait_sync(&g_bp->parameters_ui_sync, timeout_ms, os_wait_on_value); + if (result) { + work->type = BW_UPLOAD_PARAMETERS_UI; + work->completion_barrier = offsetof(BeamformerSharedMemory, parameters_ui_sync); + mem_copy(&g_bp->parameters_ui, bp, sizeof(g_bp->parameters_ui)); + beamform_work_queue_push_commit(&g_bp->external_work_queue); + } + } + return result; +} + +b32 +beamformer_push_parameters_head(char *shm_name, BeamformerParametersHead *bp, i32 timeout_ms) +{ + b32 result = check_shared_memory(shm_name); + if (result) { + BeamformWork *work = beamform_work_queue_push(&g_bp->external_work_queue); + result = work && try_wait_sync(&g_bp->parameters_head_sync, timeout_ms, os_wait_on_value); + if (result) { + work->type = BW_UPLOAD_PARAMETERS_HEAD; + work->completion_barrier = offsetof(BeamformerSharedMemory, parameters_head_sync); + mem_copy(&g_bp->parameters_head, bp, sizeof(g_bp->parameters_head)); + beamform_work_queue_push_commit(&g_bp->external_work_queue); + } + } + return result; +} + +b32 set_beamformer_parameters(char *shm_name, BeamformerParametersV0 *new_bp) { b32 result = 0; diff --git a/helpers/ogl_beamformer_lib.h b/helpers/ogl_beamformer_lib.h @@ -39,3 +39,5 @@ LIB_FN b32 beamformer_push_channel_mapping(char *shm_name, i16 *mapping, u32 cou LIB_FN b32 beamformer_push_sparse_elements(char *shm_name, i16 *elements, u32 count, i32 timeout_ms); LIB_FN b32 beamformer_push_focal_vectors(char *shm_name, f32 *vectors, u32 count, i32 timeout_ms); LIB_FN b32 beamformer_push_parameters(char *shm_name, BeamformerParameters *bp, i32 timeout_ms); +LIB_FN b32 beamformer_push_parameters_ui(char *shm_name, BeamformerUIParameters *, i32 timeout_ms); +LIB_FN b32 beamformer_push_parameters_head(char *shm_name, BeamformerParametersHead *, i32 timeout_ms);