ogl_beamforming

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

Commit: c7a78f342b205e06b80aada2871b81dce7b6f6f9
Parent: a425672a4da9bce718f4469b058fa25acdd0a440
Author: Randy Palamar
Date:   Fri,  5 Jul 2024 15:44:33 -0600

change decoding to work on i16 data directly

Diffstat:
Mbeamformer.c | 2+-
Mmain.c | 2+-
Mshaders/hadamard.glsl | 22+++++++++++++++++++---
3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/beamformer.c b/beamformer.c @@ -124,7 +124,7 @@ do_beamformer(BeamformerCtx *ctx, Arena arena) void *rf_data_buf = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY); ASSERT(rf_data_buf); uv3 rf_data_dim = ctx->csctx.rf_data_dim; - size rf_raw_size = rf_data_dim.w * rf_data_dim.h * rf_data_dim.d * sizeof(i32); + size rf_raw_size = rf_data_dim.w * rf_data_dim.h * rf_data_dim.d * sizeof(i16); size rlen = os_read_pipe_data(ctx->data_pipe, rf_data_buf, rf_raw_size); glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); if (rlen == rf_raw_size) { diff --git a/main.c b/main.c @@ -121,7 +121,7 @@ init_compute_shader_ctx(ComputeShaderCtx *ctx, Arena a, uv3 rf_data_dim) { ctx->rf_data_dim = rf_data_dim; /* TODO: send i16 data and convert to i32 on GPU */ - size rf_raw_size = rf_data_dim.w * rf_data_dim.h * rf_data_dim.d * sizeof(i32); + size rf_raw_size = rf_data_dim.w * rf_data_dim.h * rf_data_dim.d * sizeof(i16); size rf_decoded_size = rf_data_dim.w * rf_data_dim.h * rf_data_dim.d * sizeof(i32); glGenBuffers(ARRAY_COUNT(ctx->rf_data_ssbos), ctx->rf_data_ssbos); diff --git a/shaders/hadamard.glsl b/shaders/hadamard.glsl @@ -38,10 +38,26 @@ void main() uint rstride = u_rf_data_dim.x * u_rf_data_dim.y; uint rfoff = u_rf_data_dim.x * channel + time_sample; - /* N-D dot product */ + uint ridx = rfoff / 2; + uint ridx_delta = rstride / 2; + + /* NOTE: Compute N-D dot product */ int sum = 0; - for (int i = 0; i < u_rf_data_dim.z; i++) - sum += hadamard[hoff + i] * rf_data[rfoff + rstride * i]; + for (int i = 0; i < u_rf_data_dim.z; i++) { + int data = rf_data[ridx]; + + /* NOTE: rf_data is i16 so each access grabs two time samples at time. + * We need to shift and mask to get the desired element. If the time sample + * is even we take the upper half and if its odd we take the lower half. + * Hopefully shader compiler is smart enough to lift this out of the loop. */ + if ((int(time_sample) & 1) == 1) + data = data >> 16; + else + data = (data << 16) >> 16; + + sum += hadamard[hoff + i] * data; + ridx += ridx_delta; + } out_data[rfoff + rstride * acq] = float(sum); }