ogl_beamforming

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

Commit: b19705071b7a92e382f61f380985fbc9b1b117ac
Parent: fe976129d5b9e6804c5b1f59722ac3e891f7ed3d
Author: Randy Palamar
Date:   Mon, 19 Oct 2026 18:08:03 -0700

shaders/das: drop SingleFocus/SingleOrientation flag

AcquisitionKinds which use this now get the focus and orientation
out of the push constants.

Diffstat:
Mbeamformer.meta | 5-----
Mbeamformer_core.c | 4----
Mgenerated/beamformer.c | 32++++++++++----------------------
Mlib/ogl_beamformer_lib.c | 10++++++----
Mshaders/das.glsl | 18+++---------------
5 files changed, 19 insertions(+), 50 deletions(-)

diff --git a/beamformer.meta b/beamformer.meta @@ -404,8 +404,6 @@ @Flags { CoherencyWeighting - SingleFocus - SingleOrientation Sparse } @@ -440,9 +438,6 @@ [TimeOffset F32] [FNumber F32] - [FocusDepth F32] - [TransmitAngle F32] - [OutputSizeX U32] [OutputSizeY U32] [OutputSizeZ U32] diff --git a/beamformer_core.c b/beamformer_core.c @@ -938,8 +938,6 @@ plan_compute_pipeline(BeamformerComputePlan *cp, BeamformerParameterBlock *pb, A db->TransmitTileCount = 1; db->InterpolationMode = pb->parameters.interpolation_mode; - db->TransmitAngle = pb->parameters.focal_vector.E[0]; - db->FocusDepth = pb->parameters.focal_vector.E[1]; db->ReadiGroupCount = pb->parameters.readi_group_count; db->OutputSizeX = cp->output_points.x; db->OutputSizeY = cp->output_points.y; @@ -956,8 +954,6 @@ plan_compute_pipeline(BeamformerComputePlan *cp, BeamformerParameterBlock *pb, A b32 single_orientation = pb->parameters.single_orientation != 0; sd->compile_flags |= BeamformerDASCompileFlags_CoherencyWeighting * (pb->parameters.coherency_weighting != 0); - sd->compile_flags |= BeamformerDASCompileFlags_SingleFocus * single_focus; - sd->compile_flags |= BeamformerDASCompileFlags_SingleOrientation * single_orientation; sd->compile_flags |= BeamformerDASCompileFlags_Sparse * sparse; sd->layout = layout_for_output(cp->output_points); diff --git a/generated/beamformer.c b/generated/beamformer.c @@ -146,9 +146,7 @@ typedef enum { typedef enum { BeamformerDASCompileFlags_CoherencyWeighting = 1 << 0, - BeamformerDASCompileFlags_SingleFocus = 1 << 1, - BeamformerDASCompileFlags_SingleOrientation = 1 << 2, - BeamformerDASCompileFlags_Sparse = 1 << 3, + BeamformerDASCompileFlags_Sparse = 1 << 1, } BeamformerDASCompileFlags; typedef enum { @@ -235,8 +233,6 @@ typedef struct { f32 SpeedOfSound; f32 TimeOffset; f32 FNumber; - f32 FocusDepth; - f32 TransmitAngle; u32 OutputSizeX; u32 OutputSizeY; u32 OutputSizeZ; @@ -509,11 +505,9 @@ read_only MetaStructMember *meta_struct_members_by_id[] = { {8, 68, 1, 0}, {8, 72, 1, 0}, {8, 76, 1, 0}, - {8, 80, 1, 0}, - {8, 84, 1, 0}, + {18, 80, 1, 0}, + {18, 84, 1, 0}, {18, 88, 1, 0}, - {18, 92, 1, 0}, - {18, 96, 1, 0}, }, (MetaStructMember []){ {18, 0, 1, 0}, @@ -587,8 +581,6 @@ read_only str8 *meta_struct_member_names_by_id[] = { str8_comp("SpeedOfSound"), str8_comp("TimeOffset"), str8_comp("FNumber"), - str8_comp("FocusDepth"), - str8_comp("TransmitAngle"), str8_comp("OutputSizeX"), str8_comp("OutputSizeY"), str8_comp("OutputSizeZ"), @@ -612,11 +604,11 @@ read_only str8 *meta_struct_member_names_by_id[] = { }; read_only MetaStructInfo meta_struct_info_by_id[] = { - {str8_comp("DecodeBakeParameters"), 11, 44, 0}, - {str8_comp("FilterBakeParameters"), 13, 52, 0}, - {str8_comp("DASBakeParameters"), 29, 100, 0}, - {str8_comp("CoherencyWeightingBakeParameters"), 3, 12, 0}, - {str8_comp("ReshapeBakeParameters"), 9, 36, 0}, + {str8_comp("DecodeBakeParameters"), 11, 44, 0}, + {str8_comp("FilterBakeParameters"), 13, 52, 0}, + {str8_comp("DASBakeParameters"), 27, 92, 0}, + {str8_comp("CoherencyWeightingBakeParameters"), 3, 12, 0}, + {str8_comp("ReshapeBakeParameters"), 9, 36, 0}, }; read_only str8 beamformer_shader_names[] = { @@ -736,9 +728,7 @@ read_only str8 beamformer_shader_global_header_strings[] = { "\n"), str8_comp("" "#define CoherencyWeighting ((CompileFlags & (1 << 0)) != 0)\n" - "#define SingleFocus ((CompileFlags & (1 << 1)) != 0)\n" - "#define SingleOrientation ((CompileFlags & (1 << 2)) != 0)\n" - "#define Sparse ((CompileFlags & (1 << 3)) != 0)\n" + "#define Sparse ((CompileFlags & (1 << 1)) != 0)\n" "\n"), str8_comp("" "layout(push_constant, std430) uniform PushConstants {\n" @@ -851,8 +841,6 @@ read_only str8 *beamformer_shader_compile_flag_names[] = { }, (str8 []){ str8_comp("CoherencyWeighting"), - str8_comp("SingleFocus"), - str8_comp("SingleOrientation"), str8_comp("Sparse"), }, 0, @@ -868,7 +856,7 @@ read_only str8 *beamformer_shader_compile_flag_names[] = { read_only u8 beamformer_shader_compile_flag_counts[] = { 2, 2, - 4, + 2, 0, 2, 0, diff --git a/lib/ogl_beamformer_lib.c b/lib/ogl_beamformer_lib.c @@ -573,7 +573,8 @@ beamformer_start_compute(u64 offset, u32 image_plane_tag, u32 parameter_slot) lib_error_check(image_plane_tag < BeamformerViewPlaneTag_Count, InvalidImagePlane)) { // TODO(rnp): this stuff will be passed in rather than taken from the existing set - BeamformerParameters *bp = &beamformer_parameter_block(g_beamformer_library_context.bp, parameter_slot)->parameters; + BeamformerParameterBlock *pb = beamformer_parameter_block(g_beamformer_library_context.bp, parameter_slot); + BeamformerParameters *bp = &pb->parameters; BeamformWork *work = try_push_work_queue(); if (work) { @@ -582,9 +583,10 @@ beamformer_start_compute(u64 offset, u32 image_plane_tag, u32 parameter_slot) work->compute_context.view_plane = image_plane_tag; work->compute_context.parameter_set = parameter_slot; work->compute_context.rf_offset = offset; - work->compute_context.steering_angle = bp->focal_vector.x; - work->compute_context.focus_depth = bp->focal_vector.y; - work->compute_context.tx_rx_orientation = bp->transmit_receive_orientation; + work->compute_context.steering_angle = bp->single_focus ? bp->focal_vector.x : pb->focal_vectors[0].x; + work->compute_context.focus_depth = bp->single_focus ? bp->focal_vector.y : pb->focal_vectors[0].y; + work->compute_context.tx_rx_orientation = bp->single_orientation ? bp->transmit_receive_orientation + : pb->transmit_receive_orientations[0]; memory_copy(&work->compute_context.voxel_transform, &bp->das_voxel_transform, sizeof(bp->das_voxel_transform)); beamform_work_queue_push_commit(&g_beamformer_library_context.bp->external_work_queue); beamformer_flush_commands(); diff --git a/shaders/das.glsl b/shaders/das.glsl @@ -228,19 +228,6 @@ float cylindrical_wave_transmit_distance(const vec3 point, const float focal_dep return distance(rca_plane_projection(point, tx_rows), f); } -u8 tx_rx_orientation_for_acquisition(const s32 acquisition) -{ - u8 result = u8(TransmitReceiveOrientation); - if (!SingleOrientation) result = U8(HeapBase + TransmitReceiveOrientations).x[acquisition]; - return result; -} - -f32vec2 focal_vector_for_acquisition(const s32 acquisition) -{ - f32vec2 result = SingleFocus ? f32vec2(TransmitAngle, FocusDepth) : F32V2(HeapBase + FocalVectors).x[acquisition]; - return result; -} - f32 rca_transmit_distance(const vec3 world_point, const vec2 focal_vector, const u8 transmit_receive_orientation) { float result = 0; @@ -276,9 +263,10 @@ RESULT_TYPE RCA(const vec3 world_point) const mat4 xdc_transform = transducer_transform(0); for (s32 acquisition = 0; acquisition < s32(AcquisitionCount); acquisition++) { - const u8 tx_rx_orientation = tx_rx_orientation_for_acquisition(acquisition); + const u8 tx_rx_orientation = U8(HeapBase + TransmitReceiveOrientations).x[acquisition]; const bool rx_rows = RX_ORIENTATION(tx_rx_orientation) == RCAOrientation_Rows; - const vec2 focal_vector = focal_vector_for_acquisition(acquisition); + const vec2 focal_vector = F32V2(HeapBase + FocalVectors).x[acquisition]; + vec2 xdc_world_point = rca_plane_projection((xdc_transform * vec4(world_point, 1)).xyz, rx_rows); f32 transmit_index = sample_index(rca_transmit_distance(world_point, focal_vector, tx_rx_orientation));