ogl_beamforming

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

Commit: 2161024972b50c62f2a946bdb07fdfdd09789c43
Parent: 1d4edb253aed00cf8026c63a4433cd5252939887
Author: Randy Palamar
Date:   Tue, 14 Oct 2025 12:08:56 -0600

shaders/das: add RCAOrientation none, change tx_rx packing

after some conversation we decided this makes the most sense

Diffstat:
Mbeamformer.c | 3---
Mbeamformer.meta | 4++--
Mgenerated/beamformer.meta.c | 18+++++++++---------
Mshaders/das.glsl | 14+++++++-------
Mtests/throughput.c | 30+++++++++++++++++++-----------
5 files changed, 37 insertions(+), 32 deletions(-)

diff --git a/beamformer.c b/beamformer.c @@ -634,9 +634,6 @@ plan_compute_pipeline(BeamformerComputePlan *cp, BeamformerParameterBlock *pb) if (id == BeamformerAcquisitionKind_UFORCES || id == BeamformerAcquisitionKind_UHERCULES) bp->flags |= BeamformerShaderDASFlags_Sparse; - if (id == BeamformerAcquisitionKind_HERO_PA) - bp->flags |= BeamformerShaderDASFlags_ReceiveOnly; - commit = 1; }break; default:{ commit = 1; }break; diff --git a/beamformer.meta b/beamformer.meta @@ -1,6 +1,6 @@ @Enumeration(DataKind [Int16 Int16Complex Float32 Float32Complex]) @Enumeration(DecodeMode [None Hadamard]) -@Enumeration(RCAOrientation [Rows Columns]) +@Enumeration(RCAOrientation [None Rows Columns]) @Enumeration(SamplingMode [2X 4X]) @Table([name pretty_name fixed_transmits]) AcquisitionKind @@ -104,7 +104,7 @@ @Enumeration(DataKind) @Enumeration(InterpolationMode) @Enumeration(RCAOrientation) - @Flags([Fast Sparse CoherencyWeighting ReceiveOnly SingleFocus SingleOrientation]) + @Flags([Fast Sparse CoherencyWeighting SingleFocus SingleOrientation]) @Bake { diff --git a/generated/beamformer.meta.c b/generated/beamformer.meta.c @@ -17,8 +17,9 @@ typedef enum { } BeamformerDecodeMode; typedef enum { - BeamformerRCAOrientation_Rows = 0, - BeamformerRCAOrientation_Columns = 1, + BeamformerRCAOrientation_None = 0, + BeamformerRCAOrientation_Rows = 1, + BeamformerRCAOrientation_Columns = 2, BeamformerRCAOrientation_Count, } BeamformerRCAOrientation; @@ -65,9 +66,8 @@ typedef enum { BeamformerShaderDASFlags_Fast = (1 << 0), BeamformerShaderDASFlags_Sparse = (1 << 1), BeamformerShaderDASFlags_CoherencyWeighting = (1 << 2), - BeamformerShaderDASFlags_ReceiveOnly = (1 << 3), - BeamformerShaderDASFlags_SingleFocus = (1 << 4), - BeamformerShaderDASFlags_SingleOrientation = (1 << 5), + BeamformerShaderDASFlags_SingleFocus = (1 << 3), + BeamformerShaderDASFlags_SingleOrientation = (1 << 4), } BeamformerShaderDASFlags; typedef enum { @@ -207,8 +207,9 @@ read_only global s8 beamformer_shader_global_header_strings[] = { "#define DecodeMode_Hadamard 1\n" "\n"), s8_comp("" - "#define RCAOrientation_Rows 0\n" - "#define RCAOrientation_Columns 1\n" + "#define RCAOrientation_None 0\n" + "#define RCAOrientation_Rows 1\n" + "#define RCAOrientation_Columns 2\n" "\n"), s8_comp("" "#define SamplingMode_2X 0\n" @@ -248,7 +249,6 @@ read_only global s8 *beamformer_shader_flag_strings[] = { s8_comp("Fast"), s8_comp("Sparse"), s8_comp("CoherencyWeighting"), - s8_comp("ReceiveOnly"), s8_comp("SingleFocus"), s8_comp("SingleOrientation"), }, @@ -260,7 +260,7 @@ read_only global s8 *beamformer_shader_flag_strings[] = { read_only global u8 beamformer_shader_flag_strings_count[] = { 1, 3, - 6, + 5, 0, 0, 0, diff --git a/shaders/das.glsl b/shaders/das.glsl @@ -41,8 +41,8 @@ layout(r16i, binding = 1) readonly restrict uniform iimage1D sparse_elements; layout(rg32f, binding = 2) readonly restrict uniform image1D focal_vectors; layout(r8i, binding = 3) readonly restrict uniform iimage1D transmit_receive_orientations; -#define RX_ORIENTATION_MASK (1 << 0) -#define TX_ORIENTATION_MASK (1 << 1) +#define RX_ORIENTATION(tx_rx) (((tx_rx) >> 0) & 0x0F) +#define TX_ORIENTATION(tx_rx) (((tx_rx) >> 4) & 0x0F) #define C_SPLINE 0.5 @@ -173,8 +173,8 @@ vec2 focal_vector_for_acquisition(const int acquisition) float rca_transmit_distance(const vec3 world_point, const vec2 focal_vector, const int transmit_receive_orientation) { float result = 0; - #if !ReceiveOnly - bool tx_rows = (transmit_receive_orientation & TX_ORIENTATION_MASK) == 0; + if (TX_ORIENTATION(transmit_receive_orientation) != RCAOrientation_None) { + bool tx_rows = TX_ORIENTATION(transmit_receive_orientation) == RCAOrientation_Rows; float transmit_angle = radians(focal_vector.x); float focal_depth = focal_vector.y; @@ -183,7 +183,7 @@ float rca_transmit_distance(const vec3 world_point, const vec2 focal_vector, con } else { result = cylindrical_wave_transmit_distance(world_point, focal_depth, transmit_angle, tx_rows); } - #endif + } return result; } @@ -194,7 +194,7 @@ RESULT_TYPE RCA(const vec3 world_point) RESULT_TYPE result = RESULT_TYPE(0); for (int acquisition = acquisition_start; acquisition < acquisition_end; acquisition++) { const int tx_rx_orientation = tx_rx_orientation_for_acquisition(acquisition); - const bool rx_rows = (tx_rx_orientation & RX_ORIENTATION_MASK) == 0; + const bool rx_rows = RX_ORIENTATION(tx_rx_orientation) == RCAOrientation_Rows; const vec2 focal_vector = focal_vector_for_acquisition(acquisition); vec2 xdc_world_point = rca_plane_projection((xdc_transform * vec4(world_point, 1)).xyz, rx_rows); float transmit_distance = rca_transmit_distance(world_point, focal_vector, tx_rx_orientation); @@ -220,7 +220,7 @@ RESULT_TYPE HERCULES(const vec3 world_point) const int rx_channel_end = bool(Fast)? u_channel + 1 : ChannelCount; const int tx_rx_orientation = tx_rx_orientation_for_acquisition(0); - const bool rx_cols = (tx_rx_orientation & RX_ORIENTATION_MASK) != 0; + const bool rx_cols = RX_ORIENTATION(tx_rx_orientation) == RCAOrientation_Columns; const vec2 focal_vector = focal_vector_for_acquisition(0); const float transmit_distance = rca_transmit_distance(world_point, focal_vector, tx_rx_orientation); const vec3 xdc_world_point = (xdc_transform * vec4(world_point, 1)).xyz; diff --git a/tests/throughput.c b/tests/throughput.c @@ -369,27 +369,35 @@ execute_study(s8 study, Arena arena, Stream path, Options *options) zbp->sparse_elements[i] = i; } - #if 1 + b32 tx_rows = (zbp->transmit_mode & (1 << 1)) == 0; + b32 rx_rows = (zbp->transmit_mode & (1 << 0)) == 0; + u8 packed_tx_rx = 0; + if (tx_rows) packed_tx_rx |= BeamformerRCAOrientation_Rows << 4; + else packed_tx_rx |= BeamformerRCAOrientation_Columns << 4; + if (rx_rows) packed_tx_rx |= BeamformerRCAOrientation_Rows << 0; + else packed_tx_rx |= BeamformerRCAOrientation_Columns << 0; + + if (bp.das_shader_id == BeamformerAcquisitionKind_HERCULES || + bp.das_shader_id == BeamformerAcquisitionKind_UHERCULES) { + bp.single_focus = 1; + bp.single_orientation = 1; + + bp.transmit_receive_orientation = packed_tx_rx; + bp.focal_vector[0] = zbp->transmit_angles[0]; + bp.focal_vector[1] = zbp->focal_depths[0]; + } else { alignas(64) v2 focal_vectors[BeamformerMaxChannelCount]; for (u32 i = 0; i < countof(focal_vectors); i++) focal_vectors[i] = (v2){{zbp->transmit_angles[i], zbp->focal_depths[i]}}; beamformer_push_focal_vectors((f32 *)focal_vectors, countof(focal_vectors)); - } - { + alignas(64) u8 transmit_receive_orientations[BeamformerMaxChannelCount]; for (u32 i = 0; i < countof(transmit_receive_orientations); i++) - transmit_receive_orientations[i] = (u8)zbp->transmit_mode; + transmit_receive_orientations[i] = packed_tx_rx; beamformer_push_transmit_receive_orientations(transmit_receive_orientations, countof(transmit_receive_orientations)); } - #else - bp.single_focus = 1; - bp.single_orientation = 1; - bp.transmit_receive_orientation = zbp->transmit_mode; - bp.focal_vector[0] = zbp->transmit_angles[0]; - bp.focal_vector[1] = zbp->focal_depths[0]; - #endif beamformer_push_channel_mapping(zbp->channel_mapping, countof(zbp->channel_mapping)); beamformer_push_sparse_elements(zbp->sparse_elements, countof(zbp->sparse_elements));