Commit: 0d7e5e3f8abcd482e616e918c38277e251503b01
Parent: 0163bc9079c9e3c72220ae82a3c40923f160e76e
Author: Randy Palamar
Date: Tue, 18 Jun 2024 15:10:09 -0600
reorganize structs and actually add shaders
Diffstat:
5 files changed, 123 insertions(+), 56 deletions(-)
diff --git a/beamformer.c b/beamformer.c
@@ -14,6 +14,21 @@
#include "util.c"
+static void
+do_compute_shader(BeamformerCtx *ctx, enum compute_shaders shader)
+{
+ ComputeShaderCtx *csctx = &ctx->csctx;
+ glUseProgram(csctx->programs[shader]);
+
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, csctx->rf_data_ssbo);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ctx->out_data_ssbo);
+
+ glUniform3uiv(csctx->rf_data_dim_id, 1, csctx->rf_data_dim.E);
+ glUniform3uiv(csctx->out_data_dim_id, 1, ctx->out_data_dim.E);
+
+ glDispatchCompute(ctx->out_data_dim.x, ctx->out_data_dim.y, ctx->out_data_dim.z);
+}
+
DEBUG_EXPORT void
do_beamformer(BeamformerCtx *ctx, Arena arena, s8 rf_data)
{
@@ -45,31 +60,20 @@ do_beamformer(BeamformerCtx *ctx, Arena arena, s8 rf_data)
scale.y *= -1.0;
}
- {
- ComputeShaderCtx *csctx = &ctx->csctx;
- glUseProgram(csctx->programs[CS_UFORCES]);
-
- glBindBuffer(GL_SHADER_STORAGE_BUFFER, csctx->rf_data_ssbo);
- glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, rf_data.len, rf_data.data);
-
- glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, csctx->rf_data_ssbo);
- glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, csctx->out_img_ssbo);
+ /* Load RF Data into GPU */
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER, ctx->csctx.rf_data_ssbo);
+ glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, rf_data.len, rf_data.data);
- glUniform3uiv(csctx->u_rf_dim_id, 1, csctx->rf_data_dim.E);
- glUniform3ui(csctx->u_out_dim_id, ctx->out_img_dim.x, ctx->out_img_dim.y, 0);
-
- glDispatchCompute(ctx->out_img_dim.x, ctx->out_img_dim.y, 1);
- }
+ do_compute_shader(ctx, CS_UFORCES);
BeginDrawing();
- ClearBackground(PINK);
+ ClearBackground(ctx->bg);
BeginShaderMode(ctx->fsctx.shader);
glUseProgram(ctx->fsctx.shader.id);
- glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ctx->csctx.out_img_ssbo);
- glUniform2uiv(ctx->fsctx.u_out_dim_id, 1, ctx->out_img_dim.E);
- ASSERT(ctx->fsctx.u_out_dim_id != -1);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ctx->out_data_ssbo);
+ glUniform3uiv(ctx->fsctx.out_data_dim_id, 1, ctx->out_data_dim.E);
DrawTexture(ctx->fsctx.output, 0, 0, WHITE);
EndShaderMode();
diff --git a/main.c b/main.c
@@ -95,7 +95,7 @@ update_output_image_dimensions(BeamformerCtx *ctx, uv2 new_size)
#endif
static void
-init_compute_shader_ctx(ComputeShaderCtx *ctx, uv3 rf_data_dim, uv2 out_img_dim)
+init_compute_shader_ctx(ComputeShaderCtx *ctx, uv3 rf_data_dim)
{
for (u32 i = 0; i < ARRAY_COUNT(ctx->programs); i++) {
char *shader_text = LoadFileText(compute_shader_paths[i]);
@@ -105,30 +105,27 @@ init_compute_shader_ctx(ComputeShaderCtx *ctx, uv3 rf_data_dim, uv2 out_img_dim)
UnloadFileText(shader_text);
}
- ctx->u_rf_dim_id = glGetUniformLocation(ctx->programs[CS_UFORCES], "u_rf_dim");
- ctx->u_out_dim_id = glGetUniformLocation(ctx->programs[CS_UFORCES], "u_out_dim");
-
- ctx->rf_data_dim = 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->rf_data_dim = rf_data_dim;
size rf_data_size = rf_data_dim.w * rf_data_dim.h * rf_data_dim.d * sizeof(f32);
- size out_img_size = out_img_dim.w * out_img_dim.h * sizeof(f32);
-
- ctx->rf_data_ssbo = rlLoadShaderBuffer(rf_data_size, NULL, GL_DYNAMIC_COPY);
- ctx->out_img_ssbo = rlLoadShaderBuffer(out_img_size, NULL, GL_DYNAMIC_COPY);
+ ctx->rf_data_ssbo = rlLoadShaderBuffer(rf_data_size, NULL, GL_DYNAMIC_COPY);
}
static void
-init_fragment_shader_ctx(FragmentShaderCtx *ctx, uv2 window_size)
+init_fragment_shader_ctx(FragmentShaderCtx *ctx, uv3 out_data_dim)
{
- ctx->shader = LoadShader(NULL, "shaders/render.glsl");
- ctx->u_out_dim_id = glGetUniformLocation(ctx->shader.id, "u_out_img_dim");
- glUniform2uiv(ctx->u_out_dim_id, 1, window_size.E);
+ ctx->shader = LoadShader(NULL, "shaders/render.glsl");
+
+ ctx->out_data_dim_id = glGetUniformLocation(ctx->shader.id, "u_out_data_dim");
+ glUniform3uiv(ctx->out_data_dim_id, 1, out_data_dim.E);
/* TODO: add min max uniform */
/* output texture for image blitting */
Texture2D new;
- new.width = window_size.w;
- new.height = window_size.h;
+ new.width = out_data_dim.w;
+ new.height = out_data_dim.h;
new.mipmaps = 1;
new.format = RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32;
new.id = rlLoadTexture(0, new.width, new.height, new.format, new.mipmaps);
@@ -167,18 +164,16 @@ compile_shader(Arena a, u32 type, s8 shader)
}
static void
-reload_shaders(Arena a, BeamformerCtx *ctx)
+reload_shaders(BeamformerCtx *ctx, Arena a)
{
- u32 cs_programs[ARRAY_COUNT(((ComputeShaderCtx *)0)->programs)];
-
ComputeShaderCtx *csctx = &ctx->csctx;
- for (u32 i = 0; i < ARRAY_COUNT(cs_programs); i++) {
+ for (u32 i = 0; i < ARRAY_COUNT(csctx->programs); i++) {
Arena tmp = a;
os_file_stats fs = os_get_file_stats(compute_shader_paths[i]);
s8 shader_text = os_read_file(&tmp, compute_shader_paths[i], fs.filesize);
u32 shader_id = compile_shader(tmp, GL_COMPUTE_SHADER, shader_text);
- if (shader_id != rlGetShaderIdDefault()) {
+ if (shader_id) {
glDeleteProgram(csctx->programs[i]);
csctx->programs[i] = rlLoadComputeShaderProgram(shader_id);
}
@@ -186,15 +181,15 @@ reload_shaders(Arena a, BeamformerCtx *ctx)
glDeleteShader(shader_id);
}
- csctx->u_rf_dim_id = glGetUniformLocation(csctx->programs[CS_UFORCES], "u_rf_dim");
- csctx->u_out_dim_id = glGetUniformLocation(csctx->programs[CS_UFORCES], "u_out_dim");
+ 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");
Shader updated_fs = LoadShader(NULL, "shaders/render.glsl");
if (updated_fs.id != rlGetShaderIdDefault()) {
UnloadShader(ctx->fsctx.shader);
- ctx->fsctx.shader = updated_fs;
- ctx->fsctx.u_out_dim_id = GetShaderLocation(updated_fs, "u_out_img_dim");
- glUniform2ui(ctx->fsctx.u_out_dim_id, ctx->out_img_dim.x, ctx->out_img_dim.y);
+ ctx->fsctx.shader = updated_fs;
+ ctx->fsctx.out_data_dim_id = GetShaderLocation(updated_fs, "u_out_data_dim");
+ glUniform3uiv(ctx->fsctx.out_data_dim_id, 1, ctx->out_data_dim.E);
}
}
@@ -209,17 +204,19 @@ main(void)
os_file_stats decoded_stats = os_get_file_stats(decoded_name);
s8 raw_rf_data = os_read_file(&temp_arena, decoded_name, decoded_stats.filesize);
- ctx.window_size = (uv2){.w = 720, .h = 720};
- ctx.out_img_dim = (uv2){.w = 720, .h = 720};
+ ctx.window_size = (uv2){.w = 720, .h = 720};
+ ctx.out_data_dim = (uv3){.w = 720, .h = 720, .d = 1};
- ctx.bg = DARKGRAY;
+ ctx.bg = PINK;
ctx.fg = (Color){ .r = 0xea, .g = 0xe1, .b = 0xb4, .a = 0xff };
SetConfigFlags(FLAG_VSYNC_HINT);
InitWindow(ctx.window_size.w, ctx.window_size.h, "OGL Beamformer");
- init_compute_shader_ctx(&ctx.csctx, (uv3){.w = 4093, .h = 128, .d = 1}, ctx.window_size);
- init_fragment_shader_ctx(&ctx.fsctx, ctx.window_size);
+ 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, (uv3){.w = 4093, .h = 128, .d = 1});
+ init_fragment_shader_ctx(&ctx.fsctx, ctx.out_data_dim);
ctx.flags |= RELOAD_SHADERS;
@@ -228,7 +225,7 @@ main(void)
if (ctx.flags & RELOAD_SHADERS) {
ctx.flags &= ~RELOAD_SHADERS;
- reload_shaders(temp_arena, &ctx);
+ reload_shaders(&ctx, temp_arena);
}
do_beamformer(&ctx, temp_arena, raw_rf_data);
diff --git a/shaders/render.glsl b/shaders/render.glsl
@@ -0,0 +1,29 @@
+#version 430
+
+in vec2 fragTexCoord;
+out vec4 v_out_colour;
+
+layout(std430, binding = 1) readonly buffer beamformed_data
+{
+ float out_data[];
+};
+
+layout(location = 1) uniform uvec3 u_out_data_dim;
+
+/* input: h [0,360] | s,v [0, 1] *
+ * output: rgb [0,1] */
+vec3 hsv2rgb(vec3 hsv)
+{
+ vec3 k = mod(vec3(5, 3, 1) + hsv.x / 60, 6);
+ k = max(min(min(k, 4 - k), 1), 0);
+ return hsv.z - hsv.z * hsv.y * k;
+}
+
+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;
+
+ v_out_colour = vec4(hsv2rgb(vec3(smp, 0.8, 0.95)), 1);
+}
diff --git a/shaders/uforces.glsl b/shaders/uforces.glsl
@@ -0,0 +1,39 @@
+#version 460 core
+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[];
+};
+
+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;
+
+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;
+}
+
+void main()
+{
+ vec3 scale = vec3(u_out_data_dim) / vec3(u_rf_data_dim);
+ ivec3 rf_coord = ivec3(gl_GlobalInvocationID.xyz * scale);
+ ivec3 out_coord = ivec3(gl_GlobalInvocationID.xyz);
+
+ /* 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.x, out_coord.y, out_coord.z);
+ uint ridx = rf_idx(x, y, z);
+ out_data[oidx] = rf_data[ridx];
+}
diff --git a/util.c b/util.c
@@ -67,19 +67,16 @@ enum program_flags {
typedef struct {
u32 programs[CS_LAST];
- u32 out_img_ssbo;
-
u32 rf_data_ssbo;
uv3 rf_data_dim;
-
- i32 u_rf_dim_id;
- i32 u_out_dim_id;
+ i32 rf_data_dim_id;
+ i32 out_data_dim_id;
} ComputeShaderCtx;
typedef struct {
Shader shader;
Texture2D output;
- i32 u_out_dim_id;
+ i32 out_data_dim_id;
} FragmentShaderCtx;
typedef struct {
@@ -88,7 +85,8 @@ typedef struct {
Color bg, fg;
- uv2 out_img_dim; /* shared output image dimension */
+ u32 out_data_ssbo;
+ uv3 out_data_dim;
ComputeShaderCtx csctx;
FragmentShaderCtx fsctx;