Commit: 8a48d013d4dfa2c00f7566b5312cceed14f76984
Parent: 5755f89922f954ba8853baac509c2b989908c8a8
Author: Randy Palamar
Date: Fri, 21 Jun 2024 19:24:04 -0600
GPU UFORCES
Diffstat:
6 files changed, 57 insertions(+), 53 deletions(-)
diff --git a/beamformer.c b/beamformer.c
@@ -23,7 +23,6 @@ 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;
@@ -33,12 +32,12 @@ do_compute_shader(BeamformerCtx *ctx, u32 rf_ssbo_idx, enum compute_shaders shad
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, csctx->rf_data_ssbos[rf_ssbo_idx]);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, csctx->rf_data_ssbos[2]);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, csctx->hadamard_ssbo);
- glDispatchCompute(csctx->rf_data_dim.x, csctx->rf_data_dim.y, csctx->rf_data_dim.z);
+ glDispatchCompute(csctx->rf_data_dim.x / 32, csctx->rf_data_dim.y / 32, csctx->rf_data_dim.z);
break;
case CS_UFORCES:
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, csctx->rf_data_ssbos[data_idx]);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ctx->out_data_ssbo);
- glDispatchCompute(ctx->out_data_dim.x, ctx->out_data_dim.y, ctx->out_data_dim.z);
+ glDispatchCompute(ctx->out_data_dim.x / 32, ctx->out_data_dim.y / 32, ctx->out_data_dim.z);
break;
default: ASSERT(0);
}
@@ -51,26 +50,18 @@ 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 *)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 - 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 };
+ 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 };
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);
@@ -153,14 +144,4 @@ 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,7 +129,6 @@ 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(i32);
@@ -222,7 +221,6 @@ 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");
if (updated_fs.id != rlGetShaderIdDefault()) {
@@ -244,8 +242,8 @@ main(void)
os_file_stats decoded_stats = os_get_file_stats(decoded_name);
s8 raw_rf_data = os_read_file(&temp_memory, decoded_name, decoded_stats.filesize);
- ctx.window_size = (uv2){.w = 720, .h = 720};
- ctx.out_data_dim = (uv3){.w = 720, .h = 720, .d = 1};
+ ctx.window_size = (uv2){.w = 2048, .h = 2048};
+ ctx.out_data_dim = (uv3){.w = 2048, .h = 2048, .d = 1};
ctx.bg = PINK;
ctx.fg = (Color){ .r = 0xea, .g = 0xe1, .b = 0xb4, .a = 0xff };
diff --git a/shaders/hadamard.glsl b/shaders/hadamard.glsl
@@ -1,5 +1,5 @@
#version 460 core
-layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in;
layout(std430, binding = 1) readonly restrict buffer buffer_1 {
int rf_data[];
diff --git a/shaders/render.glsl b/shaders/render.glsl
@@ -23,7 +23,7 @@ void main()
{
ivec2 coord = ivec2(fragTexCoord * u_out_data_dim.xy);
float smp = out_data[coord.y * u_out_data_dim.x + coord.x];
- smp = 20 * log(abs(smp) + 1e-12) + 60;
+ smp = 20 * log(abs(smp)) + 50;
v_out_colour = vec4(hsv2rgb(vec3(smp, 0.8, 0.95)), 1);
}
diff --git a/shaders/uforces.glsl b/shaders/uforces.glsl
@@ -1,5 +1,5 @@
#version 460 core
-layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in;
layout(std430, binding = 1) readonly restrict buffer buffer_1 {
float rf_data[];
@@ -9,33 +9,61 @@ layout(std430, binding = 2) writeonly restrict buffer buffer_2 {
float out_data[];
};
-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)
-{
- return u_rf_data_dim.y * u_rf_data_dim.x * z + u_rf_data_dim.x * y + x;
-}
-
-uint out_idx(uint x, uint y, uint z)
-{
- return u_out_data_dim.y * u_out_data_dim.x * z + u_out_data_dim.x * y + x;
-}
+layout(location = 3) uniform uvec3 u_rf_data_dim;
+layout(location = 4) uniform uvec3 u_out_data_dim;
+layout(location = 5) uniform float u_sound_speed = 1452;
+layout(location = 6) uniform float u_sampling_frequency = 2.0833e7;
+layout(location = 7) uniform float u_focal_depth = 0.07;
+//layout(location = 10) uniform sampler2D u_element_positions;
void main()
{
vec3 scale = vec3(u_rf_data_dim) / vec3(u_out_data_dim);
+ vec2 pixel = vec2(gl_GlobalInvocationID.xy);
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;
+ /* NOTE: Convert pixel to physical coordinates */
+ /* TODO: Send these in like the 3D program */
+
+ vec2 xdc_upper_left = vec2(-0.0096, -0.0096);
+ vec2 xdc_bottom_right = vec2( 0.0096, 0.0096);
+ //vec2 xdc_upper_left = texture(u_element_positions, ivec2(0, 0)).xy;
+ //vec2 xdc_bottom_right = texture(u_element_positions, ivec2(1, 1)).xy;
+ vec2 xdc_size = abs(xdc_upper_left - xdc_bottom_right);
+
+ /* TODO: for now assume y-dimension is along transducer center */
+ vec3 image_point = vec3(
+ xdc_upper_left.x + pixel.x * xdc_size.x / u_out_data_dim.x,
+ 0,
+ pixel.y * 80e-3 / u_out_data_dim.y
+ );
+
+ float dx = xdc_size.x / float(u_rf_data_dim.y);
+ float dzsign = sign(image_point.z - u_focal_depth);
+
+ /* TODO: Send this into the GPU */
+ float sparse_elems[] = {17, 33, 49, 65, 80, 96, 112};
+
+ float sum = 0;
+ float x = image_point.x - xdc_upper_left.x;
+ /* NOTE: skip first acquisition since its garbage */
+ uint ridx = u_rf_data_dim.y * u_rf_data_dim.x;
+ for (uint i = 1; i < u_rf_data_dim.z; i++) {
+ vec3 focal_point = vec3(sparse_elems[i - 1] * dx, 0, u_focal_depth);
+ float transmit_dist = u_focal_depth + dzsign * distance(image_point, focal_point);
- /* TODO: Probably should rotate in the fragment shader */
- uint oidx = out_idx(out_coord.y, out_coord.x, out_coord.z);
+ vec2 rdist = vec2(x, image_point.z);
+ for (uint j = 0; j < u_rf_data_dim.y; j++) {
+ float dist = transmit_dist + length(rdist);
+ uint rx = uint(dist * u_sampling_frequency / u_sound_speed);
- uint ridx = rf_idx(x, y, z);
- out_data[oidx] = rf_data[ridx];
+ sum += rf_data[ridx + rx];
+ rdist.x -= dx;
+ ridx += u_rf_data_dim.x;
+ }
+ ridx += u_rf_data_dim.y * u_rf_data_dim.x;
+ }
+ uint oidx = u_out_data_dim.x * out_coord.y + out_coord.x;
+ out_data[oidx] = sum;
}
diff --git a/util.h b/util.h
@@ -82,7 +82,6 @@ typedef struct {
uv3 rf_data_dim;
i32 rf_data_dim_id;
- i32 acquisition_id;
i32 out_data_dim_id;
} ComputeShaderCtx;
@@ -103,8 +102,6 @@ typedef struct {
u32 out_data_ssbo;
uv3 out_data_dim;
- i32 acquisition;
-
ComputeShaderCtx csctx;
FragmentShaderCtx fsctx;
} BeamformerCtx;