Commit: 5755f89922f954ba8853baac509c2b989908c8a8
Parent: b121b2c6f32ad34016c3748c67713a328a9fb852
Author: Randy Palamar
Date: Fri, 21 Jun 2024 06:22:05 -0600
update for real uforces data
Diffstat:
5 files changed, 62 insertions(+), 25 deletions(-)
diff --git a/beamformer.c b/beamformer.c
@@ -23,6 +23,7 @@ do_compute_shader(BeamformerCtx *ctx, u32 rf_ssbo_idx, enum compute_shaders shad
glUniform3uiv(csctx->rf_data_dim_id, 1, csctx->rf_data_dim.E);
glUniform3uiv(csctx->out_data_dim_id, 1, ctx->out_data_dim.E);
+ glUniform1ui(csctx->acquisition_id, ctx->acquisition);
/* NOTE: Temporary flag for testing */
u32 data_idx = ctx->flags & DO_DECODE? 2 : rf_ssbo_idx;
@@ -50,16 +51,26 @@ draw_debug_overlay(BeamformerCtx *ctx, Arena arena)
u32 fontsize = 32;
u32 fontspace = 1;
+ s8 acq_txt = s8alloc(&arena, 64);
s8 decode_txt = s8alloc(&arena, 64);
s8 compute_txt = s8alloc(&arena, 64);
- snprintf((char *)decode_txt.data, decode_txt.len, "Decoding: %d", !!(ctx->flags & DO_DECODE));
- snprintf((char *)compute_txt.data, compute_txt.len, "Compute: %d", !!(ctx->flags & DO_COMPUTE));
+ snprintf((char *)acq_txt.data, acq_txt.len, "Acquisition: %d", ctx->acquisition);
+ snprintf((char *)decode_txt.data, decode_txt.len, "Decoding: %d", !!(ctx->flags & DO_DECODE));
+ snprintf((char *)compute_txt.data, compute_txt.len, "Compute: %d", !!(ctx->flags & DO_COMPUTE));
+
+ v2 acq_fs = {.rl = MeasureTextEx(ctx->font, (char *)acq_txt.data, fontsize, fontspace)};
v2 decode_fs = {.rl = MeasureTextEx(ctx->font, (char *)decode_txt.data, fontsize, fontspace)};
v2 compute_fs = {.rl = MeasureTextEx(ctx->font, (char *)compute_txt.data, fontsize, fontspace)};
v2 scale = {.x = 90, .y = 20 };
- v2 dpos = {.x = 20, .y = ctx->window_size.y - decode_fs.y - compute_fs.y - 20};
- v2 dposa = {.x = dpos.x + decode_fs.x / scale.x, .y = dpos.y + decode_fs.y / scale.y };
+
+ v2 dpos = {.x = 20, .y = ctx->window_size.y - acq_fs.y - decode_fs.y - compute_fs.y - 20};
+ v2 dposa = {.x = dpos.x + acq_fs.x / scale.x, .y = dpos.y + acq_fs.y / scale.y };
+ DrawTextEx(ctx->font, (char *)acq_txt.data, dposa.rl, fontsize, fontspace, Fade(BLACK, 0.8));
+ DrawTextEx(ctx->font, (char *)acq_txt.data, dpos.rl, fontsize, fontspace, RED);
+
+ dpos.y += 2 + acq_fs.y;
+ dposa = (v2){ .x = dpos.x + decode_fs.x / scale.x, .y = dpos.y + decode_fs.y / scale.y };
DrawTextEx(ctx->font, (char *)decode_txt.data, dposa.rl, fontsize, fontspace, Fade(BLACK, 0.8));
DrawTextEx(ctx->font, (char *)decode_txt.data, dpos.rl, fontsize, fontspace, RED);
@@ -110,7 +121,7 @@ do_beamformer(BeamformerCtx *ctx, Arena arena, s8 rf_data)
ASSERT(rf_ssbo_idx == 0 || rf_ssbo_idx == 1);
/* NOTE: Load RF Data into GPU */
- /* TODO: This should be done in a seperate thread */
+ /* TODO: This should be done in a separate thread */
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ctx->csctx.rf_data_ssbos[!rf_ssbo_idx]);
glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, rf_data.len, rf_data.data);
@@ -142,4 +153,14 @@ do_beamformer(BeamformerCtx *ctx, Arena arena, s8 rf_data)
ctx->flags ^= DO_COMPUTE;
if (IsKeyPressed(KEY_D))
ctx->flags ^= DO_DECODE;
+ if (IsKeyPressed(KEY_LEFT)) {
+ ctx->acquisition--;
+ if (ctx->acquisition < 0)
+ ctx->acquisition = ctx->csctx.rf_data_dim.d - 1;
+ }
+ if (IsKeyPressed(KEY_RIGHT)) {
+ ctx->acquisition++;
+ if (ctx->acquisition > ctx->csctx.rf_data_dim.d - 1)
+ ctx->acquisition = 0;
+ }
}
diff --git a/main.c b/main.c
@@ -129,19 +129,27 @@ init_compute_shader_ctx(ComputeShaderCtx *ctx, Arena a, uv3 rf_data_dim)
ctx->rf_data_dim_id = glGetUniformLocation(ctx->programs[CS_UFORCES], "u_rf_data_dim");
ctx->out_data_dim_id = glGetUniformLocation(ctx->programs[CS_UFORCES], "u_out_data_dim");
+ ctx->acquisition_id = glGetUniformLocation(ctx->programs[CS_UFORCES], "u_acquisition");
ctx->rf_data_dim = rf_data_dim;
- size rf_data_size = rf_data_dim.w * rf_data_dim.h * rf_data_dim.d * sizeof(f32);
- for (u32 i = 0; i < ARRAY_COUNT(ctx->rf_data_ssbos); i++)
- ctx->rf_data_ssbos[i] = rlLoadShaderBuffer(rf_data_size, NULL, GL_DYNAMIC_COPY);
+ size rf_data_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);
+ for (u32 i = 0; i < ARRAY_COUNT(ctx->rf_data_ssbos); i++) {
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER, ctx->rf_data_ssbos[i]);
+ glBufferData(GL_SHADER_STORAGE_BUFFER, rf_data_size, 0, GL_DYNAMIC_COPY);
+ /* TODO: This doesn't actually work; need to use
+ * a texture to store i16 data and load i32 data */
+ glClearBufferData(GL_SHADER_STORAGE_BUFFER, GL_R32I, GL_R16I, GL_SHORT, 0);
+ }
ctx->rf_data_idx = 0;
/* NOTE: store hadamard in GPU once; it won't change for a particular imaging session */
- ctx->hadamard_dim = (uv2){ .x = rf_data_dim.y, .y = rf_data_dim.y };
+ ctx->hadamard_dim = (uv2){ .x = rf_data_dim.d, .y = rf_data_dim.d };
size hadamard_elements = ctx->hadamard_dim.x * ctx->hadamard_dim.y;
i32 *hadamard = alloc(&a, i32, hadamard_elements);
fill_hadamard(hadamard, ctx->hadamard_dim.x);
- ctx->hadamard_ssbo = rlLoadShaderBuffer(hadamard_elements * sizeof(i32), hadamard, GL_DYNAMIC_COPY);
+ ctx->hadamard_ssbo = rlLoadShaderBuffer(hadamard_elements * sizeof(i32), hadamard, GL_STATIC_DRAW);
}
static void
@@ -214,8 +222,9 @@ reload_shaders(BeamformerCtx *ctx, Arena a)
csctx->rf_data_dim_id = glGetUniformLocation(csctx->programs[CS_UFORCES], "u_rf_data_dim");
csctx->out_data_dim_id = glGetUniformLocation(csctx->programs[CS_UFORCES], "u_out_data_dim");
+ csctx->acquisition_id = glGetUniformLocation(csctx->programs[CS_UFORCES], "u_acquisition");
- Shader updated_fs = LoadShader(NULL, "shaders/render.glsl");
+ Shader updated_fs = LoadShader(NULL, "shaders/render.glsl");
if (updated_fs.id != rlGetShaderIdDefault()) {
UnloadShader(ctx->fsctx.shader);
ctx->fsctx.shader = updated_fs;
@@ -248,7 +257,7 @@ main(void)
size out_data_size = ctx.out_data_dim.w * ctx.out_data_dim.h * ctx.out_data_dim.d * sizeof(f32);
ctx.out_data_ssbo = rlLoadShaderBuffer(out_data_size, NULL, GL_DYNAMIC_COPY);
- init_compute_shader_ctx(&ctx.csctx, temp_memory, (uv3){.w = 4093, .h = 128, .d = 1});
+ init_compute_shader_ctx(&ctx.csctx, temp_memory, (uv3){.w = 3456, .h = 128, .d = 8});
init_fragment_shader_ctx(&ctx.fsctx, ctx.out_data_dim);
ctx.flags |= RELOAD_SHADERS;
diff --git a/shaders/hadamard.glsl b/shaders/hadamard.glsl
@@ -2,7 +2,7 @@
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(std430, binding = 1) readonly restrict buffer buffer_1 {
- float rf_data[];
+ int rf_data[];
};
layout(std430, binding = 2) writeonly restrict buffer buffer_2 {
@@ -22,10 +22,11 @@ void main()
* the result is stored to the same row, column index of the output data.
*/
uint time_sample = gl_GlobalInvocationID.x;
- uint column = gl_GlobalInvocationID.y;
+ uint channel = gl_GlobalInvocationID.y;
+ uint acq = gl_GlobalInvocationID.z;
/* offset to get the correct column in hadamard matrix */
- uint hoff = column * u_rf_data_dim.y;
+ uint hoff = u_rf_data_dim.z * acq;
/* TODO: make sure incoming data is organized so that stride is 1
* i.e. each column should be a single time sample for all channels
@@ -33,13 +34,13 @@ void main()
*/
/* offset to get the time sample and row in rf data */
- uint rstride = u_rf_data_dim.x;
- uint rfoff = column * rstride + time_sample;
+ 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 */
- float sum = 0;
- for (int i = 0; i < u_rf_data_dim.y; i++)
+ int sum = 0;
+ for (int i = 0; i < u_rf_data_dim.z; i++)
sum += hadamard[hoff + i] * rf_data[rfoff + rstride * i];
- out_data[rfoff] = float(sum);
+ out_data[rfoff + rstride * acq] = float(sum);
}
diff --git a/shaders/uforces.glsl b/shaders/uforces.glsl
@@ -11,6 +11,7 @@ layout(std430, binding = 2) writeonly restrict buffer buffer_2 {
layout(location = 3) uniform uvec3 u_rf_data_dim;
layout(location = 4) uniform uvec3 u_out_data_dim;
+layout(location = 5) uniform uint u_acquisition;
uint rf_idx(uint x, uint y, uint z)
{
@@ -24,16 +25,17 @@ uint out_idx(uint x, uint y, uint z)
void main()
{
- vec3 scale = vec3(u_out_data_dim) / vec3(u_rf_data_dim);
+ vec3 scale = vec3(u_rf_data_dim) / vec3(u_out_data_dim);
ivec3 rf_coord = ivec3(gl_GlobalInvocationID.xyz * scale);
ivec3 out_coord = ivec3(gl_GlobalInvocationID.xyz);
+ uint x = rf_coord.x;
+ uint y = rf_coord.y;
+ uint z = u_acquisition;
+
/* TODO: Probably should rotate in the fragment shader */
- uint x = rf_coord.y;
- uint y = rf_coord.x;
- uint z = 0;
+ uint oidx = out_idx(out_coord.y, out_coord.x, out_coord.z);
- uint oidx = out_idx(out_coord.x, out_coord.y, out_coord.z);
uint ridx = rf_idx(x, y, z);
out_data[oidx] = rf_data[ridx];
}
diff --git a/util.h b/util.h
@@ -14,6 +14,7 @@
#endif
typedef uint8_t u8;
+typedef int16_t i16;
typedef int32_t i32;
typedef uint32_t u32;
typedef uint32_t b32;
@@ -81,6 +82,7 @@ typedef struct {
uv3 rf_data_dim;
i32 rf_data_dim_id;
+ i32 acquisition_id;
i32 out_data_dim_id;
} ComputeShaderCtx;
@@ -101,6 +103,8 @@ typedef struct {
u32 out_data_ssbo;
uv3 out_data_dim;
+ i32 acquisition;
+
ComputeShaderCtx csctx;
FragmentShaderCtx fsctx;
} BeamformerCtx;