Commit: 95b319ebf6d812636e292454c121b347e9cf6f2e
Parent: c52cee3a74e9ea982371d75b58c36f78bb3e05fb
Author: Randy Palamar
Date: Mon, 10 Mar 2025 18:36:59 -0600
core: do more compute shader preprocessing
This will aid in minimizing the number of places we need to modify
to add new DAS IDs and other things.
Diffstat:
6 files changed, 68 insertions(+), 59 deletions(-)
diff --git a/beamformer.c b/beamformer.c
@@ -362,7 +362,7 @@ compute_cursor_finished(struct compute_cursor *cursor)
}
static void
-do_compute_shader(BeamformerCtx *ctx, Arena arena, BeamformFrame *frame, enum compute_shaders shader)
+do_compute_shader(BeamformerCtx *ctx, Arena arena, BeamformFrame *frame, ComputeShaderID shader)
{
ComputeShaderCtx *csctx = &ctx->csctx;
@@ -511,6 +511,37 @@ link_program(Platform *platform, Arena a, u32 shader_id)
return result;
}
+static s8
+push_compute_shader_header(Arena *a, ComputeShaderID shader)
+{
+ s8 result = {.data = a->beg};
+ push_s8(a, s8(COMPUTE_SHADER_HEADER));
+ switch (shader) {
+ case CS_DAS: {
+ push_s8(a, s8("layout("
+ "local_size_x = " str(DAS_LOCAL_SIZE_X) ", "
+ "local_size_y = " str(DAS_LOCAL_SIZE_Y) ", "
+ "local_size_z = " str(DAS_LOCAL_SIZE_Z) ") "
+ "in;\n\n"));
+ #define X(type, id, pretty) push_s8(a, s8("#define DAS_ID_" #type " " #id "\n"));
+ DAS_TYPES
+ #undef X
+ } break;
+ case CS_DECODE_FLOAT: {
+ push_s8(a, s8("#define INPUT_DATA_TYPE_FLOAT\n\n"));
+ } /* FALLTHROUGH */
+ case CS_DECODE: {
+ #define X(type, id, pretty) push_s8(a, s8("#define DECODE_MODE_" #type " " #id "\n"));
+ DECODE_TYPES
+ #undef X
+ } break;
+ default: break;
+ }
+ s8 end = push_s8(a, s8("\n#line 1\n"));
+ result.len = end.data + end.len - result.data;
+ return result;
+}
+
static void
reload_compute_shader(BeamformerCtx *ctx, s8 path, ComputeShaderReloadContext *csr, Arena tmp)
{
@@ -518,14 +549,8 @@ reload_compute_shader(BeamformerCtx *ctx, s8 path, ComputeShaderReloadContext *c
/* NOTE: arena works as stack (since everything here is 1 byte aligned) */
s8 header = {.data = tmp.beg};
- if (csr->needs_header) {
- header = push_s8(&tmp, s8(COMPUTE_SHADER_HEADER));
- if (csr->shader == CS_DECODE_FLOAT) {
- s8 extra = push_s8(&tmp, s8(COMPUTE_FLOAT_DECODE_HEADER));
- ASSERT(extra.data == header.data + header.len);
- header.len += extra.len;
- }
- }
+ if (csr->needs_header)
+ header = push_compute_shader_header(&tmp, csr->shader);
s8 shader_text = ctx->platform.read_whole_file(&tmp, (c8 *)path.data);
shader_text.data -= header.len;
@@ -644,7 +669,7 @@ DEBUG_EXPORT BEAMFORMER_COMPLETE_COMPUTE_FN(beamformer_complete_compute)
frame->max_coordinate = ctx->params->raw.output_max_coordinate;
u32 stage_count = ctx->params->compute_stages_count;
- enum compute_shaders *stages = ctx->params->compute_stages;
+ ComputeShaderID *stages = ctx->params->compute_stages;
for (u32 i = 0; i < stage_count; i++) {
frame->timer_active[stages[i]] = 1;
glBeginQuery(GL_TIME_ELAPSED, frame->timer_ids[stages[i]]);
diff --git a/beamformer.h b/beamformer.h
@@ -142,12 +142,12 @@ typedef struct {
typedef struct {
BeamformerParameters raw;
- enum compute_shaders compute_stages[16];
- u32 compute_stages_count;
- b32 upload;
- u32 raw_data_size;
- b32 export_next_frame;
- c8 export_pipe_name[1024];
+ ComputeShaderID compute_stages[16];
+ u32 compute_stages_count;
+ b32 upload;
+ u32 raw_data_size;
+ b32 export_next_frame;
+ c8 export_pipe_name[1024];
} BeamformerParametersFull;
typedef struct {
@@ -267,7 +267,7 @@ typedef struct {
void *beamformer_ctx;
s8 label;
s8 path;
- u32 shader;
+ ComputeShaderID shader;
b32 needs_header;
} ComputeShaderReloadContext;
diff --git a/beamformer_parameters.h b/beamformer_parameters.h
@@ -11,21 +11,27 @@
X(MIN_MAX, 6, "min_max", 0, "Min/Max") \
X(SUM, 7, "sum", 0, "Sum")
-enum compute_shaders {
+typedef enum {
#define X(e, n, s, h, pn) CS_ ##e = n,
COMPUTE_SHADERS
#undef X
CS_LAST
-};
+} ComputeShaderID;
-#define DECODE_MODE_NONE 0
-#define DECODE_MODE_HADAMARD 1
+#define DECODE_TYPES \
+ X(NONE, 0, "None") \
+ X(HADAMARD, 1, "Hadamard")
-#define DAS_ID_FORCES 0
-#define DAS_ID_UFORCES 1
-#define DAS_ID_HERCULES 2
-#define DAS_ID_RCA_VLS 3
-#define DAS_ID_RCA_TPW 4
+#define DAS_TYPES \
+ X(FORCES, 0, "FORCES") \
+ X(UFORCES, 1, "UFORCES") \
+ X(HERCULES, 2, "HERCULES") \
+ X(RCA_VLS, 3, "VLS") \
+ X(RCA_TPW, 4, "TPW")
+
+#define DAS_LOCAL_SIZE_X 32
+#define DAS_LOCAL_SIZE_Y 1
+#define DAS_LOCAL_SIZE_Z 32
#define MAX_BEAMFORMED_SAVED_FRAMES 16
/* NOTE: This struct follows the OpenGL std140 layout. DO NOT modify unless you have
@@ -77,10 +83,6 @@ _Static_assert((offsetof(BeamformerParameters, output_min_coordinate) & 15) == 0
_Static_assert((sizeof(BeamformerParameters) & 15) == 0,
"sizeof(BeamformerParameters) must be a multiple of 16");
-/* NOTE: garbage to get the prepocessor to properly stringize the value of a macro */
-#define str_(x) #x
-#define str(x) str_(x)
-
#define COMPUTE_SHADER_HEADER "\
#version 460 core\n\
\n\
@@ -108,24 +110,4 @@ layout(std140, binding = 0) uniform parameters {\n\
float f_number; /* F# (set to 0 to disable) */\n\
uint readi_group_id; /* Which readi group this data is from */\n\
uint readi_group_size; /* Size of readi transmit group */\n\
-};\n\
-\n\
-#define DECODE_MODE_NONE " str(DECODE_MODE_NONE) "\n\
-#define DECODE_MODE_HADAMARD " str(DECODE_MODE_HADAMARD) "\n\
-\n\
-#define DAS_ID_FORCES " str(DAS_ID_FORCES) "\n\
-#define DAS_ID_UFORCES " str(DAS_ID_UFORCES) "\n\
-#define DAS_ID_HERCULES " str(DAS_ID_HERCULES) "\n\
-#define DAS_ID_RCA_VLS " str(DAS_ID_RCA_VLS) "\n\
-#define DAS_ID_RCA_TPW " str(DAS_ID_RCA_TPW) "\n\
-\n\
-#line 1\n"
-
-#define COMPUTE_FLOAT_DECODE_HEADER "\
-#define INPUT_DATA_TYPE_FLOAT\n\
-#line 1\n"
-
-/* TODO(rnp): bake this into the das shader header */
-#define DAS_LOCAL_SIZE_X 32
-#define DAS_LOCAL_SIZE_Y 1
-#define DAS_LOCAL_SIZE_Z 32
+};\n\n"
diff --git a/helpers/ogl_beamformer_lib.c b/helpers/ogl_beamformer_lib.c
@@ -3,12 +3,12 @@
typedef struct {
BeamformerParameters raw;
- enum compute_shaders compute_stages[16];
- u32 compute_stages_count;
- b32 upload;
- u32 raw_data_size;
- b32 export_next_frame;
- c8 export_pipe_name[1024];
+ ComputeShaderID compute_stages[16];
+ u32 compute_stages_count;
+ b32 upload;
+ u32 raw_data_size;
+ b32 export_next_frame;
+ c8 export_pipe_name[1024];
} BeamformerParametersFull;
typedef struct {
diff --git a/shaders/das.glsl b/shaders/das.glsl
@@ -1,6 +1,4 @@
/* See LICENSE for license details. */
-layout(local_size_x = 32, local_size_y = 1, local_size_z = 32) in;
-
layout(std430, binding = 1) readonly restrict buffer buffer_1 {
vec2 rf_data[];
};
diff --git a/util.h b/util.h
@@ -39,6 +39,10 @@
#define static_assert _Static_assert
+/* NOTE: garbage to get the prepocessor to properly stringize the value of a macro */
+#define str_(x) #x
+#define str(x) str_(x)
+
#define ARRAY_COUNT(a) (sizeof(a) / sizeof(*a))
#define ABS(x) ((x) < 0 ? (-x) : (x))
#define BETWEEN(x, a, b) ((x) >= (a) && (x) <= (b))