ogl_beamforming

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

Commit: e8d1a03b9b06749caf157a9a149ff429ca8ce819
Parent: e50628ac71c3ab8e3cb69e4070429101b45f0e47
Author: Randy Palamar
Date:   Fri, 12 Jul 2024 13:22:29 -0600

for now send lpf_coefficients in UBO

Diffstat:
Mbeamformer.c | 8++++++--
Mbeamformer.h | 6+++---
Mbeamformer_parameters.h | 4+++-
Mmain.c | 2+-
Mshaders/hadamard.glsl | 2++
Mshaders/lpf.glsl | 14++++++++------
Mshaders/uforces.glsl | 2++
7 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/beamformer.c b/beamformer.c @@ -31,6 +31,9 @@ alloc_output_image(BeamformerCtx *ctx) static void upload_filter_coefficients(BeamformerCtx *ctx, Arena a) { + ctx->flags &= ~UPLOAD_FILTER; + return; +#if 0 f32 lpf_coeff[] = { 0.001504252781, 0.006636276841, 0.01834679954, 0.0386288017, 0.06680636108, 0.09852545708, 0.1264867932, 0.1429549307, @@ -41,8 +44,7 @@ upload_filter_coefficients(BeamformerCtx *ctx, Arena a) ctx->csctx.lpf_order = lpf_coeff_count - 1; rlUnloadShaderBuffer(ctx->csctx.lpf_ssbo); ctx->csctx.lpf_ssbo = rlLoadShaderBuffer(lpf_coeff_count * sizeof(f32), lpf_coeff, GL_STATIC_DRAW); - - ctx->flags &= ~UPLOAD_FILTER; +#endif } static void @@ -102,8 +104,10 @@ do_compute_shader(BeamformerCtx *ctx, enum compute_shaders shader) case CS_LPF: glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, csctx->rf_data_ssbos[input_ssbo_idx]); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, csctx->rf_data_ssbos[output_ssbo_idx]); + #if 0 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, csctx->lpf_ssbo); glUniform1i(csctx->lpf_order_id, csctx->lpf_order); + #endif glDispatchCompute(ORONE(csctx->rf_data_dim.x / 32), ORONE(csctx->rf_data_dim.y / 32), ORONE(csctx->rf_data_dim.z)); diff --git a/beamformer.h b/beamformer.h @@ -64,9 +64,9 @@ typedef struct { i32 mip_view_tex_id; i32 mips_level_id; - u32 lpf_ssbo; - u32 lpf_order; - i32 lpf_order_id; + //u32 lpf_ssbo; + //u32 lpf_order; + //i32 lpf_order_id; } ComputeShaderCtx; typedef struct { diff --git a/beamformer_parameters.h b/beamformer_parameters.h @@ -5,6 +5,7 @@ typedef struct { u32 channel_mapping[256]; /* Transducer Channel to Verasonics Channel */ u32 uforces_channels[128]; /* Channels used for virtual UFORCES elements */ + f32 lpf_coefficients[64]; /* Low Pass Filter Cofficients */ uv4 rf_data_dim; /* Samples * Channels * Acquisitions; last element ignored */ uv4 output_points; /* Width * Height * Depth; last element ignored */ v2 output_min_xz; /* [m] Top left corner of output region */ @@ -13,9 +14,10 @@ typedef struct { v2 xdc_max_xy; /* [m] Max center of transducer elements */ u32 channel_data_stride; /* Data points between channels (samples * acq + padding) */ u32 channel_offset; /* Offset into channel_mapping: 0 or 128 (rows or columns) */ + u32 lpf_order; /* Order of Low Pass Filter */ f32 speed_of_sound; /* [m/s] */ f32 sampling_frequency; /* [Hz] */ f32 center_frequency; /* [Hz] */ f32 focal_depth; /* [m] */ - f32 _pad[3]; + f32 _pad[2]; } BeamformerParameters; diff --git a/main.c b/main.c @@ -123,7 +123,7 @@ reload_shaders(BeamformerCtx *ctx, Arena a) glDeleteShader(shader_id); } - csctx->lpf_order_id = glGetUniformLocation(csctx->programs[CS_LPF], "u_lpf_order"); + //csctx->lpf_order_id = glGetUniformLocation(csctx->programs[CS_LPF], "u_lpf_order"); csctx->out_data_tex_id = glGetUniformLocation(csctx->programs[CS_UFORCES], "u_out_data_tex"); csctx->mip_view_tex_id = glGetUniformLocation(csctx->programs[CS_MIN_MAX], "u_mip_view_tex"); csctx->mips_level_id = glGetUniformLocation(csctx->programs[CS_MIN_MAX], "u_mip_map"); diff --git a/shaders/hadamard.glsl b/shaders/hadamard.glsl @@ -17,6 +17,7 @@ layout(std430, binding = 3) readonly restrict buffer buffer_3 { layout(std140, binding = 0) uniform parameters { uvec4 channel_mapping[64]; /* Transducer Channel to Verasonics Channel */ uvec4 uforces_channels[32]; /* Channels used for virtual UFORCES elements */ + vec4 lpf_coefficients[16]; /* Low Pass Filter Cofficients */ uvec4 rf_data_dim; /* Samples * Channels * Acquisitions; last element ignored */ uvec4 output_points; /* Width * Height * Depth; last element ignored */ vec2 output_min_xz; /* [m] Top left corner of output region */ @@ -25,6 +26,7 @@ layout(std140, binding = 0) uniform parameters { vec2 xdc_max_xy; /* [m] Max center of transducer elements */ uint channel_data_stride; /* Data points between channels (samples * acq + padding) */ uint channel_offset; /* Offset into channel_mapping: 0 or 128 (rows or columns) */ + uint lpf_order; /* Order of Low Pass Filter */ float speed_of_sound; /* [m/s] */ float sampling_frequency; /* [Hz] */ float center_frequency; /* [Hz] */ diff --git a/shaders/lpf.glsl b/shaders/lpf.glsl @@ -10,13 +10,14 @@ layout(std430, binding = 2) writeonly restrict buffer buffer_2 { vec2 out_data[]; }; -layout(std430, binding = 3) readonly restrict buffer buffer_3 { - float lpf_coeff[]; -}; +//layout(std430, binding = 3) readonly restrict buffer buffer_3 { +// float lpf_coeff[]; +//}; layout(std140, binding = 0) uniform parameters { uvec4 channel_mapping[64]; /* Transducer Channel to Verasonics Channel */ uvec4 uforces_channels[32]; /* Channels used for virtual UFORCES elements */ + vec4 lpf_coefficients[16]; /* Low Pass Filter Cofficients */ uvec4 rf_data_dim; /* Samples * Channels * Acquisitions; last element ignored */ uvec4 output_points; /* Width * Height * Depth; last element ignored */ vec2 output_min_xz; /* [m] Top left corner of output region */ @@ -25,13 +26,14 @@ layout(std140, binding = 0) uniform parameters { vec2 xdc_max_xy; /* [m] Max center of transducer elements */ uint channel_data_stride; /* Data points between channels (samples * acq + padding) */ uint channel_offset; /* Offset into channel_mapping: 0 or 128 (rows or columns) */ + uint lpf_order; /* Order of Low Pass Filter */ float speed_of_sound; /* [m/s] */ float sampling_frequency; /* [Hz] */ float center_frequency; /* [Hz] */ float focal_depth; /* [m] */ }; -layout(location = 1) uniform uint u_lpf_order; +//layout(location = 1) uniform uint u_lpf_order; void main() { @@ -44,12 +46,12 @@ void main() uint off = rf_data_dim.x * channel + time_sample; vec2 sum = vec2(0); - for (int i = 0; i <= u_lpf_order; i++) { + for (int i = 0; i <= lpf_order; i++) { vec2 data; /* NOTE: make sure data samples come from the same acquisition */ if (time_sample > i) data = in_data[off - i]; else data = vec2(0); - sum += lpf_coeff[i] * data; + sum += lpf_coefficients[i / 4][i % 4] * data; } out_data[stride * acq + off] = sum; } diff --git a/shaders/uforces.glsl b/shaders/uforces.glsl @@ -9,6 +9,7 @@ layout(std430, binding = 1) readonly restrict buffer buffer_1 { layout(std140, binding = 0) uniform parameters { uvec4 channel_mapping[64]; /* Transducer Channel to Verasonics Channel */ uvec4 uforces_channels[32]; /* Channels used for virtual UFORCES elements */ + vec4 lpf_coefficients[16]; /* Low Pass Filter Cofficients */ uvec4 rf_data_dim; /* Samples * Channels * Acquisitions; last element ignored */ uvec4 output_points; /* Width * Height * Depth; last element ignored */ vec2 output_min_xz; /* [m] Top left corner of output region */ @@ -17,6 +18,7 @@ layout(std140, binding = 0) uniform parameters { vec2 xdc_max_xy; /* [m] Max center of transducer elements */ uint channel_data_stride; /* Data points between channels (samples * acq + padding) */ uint channel_offset; /* Offset into channel_mapping: 0 or 128 (rows or columns) */ + uint lpf_order; /* Order of Low Pass Filter */ float speed_of_sound; /* [m/s] */ float sampling_frequency; /* [Hz] */ float center_frequency; /* [Hz] */