Commit: 0afdb85ac35a8c54946ce288f9ea7e76ae0a7e29
Parent: ae0fe93f0853be0a368a03f4d8682d23f09cf5c8
Author: Randy Palamar
Date: Thu, 11 Jul 2024 23:15:31 -0600
add an extra flag after parameters to indicate new data
This is hidden from the helper's caller but visible in the main process.
Diffstat:
6 files changed, 74 insertions(+), 60 deletions(-)
diff --git a/beamformer.c b/beamformer.c
@@ -4,10 +4,11 @@
static void
alloc_shader_storage(BeamformerCtx *ctx, Arena a)
{
- uv4 rf_data_dim = ctx->params->rf_data_dim;
- ctx->csctx.rf_data_dim = rf_data_dim;
- size rf_raw_size = ctx->params->channel_data_stride * 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);
+ BeamformerParameters *bp = &ctx->params->raw;
+ uv4 rf_data_dim = bp->rf_data_dim;
+ ctx->csctx.rf_data_dim = rf_data_dim;
+ size rf_raw_size = bp->channel_data_stride * 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);
@@ -27,6 +28,7 @@ alloc_shader_storage(BeamformerCtx *ctx, Arena a)
ctx->csctx.hadamard_ssbo = rlLoadShaderBuffer(hadamard_elements * sizeof(i32), hadamard,
GL_STATIC_DRAW);
+ ctx->out_data_dim = bp->output_points;
/* NOTE: allocate storage for beamformed output data;
* this is shared between compute and fragment shaders */
uv4 odim = ctx->out_data_dim;
@@ -125,7 +127,7 @@ move_towards_v4(v4 current, v4 target, v4 delta)
}
static v4
-fmsub_v4(v4 a, v4 b, v4 scale)
+scaled_sub_v4(v4 a, v4 b, v4 scale)
{
return (v4){
.x = scale.x * (a.x - b.x),
@@ -138,6 +140,8 @@ fmsub_v4(v4 a, v4 b, v4 scale)
static void
draw_settings_ui(BeamformerCtx *ctx, Arena arena, f32 dt, Rect r, v2 mouse)
{
+ BeamformerParameters *bp = &ctx->params->raw;
+
struct listing {
char *prefix;
char *suffix;
@@ -145,22 +149,22 @@ draw_settings_ui(BeamformerCtx *ctx, Arena arena, f32 dt, Rect r, v2 mouse)
f32 data_scale;
b32 editable;
} listings[] = {
- { "Sampling Rate:", " [MHz]", &ctx->params->sampling_frequency, 1e-6, 0 },
- { "Speed of Sound:", " [m/s]", &ctx->params->speed_of_sound, 1, 1 },
- { "Min X Point:", " [mm]", &ctx->params->output_min_xz.x, 1e3, 1 },
- { "Max X Point:", " [mm]", &ctx->params->output_max_xz.x, 1e3, 1 },
- { "Min Z Point:", " [mm]", &ctx->params->output_min_xz.y, 1e3, 1 },
- { "Max Z Point:", " [mm]", &ctx->params->output_max_xz.y, 1e3, 1 },
- { "Dynamic Range:", " [dB]", &ctx->fsctx.db, 1, 1 },
+ { "Sampling Rate:", " [MHz]", &bp->sampling_frequency, 1e-6, 0 },
+ { "Speed of Sound:", " [m/s]", &bp->speed_of_sound, 1, 1 },
+ { "Min X Point:", " [mm]", &bp->output_min_xz.x, 1e3, 1 },
+ { "Max X Point:", " [mm]", &bp->output_max_xz.x, 1e3, 1 },
+ { "Min Z Point:", " [mm]", &bp->output_min_xz.y, 1e3, 1 },
+ { "Max Z Point:", " [mm]", &bp->output_max_xz.y, 1e3, 1 },
+ { "Dynamic Range:", " [dB]", &ctx->fsctx.db, 1, 1 },
};
struct { f32 min, max; } limits[] = {
{0},
- {0, 1e6},
- {-1e3, ctx->params->output_max_xz.x - 1e-6},
- {ctx->params->output_min_xz.x + 1e-6, 1e3},
- {0, ctx->params->output_max_xz.y - 1e-6},
- {ctx->params->output_min_xz.y + 1e-6, 1e3},
+ {0, 1e6},
+ {-1e3, bp->output_max_xz.x - 1e-6},
+ {bp->output_min_xz.x + 1e-6, 1e3},
+ {0, bp->output_max_xz.y - 1e-6},
+ {bp->output_min_xz.y + 1e-6, 1e3},
{-120, 0},
};
@@ -168,7 +172,7 @@ draw_settings_ui(BeamformerCtx *ctx, Arena arena, f32 dt, Rect r, v2 mouse)
static v4 colours[ARRAY_COUNT(listings)];
f32 scale = 6;
v4 scaled_dt = (v4){.x = scale * dt, .y = scale * dt, .z = scale * dt, .w = scale * dt};
- v4 delta = fmsub_v4(ctx->fg, ctx->hovered_colour, scaled_dt);
+ v4 delta = scaled_sub_v4(ctx->fg, ctx->hovered_colour, scaled_dt);
if (init) {
for (i32 i = 0; i < ARRAY_COUNT(colours); i++)
colours[i] = ctx->fg;
@@ -210,7 +214,8 @@ draw_settings_ui(BeamformerCtx *ctx, Arena arena, f32 dt, Rect r, v2 mouse)
if (mouse_scroll) {
*l->data += mouse_scroll / l->data_scale;
CLAMP(*l->data, limits[i].min, limits[i].max);
- ctx->flags |= UPLOAD_UBO|DO_COMPUTE;
+ ctx->flags |= DO_COMPUTE;
+ ctx->params->upload = 1;
}
}
@@ -220,10 +225,8 @@ draw_settings_ui(BeamformerCtx *ctx, Arena arena, f32 dt, Rect r, v2 mouse)
else
colours[i] = move_towards_v4(colours[i], ctx->fg, delta);
- if (i == focused_idx)
- tcol = colour_from_normalized(ctx->focused_colour);
- else
- tcol = colour_from_normalized(colours[i]);
+ if (i == focused_idx) tcol = colour_from_normalized(ctx->focused_colour);
+ else tcol = colour_from_normalized(colours[i]);
DrawTextEx(ctx->font, (char *)txt.data, rpos.rl, ctx->font_size,
ctx->font_spacing, tcol);
@@ -242,7 +245,8 @@ draw_settings_ui(BeamformerCtx *ctx, Arena arena, f32 dt, Rect r, v2 mouse)
*listings[focused_idx].data = new_val / listings[focused_idx].data_scale;
CLAMP(*listings[focused_idx].data, limits[focused_idx].min,
limits[focused_idx].max);
- ctx->flags |= UPLOAD_UBO|DO_COMPUTE;
+ ctx->flags |= DO_COMPUTE;
+ ctx->params->upload = 1;
}
focused_idx = -1;
focus_buf[0] = 0;
@@ -344,10 +348,13 @@ do_beamformer(BeamformerCtx *ctx, Arena arena)
ctx->window_size.w = GetScreenWidth();
}
+ BeamformerParameters *bp = &ctx->params->raw;
/* NOTE: Check for and Load RF Data into GPU */
if (os_poll_pipe(ctx->data_pipe)) {
- if (!uv4_equal(ctx->csctx.rf_data_dim, ctx->params->rf_data_dim))
+ if (!uv4_equal(ctx->csctx.rf_data_dim, bp->rf_data_dim) ||
+ !uv4_equal(ctx->out_data_dim, bp->output_points)) {
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);
@@ -356,21 +363,19 @@ do_beamformer(BeamformerCtx *ctx, Arena arena)
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) {
- ctx->flags |= DO_COMPUTE;
- } else {
- ctx->partial_transfer_count++;
- }
+
+ if (rlen == rf_raw_size) ctx->flags |= DO_COMPUTE;
+ else ctx->partial_transfer_count++;
}
if (ctx->flags & DO_COMPUTE) {
- if (ctx->flags & UPLOAD_UBO) {
+ if (ctx->params->upload) {
glBindBuffer(GL_UNIFORM_BUFFER, ctx->csctx.shared_ubo);
void *ubo = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY);
- mem_copy((s8){.data = (u8 *)ctx->params, .len = sizeof(BeamformerParameters)},
- (s8){.data = (u8 *)ubo, .len = sizeof(BeamformerParameters)});
+ mem_copy((s8){.data = (u8 *)bp, .len = sizeof(*bp)},
+ (s8){.data = (u8 *)ubo, .len = sizeof(*bp)});
glUnmapBuffer(GL_UNIFORM_BUFFER);
- ctx->flags &= ~UPLOAD_UBO;
+ ctx->params->upload = 0;
}
do_compute_shader(ctx, CS_HADAMARD);
do_compute_shader(ctx, CS_UFORCES);
@@ -397,8 +402,8 @@ do_beamformer(BeamformerCtx *ctx, Arena arena)
Texture *output = &ctx->fsctx.output.texture;
v2 output_dim = {
- .x = ctx->params->output_max_xz.x - ctx->params->output_min_xz.x,
- .y = ctx->params->output_max_xz.y - ctx->params->output_min_xz.y,
+ .x = bp->output_max_xz.x - bp->output_min_xz.x,
+ .y = bp->output_max_xz.y - bp->output_min_xz.y,
};
v2 line_step_mm = {.x = 3, .y = 5};
@@ -442,7 +447,7 @@ do_beamformer(BeamformerCtx *ctx, Arena arena)
v2 start_pos = vr.pos;
start_pos.y += vr.size.h;
- f32 x_mm = ctx->params->output_min_xz.x * 1e3;
+ f32 x_mm = bp->output_min_xz.x * 1e3;
f32 x_mm_inc = x_inc * output_dim.x * 1e3 / vr.size.w;
v2 end_pos = start_pos;
@@ -471,7 +476,7 @@ do_beamformer(BeamformerCtx *ctx, Arena arena)
v2 start_pos = vr.pos;
start_pos.x += vr.size.w;
- f32 y_mm = ctx->params->output_min_xz.y * 1e3;
+ f32 y_mm = bp->output_min_xz.y * 1e3;
f32 y_mm_inc = y_inc * output_dim.y * 1e3 / vr.size.h;
v2 end_pos = start_pos;
diff --git a/beamformer.h b/beamformer.h
@@ -41,7 +41,6 @@ enum compute_shaders {
enum program_flags {
RELOAD_SHADERS = 1 << 0,
DO_COMPUTE = 1 << 1,
- UPLOAD_UBO = 1 << 2,
};
typedef struct {
@@ -69,6 +68,10 @@ typedef struct {
} FragmentShaderCtx;
#include "beamformer_parameters.h"
+typedef struct {
+ BeamformerParameters raw;
+ b32 upload;
+} BeamformerParametersFull;
#if defined(__unix__)
#define GL_GLEXT_PROTOTYPES 1
@@ -104,7 +107,7 @@ typedef struct {
os_pipe data_pipe;
u32 partial_transfer_count;
- BeamformerParameters *params;
+ BeamformerParametersFull *params;
} BeamformerCtx;
#endif /*_BEAMFORMER_H_ */
diff --git a/helpers/ogl_beamformer_lib.c b/helpers/ogl_beamformer_lib.c
@@ -1,4 +1,8 @@
#include "ogl_beamformer_lib.h"
+typedef struct {
+ BeamformerParameters raw;
+ b32 upload;
+} BeamformerParametersFull;
#if defined(__unix__)
#include <fcntl.h>
@@ -26,7 +30,7 @@ typedef struct {
#error Unsupported Platform
#endif
-static volatile BeamformerParameters *g_bp;
+static volatile BeamformerParametersFull *g_bp;
static os_pipe g_pipe = {.file = OS_INVALID_FILE};
#if defined(__unix__)
@@ -53,15 +57,15 @@ os_close_pipe(void)
close(g_pipe.file);
}
-static BeamformerParameters *
+static BeamformerParametersFull *
os_open_shared_memory_area(char *name)
{
i32 fd = shm_open(name, O_RDWR, S_IRUSR|S_IWUSR);
if (fd == -1)
return NULL;
- BeamformerParameters *new;
- new = mmap(NULL, sizeof(BeamformerParameters), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ BeamformerParametersFull *new;
+ new = mmap(NULL, sizeof(*new), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
if (new == MAP_FAILED)
@@ -93,15 +97,15 @@ os_close_pipe(void)
CloseHandle(g_pipe.file);
}
-static BeamformerParameters *
+static BeamformerParametersFull *
os_open_shared_memory_area(char *name)
{
HANDLE h = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, name);
if (h == OS_INVALID_FILE)
return NULL;
- BeamformerParameters *new;
- new = MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(BeamformerParameters));
+ BeamformerParametersFull *new;
+ new = MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(*new));
CloseHandle(h);
return new;
@@ -132,12 +136,13 @@ send_data(char *pipe_name, char *shm_name, i16 *data, uv4 data_dim)
check_shared_memory(shm_name);
/* TODO: this probably needs a mutex around it if we want to change it here */
- g_bp->rf_data_dim = data_dim;
- size data_size = data_dim.x * data_dim.y * data_dim.z * sizeof(i16);
- size written = os_write_to_pipe(g_pipe, data, data_size);
+ g_bp->raw.rf_data_dim = data_dim;
+ size data_size = data_dim.x * data_dim.y * data_dim.z * sizeof(i16);
+ size written = os_write_to_pipe(g_pipe, data, data_size);
if (written != data_size)
mexWarnMsgIdAndTxt("ogl_beamformer:write_error",
"failed to write full data to pipe: wrote: %ld", written);
+ g_bp->upload = 1;
}
void
@@ -148,7 +153,8 @@ set_beamformer_parameters(char *shm_name, BeamformerParameters *new_bp)
if (!g_bp)
return;
- u8 *src = (u8 *)new_bp, *dest = (u8 *)g_bp;
+ u8 *src = (u8 *)new_bp, *dest = (u8 *)&g_bp->raw;
for (size i = 0; i < sizeof(BeamformerParameters); i++)
dest[i] = src[i];
+ g_bp->upload = 1;
}
diff --git a/main.c b/main.c
@@ -165,7 +165,7 @@ main(void)
ASSERT(ctx.data_pipe.file != OS_INVALID_FILE);
ASSERT(ctx.params);
- ctx.params->output_points = ctx.out_data_dim;
+ ctx.params->raw.output_points = ctx.out_data_dim;
/* NOTE: allocate space for Uniform Buffer Object but don't send anything yet */
glGenBuffers(1, &ctx.csctx.shared_ubo);
diff --git a/os_unix.c b/os_unix.c
@@ -102,20 +102,20 @@ os_read_pipe_data(os_pipe p, void *buf, size len)
return total_read;
}
-static BeamformerParameters *
+static BeamformerParametersFull *
os_open_shared_memory_area(char *name)
{
i32 fd = shm_open(name, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
if (fd == -1)
return NULL;
- if (ftruncate(fd, sizeof(BeamformerParameters)) == -1) {
+ if (ftruncate(fd, sizeof(BeamformerParametersFull)) == -1) {
close(fd);
return NULL;
}
- BeamformerParameters *new;
- new = mmap(NULL, sizeof(BeamformerParameters), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ BeamformerParametersFull *new;
+ new = mmap(NULL, sizeof(*new), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
if (new == MAP_FAILED)
diff --git a/os_win32.c b/os_win32.c
@@ -117,16 +117,16 @@ os_read_pipe_data(os_pipe p, void *buf, size len)
return total_read;
}
-static BeamformerParameters *
+static BeamformerParametersFull *
os_open_shared_memory_area(char *name)
{
HANDLE h = CreateFileMappingA(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0,
- sizeof(BeamformerParameters), name);
+ sizeof(BeamformerParametersFull), name);
if (h == INVALID_HANDLE_VALUE)
return NULL;
- BeamformerParameters *new;
- new = MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(BeamformerParameters));
+ BeamformerParametersFull *new;
+ new = MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(*new));
return new;
}