ogl_beamforming

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

Commit: dbe78a8bfb4cac017d58a417150ad3d459d7d97b
Parent: aa57cf8ebd7c9fae917350ccc850dc57030ddf34
Author: Randy Palamar
Date:   Wed, 10 Jul 2024 06:20:02 -0600

share the BeamformerParameters definition

Diffstat:
Mbeamformer.c | 24++++++++++++------------
Mbeamformer.h | 15+++------------
Abeamformer_parameters.h | 14++++++++++++++
Mhelpers/ogl_beamformer_lib.c | 2+-
Mhelpers/ogl_beamformer_lib.h | 14++------------
Mmain.c | 6+++---
Mutil.c | 4++--
Mutil.h | 7+++----
8 files changed, 40 insertions(+), 46 deletions(-)

diff --git a/beamformer.c b/beamformer.c @@ -4,10 +4,10 @@ static void alloc_shader_storage(BeamformerCtx *ctx, Arena a) { - uv3 rf_data_dim = ctx->params->rf_data_dim; + uv4 rf_data_dim = ctx->params->rf_data_dim; ctx->csctx.rf_data_dim = rf_data_dim; - 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(f32); + size rf_raw_size = rf_data_dim.x * rf_data_dim.y * rf_data_dim.z * sizeof(i16); + size rf_decoded_size = rf_data_dim.x * rf_data_dim.y * rf_data_dim.z * sizeof(f32); glDeleteBuffers(ARRAY_COUNT(ctx->csctx.rf_data_ssbos), ctx->csctx.rf_data_ssbos); glGenBuffers(ARRAY_COUNT(ctx->csctx.rf_data_ssbos), ctx->csctx.rf_data_ssbos); @@ -18,7 +18,7 @@ alloc_shader_storage(BeamformerCtx *ctx, Arena a) glBufferStorage(GL_SHADER_STORAGE_BUFFER, rf_decoded_size, 0, GL_DYNAMIC_STORAGE_BIT); /* NOTE: store hadamard in GPU once; it won't change for a particular imaging session */ - ctx->csctx.hadamard_dim = (uv2){ .x = rf_data_dim.d, .y = rf_data_dim.d }; + ctx->csctx.hadamard_dim = (uv2){ .x = rf_data_dim.z, .y = rf_data_dim.z }; size hadamard_elements = ctx->csctx.hadamard_dim.x * ctx->csctx.hadamard_dim.y; i32 *hadamard = alloc(&a, i32, hadamard_elements); fill_hadamard(hadamard, ctx->csctx.hadamard_dim.x); @@ -29,7 +29,7 @@ alloc_shader_storage(BeamformerCtx *ctx, Arena a) /* NOTE: allocate storage for beamformed output data; * this is shared between compute and fragment shaders */ - uv3 odim = ctx->out_data_dim; + uv4 odim = ctx->out_data_dim; u32 max_dim = MAX(odim.x, MAX(odim.y, odim.z)); /* TODO: does this actually matter or is 0 fine? */ ctx->out_texture_unit = 0; @@ -41,7 +41,7 @@ alloc_shader_storage(BeamformerCtx *ctx, Arena a) glTexStorage3D(GL_TEXTURE_3D, ctx->out_texture_mips, GL_RG32F, odim.x, odim.y, odim.z); UnloadRenderTexture(ctx->fsctx.output); - ctx->fsctx.output = LoadRenderTexture(odim.w, odim.h); + ctx->fsctx.output = LoadRenderTexture(odim.x, odim.y); } static void @@ -76,9 +76,9 @@ do_compute_shader(BeamformerCtx *ctx, enum compute_shaders shader) glUniform1i(csctx->mips_level_id, i); #define ORONE(x) ((x)? (x) : 1) - u32 width = ctx->out_data_dim.w >> i; - u32 height = ctx->out_data_dim.h >> i; - u32 depth = ctx->out_data_dim.d >> i; + u32 width = ctx->out_data_dim.x >> i; + u32 height = ctx->out_data_dim.y >> i; + u32 depth = ctx->out_data_dim.z >> i; glDispatchCompute(ORONE(width / 32), ORONE(height / 32), ORONE(depth)); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); } @@ -163,14 +163,14 @@ do_beamformer(BeamformerCtx *ctx, Arena arena) /* NOTE: Check for and Load RF Data into GPU */ if (os_poll_pipe(ctx->data_pipe)) { - if (!uv3_equal(ctx->csctx.rf_data_dim, ctx->params->rf_data_dim)) + if (!uv4_equal(ctx->csctx.rf_data_dim, ctx->params->rf_data_dim)) alloc_shader_storage(ctx, arena); glBindBuffer(GL_SHADER_STORAGE_BUFFER, ctx->csctx.rf_data_ssbos[0]); 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(i16); + uv4 rf_data_dim = ctx->csctx.rf_data_dim; + size rf_raw_size = rf_data_dim.x * rf_data_dim.y * rf_data_dim.z * 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/beamformer.h b/beamformer.h @@ -45,7 +45,7 @@ typedef struct { u32 hadamard_ssbo; uv2 hadamard_dim; - uv3 rf_data_dim; + uv4 rf_data_dim; i32 rf_data_dim_id; i32 out_data_tex_id; i32 mip_view_tex_id; @@ -60,16 +60,7 @@ typedef struct { f32 db; } FragmentShaderCtx; -typedef struct { - u32 channel_row_mapping[128]; - u32 channel_column_mapping[128]; - u32 uforces_channels[128]; - u32 channel_data_stride; - f32 speed_of_sound; - f32 sampling_frequency; - uv3 rf_data_dim; - uv3 output_points; -} BeamformerParameters; +#include "beamformer_parameters.h" #if defined(__unix__) #define GL_GLEXT_PROTOTYPES 1 @@ -91,7 +82,7 @@ typedef struct { Color bg, fg; - uv3 out_data_dim; + uv4 out_data_dim; u32 out_texture; u32 out_texture_unit; u32 out_texture_mips; diff --git a/beamformer_parameters.h b/beamformer_parameters.h @@ -0,0 +1,14 @@ +/* See LICENSE for license details. */ + +/* NOTE: This struct follows the OpenGL std140 layout. DO NOT modify unless you have + * read and understood the rules, particulary with regards to _member alignment_ */ +typedef struct { + u32 channel_mapping[256]; /* Transducer Channel to Verasonics Channel */ + u32 uforces_channels[128]; /* Channels used for virtual UFORCES elements */ + uv4 rf_data_dim; /* Samples * Channels * Acquisitions; last element ignored */ + uv4 output_points; /* Width * Height * Depth; last element ignored */ + u32 channel_data_stride; /* Data points between channels (samples * acq + padding) */ + u32 channel_offset; /* Offset into channel_mapping: 0 or 128 (rows or columns) */ + f32 speed_of_sound; + f32 sampling_frequency; +} BeamformerParameters; diff --git a/helpers/ogl_beamformer_lib.c b/helpers/ogl_beamformer_lib.c @@ -107,7 +107,7 @@ check_shared_memory(void) } void -send_data(char *pipe_name, i16 *data, uv3 data_dim) +send_data(char *pipe_name, i16 *data, uv4 data_dim) { if (g_pipe.file == OS_INVALID_FILE) { g_pipe = os_open_named_pipe(pipe_name); diff --git a/helpers/ogl_beamformer_lib.h b/helpers/ogl_beamformer_lib.h @@ -19,19 +19,9 @@ typedef ptrdiff_t size; #define LIB_FN #endif -typedef struct { u32 x, y, z; } uv3; -typedef struct { f32 x, y, z; } v3; +typedef struct { u32 x, y, z, w; } uv4; -typedef struct { - u32 channel_row_mapping[128]; - u32 channel_column_mapping[128]; - u32 uforces_channels[128]; - u32 channel_data_stride; - f32 speed_of_sound; - f32 sampling_frequency; - uv3 rf_data_dim; - uv3 output_points; -} BeamformerParameters; +#include "../beamformer_parameters.h" LIB_FN void set_beamformer_parameters(BeamformerParameters *); LIB_FN void send_data(char *, i16 *, uv3 data_dim); diff --git a/main.c b/main.c @@ -97,9 +97,9 @@ compile_shader(Arena a, u32 type, s8 shader) } static void -init_fragment_shader_ctx(FragmentShaderCtx *ctx, uv3 out_data_dim) +init_fragment_shader_ctx(FragmentShaderCtx *ctx, uv4 out_data_dim) { - ctx->output = LoadRenderTexture(out_data_dim.w, out_data_dim.h); + ctx->output = LoadRenderTexture(out_data_dim.x, out_data_dim.y); ctx->db = -50.0f; } @@ -144,7 +144,7 @@ main(void) Arena temp_memory = os_new_arena(256 * MEGABYTE); ctx.window_size = (uv2){.w = 1024, .h = 1024}; - ctx.out_data_dim = (uv3){.w = 256, .h = 1024, .d = 1}; + ctx.out_data_dim = (uv4){.x = 256, .y = 1024, .z = 1}; ctx.bg = PINK; ctx.fg = (Color){ .r = 0xea, .g = 0xe1, .b = 0xb4, .a = 0xff }; diff --git a/util.c b/util.c @@ -46,9 +46,9 @@ s8alloc(Arena *a, size len) } static b32 -uv3_equal(uv3 a, uv3 b) +uv4_equal(uv4 a, uv4 b) { - return a.x == b.x && a.y == b.y && a.z == b.z; + return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w; } static void diff --git a/util.h b/util.h @@ -44,10 +44,9 @@ typedef union { } uv2; typedef union { - struct { u32 x, y, z; }; - struct { u32 w, h, d; }; - u32 E[3]; -} uv3; + struct { u32 x, y, z, w; }; + u32 E[4]; +} uv4; #include "util.c"