ogl_beamforming

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

Commit: b02956354378b13c98d03b384ecfa85d36cb0b3a
Parent: 624474e12fd652fa54502ae39511f88577ecbdbd
Author: Randy Palamar
Date:   Fri, 21 Aug 2026 18:36:16 -0700

das: switch transmit receive orientations to 8 bits again

As far as I can tell this is supported pretty much everywhere. Use
it so we can skip extra conversion code.

Diffstat:
Mbeamformer.meta | 2+-
Mbeamformer_core.c | 17+++++------------
Mgenerated/beamformer.c | 16++++++++--------
Mshaders/das.glsl | 24++++++++++++------------
Mvulkan.c | 1+
5 files changed, 27 insertions(+), 33 deletions(-)

diff --git a/beamformer.meta b/beamformer.meta @@ -270,7 +270,7 @@ { [FocalVectors focal_vectors V2 MaxChannelCount] [SparseElements sparse_elements S16 MaxChannelCount] - [TransmitReceiveOrientations transmit_receive_orientations U16 MaxChannelCount] + [TransmitReceiveOrientations transmit_receive_orientations U8 MaxChannelCount] } @Expand(ComputeArrayParametersTable) @Enumeration(`$(name_upper)`) ComputeArrayParametersField diff --git a/beamformer_core.c b/beamformer_core.c @@ -1045,6 +1045,7 @@ stream_append_shader_header(Stream *s, i32 reloadable_index, BeamformerShaderDes "#define u32 uint32_t\n" "#define s16 int16_t\n" "#define u16 uint16_t\n" + "#define u8 uint8_t\n" "#define s32vec2 i32vec2\n" "#define s16vec2 i16vec2\n" "\n")); @@ -1274,24 +1275,16 @@ beamformer_commit_parameter_block(BeamformerCtx *ctx, BeamformerComputePlan *cp, case BeamformerParameterBlockRegion_ChannelMapping:{ cuda_set_channel_mapping(pb->channel_mapping); }break; - case BeamformerParameterRegionFlag_TransmitReceiveOrientations:{ - GPUBuffer *b = &cp->array_parameters; - u32 kind = BeamformerComputeArrayParametersField_TransmitReceiveOrientations; - u64 offset = beamformer_compute_array_parameter_offsets[kind]; - u64 size = beamformer_compute_array_parameter_sizes[kind]; - { - u16 *u16s = push_array(scratch, u16, countof(pb->transmit_receive_orientations)); - for (u32 i = 0; i < countof(pb->transmit_receive_orientations); i++) - u16s[i] = pb->transmit_receive_orientations[i]; - gpu_buffer_range_upload(b, u16s, offset, size, 0); - } - }break; case BeamformerParameterRegionFlag_FocalVectors: case BeamformerParameterRegionFlag_SparseElements: + case BeamformerParameterRegionFlag_TransmitReceiveOrientations: { u32 kind = BeamformerComputeArrayParametersField_Count; switch (region) { + case BeamformerParameterRegionFlag_TransmitReceiveOrientations:{ + kind = BeamformerComputeArrayParametersField_TransmitReceiveOrientations; + }break; case BeamformerParameterBlockRegion_FocalVectors:{ kind = BeamformerComputeArrayParametersField_FocalVectors; }break; diff --git a/generated/beamformer.c b/generated/beamformer.c @@ -463,7 +463,7 @@ typedef struct { typedef struct { v2 focal_vectors[BeamformerMaxChannelCount]; i16 sparse_elements[BeamformerMaxChannelCount]; - u16 transmit_receive_orientations[BeamformerMaxChannelCount]; + u8 transmit_receive_orientations[BeamformerMaxChannelCount]; } BeamformerComputeArrayParameters; typedef union { @@ -477,7 +477,7 @@ typedef union { read_only global u32 beamformer_compute_array_parameter_sizes[] = { sizeof(v2) * BeamformerMaxChannelCount, sizeof(i16) * BeamformerMaxChannelCount, - sizeof(u16) * BeamformerMaxChannelCount, + sizeof(u8) * BeamformerMaxChannelCount, }; read_only global u32 beamformer_compute_array_parameter_offsets[] = { @@ -892,14 +892,14 @@ read_only global str8 beamformer_shader_global_header_strings[] = { "\n"), str8_comp("" "struct ComputeArrayParameters {\n" - " f32vec2 focal_vectors[MaxChannelCount];\n" - " int16_t sparse_elements[MaxChannelCount];\n" - " uint16_t transmit_receive_orientations[MaxChannelCount];\n" + " f32vec2 focal_vectors[MaxChannelCount];\n" + " int16_t sparse_elements[MaxChannelCount];\n" + " uint8_t transmit_receive_orientations[MaxChannelCount];\n" "};\n" "layout(std430, buffer_reference) buffer ComputeArrayParametersReference {\n" - " f32vec2 focal_vectors[MaxChannelCount];\n" - " int16_t sparse_elements[MaxChannelCount];\n" - " uint16_t transmit_receive_orientations[MaxChannelCount];\n" + " f32vec2 focal_vectors[MaxChannelCount];\n" + " int16_t sparse_elements[MaxChannelCount];\n" + " uint8_t transmit_receive_orientations[MaxChannelCount];\n" "};\n" "\n"), str8_comp("" diff --git a/shaders/das.glsl b/shaders/das.glsl @@ -169,22 +169,22 @@ float cylindrical_wave_transmit_distance(const vec3 point, const float focal_dep return distance(rca_plane_projection(point, tx_rows), f); } -u16 tx_rx_orientation_for_acquisition(const s16 acquisition) +u8 tx_rx_orientation_for_acquisition(const s32 acquisition) { - u16 result = u16(TransmitReceiveOrientation); + u8 result = u8(TransmitReceiveOrientation); ComputeArrayParametersReference dp = ComputeArrayParametersReference(ArrayParameters); if (!SingleOrientation) result = dp.transmit_receive_orientations[acquisition]; return result; } -f32vec2 focal_vector_for_acquisition(const s16 acquisition) +f32vec2 focal_vector_for_acquisition(const s32 acquisition) { ComputeArrayParametersReference dp = ComputeArrayParametersReference(ArrayParameters); f32vec2 result = SingleFocus ? f32vec2(TransmitAngle, FocusDepth) : dp.focal_vectors[acquisition]; return result; } -float rca_transmit_distance(const vec3 world_point, const vec2 focal_vector, const uint16_t transmit_receive_orientation) +f32 rca_transmit_distance(const vec3 world_point, const vec2 focal_vector, const u8 transmit_receive_orientation) { float result = 0; if (TX_ORIENTATION(transmit_receive_orientation) != RCAOrientation_None) { @@ -204,10 +204,10 @@ float rca_transmit_distance(const vec3 world_point, const vec2 focal_vector, con RESULT_TYPE RCA(const vec3 world_point) { RESULT_TYPE result = RESULT_TYPE(0); - for (int16_t acquisition = int16_t(0); acquisition < int16_t(AcquisitionCount); acquisition++) { - const uint16_t tx_rx_orientation = tx_rx_orientation_for_acquisition(acquisition); - const bool rx_rows = RX_ORIENTATION(tx_rx_orientation) == RCAOrientation_Rows; - const vec2 focal_vector = focal_vector_for_acquisition(acquisition); + for (s32 acquisition = 0; acquisition < s32(AcquisitionCount); acquisition++) { + const u8 tx_rx_orientation = tx_rx_orientation_for_acquisition(acquisition); + 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); @@ -234,10 +234,10 @@ RESULT_TYPE HERCULES(const vec3 world_point) { ComputeArrayParametersReference dp = ComputeArrayParametersReference(ArrayParameters); - const uint16_t tx_rx_orientation = tx_rx_orientation_for_acquisition(int16_t(0)); - const bool rx_cols = RX_ORIENTATION(tx_rx_orientation) == RCAOrientation_Columns; - const vec2 focal_vector = focal_vector_for_acquisition(int16_t(0)); - const vec3 xdc_world_point = (xdc_transform * vec4(world_point, 1)).xyz; + const u8 tx_rx_orientation = tx_rx_orientation_for_acquisition(0); + const bool rx_cols = RX_ORIENTATION(tx_rx_orientation) == RCAOrientation_Columns; + const vec2 focal_vector = focal_vector_for_acquisition(0); + const vec3 xdc_world_point = (xdc_transform * vec4(world_point, 1)).xyz; const float transmit_index = sample_index(rca_transmit_distance(world_point, focal_vector, tx_rx_orientation)); const float z_delta_squared = xdc_world_point.z * xdc_world_point.z; diff --git a/vulkan.c b/vulkan.c @@ -183,6 +183,7 @@ read_only global const char *vk_required_instance_extensions[] = { #define VK_REQUIRED_DEVICE_EXTENSIONS_LIST \ X("VK_KHR_16bit_storage") \ + X("VK_KHR_8bit_storage") \ X("VK_KHR_external_memory") \ X("VK_KHR_external_semaphore") \ X("VK_KHR_robustness2") \