ogl_beamforming

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

Commit: 6b005a1202c2747d9f037a063a81ca69f75739bb
Parent: 65151d60468544067e9572993df1fd47ff0558c7
Author: Randy Palamar
Date:   Mon, 20 Apr 2026 19:59:54 -0600

lib: cleanup parameter validation, drop deprecated functions

validation should be easy to follow and easy to modify. typically
I prefer to avoid early return but in this case it greatly
improves readability and ease of constaint addition.

Diffstat:
Mbeamformer.meta | 20+++++---------------
Mbeamformer_shared_memory.c | 8++++----
Mgenerated/beamformer.meta.c | 15+++++++--------
Mlib/ogl_beamformer_lib.c | 81++++++++++++++++++++++++++++++-------------------------------------------------
Mlib/ogl_beamformer_lib_base.h | 19++++++++-----------
5 files changed, 55 insertions(+), 88 deletions(-)

diff --git a/beamformer.meta b/beamformer.meta @@ -10,7 +10,7 @@ [Float32Complex 4 2] } -@Enumeration(EmissionKind [Sine SineAM Chirp]) +@Enumeration(EmissionKind [Sine Chirp]) @Table([type name]) SineParameters { @@ -18,13 +18,6 @@ [F32 frequency] } -@Table([type name]) SineAMParameters -{ - [F32 cycles ] - [F32 frequency] - [U32 emissions] -} - @Table([type name]) ChirpParameters { [F32 duration ] @@ -34,7 +27,6 @@ @MUnion(EmissionKind [ SineParameters - SineAMParameters ChirpParameters ]) Emission @@ -149,9 +141,6 @@ @Expand(SineParameters) ` $(%type)$(|)$(name);` ` } sine;` ` struct {` - @Expand(SineAMParameters) ` $(%type)$(|)$(name);` - ` } sine_am;` - ` struct {` @Expand(ChirpParameters) ` $(%type)$(|)$(name);` ` } chirp;` `} BeamformerEmissionParameters;` @@ -171,6 +160,10 @@ `} BeamformerUIParameters;` `` `typedef struct {` + @Expand(ParametersExtra) ` $(c_type)$(|)$(name);` + `} BeamformerParametersExtra;` + `` + `typedef struct {` @Expand(ParametersHead) ` $(%type)$(|)$(name);` @Expand(ParametersUI) ` $(%type)$(|)$(name);` @Expand(ParametersExtra) ` $(c_type)$(|)$(name);` @@ -314,9 +307,6 @@ @Expand(SineParameters) ` $(%type)$(|)$(name);` ` } sine;` ` struct {` - @Expand(SineAMParameters) ` $(%type)$(|)$(name);` - ` } sine_am;` - ` struct {` @Expand(ChirpParameters) ` $(%type)$(|)$(name);` ` } chirp;` `} BeamformerEmissionParameters;` diff --git a/beamformer_shared_memory.c b/beamformer_shared_memory.c @@ -1,5 +1,5 @@ /* See LICENSE for license details. */ -#define BEAMFORMER_SHARED_MEMORY_VERSION (24UL) +#define BEAMFORMER_SHARED_MEMORY_VERSION (25UL) typedef struct BeamformerFrame BeamformerFrame; @@ -8,7 +8,6 @@ typedef enum { BeamformerWorkKind_ComputeIndirect, BeamformerWorkKind_CreateFilter, BeamformerWorkKind_ExportBuffer, - BeamformerWorkKind_UploadBuffer, } BeamformerWorkKind; typedef struct { @@ -105,8 +104,9 @@ typedef struct { alignas(16) union { BeamformerParameters parameters; struct { - BeamformerParametersHead parameters_head; - BeamformerUIParameters parameters_ui; + BeamformerParametersHead parameters_head; + BeamformerUIParameters parameters_ui; + BeamformerParametersExtra parameters_extra; }; }; diff --git a/generated/beamformer.meta.c b/generated/beamformer.meta.c @@ -22,9 +22,8 @@ typedef enum { } BeamformerSamplingMode; typedef enum { - BeamformerEmissionKind_Sine = 0, - BeamformerEmissionKind_SineAM = 1, - BeamformerEmissionKind_Chirp = 2, + BeamformerEmissionKind_Sine = 0, + BeamformerEmissionKind_Chirp = 1, BeamformerEmissionKind_Count, } BeamformerEmissionKind; @@ -162,11 +161,6 @@ typedef union { f32 frequency; } sine; struct { - f32 cycles; - f32 frequency; - u32 emissions; - } sine_am; - struct { f32 duration; f32 min_frequency; f32 max_frequency; @@ -231,6 +225,11 @@ typedef struct { } BeamformerUIParameters; typedef struct { + BeamformerEmissionKind emission_kind; + BeamformerEmissionParameters emission_parameters; +} BeamformerParametersExtra; + +typedef struct { m4 das_voxel_transform; m4 xdc_transform; v2 xdc_element_pitch; diff --git a/lib/ogl_beamformer_lib.c b/lib/ogl_beamformer_lib.c @@ -251,37 +251,33 @@ beamformer_reserve_parameter_blocks(uint32_t count) function b32 validate_pipeline(i32 *shaders, u32 shader_count, BeamformerDataKind data_kind) { - b32 result = lib_error_check(shader_count <= BeamformerMaxComputeShaderStages, ComputeStageOverflow); - if (result) { - for (u32 i = 0; i < shader_count; i++) - result &= BETWEEN(shaders[i], BeamformerShaderKind_ComputeFirst, BeamformerShaderKind_ComputeLast); - if (!result) { - g_beamformer_library_context.last_error = BeamformerLibErrorKind_InvalidComputeStage; - } else if (shaders[0] != BeamformerShaderKind_Demodulate && - shaders[0] != BeamformerShaderKind_Decode) - { - g_beamformer_library_context.last_error = BeamformerLibErrorKind_InvalidStartShader; - result = 0; - } else if (shaders[0] == BeamformerShaderKind_Demodulate && - !(data_kind == BeamformerDataKind_Int16 || data_kind == BeamformerDataKind_Float32)) + b32 data_kind_test = Between(data_kind, 0, BeamformerDataKind_Count - 1) && + data_kind != BeamformerDataKind_Float16 && + data_kind != BeamformerDataKind_Float16Complex; + if (!lib_error_check(data_kind_test, InvalidDataKind)) + return 0; + + if (!lib_error_check(shader_count <= BeamformerMaxComputeShaderStages, ComputeStageOverflow)) + return 0; + + for (u32 i = 0; i < shader_count; i++) { + b32 stage_test = Between(shaders[i], BeamformerShaderKind_ComputeFirst, BeamformerShaderKind_ComputeLast); + if (!lib_error_check(stage_test, InvalidComputeStage)) + return 0; + + if (shaders[i] == BeamformerShaderKind_Demodulate && + !lib_error_check(!beamformer_data_kind_complex[data_kind], InvalidDemodulationDataKind)) { - g_beamformer_library_context.last_error = BeamformerLibErrorKind_InvalidDemodulationDataKind; - result = 0; + return 0; } } - return result; -} -function b32 -validate_simple_parameters(BeamformerSimpleParameters *bp) -{ - b32 result = check_shared_memory(); - if (result) { - result &= bp->channel_count <= BeamformerMaxChannelCount; - if (!result) - g_beamformer_library_context.last_error = BeamformerLibErrorKind_InvalidSimpleParameters; - } - return result; + b32 start_stage_test = shaders[0] == BeamformerShaderKind_Demodulate || + shaders[0] == BeamformerShaderKind_Decode; + if (!lib_error_check(start_stage_test, InvalidStartShader)) + return 0; + + return 1; } function b32 @@ -486,10 +482,13 @@ beamformer_push_data_with_compute(void *data, u32 data_size, u32 image_plane_tag b32 beamformer_push_parameters_at(BeamformerParameters *bp, u32 block) { - b32 result = parameter_block_region_upload(bp, sizeof(*bp), block, - BeamformerParameterBlockRegion_Parameters, - offsetof(BeamformerParameterBlock, parameters), - g_beamformer_library_context.timeout_ms); + b32 result = check_shared_memory(); + if (result) { + result = parameter_block_region_upload(bp, sizeof(*bp), block, + BeamformerParameterBlockRegion_Parameters, + offsetof(BeamformerParameterBlock, parameters), + g_beamformer_library_context.timeout_ms); + } return result; } @@ -503,7 +502,7 @@ beamformer_push_parameters(BeamformerParameters *bp) b32 beamformer_push_simple_parameters_at(BeamformerSimpleParameters *bp, u32 block) { - b32 result = validate_simple_parameters(bp); + b32 result = check_shared_memory(); if (result) { alignas(64) v2 focal_vectors[countof(bp->steering_angles)]; for (u32 i = 0; i < countof(bp->steering_angles); i++) @@ -535,24 +534,6 @@ beamformer_push_simple_parameters(BeamformerSimpleParameters *bp) return result; } -b32 -beamformer_push_parameters_ui(BeamformerUIParameters *bp) -{ - b32 result = parameter_block_region_upload(bp, sizeof(*bp), 0, BeamformerParameterBlockRegion_Parameters, - offsetof(BeamformerParameterBlock, parameters_ui), - g_beamformer_library_context.timeout_ms); - return result; -} - -b32 -beamformer_push_parameters_head(BeamformerParametersHead *bp) -{ - b32 result = parameter_block_region_upload(bp, sizeof(*bp), 0, BeamformerParameterBlockRegion_Parameters, - offsetof(BeamformerParameterBlock, parameters_head), - g_beamformer_library_context.timeout_ms); - return result; -} - function b32 beamformer_export_buffer(BeamformerExportContext export_context) { diff --git a/lib/ogl_beamformer_lib_base.h b/lib/ogl_beamformer_lib_base.h @@ -18,14 +18,14 @@ X(InvalidStartShader, 7, "starting shader not Decode or Demodulate") \ X(InvalidDemodulationDataKind, 8, "data kind for demodulation not Int16 or Float") \ X(InvalidImagePlane, 9, "invalid image plane") \ - X(BufferOverflow, 10, "passed buffer size exceeds available space") \ - X(DataSizeMismatch, 11, "data size doesn't match the size specified in parameters") \ - X(WorkQueueFull, 12, "work queue full") \ - X(ExportSpaceOverflow, 13, "not enough space for data export") \ - X(SharedMemory, 14, "failed to open shared memory region") \ - X(SyncVariable, 15, "failed to acquire lock within timeout period") \ - X(InvalidFilterKind, 16, "invalid filter kind") \ - X(InvalidSimpleParameters, 17, "invalid simple parameters struct") + X(InvalidFilterKind, 10, "invalid filter kind") \ + X(InvalidDataKind, 11, "invalid data kind") \ + X(BufferOverflow, 12, "passed buffer size exceeds available space") \ + X(DataSizeMismatch, 13, "data size doesn't match the size specified in parameters") \ + X(WorkQueueFull, 14, "work queue full") \ + X(ExportSpaceOverflow, 15, "not enough space for data export") \ + X(SharedMemory, 16, "failed to open shared memory region") \ + X(SyncVariable, 17, "failed to acquire lock within timeout period") \ #define X(type, num, string) BeamformerLibErrorKind_##type = num, typedef enum {BEAMFORMER_LIB_ERRORS} BeamformerLibErrorKind; @@ -95,9 +95,6 @@ BEAMFORMER_LIB_EXPORT uint32_t beamformer_push_simple_parameters_at(BeamformerSi uint32_t parameter_slot); BEAMFORMER_LIB_EXPORT uint32_t beamformer_push_parameters(BeamformerParameters *); -BEAMFORMER_LIB_EXPORT uint32_t beamformer_push_parameters_ui(BeamformerUIParameters *); -BEAMFORMER_LIB_EXPORT uint32_t beamformer_push_parameters_head(BeamformerParametersHead *); - BEAMFORMER_LIB_EXPORT uint32_t beamformer_push_parameters_at(BeamformerParameters *, uint32_t parameter_slot);