ogl_beamforming

Ultrasound Beamforming Implemented with OpenGL
git clone anongit@rnpnr.xyz:ogl_beamforming.git
Log | Files | Refs | Feed | Submodules | README | LICENSE

Commit: d9d790381f3f551e0a11f837e5d77d8c0b76da98
Parent: 95061183cdefcd4fb2ef8f1cf0eaf4ae33fef506
Author: Randy Palamar
Date:   Sat, 25 Jul 2026 05:51:30 -0700

meta: build some compile time struct info into beamformer

This will be needed to convert bake parameters into vulkan
specialization constants and something else :)

Diffstat:
Mbeamformer_core.c | 24++++++++++++++----------
Mbeamformer_internal.h | 1+
Mbuild.c | 305++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Mgenerated/beamformer.c | 174++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Mlib/ogl_beamformer_lib.c | 1+
Ameta.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 395 insertions(+), 164 deletions(-)

diff --git a/beamformer_core.c b/beamformer_core.c @@ -877,16 +877,20 @@ stream_append_shader_header(Stream *s, i32 reloadable_index, BeamformerShaderDes } stream_append_byte(s, '\n'); - u32 *parameters = (u32 *)&sd->bake; - str8 *names = beamformer_shader_bake_parameter_names[reloadable_index]; - u32 float_bits = beamformer_shader_bake_parameter_float_bits[reloadable_index]; - i32 count = beamformer_shader_bake_parameter_counts[reloadable_index]; - - for (i32 index = 0; index < count; index++) { - stream_append_str8s(s, str8("#define "), names[index], - (float_bits & (1 << index))? str8(" uintBitsToFloat") : str8(" "), str8("(0x")); - stream_append_hex_u64(s, parameters[index]); - stream_append_str8(s, str8(")\n")); + i32 struct_id = beamformer_base_shader_to_bake_struct_id[reloadable_index]; + if (struct_id != -1) { + u32 *parameters = (u32 *)&sd->bake; + str8 *names = beamformer_shader_bake_parameter_names[reloadable_index]; + MetaStructInfo *si = meta_struct_info_by_id + struct_id; + MetaStructMember *sm = meta_struct_members_by_id[struct_id]; + + for (u32 index = 0; index < si->member_count; index++) { + b32 is_float = sm[index].type_id == MetaKind_F32; + stream_append_str8s(s, str8("#define "), names[index], + is_float ? str8(" uintBitsToFloat") : str8(" "), str8("(0x")); + stream_append_hex_u64(s, parameters[index]); + stream_append_str8(s, str8(")\n")); + } } } diff --git a/beamformer_internal.h b/beamformer_internal.h @@ -7,6 +7,7 @@ #include "util.h" #include "opengl.h" +#include "meta.h" #include "generated/beamformer.c" #include "generated/beamformer_core.c" #include "generated/beamformer_shader_data.c" diff --git a/build.c b/build.c @@ -572,7 +572,7 @@ function void check_rebuild_self(Arena arena, i32 argc, char *argv[]) { char *binary = shift(argv, argc); - if (needs_rebuild(binary, __FILE__, "os_win32.c", "os_linux.c", "util.c", "util.h")) { + if (needs_rebuild(binary, __FILE__, "meta.h", "os_win32.c", "os_linux.c", "util.c", "util.h")) { Stream name_buffer = arena_stream(arena); stream_append_str8s(&name_buffer, str8_from_c_str(binary), str8(".old")); char *old_name = (char *)arena_stream_commit_zero(&arena, &name_buffer).data; @@ -1065,34 +1065,7 @@ typedef enum { MetaEmitLang_Count, } MetaEmitLang; -#define META_KIND_LIST \ - X(M4, m4, f32mat4, float, single, 64, 16) \ - X(V4, v4, f32vec4, float, single, 16, 4) \ - X(SV4, iv4, i32vec4, int32_t, int32, 16, 4) \ - X(UV4, uv4, u32vec4, uint32_t, uint32, 16, 4) \ - X(UV2, uv2, u32vec2, uint32_t, uint32, 8, 2) \ - X(V3, v3, f32vec3, float, single, 12, 3) \ - X(V2, v2, f32vec2, float, single, 8, 2) \ - X(F32, f32, float32_t, float, single, 4, 1) \ - X(S32, i32, int32_t, int32_t, int32, 4, 1) \ - X(S16, i16, int16_t, int16_t, int16, 2, 1) \ - X(S8, i8, int8_t, int8_t, int8, 1, 1) \ - X(B64, b64, uint64_t, uint64_t, uint64, 8, 1) \ - X(B32, b32, bool, uint32_t, uint32, 4, 1) \ - X(B16, b16, uint16_t, uint16_t, uint16, 2, 1) \ - X(B8, b8, uint8_t, uint8_t, uint8, 1, 1) \ - X(U64, u64, uint64_t, uint64_t, uint64, 8, 1) \ - X(U32, u32, uint32_t, uint32_t, uint32, 4, 1) \ - X(U16, u16, uint16_t, uint16_t, uint16, 2, 1) \ - X(U8, u8, uint8_t, uint8_t, uint8, 1, 1) \ - X(STR, str8, error, error, error, 16, 1) \ - -typedef enum { - #define X(k, ...) MetaKind_## k, - META_KIND_LIST - #undef X - MetaKind_Count, -} MetaKind; +#include "meta.h" read_only global u8 meta_kind_byte_sizes[] = { #define X(_k, _c, _g, _b, _m, bytes, ...) bytes, @@ -1893,29 +1866,19 @@ read_only global b8 meta_struct_emit[] = {META_STRUCT_MAP_LIST}; #undef X typedef enum { - MetaStructFlag_Union = 1 << 0, - MetaStructFlag_ContainsUnion = 1 << 1, -} MetaStructFlags; - -typedef enum { - MetaStructMemberFlag_ReferenceType = 1 << 0, - MetaStructMemberFlag_ReferenceElements = 1 << 1, - MetaStructMemberFlag_EnumerationCount = 1 << 2, -} MetaStructMemberFlags; + MetaBuildStructMemberFlag_ReferenceType = 1 << 0, + MetaBuildStructMemberFlag_ReferenceElements = 1 << 1, + MetaBuildStructMemberFlag_EnumerationCount = 1 << 2, +} MetaBuildStructMemberFlags; typedef struct { - str8 name; + MetaStructInfo info; str8 *members; i32 *type_ids; i32 *elements; - MetaStructMemberFlags *member_flags; - - u32 member_count; - u32 byte_size; - - MetaStructFlags flags; + MetaBuildStructMemberFlags *member_flags; MetaEntityID entity; MetaLocation location; @@ -3325,11 +3288,11 @@ metagen_run_emit_set(MetaprogramContext *m, MetaContext *ctx, MetaEmitOperationL function i32 meta_struct_member_elements(MetaContext *ctx, MetaStruct *s, u32 member) { - assert(member < s->member_count); + assert(member < s->info.member_count); i32 result = s->elements[member]; - if (s->member_flags[member] & MetaStructMemberFlag_ReferenceElements) + if (s->member_flags[member] & MetaBuildStructMemberFlag_ReferenceElements) result = (i32)meta_entity(ctx, (MetaEntityID){result})->constant.U64; - if (s->member_flags[member] & MetaStructMemberFlag_EnumerationCount) + if (s->member_flags[member] & MetaBuildStructMemberFlag_EnumerationCount) result = (i32)meta_entity(ctx, (MetaEntityID){result})->table.entry_count; return result; } @@ -3394,11 +3357,11 @@ meta_struct_flattened_member_count(Arena scratch, MetaContext *ctx, MetaStruct * stack.count--; MetaStruct *s = stack.data[stack.count].s; u32 member = stack.data[stack.count].member_offset; - while (member < s->member_count) { + while (member < s->info.member_count) { if (s->members[member].length == 0) { assert(s->member_flags[member] & MetaStructMemberFlag_ReferenceType); MetaStruct *ss = ctx->struct_infos + ctx->entities.data[s->type_ids[member]].table.struct_info_id; - if (ss->flags & MetaStructFlag_Union) { + if (ss->info.flags & MetaStructFlag_Union) { member++; result++; } else { @@ -3458,7 +3421,7 @@ meta_push_struct_body(MetaContext *ctx, MetaprogramContext *m, MetaEntity *struc MetaStruct *s = ctx->struct_infos + se->table.struct_info_id; u32 member = stack.data[stack.count].member_offset; - while (member < s->member_count) { + while (member < s->info.member_count) { b32 type_reference = (s->member_flags[member] & MetaStructMemberFlag_ReferenceType) != 0; i32 type_id = s->type_ids[member]; str8 member_name = s->members[member]; @@ -3472,7 +3435,7 @@ meta_push_struct_body(MetaContext *ctx, MetaprogramContext *m, MetaEntity *struc *da_push(&m->scratch, &stack) = (struct stack_item){ctx->entities.data + type_id, 0}; MetaStruct *ss = ctx->struct_infos + ctx->entities.data[type_id].table.struct_info_id; - if (p.layout_style == MetaPushStructStyle_C && ss->flags & MetaStructFlag_Union) { + if (p.layout_style == MetaPushStructStyle_C && ss->info.flags & MetaStructFlag_Union) { metagen_push_table(m, m->scratch, p.prefix, p.suffix, columns, row, 2); meta_begin_scope(m, str8("union {")); row = 0; @@ -3483,8 +3446,8 @@ meta_push_struct_body(MetaContext *ctx, MetaprogramContext *m, MetaEntity *struc } else { Stream sb = arena_stream(m->scratch); - b32 enum_count = (s->member_flags[member] & MetaStructMemberFlag_EnumerationCount) != 0; - b32 elements_reference = enum_count || (s->member_flags[member] & MetaStructMemberFlag_ReferenceElements) != 0; + b32 enum_count = (s->member_flags[member] & MetaBuildStructMemberFlag_EnumerationCount) != 0; + b32 elements_reference = enum_count || (s->member_flags[member] & MetaBuildStructMemberFlag_ReferenceElements) != 0; // NOTE(rnp): member name column { read_only local_persist str8 elements_count_open[MetaPushStructStyle_Count] = { @@ -3506,11 +3469,11 @@ meta_push_struct_body(MetaContext *ctx, MetaprogramContext *m, MetaEntity *struc MetaEntity *re = ctx->entities.data + type_id; MetaStruct *rs = ctx->struct_infos + re->table.struct_info_id; if (member_name.length == 0) { - assert(rs->flags & MetaStructFlag_Union); + assert(rs->info.flags & MetaStructFlag_Union); member_name = str8("data"); } - if (rs->flags & MetaStructFlag_Union) - resolved_element_count *= rs->byte_size; + if (rs->info.flags & MetaStructFlag_Union) + resolved_element_count *= rs->info.size; } else if (!type_reference && p.base_type_element_count_scales) { resolved_element_count *= p.base_type_element_count_scales[type_id]; } @@ -3546,7 +3509,7 @@ meta_push_struct_body(MetaContext *ctx, MetaprogramContext *m, MetaEntity *struc if (meta_entity_kind_is_struct[re->kind]) rs = ctx->struct_infos + re->table.struct_info_id; - if (rs && rs->flags & MetaStructFlag_Union && p.union_style == MetaPushStructStyle_MATLAB) { + if (rs && rs->info.flags & MetaStructFlag_Union && p.union_style == MetaPushStructStyle_MATLAB) { stream_append_str8(&sb, p.base_types[MetaKind_U8]); if (p.layout_style == MetaPushStructStyle_MATLAB) stream_append_str8(&sb, str8(" % +")); @@ -3562,14 +3525,14 @@ meta_push_struct_body(MetaContext *ctx, MetaprogramContext *m, MetaEntity *struc // we can only use an opaque struct here stream_append_str8(&sb, str8("struct % ")); } else { - str8 name = rs ? rs->name : ctx->entity_names.data[type_id]; + str8 name = rs ? rs->info.name : ctx->entity_names.data[type_id]; stream_append_str8s(&sb, p.str_element_prefix, name); } } if (p.layout_style == MetaPushStructStyle_MATLAB) { stream_append_str8s(&sb, p.str_element_prefix, - rs ? rs->name : ctx->entity_names.data[type_id]); + rs ? rs->info.name : ctx->entity_names.data[type_id]); } columns[type_column[p.layout_style]][row] = arena_stream_commit_and_reset(&m->scratch, &sb); @@ -3583,7 +3546,7 @@ meta_push_struct_body(MetaContext *ctx, MetaprogramContext *m, MetaEntity *struc } } - if (member == s->member_count && s->flags & MetaStructFlag_Union && p.layout_style == MetaPushStructStyle_C) { + if (member == s->info.member_count && s->info.flags & MetaStructFlag_Union && p.layout_style == MetaPushStructStyle_C) { metagen_push_table(m, m->scratch, p.prefix, p.suffix, columns, row, 2); while (scope > 0) { meta_end_scope(m, str8("};")); @@ -4088,6 +4051,103 @@ metagen_emit_c_code(MetaContext *ctx, Arena arena) metagen_run_emit_set(m, ctx, ctx->emit_sets + MetaEmitLang_C, meta_kind_c_types); + // TODO(rnp): we may want this to include more than just the bake structs + if (ctx->base_shader_count) + DeferLoop(meta_begin_scope(m, str8("typedef enum {")), + meta_end_scope(m, str8("} " META_NAMESPACE_UPPER "StructKind;\n"))) + { + str8 kind_full = str8(META_NAMESPACE_UPPER "StructKind_"); + metagen_push_counted_enum_body_from_ids(m, kind_full, str8(""), str8("= "), str8(","), + ctx->entity_kind_ids[MetaEntityKind_BakeParameters], + ctx->entity_names.data, + ctx->entity_kind_counts[MetaEntityKind_BakeParameters]); + meta_push_line(m, kind_full, str8("Count,")); + } + m->scratch = ctx->scratch; + + // TODO(rnp): we may want this to include more than just the bake structs + if (ctx->base_shader_count) + DeferLoop(meta_begin_scope(m, str8("read_only global MetaStructMember *meta_struct_members_by_id[] = {")), + meta_end_scope(m, str8("};\n"))) + { + for EachIndex((u64)ctx->entity_kind_counts[MetaEntityKind_BakeParameters], id) { + MetaTable *t = &ctx->entities.data[ctx->entity_kind_ids[MetaEntityKind_BakeParameters][id]].table; + MetaStruct *s = ctx->struct_infos + t->struct_info_id; + + str8 *columns[4]; + for EachElement(columns, it) + columns[it] = push_array(&m->scratch, str8, s->info.member_count); + + u32 offset = 0; + for EachIndex((u64)s->info.member_count, member) { + // TODO(rnp): for now we only handle bake structs which must only have base types + assert((s->member_flags[member] & MetaStructMemberFlag_ReferenceType) == 0); + + Stream sb = arena_stream(m->scratch); + stream_append_u64(&sb, s->type_ids[member]); stream_append_byte(&sb, ','); + columns[0][member] = arena_stream_commit_and_reset(&m->scratch, &sb); + + stream_append_u64(&sb, offset); stream_append_byte(&sb, ','); + columns[1][member] = arena_stream_commit_and_reset(&m->scratch, &sb); + + stream_append_u64(&sb, s->elements[member]); stream_append_byte(&sb, ','); + columns[2][member] = arena_stream_commit_and_reset(&m->scratch, &sb); + + columns[3][member] = str8("0"); // TODO(rnp): reference type flag + + offset += meta_kind_byte_sizes[s->type_ids[member]]; + } + + DeferLoop(meta_begin_scope(m, str8("(MetaStructMember []){")), meta_end_scope(m, str8("},"))) + metagen_push_table(m, m->scratch, str8("{"), str8("},"), columns, s->info.member_count, countof(columns)); + m->scratch = ctx->scratch; + } + } + + if (ctx->base_shader_count) + DeferLoop(meta_begin_scope(m, str8("read_only global str8 *meta_struct_member_names_by_id[] = {")), + meta_end_scope(m, str8("};\n"))) + { + for EachIndex((u64)ctx->entity_kind_counts[MetaEntityKind_BakeParameters], id) { + MetaTable *t = &ctx->entities.data[ctx->entity_kind_ids[MetaEntityKind_BakeParameters][id]].table; + MetaStruct *s = ctx->struct_infos + t->struct_info_id; + + DeferLoop(meta_begin_scope(m, str8("(str8 []){")), meta_end_scope(m, str8("},"))) + for EachIndex((u64)s->info.member_count, member) + meta_push_line(m, str8("str8_comp(\""), s->members[member], str8("\"),")); + } + } + + if (ctx->base_shader_count) + DeferLoop(meta_begin_scope(m, str8("read_only global MetaStructInfo meta_struct_info_by_id[] = {")), + meta_end_scope(m, str8("};\n"))) + { + str8 *columns[4]; + for EachElement(columns, it) + columns[it] = push_array(&m->scratch, str8, ctx->entity_kind_counts[MetaEntityKind_BakeParameters]); + + for EachIndex((u64)ctx->entity_kind_counts[MetaEntityKind_BakeParameters], id) { + da_count entity = ctx->entity_kind_ids[MetaEntityKind_BakeParameters][id]; + MetaTable *t = &ctx->entities.data[entity].table; + MetaStruct *s = ctx->struct_infos + t->struct_info_id; + + columns[0][id] = push_str8_from_parts(&m->scratch, str8(""), ctx->entity_names.data[entity], str8("\"),")); + + Stream sb = arena_stream(m->scratch); + stream_append_u64(&sb, s->info.member_count); stream_append_byte(&sb, ','); + columns[1][id] = arena_stream_commit_and_reset(&m->scratch, &sb); + + stream_append_u64(&sb, s->info.size); stream_append_byte(&sb, ','); + columns[2][id] = arena_stream_commit_and_reset(&m->scratch, &sb); + + columns[3][id] = str8("0"); // TODO(rnp): union flags + } + + metagen_push_table(m, m->scratch, str8("{str8_comp(\""), str8("},"), columns, + ctx->entity_kind_counts[MetaEntityKind_BakeParameters], countof(columns)); + m->scratch = ctx->scratch; + } + ///////////////////////////////// // NOTE(rnp): shader info tables if (ctx->entity_kind_counts[MetaEntityKind_Shader]) @@ -4156,43 +4216,18 @@ metagen_emit_c_code(MetaContext *ctx, Arena arena) } if (ctx->base_shader_count) - DeferLoop(meta_begin_scope(m, str8("read_only global u32 " META_NAMESPACE_LOWER "_shader_bake_parameter_float_bits[] = {")), + DeferLoop(meta_begin_scope(m, str8("read_only global i32 " + META_NAMESPACE_LOWER "_base_shader_to_bake_struct_id[] = {")), meta_end_scope(m, str8("};\n"))) { for (da_count bs = 0; bs < ctx->base_shader_count; bs++) { da_count id = ctx->base_shader_ids[bs]; MetaEntity *e = ctx->entities.data + id; MetaEntityID bp_id = meta_entity_first_child_of_kind(ctx, e, MetaEntityKind_BakeParameters); - u32 hex = 0; - if (bp_id.value != 0) { - MetaTable *t = &ctx->entities.data[bp_id.value].table; - MetaStruct *s = ctx->struct_infos + t->struct_info_id; - for EachIndex(s->member_count, member) { - b32 type_reference = (s->member_flags[member] & MetaStructMemberFlag_ReferenceType) != 0; - if (!type_reference && s->type_ids[member] == MetaKind_F32) - hex |= 1 << member; - } - } - meta_begin_line(m, str8("0x")); - meta_push_u64_hex_width(m, hex, 8); - meta_end_line(m, str8("UL,")); - } - } - - if (ctx->base_shader_count) - DeferLoop(meta_begin_scope(m, str8("read_only global u8 " META_NAMESPACE_LOWER "_shader_bake_parameter_counts[] = {")), - meta_end_scope(m, str8("};\n"))) - { - for (da_count bs = 0; bs < ctx->base_shader_count; bs++) { - da_count id = ctx->base_shader_ids[bs]; - MetaEntity *e = ctx->entities.data + id; - MetaEntityID bp_id = meta_entity_first_child_of_kind(ctx, e, MetaEntityKind_BakeParameters); - u32 count = 0; - if (bp_id.value != 0) - count = ctx->entities.data[bp_id.value].table.entry_count; - meta_indent(m); - meta_push_u64(m, count); - meta_end_line(m, str8(",")); + i64 index = meta_lookup_id_slow(ctx->entity_kind_ids[MetaEntityKind_BakeParameters], + ctx->entity_kind_counts[MetaEntityKind_BakeParameters], + bp_id.value); + meta_indent(m); meta_push_i64(m, index); meta_end_line(m, str8(",")); } } @@ -4231,14 +4266,14 @@ metagen_matlab_union(MetaprogramContext *m, MetaContext *ctx, MetaStruct *u, str meta_begin_scope(m, str8("properties (Constant)")); { meta_begin_line(m, str8("byteSize(1,1) uint32 = ")); - meta_push_u64(m, u->byte_size); + meta_push_u64(m, u->info.size); meta_end_line(m); } meta_end_scope(m, str8("end")); } meta_end_scope(m, str8("end")); result &= meta_end_and_write_matlab(m, (c8 *)outfile.data); } - for EachIndex(u->member_count, union_member) { + for EachIndex(u->info.member_count, union_member) { if ((u->member_flags[union_member] & MetaStructMemberFlag_ReferenceType) == 0) { str8 type_name = meta_kind_c_types[u->type_ids[union_member]]; str8 name = u->members[union_member]; @@ -4276,12 +4311,12 @@ metagen_matlab_union(MetaprogramContext *m, MetaContext *ctx, MetaStruct *u, str meta_push_line(m, str8("bytes = zeros(1, obj.byteSize, 'uint8');")); str8 *columns[3]; - columns[0] = push_array(&m->scratch, str8, s->member_count); - columns[1] = push_array(&m->scratch, str8, s->member_count); - columns[2] = push_array(&m->scratch, str8, s->member_count); + columns[0] = push_array(&m->scratch, str8, s->info.member_count); + columns[1] = push_array(&m->scratch, str8, s->info.member_count); + columns[2] = push_array(&m->scratch, str8, s->info.member_count); u32 offset = 1; - for EachIndex(s->member_count, member) { + for EachIndex(s->info.member_count, member) { Stream sb = arena_stream(m->scratch); i32 type_id = s->type_ids[member]; @@ -4289,7 +4324,7 @@ metagen_matlab_union(MetaprogramContext *m, MetaContext *ctx, MetaStruct *u, str u32 member_size = 0; if (s->member_flags[member] & MetaStructMemberFlag_ReferenceType) { MetaStruct *ref = ctx->struct_infos + ctx->entities.data[type_id].table.struct_info_id; - member_size = ref->byte_size; + member_size = ref->info.size; // TODO(rnp): arrays of structs // - calculate member count with element count multiplied in for struct members // - do a sub loop for struct arrays calling toBytes method on each struct array element @@ -4299,7 +4334,7 @@ metagen_matlab_union(MetaprogramContext *m, MetaContext *ctx, MetaStruct *u, str "%.*s %.*s\n" "MATLAB unions do not currently support array of structs\n", (i32)ctx->filename.length, ctx->filename.data, u->location.line, u->location.column, - (i32)name.length, name.data, (i32)ref->name.length, ref->name.data); + (i32)name.length, name.data, (i32)ref->info.name.length, ref->info.name.data); } } else { member_size = meta_kind_byte_sizes[type_id]; @@ -4320,7 +4355,7 @@ metagen_matlab_union(MetaprogramContext *m, MetaContext *ctx, MetaStruct *u, str // - do a sub loop for struct arrays calling toBytes method on each struct array element // lookup subtype, if union replace with byte array, else reference sub type MetaStruct *ref = ctx->struct_infos + ctx->entities.data[type_id].table.struct_info_id; - if ((ref->flags & MetaStructFlag_Union) == 0) { + if ((ref->info.flags & MetaStructFlag_Union) == 0) { stream_append_str8(&sb, str8(".toBytes()")); } } else { @@ -4332,7 +4367,7 @@ metagen_matlab_union(MetaprogramContext *m, MetaContext *ctx, MetaStruct *u, str columns[2][member] = str8("'uint8');"); } - metagen_push_table(m, m->scratch, str8("bytes("), str8(""), columns, s->member_count, 3); + metagen_push_table(m, m->scratch, str8("bytes("), str8(""), columns, s->info.member_count, 3); } } } @@ -4443,7 +4478,7 @@ metagen_emit_matlab_code(MetaContext *ctx, Arena arena) Arena scratch; DeferLoop(scratch = m->scratch, m->scratch = scratch) { MetaStruct *s = ctx->struct_infos + re->table.struct_info_id; - str8 name = (rr->reference.scope_name.length > 0) ? rr->reference.scope_name : s->name; + str8 name = (rr->reference.scope_name.length > 0) ? rr->reference.scope_name : s->info.name; str8 outdir = push_str8_from_parts(&m->scratch, str8(""), str8(OUTPUT("matlab") OS_PATH_SEPARATOR), str8("+" MATLAB_NAMESPACE META_NAMESPACE_UPPER), name); os_make_directory((c8 *)outdir.data); @@ -4453,7 +4488,7 @@ metagen_emit_matlab_code(MetaContext *ctx, Arena arena) case MetaEntityKind_Struct:{ MetaStruct *s = ctx->struct_infos + re->table.struct_info_id; - str8 name = (rr->reference.scope_name.length > 0) ? rr->reference.scope_name : s->name; + str8 name = (rr->reference.scope_name.length > 0) ? rr->reference.scope_name : s->info.name; str8 outfile = push_str8_from_parts(&m->scratch, str8(""), str8(OUTPUT("matlab") OS_PATH_SEPARATOR), str8(MATLAB_NAMESPACE META_NAMESPACE_UPPER), name, str8(".m")); meta_begin_scope(m, str8("classdef " MATLAB_NAMESPACE META_NAMESPACE_UPPER), name); @@ -4846,21 +4881,21 @@ metagen_load_context(Arena *arena, char *filename) MetaEntity *e = ctx->entities.data + entity; e->table.struct_info_id = struct_info_index++; - MetaStruct *s = ctx->struct_infos + e->table.struct_info_id; - s->name = ctx->entity_names.data[entity]; - s->members = e->table.entries[meta_struct_name_field[kind_it]]; - s->member_count = e->table.entry_count; - s->location = e->location; - s->byte_size = (u32)-1; - s->entity = (MetaEntityID){entity}; + MetaStruct *s = ctx->struct_infos + e->table.struct_info_id; + s->info.name = ctx->entity_names.data[entity]; + s->info.member_count = e->table.entry_count; + s->info.size = (u32)-1; + s->members = e->table.entries[meta_struct_name_field[kind_it]]; + s->location = e->location; + s->entity = (MetaEntityID){entity}; if (meta_struct_entity_kinds[kind_it] == MetaEntityKind_Union) - s->flags = MetaStructFlag_Union; + s->info.flags = MetaStructFlag_Union; - s->member_flags = push_array(ctx->arena, MetaStructMemberFlags, s->member_count); - s->elements = push_array_no_zero(ctx->arena, i32, s->member_count); - s->type_ids = push_array_no_zero(ctx->arena, i32, s->member_count); - memory_clear(s->type_ids, -1, sizeof(*s->type_ids) * s->member_count); - memory_clear(s->elements, -1, sizeof(*s->elements) * s->member_count); + s->member_flags = push_array(ctx->arena, MetaBuildStructMemberFlags, s->info.member_count); + s->elements = push_array_no_zero(ctx->arena, i32, s->info.member_count); + s->type_ids = push_array_no_zero(ctx->arena, i32, s->info.member_count); + memory_clear(s->type_ids, -1, sizeof(*s->type_ids) * s->info.member_count); + memory_clear(s->elements, -1, sizeof(*s->elements) * s->info.member_count); } } @@ -4872,27 +4907,27 @@ metagen_load_context(Arena *arena, char *filename) MetaStruct *s = ctx->struct_infos + e->table.struct_info_id; str8 *types = e->table.entries[meta_struct_type_field[kind_it]]; - for EachIndex(s->member_count, member) { + for EachIndex(s->info.member_count, member) { s->type_ids[member] = meta_lookup_string_slow(meta_kind_meta_types, MetaKind_Count, types[member]); if (s->type_ids[member] == -1 && meta_struct_allow_references[kind_it]) { - s->member_flags[member] = MetaStructMemberFlag_ReferenceType; + s->member_flags[member] = MetaBuildStructMemberFlag_ReferenceType; i64 id = meta_lookup_string_slow(ctx->entity_names.data, ctx->entity_names.count, types[member]); if (id >= 0) { MetaEntityKind kind = ctx->entities.data[id].kind; if (!meta_entity_kind_struct_reference_target[kind]) { meta_compiler_error(e->location, "struct '%.*s' references entity '%.*s' which is not a valid struct member\n", - (i32)s->name.length, s->name.data, (i32)types[member].length, types[member].data); + (i32)s->info.name.length, s->info.name.data, (i32)types[member].length, types[member].data); } if (ctx->entities.data[id].kind == MetaEntityKind_Union) - s->flags |= MetaStructFlag_ContainsUnion; + s->info.flags |= MetaStructFlag_ContainsUnion; s->type_ids[member] = id; } } if (s->type_ids[member] == -1) { meta_compiler_error(e->location, "struct '%.*s' references undefined type '%.*s'\n", - (i32)s->name.length, s->name.data, (i32)types[member].length, types[member].data); + (i32)s->info.name.length, s->info.name.data, (i32)types[member].length, types[member].data); } } } @@ -4907,7 +4942,7 @@ metagen_load_context(Arena *arena, char *filename) i32 field = meta_struct_element_field[kind_it]; str8 *elements = field >= 0 ? e->table.entries[field] : 0; - for EachIndex(s->member_count, member) { + for EachIndex(s->info.member_count, member) { if (elements) { NumberConversion integer = integer_from_str8(elements[member]); if (integer.result == NumberConversionResult_Success) { @@ -4915,10 +4950,10 @@ metagen_load_context(Arena *arena, char *filename) } else { str8 ref_name = elements[member]; if (ref_name.data[0] == '#') { - s->member_flags[member] |= MetaStructMemberFlag_EnumerationCount; + s->member_flags[member] |= MetaBuildStructMemberFlag_EnumerationCount; str8_chop(&ref_name, 1); } else { - s->member_flags[member] |= MetaStructMemberFlag_ReferenceElements; + s->member_flags[member] |= MetaBuildStructMemberFlag_ReferenceElements; } i64 id = meta_lookup_string_slow(ctx->entity_names.data, ctx->entity_names.count, ref_name); @@ -4930,7 +4965,7 @@ metagen_load_context(Arena *arena, char *filename) // TODO(rnp): point at correct member meta_compiler_error(e->location, "struct '%.*s': element count for field '%.*s'" "references '%.*s' which is not an integer constant\n", - (i32)s->name.length, s->name.data, + (i32)s->info.name.length, s->info.name.data, (i32)s->members[member].length, s->members[member].data, (i32)elements[member].length, elements[member].data); } @@ -4943,7 +4978,7 @@ metagen_load_context(Arena *arena, char *filename) if (s->elements[member] == -1) { meta_compiler_error(e->location, "struct '%.*s': element count for field '%.*s' could not be determined\n", - (i32)s->name.length, s->name.data, + (i32)s->info.name.length, s->info.name.data, (i32)s->members[member].length, s->members[member].data); } } @@ -4957,8 +4992,8 @@ metagen_load_context(Arena *arena, char *filename) for EachIndex(ctx->struct_infos_count, structure) { MetaStruct *s = ctx->struct_infos + structure; u32 size = 0; - b32 is_union = (s->flags & MetaStructFlag_Union) != 0; - for EachIndex(s->member_count, member) { + b32 is_union = (s->info.flags & MetaStructFlag_Union) != 0; + for EachIndex(s->info.member_count, member) { b32 type_reference = (s->member_flags[member] & MetaStructMemberFlag_ReferenceType) != 0; u32 elements = meta_struct_member_elements(ctx, s, member); @@ -4971,8 +5006,8 @@ metagen_load_context(Arena *arena, char *filename) else member_size = sizeof(u64); } else { MetaStruct *sub_struct = ctx->struct_infos + ref->table.struct_info_id; - if (sub_struct->byte_size != (u32)-1) { - member_size = sub_struct->byte_size * elements; + if (sub_struct->info.size != (u32)-1) { + member_size = sub_struct->info.size * elements; } else { size = (u32)-1; break; @@ -4984,20 +5019,20 @@ metagen_load_context(Arena *arena, char *filename) size = is_union ? Max(size, member_size) : size + member_size; } if (size != (u32)-1) - s->byte_size = size; + s->info.size = size; } all_done = 1; for EachIndex(ctx->struct_infos_count, structure) - all_done &= ctx->struct_infos[structure].byte_size != (u32)-1; + all_done &= ctx->struct_infos[structure].info.size != (u32)-1; } if (!all_done) { for EachIndex(ctx->struct_infos_count, structure) { MetaStruct *s = ctx->struct_infos + structure; - if (s->byte_size == (u32)-1) { + if (s->info.size == (u32)-1) { meta_compiler_error(s->location, "storage size for struct '%.*s' could not be determined\n", - (i32)s->name.length, s->name.data); + (i32)s->info.name.length, s->info.name.data); } } } diff --git a/generated/beamformer.c b/generated/beamformer.c @@ -563,6 +563,153 @@ read_only global str8 beamformer_shader_resource_kind_strings[] = { str8_comp("Buffer"), }; +typedef enum { + BeamformerStructKind_DecodeBakeParameters = 0, + BeamformerStructKind_FilterBakeParameters = 1, + BeamformerStructKind_DASBakeParameters = 2, + BeamformerStructKind_ReshapeBakeParameters = 3, + BeamformerStructKind_Count, +} BeamformerStructKind; + +read_only global MetaStructMember *meta_struct_members_by_id[] = { + (MetaStructMember []){ + {14, 0, 1, 0}, + {18, 4, 1, 0}, + {18, 8, 1, 0}, + {18, 12, 1, 0}, + {18, 16, 1, 0}, + {18, 20, 1, 0}, + {18, 24, 1, 0}, + {18, 28, 1, 0}, + {14, 32, 1, 0}, + {18, 36, 1, 0}, + {18, 40, 1, 0}, + {18, 44, 1, 0}, + }, + (MetaStructMember []){ + {18, 0, 1, 0}, + {18, 4, 1, 0}, + {18, 8, 1, 0}, + {18, 12, 1, 0}, + {18, 16, 1, 0}, + {18, 20, 1, 0}, + {18, 24, 1, 0}, + {18, 28, 1, 0}, + {18, 32, 1, 0}, + {18, 36, 1, 0}, + {18, 40, 1, 0}, + {18, 44, 1, 0}, + {8, 48, 1, 0}, + {8, 52, 1, 0}, + }, + (MetaStructMember []){ + {18, 0, 1, 0}, + {18, 4, 1, 0}, + {18, 8, 1, 0}, + {18, 12, 1, 0}, + {18, 16, 1, 0}, + {18, 20, 1, 0}, + {18, 24, 1, 0}, + {18, 28, 1, 0}, + {18, 32, 1, 0}, + {18, 36, 1, 0}, + {18, 40, 1, 0}, + {8, 44, 1, 0}, + {8, 48, 1, 0}, + {8, 52, 1, 0}, + {8, 56, 1, 0}, + {8, 60, 1, 0}, + {8, 64, 1, 0}, + {8, 68, 1, 0}, + }, + (MetaStructMember []){ + {18, 0, 1, 0}, + {18, 4, 1, 0}, + {18, 8, 1, 0}, + {18, 12, 1, 0}, + {18, 16, 1, 0}, + {18, 20, 1, 0}, + {18, 24, 1, 0}, + {18, 28, 1, 0}, + {18, 32, 1, 0}, + {14, 36, 1, 0}, + {14, 40, 1, 0}, + }, +}; + +read_only global str8 *meta_struct_member_names_by_id[] = { + (str8 []){ + str8_comp("use_shared_memory"), + str8_comp("decode_mode"), + str8_comp("output_channel_stride"), + str8_comp("output_sample_stride"), + str8_comp("output_transmit_stride"), + str8_comp("to_process"), + str8_comp("transmit_count"), + str8_comp("chunk_channel_count"), + str8_comp("cooperative_matrix"), + str8_comp("cooperative_matrix_m"), + str8_comp("cooperative_matrix_n"), + str8_comp("cooperative_matrix_k"), + }, + (str8 []){ + str8_comp("demodulate"), + str8_comp("complex_filter"), + str8_comp("decimation_rate"), + str8_comp("filter_length"), + str8_comp("input_channel_stride"), + str8_comp("input_sample_stride"), + str8_comp("input_transmit_stride"), + str8_comp("output_channel_stride"), + str8_comp("output_sample_stride"), + str8_comp("output_transmit_stride"), + str8_comp("sample_count"), + str8_comp("batch_sample_count"), + str8_comp("demodulation_frequency"), + str8_comp("sampling_frequency"), + }, + (str8 []){ + str8_comp("coherency_weighting"), + str8_comp("single_focus"), + str8_comp("single_orientation"), + str8_comp("sparse"), + str8_comp("acquisition_count"), + str8_comp("acquisition_kind"), + str8_comp("channel_count"), + str8_comp("chunk_channel_count"), + str8_comp("interpolation_mode"), + str8_comp("sample_count"), + str8_comp("transmit_receive_orientation"), + str8_comp("demodulation_frequency"), + str8_comp("f_number"), + str8_comp("focus_depth"), + str8_comp("sampling_frequency"), + str8_comp("speed_of_sound"), + str8_comp("time_offset"), + str8_comp("transmit_angle"), + }, + (str8 []){ + str8_comp("size_x"), + str8_comp("size_y"), + str8_comp("size_z"), + str8_comp("input_stride_x"), + str8_comp("input_stride_y"), + str8_comp("input_stride_z"), + str8_comp("output_stride_x"), + str8_comp("output_stride_y"), + str8_comp("output_stride_z"), + str8_comp("interleave"), + str8_comp("deinterleave"), + }, +}; + +read_only global MetaStructInfo meta_struct_info_by_id[] = { + {str8_comp("DecodeBakeParameters"), 12, 48, 0}, + {str8_comp("FilterBakeParameters"), 14, 56, 0}, + {str8_comp("DASBakeParameters"), 18, 72, 0}, + {str8_comp("ReshapeBakeParameters"), 11, 44, 0}, +}; + read_only global str8 beamformer_shader_names[] = { str8_comp("Decode"), str8_comp("Filter"), @@ -861,26 +1008,15 @@ read_only global str8 *beamformer_shader_bake_parameter_names[] = { 0, }; -read_only global u32 beamformer_shader_bake_parameter_float_bits[] = { - 0x00000000UL, - 0x00003000UL, - 0x0003f800UL, - 0x00000000UL, - 0x00000000UL, - 0x00000000UL, - 0x00000000UL, - 0x00000000UL, -}; - -read_only global u8 beamformer_shader_bake_parameter_counts[] = { - 12, - 14, - 18, - 0, - 0, - 0, - 11, +read_only global i32 beamformer_base_shader_to_bake_struct_id[] = { 0, + 1, + 2, + -1, + -1, + -1, + 3, + -1, }; read_only global u8 beamformer_shader_push_constant_sizes[] = { diff --git a/lib/ogl_beamformer_lib.c b/lib/ogl_beamformer_lib.c @@ -6,6 +6,7 @@ #include "../beamformer.h" #include "../util.h" +#include "../meta.h" #include "../generated/beamformer.c" #include "ogl_beamformer_lib_base.h" diff --git a/meta.h b/meta.h @@ -0,0 +1,54 @@ +/* See LICENSE for license details. */ +#define META_KIND_LIST \ + X(M4, m4, f32mat4, float, single, 64, 16) \ + X(V4, v4, f32vec4, float, single, 16, 4) \ + X(SV4, iv4, i32vec4, int32_t, int32, 16, 4) \ + X(UV4, uv4, u32vec4, uint32_t, uint32, 16, 4) \ + X(UV2, uv2, u32vec2, uint32_t, uint32, 8, 2) \ + X(V3, v3, f32vec3, float, single, 12, 3) \ + X(V2, v2, f32vec2, float, single, 8, 2) \ + X(F64, f64, float64_t, double, double, 8, 1) \ + X(F32, f32, float32_t, float, single, 4, 1) \ + X(F16, f16, float16_t, _Float16, half, 2, 1) \ + X(S32, i32, int32_t, int32_t, int32, 4, 1) \ + X(S16, i16, int16_t, int16_t, int16, 2, 1) \ + X(S8, i8, int8_t, int8_t, int8, 1, 1) \ + X(B64, b64, uint64_t, uint64_t, uint64, 8, 1) \ + X(B32, b32, bool, uint32_t, uint32, 4, 1) \ + X(B16, b16, uint16_t, uint16_t, uint16, 2, 1) \ + X(B8, b8, uint8_t, uint8_t, uint8, 1, 1) \ + X(U64, u64, uint64_t, uint64_t, uint64, 8, 1) \ + X(U32, u32, uint32_t, uint32_t, uint32, 4, 1) \ + X(U16, u16, uint16_t, uint16_t, uint16, 2, 1) \ + X(U8, u8, uint8_t, uint8_t, uint8, 1, 1) \ + X(STR, str8, error, error, error, 16, 1) \ + +typedef enum { + #define X(k, ...) MetaKind_## k, + META_KIND_LIST + #undef X + MetaKind_Count, +} MetaKind; + +typedef enum { + MetaStructMemberFlag_ReferenceType = 1 << 0, +} MetaStructMemberFlags; + +typedef enum { + MetaStructFlag_Union = 1 << 0, + MetaStructFlag_ContainsUnion = 1 << 1, +} MetaStructFlags; + +typedef struct { + u32 type_id; + u32 offset; + u32 elements; + u32 flags; +} MetaStructMember; + +typedef struct { + str8 name; + u32 member_count; + u32 size; + MetaStructFlags flags; +} MetaStructInfo;