Commit: 07cbb9cf1e7d8ec3cd21e094e03c790c53bebd58
Parent: ffe7d0f89e0b7c0ed51eef32b3f84dd735625aac
Author: Randy Palamar
Date: Mon, 4 May 2026 14:55:27 -0600
meta: import entity packing/referencing code from another project
There are still some things which could be better integrated with
this project but this is a much better place for getting contants,
structs, and enumerations into shaders. This is already being used
to drop a few extra pointer push constants for DAS.
Now if only GLSL allowed struct splatting like the msvc extension.
Diffstat:
13 files changed, 1539 insertions(+), 1138 deletions(-)
diff --git a/beamformer.meta b/beamformer.meta
@@ -1,8 +1,31 @@
-@Enumeration(DecodeMode [None Hadamard])
-@Enumeration(RCAOrientation [None Rows Columns])
-@Enumeration(SamplingMode [2X 4X])
+@Constant(4) FilterSlots
+@Constant(16) MaxBacklogFrames
+@Constant(256) MaxChannelCount
+@Constant(256) MaxEmmissionsCount
+@Constant(16) MaxComputeShaderStages
+@Constant(16) MaxParameterBlocks
+@Constant(3) MaxRawDataFramesInFlight
+
+@Enumeration DecodeMode
+{
+ None
+ Hadamard
+}
+
+@Enumeration RCAOrientation
+{
+ None
+ Rows
+ Columns
+}
-@Table([name size elements complex]) DataKind
+@Enumeration SamplingMode
+{
+ 2X
+ 4X
+}
+
+@Table([name size elements complex]) DataKindTable
{
[Int16 2 1 0]
[Int16Complex 2 2 1]
@@ -11,26 +34,39 @@
[Float16 2 1 0]
[Float16Complex 2 2 1]
}
+@Expand(DataKindTable) @Enumeration(`$(name)`) DataKind
-@Table([name samples]) ContrastMode
+@Table([name samples]) ContrastModeTable
{
[None 1]
[A1S2 3]
}
+@Expand(ContrastModeTable) @Enumeration(`$(name)`) ContrastMode
-@Enumeration(EmissionKind [Sine Chirp])
+@Enumeration EmissionKind
+{
+ Sine
+ Chirp
+}
-@Table([type name]) SineParameters
+@Enumeration InterpolationMode
{
- [F32 cycles ]
- [F32 frequency]
+ Nearest
+ Linear
+ Cubic
}
-@Table([type name]) ChirpParameters
+@Struct SineParameters
{
- [F32 duration ]
- [F32 min_frequency]
- [F32 max_frequency]
+ [cycles F32]
+ [frequency F32]
+}
+
+@Struct ChirpParameters
+{
+ [duration F32]
+ [min_frequency F32]
+ [max_frequency F32]
}
@MUnion(EmissionKind [
@@ -38,24 +74,25 @@
ChirpParameters
]) Emission
-@Table([name name_lower]) FilterKind
+@Table([name name_lower]) FilterKindTable
{
[Kaiser kaiser]
[MatchedChirp matched_chirp]
}
+@Expand(FilterKindTable) @Enumeration(`$(name)`) FilterKind
-@Table([type name]) KaiserFilterParameters
+@Struct KaiserFilterParameters
{
- [F32 cutoff_frequency]
- [F32 beta]
- [U32 length]
+ [cutoff_frequency F32]
+ [beta F32]
+ [length U32]
}
-@Table([type name]) ChirpFilterParameters
+@Struct ChirpFilterParameters
{
- [F32 duration]
- [F32 min_frequency]
- [F32 max_frequency]
+ [duration F32]
+ [min_frequency F32]
+ [max_frequency F32]
}
@MUnion(FilterKind [
@@ -63,7 +100,7 @@
ChirpFilterParameters
]) Filter
-@Table([name pretty_name fixed_transmits]) AcquisitionKind
+@Table([name pretty_name fixed_transmits]) AcquisitionKindTable
{
[FORCES FORCES 1]
[UFORCES UFORCES 0]
@@ -78,15 +115,9 @@
[Flash Flash 0]
[HERO_PA HERO-PA 0]
}
+@Expand(AcquisitionKindTable) @Enumeration(`$(name)`) AcquisitionKind
-@Table([name]) InterpolationMode
-{
- [Nearest]
- [Linear]
- [Cubic]
-}
-
-@Table([name type]) ParametersHead
+@Struct ParametersHead
{
[das_voxel_transform M4]
[xdc_transform M4]
@@ -105,7 +136,7 @@
[sampling_mode U8]
}
-@Table([name type]) ParametersUI
+@Struct ParametersUI
{
[output_points SV4]
[sampling_frequency F32]
@@ -124,8 +155,8 @@
[emission_parameters BeamformerEmissionParameters uint8 12]
}
-// TODO(rnp): definable constants in meta code (or at least references to enum values)
-@Table([name type elements]) ParametersSimple
+// TODO(rnp): allow emit statements to reference Constants
+@Struct ParametersSimple
{
[channel_mapping S16 256]
[sparse_elements S16 256]
@@ -138,11 +169,6 @@
[data_kind S32 1]
}
-@Expand(AcquisitionKind) @Enumeration(AcquisitionKind `$(name)`)
-@Expand(ContrastMode) @Enumeration(ContrastMode `$(name)`)
-@Expand(DataKind) @Enumeration(DataKind `$(name)`)
-@Expand(FilterKind) @Enumeration(FilterKind `$(name)`)
-@Expand(InterpolationMode) @Enumeration(InterpolationMode `$(name)`)
@Emit
{
@@ -162,10 +188,6 @@
`} BeamformerParameters;`
``
`typedef struct {`
- @Expand(ParametersHead) ` $(%type)$(|)$(name);`
- `} BeamformerParametersHead;`
- ``
- `typedef struct {`
@Expand(ParametersUI) ` $(%type)$(|)$(name);`
`} BeamformerUIParameters;`
``
@@ -195,35 +217,35 @@
`} BeamformerFilterParameters;`
``
`read_only global u8 beamformer_data_kind_element_size[] = {`
- @Expand(DataKind) ` $(size),`
+ @Expand(DataKindTable) ` $(size),`
`};`
``
`read_only global u8 beamformer_data_kind_element_count[] = {`
- @Expand(DataKind) ` $(elements),`
+ @Expand(DataKindTable) ` $(elements),`
`};`
``
`read_only global u8 beamformer_data_kind_byte_size[] = {`
- @Expand(DataKind) ` $(size) * $(elements),`
+ @Expand(DataKindTable) ` $(size) * $(elements),`
`};`
``
`read_only global b8 beamformer_data_kind_complex[] = {`
- @Expand(DataKind) ` $(complex),`
+ @Expand(DataKindTable) ` $(complex),`
`};`
``
`read_only global u8 beamformer_contrast_mode_samples[] = {`
- @Expand(ContrastMode) ` $(samples),`
+ @Expand(ContrastModeTable) ` $(samples),`
`};`
``
`read_only global u8 beamformer_acquisition_kind_has_fixed_transmits[] = {`
- @Expand(AcquisitionKind) ` $(fixed_transmits),`
+ @Expand(AcquisitionKindTable) ` $(fixed_transmits),`
`};`
``
`read_only global s8 beamformer_acquisition_kind_strings[] = {`
- @Expand(AcquisitionKind) ` s8_comp("$(pretty_name)"),`
+ @Expand(AcquisitionKindTable) ` s8_comp("$(pretty_name)"),`
`};`
``
`read_only global s8 beamformer_filter_kind_strings[] = {`
- @Expand(FilterKind) ` s8_comp("$(name)"),`
+ @Expand(FilterKindTable) ` s8_comp("$(name)"),`
`};`
``
`read_only global s8 beamformer_interpolation_mode_strings[] = {`
@@ -238,78 +260,89 @@
@Shader(decode.glsl) Decode
{
- @Enumeration(DataKind)
- @Enumeration(DecodeMode)
- @Flags([DilateOutput UseSharedMemory])
+ @Enumeration DataKind
+ @Enumeration DecodeMode
@Bake
{
- @BakeInt(DecodeMode decode_mode )
- @BakeInt(InputChannelStride input_channel_stride )
- @BakeInt(InputSampleStride input_sample_stride )
- @BakeInt(InputTransmitStride input_transmit_stride )
- @BakeInt(OutputChannelStride output_channel_stride )
- @BakeInt(OutputSampleStride output_sample_stride )
- @BakeInt(OutputTransmitStride output_transmit_stride)
- @BakeInt(ToProcess to_process )
- @BakeInt(TransmitCount transmit_count )
+ [DataKind data_kind U32]
+ [DilateOutput dilate_output U32]
+ [UseSharedMemory use_shared_memory U32]
+ [DecodeMode decode_mode U32]
+ [InputChannelStride input_channel_stride U32]
+ [InputSampleStride input_sample_stride U32]
+ [InputTransmitStride input_transmit_stride U32]
+ [OutputChannelStride output_channel_stride U32]
+ [OutputSampleStride output_sample_stride U32]
+ [OutputTransmitStride output_transmit_stride U32]
+ [ToProcess to_process U32]
+ [TransmitCount transmit_count U32]
}
}
@Shader(filter.glsl) Filter
{
- @Enumeration(DataKind)
- @Flags([ComplexFilter OutputFloats])
+ @Enumeration DataKind
@ShaderAlias Demodulate
@Bake
{
- @BakeInt(DecimationRate decimation_rate )
- @BakeInt(FilterLength filter_length )
- @BakeInt(InputChannelStride input_channel_stride )
- @BakeInt(InputSampleStride input_sample_stride )
- @BakeInt(InputTransmitStride input_transmit_stride )
- @BakeInt(OutputChannelStride output_channel_stride )
- @BakeInt(OutputSampleStride output_sample_stride )
- @BakeInt(OutputTransmitStride output_transmit_stride)
- @BakeInt(SampleCount sample_count )
- @BakeFloat(DemodulationFrequency demodulation_frequency)
- @BakeFloat(SamplingFrequency sampling_frequency )
+ [DataKind data_kind U32]
+ [Demodulate demodulate U32]
+ [ComplexFilter complex_filter U32]
+ [OutputFloats output_floats U32]
+ [DecimationRate decimation_rate U32]
+ [FilterLength filter_length U32]
+ [InputChannelStride input_channel_stride U32]
+ [InputSampleStride input_sample_stride U32]
+ [InputTransmitStride input_transmit_stride U32]
+ [OutputChannelStride output_channel_stride U32]
+ [OutputSampleStride output_sample_stride U32]
+ [OutputTransmitStride output_transmit_stride U32]
+ [SampleCount sample_count U32]
+
+ [DemodulationFrequency demodulation_frequency F32]
+ [SamplingFrequency sampling_frequency F32]
}
}
@Shader(das.glsl) DAS
{
- @Enumeration(AcquisitionKind)
- @Enumeration(DataKind)
- @Enumeration(InterpolationMode)
- @Enumeration(RCAOrientation)
- @Flags([Fast Sparse CoherencyWeighting SingleFocus SingleOrientation])
+ @Enumeration AcquisitionKind
+ @Enumeration DataKind
+ @Enumeration InterpolationMode
+ @Enumeration RCAOrientation
@Bake
{
- @BakeInt(AcquisitionCount acquisition_count )
- @BakeInt(AcquisitionKind acquisition_kind )
- @BakeInt(ChannelCount channel_count )
- @BakeInt(InterpolationMode interpolation_mode )
- @BakeInt(SampleCount sample_count )
- @BakeInt(TransmitReceiveOrientation transmit_receive_orientation)
-
- @BakeFloat(DemodulationFrequency demodulation_frequency)
- @BakeFloat(FNumber f_number )
- @BakeFloat(FocusDepth focus_depth )
- @BakeFloat(SamplingFrequency sampling_frequency )
- @BakeFloat(SpeedOfSound speed_of_sound )
- @BakeFloat(TimeOffset time_offset )
- @BakeFloat(TransmitAngle transmit_angle )
+ [DataKind data_kind U32]
+ [CoherencyWeighting coherency_weighting U32]
+ [SingleFocus single_focus U32]
+ [SingleOrientation single_orientation U32]
+ [Fast fast U32]
+ [Sparse sparse U32]
+ [AcquisitionCount acquisition_count U32]
+ [AcquisitionKind acquisition_kind U32]
+ [ChannelCount channel_count U32]
+ [InterpolationMode interpolation_mode U32]
+ [SampleCount sample_count U32]
+ [TransmitReceiveOrientation transmit_receive_orientation U32]
+
+ [DemodulationFrequency demodulation_frequency F32]
+ [FNumber f_number F32]
+ [FocusDepth focus_depth F32]
+ [SamplingFrequency sampling_frequency F32]
+ [SpeedOfSound speed_of_sound F32]
+ [TimeOffset time_offset F32]
+ [TransmitAngle transmit_angle F32]
}
@PushConstants
{
- [mat4 M4 xdc_transform ]
- [mat4 M4 voxel_transform ]
- [vec2 V2 xdc_element_pitch]
+ [xdc_transform M4]
+ [voxel_transform M4]
+ [xdc_element_pitch V2]
}
}
@@ -412,7 +445,7 @@
` properties`
@Expand(ParametersHead) ` $(name)(1,$(#type)) $(%type)`
@Expand(ParametersUI) ` $(name)(1,$(#type)) $(%type)`
- @Expand(ParametersExtra) ` $(name)(1,$(m_size))$(|)$(m_type)`
+ @Expand(ParametersExtra) ` $(name)(1,$(m_size)) $(m_type)`
@Expand(ParametersSimple) ` $(name)(1,$(elements)) $(%type)`
` end`
`end`
diff --git a/beamformer_core.c b/beamformer_core.c
@@ -174,12 +174,12 @@ beamformer_filter_update(BeamformerFilter *f, BeamformerFilterParameters fp, u32
function ComputeFrameIterator
compute_frame_iterator(BeamformerCtx *ctx, u32 start_index, u32 needed_frames)
{
- start_index = start_index % ARRAY_COUNT(ctx->beamform_frames);
+ start_index = start_index % countof(ctx->beamform_frames);
ComputeFrameIterator result;
result.frames = ctx->beamform_frames;
result.offset = start_index;
- result.capacity = ARRAY_COUNT(ctx->beamform_frames);
+ result.capacity = countof(ctx->beamform_frames);
result.cursor = 0;
result.needed_frames = needed_frames;
return result;
@@ -394,12 +394,13 @@ plan_compute_pipeline(BeamformerComputePlan *cp, BeamformerParameterBlock *pb)
/* TODO(rnp): rework decode first and demodulate after */
b32 first = slot == 0;
- sd->bake.data_kind = data_kind;
+ BeamformerDecodeBakeParameters *db = &sd->bake.Decode;
+ db->data_kind = data_kind;
if (!first) {
if (data_kind == BeamformerDataKind_Int16) {
- sd->bake.data_kind = BeamformerDataKind_Int16Complex;
+ db->data_kind = BeamformerDataKind_Int16Complex;
} else {
- sd->bake.data_kind = BeamformerDataKind_Float32Complex;
+ db->data_kind = BeamformerDataKind_Float32Complex;
}
}
@@ -407,7 +408,6 @@ plan_compute_pipeline(BeamformerComputePlan *cp, BeamformerParameterBlock *pb)
assert(first || ((*last_shader == BeamformerShaderKind_Demodulate ||
*last_shader == BeamformerShaderKind_Filter)));
- BeamformerShaderDecodeBakeParameters *db = &sd->bake.Decode;
db->decode_mode = pb->parameters.decode_mode;
db->transmit_count = pb->parameters.acquisition_count;
@@ -424,7 +424,7 @@ plan_compute_pipeline(BeamformerComputePlan *cp, BeamformerParameterBlock *pb)
db->output_transmit_stride *= decimation_rate;
}
- if (run_cuda_hilbert) sd->bake.flags |= BeamformerShaderDecodeFlags_DilateOutput;
+ db->dilate_output = run_cuda_hilbert;
if (db->decode_mode == BeamformerDecodeMode_None) {
sd->layout = (uv3){{subgroup_size, 1, 1}};
@@ -433,8 +433,8 @@ plan_compute_pipeline(BeamformerComputePlan *cp, BeamformerParameterBlock *pb)
sd->dispatch.y = (u32)ceil_f32((f32)pb->parameters.channel_count / (f32)sd->layout.y);
sd->dispatch.z = (u32)ceil_f32((f32)pb->parameters.acquisition_count / (f32)sd->layout.z);
} else if (db->transmit_count > 40) {
- sd->bake.flags |= BeamformerShaderDecodeFlags_UseSharedMemory;
- db->to_process = 2;
+ db->use_shared_memory = 1;
+ db->to_process = 2;
if (db->transmit_count == 48)
db->to_process = db->transmit_count / 16;
@@ -475,13 +475,13 @@ plan_compute_pipeline(BeamformerComputePlan *cp, BeamformerParameterBlock *pb)
time_offset += f->time_delay;
- BeamformerShaderFilterBakeParameters *fb = &sd->bake.Filter;
- fb->filter_length = (u32)f->length;
- if (demod) sd->bake.flags |= BeamformerShaderFilterFlags_Demodulate;
- if (f->parameters.complex) sd->bake.flags |= BeamformerShaderFilterFlags_ComplexFilter;
+ BeamformerFilterBakeParameters *fb = &sd->bake.Filter;
+ fb->filter_length = (u32)f->length;
+ fb->demodulate = demod;
+ fb->complex_filter = f->parameters.complex;
- sd->bake.data_kind = data_kind;
- if (!first) sd->bake.data_kind = BeamformerDataKind_Float32;
+ fb->data_kind = data_kind;
+ if (!first) fb->data_kind = BeamformerDataKind_Float32;
/* NOTE(rnp): when we are demodulating we pretend that the sampler was alternating
* between sampling the I portion and the Q portion of an IQ signal. Therefore there
@@ -508,7 +508,7 @@ plan_compute_pipeline(BeamformerComputePlan *cp, BeamformerParameterBlock *pb)
fb->input_transmit_stride = pb->parameters.sample_count / 2;
if (pb->parameters.decode_mode == BeamformerDecodeMode_None) {
- sd->bake.flags |= BeamformerShaderFilterFlags_OutputFloats;
+ fb->output_floats = 1;
} else {
/* NOTE(rnp): output optimized layout for decoding */
fb->output_channel_stride = das_channel_stride;
@@ -541,12 +541,12 @@ plan_compute_pipeline(BeamformerComputePlan *cp, BeamformerParameterBlock *pb)
commit = 1;
}break;
case BeamformerShaderKind_DAS:{
- sd->bake.data_kind = BeamformerDataKind_Float32;
- if (cp->iq_pipeline)
- sd->bake.data_kind = BeamformerDataKind_Float32Complex;
+ BeamformerDASBakeParameters *db = &sd->bake.DAS;
- BeamformerShaderDASBakeParameters *db = &sd->bake.DAS;
- BeamformerShaderDASPushConstants *du = &cp->das_ubo_data;
+ db->data_kind = BeamformerDataKind_Float32;
+ if (cp->iq_pipeline) db->data_kind = BeamformerDataKind_Float32Complex;
+
+ BeamformerDASPushConstants *du = &cp->das_ubo_data;
du->xdc_element_pitch = pb->parameters.xdc_element_pitch;
db->sampling_frequency = sampling_frequency;
db->demodulation_frequency = pb->parameters.demodulation_frequency;
@@ -573,13 +573,13 @@ plan_compute_pipeline(BeamformerComputePlan *cp, BeamformerParameterBlock *pb)
if (id == BeamformerAcquisitionKind_UFORCES || id == BeamformerAcquisitionKind_FORCES)
du->voxel_transform = m4_mul(du->xdc_transform, du->voxel_transform);
- if (id == BeamformerAcquisitionKind_UFORCES || id == BeamformerAcquisitionKind_UHERCULES)
- sd->bake.flags |= BeamformerShaderDASFlags_Sparse;
+ db->sparse = id == BeamformerAcquisitionKind_UFORCES ||
+ id == BeamformerAcquisitionKind_UHERCULES;
- if (pb->parameters.single_focus) sd->bake.flags |= BeamformerShaderDASFlags_SingleFocus;
- if (pb->parameters.single_orientation) sd->bake.flags |= BeamformerShaderDASFlags_SingleOrientation;
- if (pb->parameters.coherency_weighting) sd->bake.flags |= BeamformerShaderDASFlags_CoherencyWeighting;
- else sd->bake.flags |= BeamformerShaderDASFlags_Fast;
+ db->single_focus = pb->parameters.single_focus;
+ db->single_orientation = pb->parameters.single_orientation;
+ db->coherency_weighting = pb->parameters.coherency_weighting;
+ db->fast = !pb->parameters.coherency_weighting;
sd->layout = (uv3){{1, 1, 1}};
@@ -702,28 +702,6 @@ load_compute_shader(BeamformerCtx *ctx, BeamformerComputePlan *cp, u32 shader_sl
stream_append_s8(&shader_stream, s8(")\n"));
}
- stream_append_s8(&shader_stream, s8("#define DataKind (0x"));
- stream_append_hex_u64(&shader_stream, sd->bake.data_kind);
- stream_append_s8(&shader_stream, s8(")\n\n"));
-
- s8 *flag_names = beamformer_shader_flag_strings[reloadable_index];
- u32 flag_count = beamformer_shader_flag_strings_count[reloadable_index];
- u32 flags = sd->bake.flags;
- for (u32 bit = 0; bit < flag_count; bit++) {
- stream_append_s8s(&shader_stream, s8("#define "), flag_names[bit],
- (flags & (1 << bit))? s8(" 1") : s8(" 0"), s8("\n"));
- }
-
- u32 pc_count = beamformer_shader_push_constant_counts[reloadable_index];
- s8 *pc_names = beamformer_shader_push_constant_names[reloadable_index];
- s8 *pc_types = beamformer_shader_push_constant_glsl_types[reloadable_index];
- if (pc_count) {
- stream_append_s8s(&shader_stream, s8("\n\nlayout(std140, binding = 0) uniform PushConstants {\n"));
- for (u32 it = 0; it < pc_count; it++)
- stream_append_s8s(&shader_stream, s8("\t"), pc_types[it], s8(" "), pc_names[it],s8(";\n"));
- stream_append_s8s(&shader_stream, s8("};"));
- }
-
if (!renderdoc_attached())
stream_append_s8(&shader_stream, s8("\n#line 1\n"));
@@ -906,11 +884,8 @@ do_compute_shader(BeamformerCtx *ctx, BeamformerComputePlan *cp, BeamformerFrame
case BeamformerShaderKind_DAS:{
local_persist u32 das_cycle_t = 0;
- BeamformerShaderBakeParameters *bp = &cp->shader_descriptors[shader_slot].bake;
- b32 fast = (bp->flags & BeamformerShaderDASFlags_Fast) != 0;
- b32 sparse = (bp->flags & BeamformerShaderDASFlags_Sparse) != 0;
-
- if (fast) {
+ BeamformerDASBakeParameters *db = &cp->shader_descriptors[shader_slot].bake.DAS;
+ if (db->fast) {
glClearTexImage(frame->texture, 0, GL_RED, GL_FLOAT, 0);
glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
glBindImageTexture(0, frame->texture, 0, GL_TRUE, 0, GL_READ_WRITE, cp->iq_pipeline ? GL_RG32F : GL_R32F);
@@ -919,7 +894,7 @@ do_compute_shader(BeamformerCtx *ctx, BeamformerComputePlan *cp, BeamformerFrame
}
u32 sparse_texture = cp->textures[BeamformerComputeTextureKind_SparseElements];
- if (!sparse) sparse_texture = 0;
+ if (!db->sparse) sparse_texture = 0;
glBindBufferBase(GL_UNIFORM_BUFFER, 0, cp->ubos[BeamformerComputeUBOKind_DAS]);
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 1, cc->ping_pong_ssbos[input_ssbo_idx], 0, cp->rf_size);
@@ -929,16 +904,16 @@ do_compute_shader(BeamformerCtx *ctx, BeamformerComputePlan *cp, BeamformerFrame
glProgramUniform1ui(program, DAS_CYCLE_T_UNIFORM_LOC, das_cycle_t++);
- if (fast) {
+ if (db->fast) {
i32 loop_end;
- if (bp->DAS.acquisition_kind == BeamformerAcquisitionKind_RCA_VLS ||
- bp->DAS.acquisition_kind == BeamformerAcquisitionKind_RCA_TPW)
+ if (db->acquisition_kind == BeamformerAcquisitionKind_RCA_VLS ||
+ db->acquisition_kind == BeamformerAcquisitionKind_RCA_TPW)
{
/* NOTE(rnp): to avoid repeatedly sampling the whole focal vectors
* texture we loop over transmits for VLS/TPW */
- loop_end = (i32)bp->DAS.acquisition_count;
+ loop_end = (i32)db->acquisition_count;
} else {
- loop_end = (i32)bp->DAS.channel_count;
+ loop_end = (i32)db->channel_count;
}
f32 percent_per_step = 1.0f / (f32)loop_end;
cc->processing_progress = -percent_per_step;
@@ -956,7 +931,7 @@ do_compute_shader(BeamformerCtx *ctx, BeamformerComputePlan *cp, BeamformerFrame
glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT|GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}break;
case BeamformerShaderKind_Sum:{
- u32 aframe_index = ctx->averaged_frame_index % ARRAY_COUNT(ctx->averaged_frames);
+ u32 aframe_index = ctx->averaged_frame_index % countof(ctx->averaged_frames);
BeamformerFrame *aframe = ctx->averaged_frames + aframe_index;
aframe->id = ctx->averaged_frame_index;
atomic_store_u32(&aframe->ready_to_present, 0);
@@ -967,7 +942,7 @@ do_compute_shader(BeamformerCtx *ctx, BeamformerComputePlan *cp, BeamformerFrame
u32 base_index = (u32)(frame - ctx->beamform_frames);
u32 to_average = (u32)cp->average_frames;
u32 frame_count = 0;
- u32 *in_textures = push_array(&arena, u32, BeamformerMaxSavedFrames);
+ u32 *in_textures = push_array(&arena, u32, BeamformerMaxBacklogFrames);
ComputeFrameIterator cfi = compute_frame_iterator(ctx, 1 + base_index - to_average, to_average);
for (BeamformerFrame *it = frame_next(&cfi); it; it = frame_next(&cfi))
in_textures[frame_count++] = it->texture;
diff --git a/beamformer_internal.h b/beamformer_internal.h
@@ -101,7 +101,7 @@ typedef struct {
/* TODO(rnp): need 1 UBO per filter slot */
#define BEAMFORMER_COMPUTE_UBO_LIST \
- X(DAS, BeamformerShaderDASPushConstants, das)
+ X(DAS, BeamformerDASPushConstants, das)
#define X(k, ...) BeamformerComputeUBOKind_##k,
typedef enum {BEAMFORMER_COMPUTE_UBO_LIST BeamformerComputeUBOKind_Count} BeamformerComputeUBOKind;
@@ -188,7 +188,7 @@ typedef struct {
typedef struct {
BeamformerRFBuffer rf_buffer;
- BeamformerComputePlan *compute_plans[BeamformerMaxParameterBlockSlots];
+ BeamformerComputePlan *compute_plans[BeamformerMaxParameterBlocks];
BeamformerComputePlan *compute_plan_freelist;
/* NOTE(rnp): two interstage ssbos are allocated so that they may be used to
@@ -316,7 +316,7 @@ typedef struct {
BeamformerSharedMemory *shared_memory;
i64 shared_memory_size;
- BeamformerFrame beamform_frames[BeamformerMaxSavedFrames];
+ BeamformerFrame beamform_frames[BeamformerMaxBacklogFrames];
BeamformerFrame *latest_frame;
u32 next_render_frame_index;
u32 display_frame_index;
diff --git a/beamformer_parameters.h b/beamformer_parameters.h
@@ -12,7 +12,7 @@
typedef struct {
/* NOTE(rnp): this wants to be iterated on both dimensions. it depends entirely on which
* visualization method you want to use. the coalescing function wants both directions */
- float times[32][BeamformerShaderKind_ComputeCount];
+ float times[32][BeamformerMaxComputeShaderStages];
float rf_time_deltas[32];
} BeamformerComputeStatsTable;
@@ -30,17 +30,6 @@ typedef enum {
BeamformerViewPlaneTag_Count,
} BeamformerViewPlaneTag;
-#define BEAMFORMER_CONSTANTS_LIST \
- X(FilterSlots, 4) \
- X(MaxChannelCount, 256) \
- X(MaxComputeShaderStages, 16) \
- X(MaxParameterBlockSlots, 16) \
- X(MaxRawDataFramesInFlight, 3) \
- X(MaxSavedFrames, 16)
-#define X(k, v, ...) Beamformer##k = v,
-typedef enum {BEAMFORMER_CONSTANTS_LIST} BeamformerConstants;
-#undef X
-
#define BEAMFORMER_LIVE_IMAGING_DIRTY_FLAG_LIST \
X(ImagePlaneOffsets, 0) \
X(TransmitPower, 1) \
diff --git a/beamformer_shared_memory.c b/beamformer_shared_memory.c
@@ -14,8 +14,8 @@ typedef struct {
BeamformerFilterParameters parameters;
u8 filter_slot;
u8 parameter_block;
- static_assert(BeamformerFilterSlots <= 255, "CreateFilterContext only supports 255 filter slots");
- static_assert(BeamformerMaxParameterBlockSlots <= 255, "CreateFilterContext only supports 255 parameter blocks");
+ static_assert(BeamformerFilterSlots <= 255, "CreateFilterContext only supports 255 filter slots");
+ static_assert(BeamformerMaxParameterBlocks <= 255, "CreateFilterContext only supports 255 parameter blocks");
} BeamformerCreateFilterContext;
typedef enum {
@@ -151,7 +151,7 @@ typedef struct {
/* NOTE(rnp): not used for locking on w32 but we can use these to peek at the status of
* the lock without leaving userspace. */
- i32 locks[(u32)BeamformerSharedMemoryLockKind_Count + (u32)BeamformerMaxParameterBlockSlots];
+ i32 locks[(u32)BeamformerSharedMemoryLockKind_Count + (u32)BeamformerMaxParameterBlocks];
/* NOTE(rnp): total number of parameter block regions the client has requested.
* used to calculate offset to scratch space and to track number of allocated
@@ -265,7 +265,7 @@ beamformer_parameter_block_dirty(BeamformerSharedMemory *sm, u32 block)
function BeamformerParameterBlock *
beamformer_parameter_block_lock(BeamformerSharedMemory *sm, u32 block, i32 timeout_ms)
{
- assert(block < BeamformerMaxParameterBlockSlots);
+ assert(block < BeamformerMaxParameterBlocks);
BeamformerParameterBlock *result = 0;
if (beamformer_shared_memory_take_lock(sm, BeamformerSharedMemoryLockKind_Count + block, (u32)timeout_ms))
result = beamformer_parameter_block(sm, block);
@@ -275,7 +275,7 @@ beamformer_parameter_block_lock(BeamformerSharedMemory *sm, u32 block, i32 timeo
function void
beamformer_parameter_block_unlock(BeamformerSharedMemory *sm, u32 block)
{
- assert(block < BeamformerMaxParameterBlockSlots);
+ assert(block < BeamformerMaxParameterBlocks);
beamformer_shared_memory_release_lock(sm, BeamformerSharedMemoryLockKind_Count + block);
}
diff --git a/build.c b/build.c
@@ -15,11 +15,14 @@
#include <setjmp.h>
#include <stdio.h>
-#define BeamformerShaderKind_ComputeCount (1)
+#define BeamformerMaxComputeShaderStages 1
#include "beamformer_parameters.h"
global char *g_argv0;
+#define META_NAMESPACE_UPPER "Beamformer"
+#define META_NAMESPACE_LOWER "beamformer"
+
#define OUTDIR "out"
#define OUTPUT(s) OUTDIR OS_PATH_SEPARATOR s
@@ -871,15 +874,15 @@ build_tests(Arena arena)
}
typedef struct {
- s8 *data;
- iz count;
- iz capacity;
+ s8 *data;
+ da_count count;
+ da_count capacity;
} s8_list;
function s8
s8_chop(s8 *in, iz count)
{
- count = CLAMP(count, 0, in->len);
+ count = Clamp(count, 0, in->len);
s8 result = {.data = in->data, .len = count};
in->data += count;
in->len -= count;
@@ -939,6 +942,7 @@ meta_push_(MetaprogramContext *m, s8 *items, iz count)
#define meta_push_line(m, ...) do { meta_indent(m); meta_push(m, ##__VA_ARGS__, s8("\n")); } while(0)
#define meta_begin_scope(m, ...) do { meta_push_line(m, __VA_ARGS__); (m)->indentation_level++; } while(0)
#define meta_end_scope(m, ...) do { (m)->indentation_level--; meta_push_line(m, __VA_ARGS__); } while(0)
+#define meta_push_f64(m, n) stream_append_f64(&(m)->stream, (n), 1000000)
#define meta_push_u64(m, n) stream_append_u64(&(m)->stream, (n))
#define meta_push_i64(m, n) stream_append_i64(&(m)->stream, (n))
#define meta_push_u64_hex(m, n) stream_append_hex_u64(&(m)->stream, (n))
@@ -974,21 +978,20 @@ meta_end_and_write_matlab(MetaprogramContext *m, char *path)
X(Invalid) \
X(Array) \
X(Bake) \
- X(BakeInt) \
- X(BakeFloat) \
X(BeginScope) \
- X(Emit) \
+ X(Constant) \
X(Embed) \
+ X(Emit) \
X(EndScope) \
X(Enumeration) \
X(Expand) \
- X(Flags) \
X(MUnion) \
X(PushConstants) \
- X(String) \
X(Shader) \
X(ShaderAlias) \
X(ShaderGroup) \
+ X(String) \
+ X(Struct) \
X(Table) \
typedef enum {
@@ -1015,19 +1018,25 @@ typedef enum {
} MetaEmitLang;
#define META_KIND_LIST \
- X(M4, m4, float, single, 64, 16) \
- X(SV4, iv4, int32_t, int32, 16, 4) \
- X(UV4, uv4, uint32_t, uint32, 16, 4) \
- X(UV2, uv2, uint32_t, uint32, 8, 2) \
- X(V3, v3, float, single, 12, 3) \
- X(V2, v2, float, single, 8, 2) \
- X(F32, f32, float, single, 4, 1) \
- X(S32, i32, int32_t, int32, 4, 1) \
- X(S16, i16, int16_t, int16, 2, 1) \
- X(S8, i8, int8_t, int8, 1, 1) \
- X(U32, u32, uint32_t, uint32, 4, 1) \
- X(U16, u16, uint16_t, uint16, 2, 1) \
- X(U8, u8, uint8_t, uint8, 1, 1)
+ X(M4, m4, mat4, float, single, 64, 16) \
+ X(V4, v4, vec4, float, single, 16, 4) \
+ X(SV4, iv4, ivec4, int32_t, int32, 16, 4) \
+ X(UV4, uv4, uvec4, uint32_t, uint32, 16, 4) \
+ X(UV2, uv2, uvec2, uint32_t, uint32, 8, 2) \
+ X(V3, v3, vec3, float, single, 12, 3) \
+ X(V2, v2, vec2, float, single, 8, 2) \
+ X(F32, f32, float, 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) \
typedef enum {
#define X(k, ...) MetaKind_## k,
@@ -1037,13 +1046,13 @@ typedef enum {
} MetaKind;
read_only global u8 meta_kind_byte_sizes[] = {
- #define X(_k, _c, _b, _m, bytes, ...) bytes,
+ #define X(_k, _c, _g, _b, _m, bytes, ...) bytes,
META_KIND_LIST
#undef X
};
read_only global u8 meta_kind_elements[] = {
- #define X(_k, _c, _b, _m, _by, elements, ...) elements,
+ #define X(_k, _c, _g, _b, _m, _by, elements, ...) elements,
META_KIND_LIST
#undef X
};
@@ -1055,13 +1064,19 @@ read_only global s8 meta_kind_meta_types[] = {
};
read_only global s8 meta_kind_matlab_types[] = {
- #define X(_k, _c, _b, m, ...) s8_comp(#m),
+ #define X(_k, _c, _g, _b, m, ...) s8_comp(#m),
META_KIND_LIST
#undef X
};
read_only global s8 meta_kind_base_c_types[] = {
- #define X(_k, _c, base, ...) s8_comp(#base),
+ #define X(_k, _c, _g, base, ...) s8_comp(#base),
+ META_KIND_LIST
+ #undef X
+};
+
+read_only global s8 meta_kind_glsl_types[] = {
+ #define X(_k, _c, glsl, ...) s8_comp(#glsl),
META_KIND_LIST
#undef X
};
@@ -1106,8 +1121,8 @@ typedef struct {
typedef struct {
MetaEntry *data;
- iz count;
- iz capacity;
+ da_count count;
+ da_count capacity;
s8 raw;
} MetaEntryStack;
@@ -1153,6 +1168,9 @@ global jmp_buf compiler_jmp_buf;
#define meta_parser_restore(v) swap((v)->p, (v)->save_point)
#define meta_parser_commit(v) meta_parser_restore(v)
+#define meta_compiler_message(format, ...) \
+ fprintf(stderr, format, ##__VA_ARGS__)
+
#define meta_compiler_error_message(loc, format, ...) \
fprintf(stderr, "%s:%u:%u: error: "format, compiler_file, \
loc.line + 1, loc.column + 1, ##__VA_ARGS__)
@@ -1263,7 +1281,7 @@ meta_parser_trim(MetaParser *p)
}break;
case '\n':{ p->p.location.line++; p->p.location.column = 0; comment = 0; }break;
case '/':{
- comment = ((s + 1) != end && s[1] == '/');
+ comment |= ((s + 1) != end && s[1] == '/');
if (comment) s++;
} /* FALLTHROUGH */
default:{done = !comment;}break;
@@ -1494,14 +1512,22 @@ meta_entry_stack_from_file(Arena *arena, char *file)
{
MetaEntry *e = da_push(arena, &result);
switch (token) {
- case MetaParseToken_RawString:{
+ case MetaParseToken_String:
+ case MetaParseToken_RawString:
+ {
e->kind = MetaEntryKind_String;
e->location = parser.save_point.location;
e->name = parser.u.string;
}break;
- case MetaParseToken_BeginArray:
+
case MetaParseToken_BeginScope:
case MetaParseToken_EndScope:
+ {
+ e->kind = parser.u.kind;
+ e->location = parser.save_point.location;
+ }break;
+
+ case MetaParseToken_BeginArray:
case MetaParseToken_Entry:
{
e->kind = parser.u.kind;
@@ -1569,63 +1595,12 @@ meta_entry_argument_expect(MetaEntry *e, u32 index, MetaEntryArgumentKind kind)
}
typedef struct {
- s8_list *data;
- iz count;
- iz capacity;
-} s8_list_table;
-
-typedef struct {
- s8 *names_upper;
- s8 *names_lower;
- u32 floating_point;
- u32 entry_count;
- u32 shader_id;
-} MetaShaderBakeParameters;
-DA_STRUCT(MetaShaderBakeParameters, MetaShaderBakeParameters);
-
-typedef struct {
- iz kind;
- iz variation;
-} MetaEnumeration;
-
-typedef struct {
- u32 *data;
- iz count;
- iz capacity;
+ da_count *data;
+ da_count count;
+ da_count capacity;
} MetaIDList;
typedef struct {
- MetaShaderBakeParameters *bake_parameters;
- u32 name_id;
- i32 base_shader_id;
- u32 push_constants_id;
- u32 flag_list_id;
- MetaIDList shader_enumeration_ids;
-} MetaShader;
-DA_STRUCT(MetaShader, MetaShader);
-
-typedef struct {
- MetaShader *shader;
- s8 file;
-} MetaBaseShader;
-DA_STRUCT(MetaBaseShader, MetaBaseShader);
-
-typedef struct {
- s8 name;
- MetaIDList shaders;
-} MetaShaderGroup;
-DA_STRUCT(MetaShaderGroup, MetaShaderGroup);
-
-typedef struct {
- s8 *fields;
- s8 **entries;
- u32 field_count;
- u32 entry_count;
- u32 table_name_id;
-} MetaTable;
-DA_STRUCT(MetaTable, MetaTable);
-
-typedef struct {
s8 enumeration_name;
s8 *sub_table_names;
u32 sub_table_count;
@@ -1690,8 +1665,8 @@ typedef enum {
typedef struct {
MetaExpansionPart *parts;
- u32 part_count;
- u32 table_id;
+ u32 part_count;
+ da_count table_entity_id;
} MetaEmitOperationExpansion;
typedef struct {
@@ -1705,54 +1680,165 @@ typedef struct {
typedef struct {
MetaEmitOperation *data;
- iz count;
- iz capacity;
+ da_count count;
+ da_count capacity;
s8 filename;
} MetaEmitOperationList;
typedef struct {
MetaEmitOperationList *data;
- iz count;
- iz capacity;
+ da_count count;
+ da_count capacity;
} MetaEmitOperationListSet;
+typedef struct { da_count value; } MetaEntityID;
+
+typedef enum {
+ MetaShaderKind_Alias,
+ MetaShaderKind_Compute,
+ MetaShaderKind_Count,
+} MetaShaderKind;
+
+typedef struct {
+ MetaShaderKind kind;
+ MetaIDList entity_reference_ids;
+ s8 file;
+ MetaEntityID alias_parent_id;
+} MetaShader;
+
+#define META_STRUCT_FIELDS \
+ X(Name, name) \
+ X(Type, type) \
+ X(Elements, elements) \
+
+#define X(id, ...) MetaStructField_##id,
+typedef enum {META_STRUCT_FIELDS} MetaStructFields;
+#undef X
+
+#define META_BAKE_FIELDS \
+ X(NameUpper, name_upper) \
+ X(NameLower, name_lower) \
+ X(Type, type) \
+
+#define X(id, ...) MetaBakeField_##id,
+typedef enum {META_BAKE_FIELDS} MetaBakeFields;
+#undef X
+
+typedef struct {
+ s8 *fields;
+ s8 **entries;
+ u32 field_count;
+ u32 entry_count;
+ union {
+ i32 *struct_type_ids;
+ };
+} MetaTable;
+
+typedef enum {
+ MetaConstantKind_Integer,
+ MetaConstantKind_Float,
+ MetaConstantKind_Count,
+} MetaConstantKind;
+
+typedef struct {
+ MetaConstantKind kind;
+ u32 name_id;
+ union {
+ u64 U64;
+ f64 F64;
+ };
+} MetaConstant;
+
+typedef struct {
+ s8 reference_name;
+ MetaEntityID resolved_id;
+ da_count reference_count;
+} MetaEntityReference;
+
+#define META_ENTITY_KINDS \
+ X(Nil, 0) \
+ X(BakeParameters, 1) \
+ X(Constant, 0) \
+ X(Enumeration, 1) \
+ X(PushConstants, 1) \
+ X(Reference, 0) \
+ X(Shader, 0) \
+ X(ShaderGroup, 0) \
+ X(Struct, 1) \
+ X(Table, 1) \
+
+read_only global s8 meta_entity_kind_names[] = {
+ #define X(name, ...) s8_comp(#name),
+ META_ENTITY_KINDS
+ #undef X
+};
+
+read_only global b8 meta_entity_kind_is_table[] = {
+ #define X(_n, table, ...) table,
+ META_ENTITY_KINDS
+ #undef X
+};
+
+typedef enum {
+ #define X(name, ...) MetaEntityKind_ ##name,
+ META_ENTITY_KINDS
+ #undef X
+ MetaEntityKind_Count,
+} MetaEntityKind;
+
+typedef struct {
+ MetaEntityKind kind;
+ MetaEntityID parent;
+ MetaEntityID first_child;
+ MetaEntityID next_sibling;
+ MetaEntityID previous_sibling;
+ MetaLocation location;
+ union {
+ MetaConstant constant;
+ MetaEntityReference reference;
+ MetaShader shader;
+ MetaTable table;
+ };
+} MetaEntity;
+DA_STRUCT(MetaEntity, MetaEntity);
+
typedef struct {
Arena *arena, scratch;
s8 filename;
s8 directory;
- s8_list enumeration_kinds;
- s8_list_table enumeration_members;
+ s8_list munion_namespaces;
+ MetaMUnionList munions;
- s8_list_table flags_for_shader;
+ // NOTE(rnp): arrays of entity ids sorted by kind and counted by entity_kind_counts
+ da_count *entity_kind_ids[MetaEntityKind_Count];
- s8_list table_names;
- MetaTableList tables;
+ da_count entity_kind_counts[MetaEntityKind_Count];
+ s8_list entity_names;
+ MetaEntityList entities;
- MetaTableList push_constant_tables;
+ // NOTE(rnp): list of all entities referenced by shaders. needed for header string baking
+ MetaIDList shader_entity_references;
- s8_list munion_namespaces;
- MetaMUnionList munions;
+ // NOTE(rnp): dumb jank to support treating CudaHilbert/CudaDecode as shaders and
+ // allowing shader names to alias.
+ da_count base_shader_count;
+ da_count *base_shader_ids;
+ // NOTE(rnp): map index in the entity_kind_ids[MetaEntityKind_Shader] to base_shader_ids index
+ da_count *base_shader_id_map;
MetaEmitOperationListSet emit_sets[MetaEmitLang_Count];
-
- MetaShaderBakeParametersList shader_bake_parameters;
- MetaIDList shader_enumerations;
- MetaShaderGroupList shader_groups;
- MetaShaderList shaders;
- MetaBaseShaderList base_shaders;
- s8_list shader_names;
} MetaContext;
-function iz
-meta_lookup_id_slow(MetaIDList *v, u32 id)
+function da_count
+meta_lookup_id_slow(da_count *v, da_count count, da_count id)
{
// TODO(rnp): obviously this is slow
- iz result = -1;
- for (iz i = 0; i < v->count; i++) {
- if (id == v->data[i]) {
+ da_count result = -1;
+ for (da_count i = 0; i < count; i++) {
+ if (id == v[i]) {
result = i;
break;
}
@@ -1760,10 +1846,10 @@ meta_lookup_id_slow(MetaIDList *v, u32 id)
return result;
}
-function iz
+function da_count
meta_intern_string(MetaContext *ctx, s8_list *sv, s8 s)
{
- iz result = meta_lookup_string_slow(sv->data, sv->count, s);
+ da_count result = meta_lookup_string_slow(sv->data, sv->count, s);
if (result < 0) {
*da_push(ctx->arena, sv) = s;
result = sv->count - 1;
@@ -1771,10 +1857,10 @@ meta_intern_string(MetaContext *ctx, s8_list *sv, s8 s)
return result;
}
-function iz
-meta_intern_id(MetaContext *ctx, MetaIDList *v, u32 id)
+function da_count
+meta_intern_id(MetaContext *ctx, MetaIDList *v, da_count id)
{
- iz result = meta_lookup_id_slow(v, id);
+ da_count result = meta_lookup_id_slow(v->data, v->count, id);
if (result < 0) {
*da_push(ctx->arena, v) = id;
result = v->count - 1;
@@ -1782,115 +1868,221 @@ meta_intern_id(MetaContext *ctx, MetaIDList *v, u32 id)
return result;
}
-function iz
-meta_pack_shader_bake_parameters(MetaContext *ctx, MetaEntry *e, iz entry_count, u32 shader_id, u32 *table_id)
+function da_count
+meta_entity_children_count(MetaContext *ctx, MetaEntityID entity_id)
{
- assert(e->kind == MetaEntryKind_Bake);
+ MetaEntityID child = ctx->entities.data[entity_id.value].first_child;
+ da_count result = 0;
+ if (child.value != 0) {
+ do {
+ result++;
+ child = ctx->entities.data[child.value].next_sibling;
+ } while (child.value != ctx->entities.data[entity_id.value].first_child.value);
+ }
+ return result;
+}
- MetaShaderBakeParameters *bp = da_push(ctx->arena, &ctx->shader_bake_parameters);
- bp->shader_id = shader_id;
- if (table_id) *table_id = (u32)da_index(bp, &ctx->shader_bake_parameters);
+function MetaEntity *
+meta_entity(MetaContext *ctx, MetaEntityID id)
+{
+ assert(id.value != 0 && id.value < ctx->entities.count);
+ MetaEntity *result = ctx->entities.data + id.value;
+ return result;
+}
- if (e->argument_count) meta_entry_argument_expected_(e, 0, 0);
+function MetaEntityID
+meta_root_entity_id(MetaContext *ctx)
+{
+ MetaEntityID result = {0};
+ return result;
+}
- MetaEntryScope scope = meta_entry_extract_scope(e, entry_count);
- if (scope.consumed > 1) {
- for (MetaEntry *row = scope.start; row != scope.one_past_last; row++) {
- if (row->kind != MetaEntryKind_BakeInt && row->kind != MetaEntryKind_BakeFloat)
- meta_entry_nesting_error(row, MetaEntryKind_Bake);
- meta_entry_argument_expected(row, s8("name"), s8("name_lower"));
- bp->entry_count++;
+function MetaEntityID
+meta_intern_entity(MetaContext *ctx, s8 name, MetaEntityKind kind, MetaEntityID parent,
+ MetaLocation location, b32 allow_existing)
+{
+ MetaEntityID result = {0};
+ assert(ctx->entities.data[0].kind == MetaEntityKind_Nil);
+ assert(Between(kind, MetaEntityKind_Nil + 1, MetaEntityKind_Count - 1));
+
+ da_count name_id = meta_intern_string(ctx, &ctx->entity_names, name);
+ if (name_id < ctx->entities.count && ctx->entities.data[name_id].kind != kind) {
+ s8 old_kind = meta_entity_kind_names[ctx->entities.data[name_id].kind];
+ s8 new_kind = meta_entity_kind_names[kind];
+ meta_compiler_error_message(location, "attempting to redefine %.*s as kind %.*s\n",
+ (i32)name.len, name.data, (i32)new_kind.len, new_kind.data);
+ meta_compiler_error_message(ctx->entities.data[name_id].location, "previously defined as kind %.*s\n",
+ (i32)old_kind.len, old_kind.data);
+ meta_error();
+ } else if (name_id < ctx->entities.count && !allow_existing) {
+ meta_compiler_error_message(location, "redefinition of %.*s\n", (i32)name.len, name.data);
+ meta_compiler_error_message(ctx->entities.data[name_id].location, "previously defined here\n");
+ meta_error();
+ } else {
+ if (name_id < ctx->entities.count) {
+ result.value = name_id;
+ } else {
+ ctx->entity_kind_counts[kind]++;
+ MetaEntity *new = da_push(ctx->arena, &ctx->entities);
+ new->location = location;
+ result.value = da_index(new, &ctx->entities);
}
- if (bp->entry_count > 32)
- meta_entry_error(e, "maximum bake parameter count exceeded: limit: 32\n");
+ MetaEntity *e = ctx->entities.data + result.value;
+ e->kind = kind;
+ e->parent = parent;
- bp->names_upper = push_array(ctx->arena, s8, bp->entry_count);
- bp->names_lower = push_array(ctx->arena, s8, bp->entry_count);
+ MetaEntity *p = ctx->entities.data + parent.value;
+ e->next_sibling = p->first_child;
+ p->first_child = result;
- u32 row_index = 0;
- for (MetaEntry *row = scope.start; row != scope.one_past_last; row++, row_index++) {
- bp->names_upper[row_index] = row->arguments[0].string;
- bp->names_lower[row_index] = row->arguments[1].string;
- bp->floating_point |= (u32)(row->kind == MetaEntryKind_BakeFloat) << row_index;
- }
+ if (e->next_sibling.value == 0)
+ e->next_sibling = p->first_child;
+
+ e->previous_sibling = ctx->entities.data[e->next_sibling.value].previous_sibling;
+ ctx->entities.data[e->next_sibling.value].previous_sibling = result;
+ ctx->entities.data[e->previous_sibling.value].next_sibling = result;
}
- return scope.consumed;
+ return result;
}
-function iz
-meta_enumeration_id(MetaContext *ctx, s8 kind)
+function MetaEntityID
+meta_entity_reference(MetaContext *ctx, s8 name, MetaLocation location)
{
- iz result = meta_intern_string(ctx, &ctx->enumeration_kinds, kind);
- if (ctx->enumeration_kinds.count != ctx->enumeration_members.count) {
- da_push(ctx->arena, &ctx->enumeration_members);
- assert(result == (ctx->enumeration_members.count - 1));
+ MetaEntityID result = {0};
+ Arena scratch;
+ DeferLoop(scratch = ctx->scratch, ctx->scratch = scratch) {
+ s8 ref_name = push_s8_from_parts(&ctx->scratch, s8(""), s8("R"), name);
+ result = meta_intern_entity(ctx, ref_name, MetaEntityKind_Reference, meta_root_entity_id(ctx),
+ location, 1);
+ MetaEntity *r = meta_entity(ctx, result);
+ if (r->reference.reference_count == 0)
+ ctx->entity_names.data[result.value] = push_s8(ctx->arena, ref_name);
+ r->reference.reference_count++;
+ r->reference.reference_name = name;
}
return result;
}
-function void
-meta_extend_enumeration(MetaContext *ctx, s8 kind, s8 *variations, uz count)
+function MetaEntityID
+meta_entity_first_child_of_kind(MetaContext *ctx, MetaEntity *e, MetaEntityKind kind)
{
- iz kidx = meta_enumeration_id(ctx, kind);
- /* NOTE(rnp): may overcommit if duplicates exist in variations */
- da_reserve(ctx->arena, ctx->enumeration_members.data + kidx, (iz)count);
- for (uz i = 0; i < count; i++)
- meta_intern_string(ctx, ctx->enumeration_members.data + kidx, variations[i]);
-}
-
-function MetaEnumeration
-meta_commit_enumeration(MetaContext *ctx, s8 kind, s8 variation)
-{
- iz kidx = meta_enumeration_id(ctx, kind);
- iz vidx = meta_intern_string(ctx, ctx->enumeration_members.data + kidx, variation);
- MetaEnumeration result = {.kind = kidx, .variation = vidx};
+ MetaEntityID result = {0};
+ MetaEntityID child = e->first_child;
+ do {
+ if (ctx->entities.data[child.value].kind == kind) {
+ result = child;
+ break;
+ }
+ child = ctx->entities.data[child.value].next_sibling;
+ } while (child.value != e->first_child.value);
return result;
}
-function u16
-meta_pack_shader_name(MetaContext *ctx, s8 base_name, MetaLocation loc)
+function void
+meta_pack_table_begin(MetaEntry *e, MetaTable *t)
{
- iz result = meta_intern_string(ctx, &ctx->shader_names, base_name);
- if (result > (iz)U16_MAX)
- meta_compiler_error(loc, "maximum base shaders exceeded: limit: %lu\n", U16_MAX);
- return (u16)result;
+ switch (e->kind) {
+
+ case MetaEntryKind_Bake:
+ {
+ meta_entry_argument_expected_(e, 0, 0);
+ #define X(_i, name, ...) s8_comp(#name),
+ read_only local_persist s8 bake_fields[] = {META_BAKE_FIELDS};
+ #undef X
+ t->fields = bake_fields;
+ t->field_count = countof(bake_fields);
+ }break;
+
+ case MetaEntryKind_Enumeration:{
+ read_only local_persist s8 enumeration_fields[] = {s8_comp("name")};
+ t->fields = enumeration_fields;
+ t->field_count = countof(enumeration_fields);
+ }break;
+
+ case MetaEntryKind_PushConstants:
+ case MetaEntryKind_Struct:
+ {
+ meta_entry_argument_expected_(e, 0, 0);
+ #define X(_i, name, ...) s8_comp(#name),
+ read_only local_persist s8 struct_fields[] = {META_STRUCT_FIELDS};
+ #undef X
+ t->fields = struct_fields;
+ t->field_count = countof(struct_fields);
+ }break;
+
+ case MetaEntryKind_Table:{
+ meta_entry_argument_expected(e, s8("[field ...]"));
+ MetaEntryArgument fields = meta_entry_argument_expect(e, 0, MetaEntryArgumentKind_Array);
+ t->fields = fields.strings;
+ t->field_count = (u32)fields.count;
+ }break;
+
+ InvalidDefaultCase;
+ }
}
-function u8
-meta_commit_shader_flag(MetaContext *ctx, u32 flag_list_id, s8 flag, MetaEntry *e)
+function void
+meta_direct_enumeration(MetaContext *ctx, s8 name, s8 *variations, u64 count, MetaLocation location)
{
- assert(flag_list_id < ctx->flags_for_shader.count);
- iz index = meta_intern_string(ctx, ctx->flags_for_shader.data + flag_list_id, flag);
- if (index > 31) meta_entry_error(e, "maximum shader local flags exceeded: limit: 32\n");
- u8 result = (u8)index;
- return result;
+ MetaEntityID entity_id = meta_intern_entity(ctx, name, MetaEntityKind_Enumeration,
+ meta_root_entity_id(ctx), location, 0);
+ MetaEntry entry = {.kind = MetaEntryKind_Enumeration};
+ MetaEntity *e = ctx->entities.data + entity_id.value;
+ meta_pack_table_begin(&entry, &e->table);
+ e->table.entries = push_array(ctx->arena, s8 *, 1);
+ e->table.entries[0] = push_array(ctx->arena, s8, count);
+ e->table.entry_count = count;
+ mem_copy(e->table.entries[0], variations, count * sizeof(*variations));
}
-function iz
-meta_fill_table(MetaContext *ctx, MetaEntry *e, iz entry_count, MetaTable *t)
+function i64
+meta_pack_table_entity(MetaContext *ctx, MetaEntry *e, i64 entry_count, s8 name, MetaEntityID parent)
{
- MetaEntryScope scope = meta_entry_extract_scope(e, entry_count);
+ MetaEntityKind entity_kind = MetaEntityKind_Nil;
+ switch (e->kind) {
+ case MetaEntryKind_Bake:{ entity_kind = MetaEntityKind_BakeParameters;}break;
+ case MetaEntryKind_Enumeration:{ entity_kind = MetaEntityKind_Enumeration; }break;
+ case MetaEntryKind_PushConstants:{entity_kind = MetaEntityKind_PushConstants; }break;
+ case MetaEntryKind_Struct:{ entity_kind = MetaEntityKind_Struct; }break;
+ case MetaEntryKind_Table:{ entity_kind = MetaEntityKind_Table; }break;
+ InvalidDefaultCase;
+ }
+
+ MetaEntityID entity_id = meta_intern_entity(ctx, name, entity_kind, parent, e->location, 0);
+ MetaTable table = {0}, *t = &table;
+ meta_pack_table_begin(e, t);
+
+ b32 structure = (e->kind == MetaEntryKind_Struct || e->kind == MetaEntryKind_PushConstants);
+
+ MetaEntryScope scope = meta_entry_extract_scope(e, entry_count);
if (scope.consumed > 1) {
for (MetaEntry *row = scope.start; row != scope.one_past_last; row++) {
- if (row->kind != MetaEntryKind_Array)
+ if (row->kind != MetaEntryKind_Array && row->kind != MetaEntryKind_String)
meta_entry_nesting_error(row, e->kind);
- MetaEntryArgument entries = meta_entry_argument_expect(row, 0, MetaEntryArgumentKind_Array);
- if (entries.count != t->field_count) {
+ MetaEntryArgument entries = {.count = 1};
+ if (row->kind == MetaEntryKind_Array)
+ entries.count = meta_entry_argument_expect(row, 0, MetaEntryArgumentKind_Array).count;
+
+ if (structure && entries.count != 2 && entries.count != 3) {
+ meta_compiler_error(row->location, "incorrect field count for @%s entry got: %zu expected: "
+ "[name type (elements)]\n", meta_entry_kind_strings[e->kind],
+ (size_t)entries.count);
+ } else if (!structure && entries.count != t->field_count) {
meta_compiler_error_message(row->location, "incorrect field count for @%s entry got: %zu expected: %u\n",
- meta_entry_kind_strings[e->kind],
- entries.count, t->field_count);
+ meta_entry_kind_strings[e->kind], (size_t)entries.count, t->field_count);
fprintf(stderr, " fields: [");
- for (uz i = 0; i < t->field_count; i++) {
+ for (u64 i = 0; i < t->field_count; i++) {
if (i != 0) fprintf(stderr, ", ");
fprintf(stderr, "%.*s", (i32)t->fields[i].len, t->fields[i].data);
}
fprintf(stderr, "]\n");
meta_error();
}
+
t->entry_count++;
}
@@ -1900,123 +2092,104 @@ meta_fill_table(MetaContext *ctx, MetaEntry *e, iz entry_count, MetaTable *t)
u32 row_index = 0;
for (MetaEntry *row = scope.start; row != scope.one_past_last; row++, row_index++) {
- s8 *fs = row->arguments->strings;
+ s8 *fs = &row->name;
+ if (row->arguments)
+ fs = row->arguments->strings;
+
for (u32 field = 0; field < t->field_count; field++)
t->entries[field][row_index] = fs[field];
+
+ // NOTE(rnp): if we are filling out a struct the array element count is optional
+ // and defaults to 1. fill this out here for uniformity elsewhere in the code
+ if (structure && row->arguments->count == 2)
+ t->entries[2][row_index] = s8("1");
}
}
+ MetaEntity *entity = meta_entity(ctx, entity_id);
+ entity->table = table;
+
+ switch (e->kind) {
+ case MetaEntryKind_Bake:
+ case MetaEntryKind_PushConstants:
+ case MetaEntryKind_Struct:
+ {
+ entity->table.struct_type_ids = push_array_no_zero(ctx->arena, i32, t->entry_count);
+ }break;
+
+ case MetaEntryKind_Enumeration:
+ case MetaEntryKind_Table:
+ {}break;
+
+ InvalidDefaultCase;
+ }
+
return scope.consumed;
}
-function iz
-meta_pack_shader_common(MetaContext *ctx, MetaShader *s, MetaEntry *e, iz entry_count, MetaEntryKind base_kind)
+function i64
+meta_pack_shader_common(MetaContext *ctx, MetaEntityID shader_id, MetaEntry *e, i64 entry_count, MetaEntityID group_entity_id)
{
- iz result = 0;
+ assert(ctx->entities.data[shader_id.value].kind == MetaEntityKind_Shader);
+ i64 result = 0;
+
switch(e->kind) {
- case MetaEntryKind_Enumeration:{
- meta_entry_argument_expected(e, s8("kind"));
- s8 kind = meta_entry_argument_expect(e, 0, MetaEntryArgumentKind_String).string;
- iz kid = meta_enumeration_id(ctx, kind);
- meta_intern_id(ctx, &s->shader_enumeration_ids,
- (u32)meta_intern_id(ctx, &ctx->shader_enumerations, (u32)kid));
+ case MetaEntryKind_Bake:{
+ e->name = push_s8_from_parts(ctx->arena, s8(""), ctx->entity_names.data[shader_id.value], s8("BakeParameters"));
+ result = meta_pack_table_entity(ctx, e, entry_count, e->name, shader_id);
}break;
case MetaEntryKind_PushConstants:{
- if (s->push_constants_id != (u32)-1) {
- meta_entry_error(e, "invalid @%s in @%s: only one @%s allowed per @%s\n",
- meta_entry_kind_strings[e->kind], meta_entry_kind_strings[base_kind],
- meta_entry_kind_strings[e->kind], meta_entry_kind_strings[base_kind]);
- }
-
- read_only local_persist s8 push_constant_fields[] = {
- s8_comp("glsl_type"),
- s8_comp("type"),
- s8_comp("name"),
- };
-
- MetaTable *t = da_push(ctx->arena, &ctx->push_constant_tables);
- t->fields = push_constant_fields;
- t->field_count = countof(push_constant_fields);
-
- s->push_constants_id = (u32)da_index(t, &ctx->push_constant_tables);
+ e->name = push_s8_from_parts(ctx->arena, s8(""), ctx->entity_names.data[shader_id.value], s8("PushConstants"));
+ result = meta_pack_table_entity(ctx, e, entry_count, e->name, shader_id);
+ goto reference;
+ }break;
- result = meta_fill_table(ctx, e, entry_count, t);
+ case MetaEntryKind_ShaderAlias:{
+ MetaEntityID alias_id = meta_intern_entity(ctx, e->name, MetaEntityKind_Shader, group_entity_id,
+ e->location, 0);
+ meta_entity(ctx, alias_id)->shader.kind = MetaShaderKind_Alias;
+ meta_entity(ctx, alias_id)->shader.alias_parent_id = shader_id;
+ }break;
- if (t->entry_count > 32)
- meta_entry_error(e, "maximum push constant parameters exceeded: limit: 32\n");
+ case MetaEntryKind_Enumeration:
+ case MetaEntryKind_Constant:
+ case MetaEntryKind_Struct:
+ reference:
+ {
+ meta_entry_argument_expected(e);
+ // TODO(rnp): MetaIDList.data should be of type MetaEntityID
+ MetaEntityID ref_id = meta_entity_reference(ctx, e->name, e->location);
+ meta_intern_id(ctx, &meta_entity(ctx, shader_id)->shader.entity_reference_ids, ref_id.value);
}break;
- default:{ meta_entry_nesting_error(e, base_kind); }break;
+ default:{ meta_entry_nesting_error(e, MetaEntryKind_Shader); }break;
}
return result;
}
-function iz
-meta_pack_compute_shader(MetaContext *ctx, MetaEntry *entries, iz entry_count, MetaShaderGroup *sg)
+function i64
+meta_pack_compute_shader(MetaContext *ctx, MetaEntry *entries, i64 entry_count, MetaEntityID group_entity_id)
{
assert(entries[0].kind == MetaEntryKind_Shader);
- MetaShader *s = da_push(ctx->arena, &ctx->shaders);
- {
- s8_list *flag_list = da_push(ctx->arena, &ctx->flags_for_shader);
- s->flag_list_id = (u32)da_index(flag_list, &ctx->flags_for_shader);
- }
- s->name_id = meta_pack_shader_name(ctx, entries->name, entries->location);
- s->push_constants_id = -1;
- s->base_shader_id = -1;
-
- *da_push(ctx->arena, &sg->shaders) = (u32)da_index(s, &ctx->shaders);
+ MetaEntityID entity_id = meta_intern_entity(ctx, entries->name, MetaEntityKind_Shader, group_entity_id,
+ entries->location, 0);
+ meta_entity(ctx, entity_id)->shader.kind = MetaShaderKind_Compute;
if (entries->argument_count > 1) {
meta_entry_argument_expected(entries, s8("[file_name]"));
} else if (entries->argument_count == 1) {
- MetaBaseShader *bs = da_push(ctx->arena, &ctx->base_shaders);
- bs->file = meta_entry_argument_expect(entries, 0, MetaEntryArgumentKind_String).string;
- bs->shader = s;
- s->base_shader_id = (u32)da_index(bs, &ctx->base_shaders);
+ s8 shader_file = meta_entry_argument_expect(entries, 0, MetaEntryArgumentKind_String).string;
+ meta_entity(ctx, entity_id)->shader.file = shader_file;
}
MetaEntryScope scope = meta_entry_extract_scope(entries, entry_count);
if (scope.consumed > 1) {
- for (MetaEntry *e = scope.start; e < scope.one_past_last; e++) {
- switch (e->kind) {
-
- case MetaEntryKind_ShaderAlias:{
- MetaShader *sa = da_push(ctx->arena, &ctx->shaders);
- sa->base_shader_id = s->base_shader_id;
- sa->name_id = meta_pack_shader_name(ctx, e->name, e->location);
- sa->push_constants_id = -1;
- *da_push(ctx->arena, &sg->shaders) = (u32)da_index(sa, &ctx->shaders);
- meta_commit_shader_flag(ctx, s->flag_list_id, e->name, e);
- }break;
-
- case MetaEntryKind_Flags:{
- meta_entry_argument_expected(e, s8("[flag ...]"));
- MetaEntryArgument flags = meta_entry_argument_expect(e, 0, MetaEntryArgumentKind_Array);
- for (u32 index = 0; index < flags.count; index++)
- meta_commit_shader_flag(ctx, s->flag_list_id, flags.strings[index], e);
- }break;
-
- case MetaEntryKind_Bake:{
- if (s->bake_parameters) {
- meta_entry_error(e, "invalid @%s in @%s: only one @%s allowed per @%s\n",
- meta_entry_kind_strings[e->kind], meta_entry_kind_strings[MetaEntryKind_Shader],
- meta_entry_kind_strings[e->kind], meta_entry_kind_strings[MetaEntryKind_Shader]);
- }
- u32 table_id;
- e += meta_pack_shader_bake_parameters(ctx, e, scope.one_past_last - e,
- (u32)da_index(s, &ctx->shaders), &table_id);
- s->bake_parameters = ctx->shader_bake_parameters.data + table_id;
- }break;
-
- default:{
- e += meta_pack_shader_common(ctx, s, e, scope.one_past_last - e, MetaEntryKind_Shader);
- }break;
- }
- }
+ for (MetaEntry *e = scope.start; e < scope.one_past_last; e++)
+ e += meta_pack_shader_common(ctx, entity_id, e, scope.one_past_last - e, group_entity_id);
} else {
assert(scope.consumed == 1);
// TODO(rnp): some functions (@Expand) expect no scope and that the next entry
@@ -2026,20 +2199,20 @@ meta_pack_compute_shader(MetaContext *ctx, MetaEntry *entries, iz entry_count, M
return scope.consumed;
}
-function iz
-meta_pack_shader_group(MetaContext *ctx, MetaEntry *entries, iz entry_count)
+function i64
+meta_pack_shader_group(MetaContext *ctx, MetaEntry *entries, i64 entry_count)
{
assert(entries->kind == MetaEntryKind_ShaderGroup);
- MetaShaderGroup *sg = da_push(ctx->arena, &ctx->shader_groups);
- sg->name = entries->name;
+ MetaEntityID entity_id = meta_intern_entity(ctx, entries->name, MetaEntityKind_ShaderGroup,
+ meta_root_entity_id(ctx), entries->location, 0);
MetaEntryScope scope = meta_entry_extract_scope(entries, entry_count);
if (scope.consumed > 1) {
for (MetaEntry *e = scope.start; e < scope.one_past_last; e++) {
switch (e->kind) {
case MetaEntryKind_Shader:{
- e += meta_pack_compute_shader(ctx, e, scope.one_past_last - e, sg);
+ e += meta_pack_compute_shader(ctx, e, scope.one_past_last - e, entity_id);
}break;
default:{meta_entry_nesting_error(e, MetaEntryKind_ShaderGroup);}break;
}
@@ -2092,27 +2265,33 @@ meta_expansion_string_split(s8 string, s8 *left, s8 *inner, s8 *remainder, MetaL
function MetaExpansionPart *
meta_push_expansion_part(MetaContext *ctx, Arena *arena, MetaExpansionPartList *parts,
- MetaExpansionPartKind kind, s8 string, MetaTable *t, MetaLocation loc)
+ MetaExpansionPartKind kind, s8 string, MetaEntity *table, MetaLocation loc)
{
MetaExpansionPart *result = da_push(arena, parts);
+
result->kind = kind;
switch (kind) {
case MetaExpansionPartKind_Alignment:
case MetaExpansionPartKind_Conditional:
{}break;
+
case MetaExpansionPartKind_EvalKind:
case MetaExpansionPartKind_EvalKindCount:
case MetaExpansionPartKind_Reference:
{
- iz index = meta_lookup_string_slow(t->fields, t->field_count, string);
+ assert(meta_entity_kind_is_table[table->kind]);
+ MetaTable *t = &table->table;
+
+ da_count index = meta_lookup_string_slow(t->fields, t->field_count, string);
result->strings = t->entries[index];
if (index < 0) {
/* TODO(rnp): fix this location to point directly at the field in the string */
- s8 table_name = ctx->table_names.data[t->table_name_id];
+ s8 table_name = ctx->entity_names.data[da_index(table, &ctx->entities)];
meta_compiler_error(loc, "table \"%.*s\" does not contain member: %.*s\n",
(i32)table_name.len, table_name.data, (i32)string.len, string.data);
}
}break;
+
case MetaExpansionPartKind_String:{ result->string = string; }break;
InvalidDefaultCase;
}
@@ -2213,8 +2392,8 @@ meta_expansion_token(MetaExpansionParser *p)
switch (result) {
case MetaExpansionToken_Number:{
- IntegerConversion integer = integer_from_s8(p->s);
- if (integer.result != IntegerConversionResult_Success) {
+ NumberConversion integer = integer_from_s8(p->s);
+ if (integer.result != NumberConversionResult_Success) {
/* TODO(rnp): point at start */
meta_compiler_error(p->loc, "invalid integer in expansion string\n");
}
@@ -2262,13 +2441,13 @@ meta_expansion_end_conditional(MetaExpansionPart *ep, MetaExpansionParser *p, Me
}
function MetaExpansionPartList
-meta_generate_expansion_set(MetaContext *ctx, Arena *arena, s8 expansion_string, MetaTable *t, MetaLocation loc)
+meta_generate_expansion_set(MetaContext *ctx, Arena *arena, s8 expansion_string, MetaEntity *table, MetaLocation loc)
{
MetaExpansionPartList result = {0};
s8 left = {0}, inner, remainder = expansion_string;
do {
meta_expansion_string_split(remainder, &left, &inner, &remainder, loc);
- if (left.len) meta_push_expansion_part(ctx, arena, &result, MetaExpansionPartKind_String, left, t, loc);
+ if (left.len) meta_push_expansion_part(ctx, arena, &result, MetaExpansionPartKind_String, left, table, loc);
if (inner.len) {
MetaExpansionParser p[1] = {{.s = inner, .loc = loc}};
@@ -2282,11 +2461,11 @@ meta_generate_expansion_set(MetaContext *ctx, Arena *arena, s8 expansion_string,
if (count_test_parts) test_part->conditional.instruction_skip++;
switch (token) {
case MetaExpansionToken_Alignment:{
- meta_push_expansion_part(ctx, arena, &result, MetaExpansionPartKind_Alignment, p->s, t, loc);
+ meta_push_expansion_part(ctx, arena, &result, MetaExpansionPartKind_Alignment, p->s, table, loc);
}break;
case MetaExpansionToken_Identifier:{
- meta_push_expansion_part(ctx, arena, &result, MetaExpansionPartKind_Reference, p->string, t, loc);
+ meta_push_expansion_part(ctx, arena, &result, MetaExpansionPartKind_Reference, p->string, table, loc);
}break;
case MetaExpansionToken_TypeEval:
@@ -2299,7 +2478,7 @@ meta_generate_expansion_set(MetaContext *ctx, Arena *arena, s8 expansion_string,
MetaExpansionPartKind kind = token == MetaExpansionToken_TypeEval ?
MetaExpansionPartKind_EvalKind :
MetaExpansionPartKind_EvalKindCount;
- meta_push_expansion_part(ctx, arena, &result, kind, p->string, t, loc);
+ meta_push_expansion_part(ctx, arena, &result, kind, p->string, table, loc);
}break;
case MetaExpansionToken_Quote:{
@@ -2311,7 +2490,7 @@ meta_generate_expansion_set(MetaContext *ctx, Arena *arena, s8 expansion_string,
/* TODO(rnp): point at start */
meta_compiler_error(loc, "unterminated string in expansion\n");
}
- meta_push_expansion_part(ctx, arena, &result, MetaExpansionPartKind_String, string, t, loc);
+ meta_push_expansion_part(ctx, arena, &result, MetaExpansionPartKind_String, string, table, loc);
}break;
case MetaExpansionToken_Dash:{
@@ -2397,10 +2576,20 @@ meta_expand(MetaContext *ctx, Arena scratch, MetaEntry *e, iz entry_count, MetaE
meta_entry_argument_expected(e, s8("table_name"));
s8 table_name = meta_entry_argument_expect(e, 0, MetaEntryArgumentKind_String).string;
- MetaTable *t = ctx->tables.data + meta_lookup_string_slow(ctx->table_names.data,
- ctx->table_names.count, table_name);
- if (t < ctx->tables.data)
+ MetaEntity *table = ctx->entities.data + meta_lookup_string_slow(ctx->entity_names.data,
+ ctx->entity_names.count,
+ table_name);
+
+ if (table < ctx->entities.data)
meta_entry_error(e, "undefined table %.*s\n", (i32)table_name.len, table_name.data);
+ if (!meta_entity_kind_is_table[table->kind]) {
+ s8 old_kind = meta_entity_kind_names[table->kind];
+ s8 wanted_kind = meta_entity_kind_names[MetaEntityKind_Table];
+ meta_entry_error(e, "%.*s previously defined as %.*s but should be %.*s\n",
+ (i32)table_name.len, table_name.data,
+ (i32)old_kind.len, old_kind.data,
+ (i32)wanted_kind.len, wanted_kind.data);
+ }
MetaEntryScope scope = meta_entry_extract_scope(e, entry_count);
for (MetaEntry *row = scope.start; row != scope.one_past_last; row++) {
@@ -2408,25 +2597,24 @@ meta_expand(MetaContext *ctx, Arena scratch, MetaEntry *e, iz entry_count, MetaE
case MetaEntryKind_String:{
if (!ops) goto error;
- MetaExpansionPartList parts = meta_generate_expansion_set(ctx, ctx->arena, row->name, t, row->location);
+ MetaExpansionPartList parts = meta_generate_expansion_set(ctx, ctx->arena, row->name, table, row->location);
MetaEmitOperation *op = da_push(ctx->arena, ops);
op->kind = MetaEmitOperationKind_Expand;
op->location = row->location;
- op->expansion_operation.parts = parts.data;
- op->expansion_operation.part_count = (u32)parts.count;
- op->expansion_operation.table_id = (u32)da_index(t, &ctx->tables);
+ op->expansion_operation.parts = parts.data;
+ op->expansion_operation.part_count = (u32)parts.count;
+ op->expansion_operation.table_entity_id = da_index(table, &ctx->entities);
}break;
case MetaEntryKind_Enumeration:{
if (ops) meta_entry_nesting_error(row, MetaEntryKind_Emit);
- meta_entry_argument_expected(row, s8("kind"), s8("`raw_string`"));
- s8 kind = meta_entry_argument_expect(row, 0, MetaEntryArgumentKind_String).string;
- s8 expand = meta_entry_argument_expect(row, 1, MetaEntryArgumentKind_String).string;
+ meta_entry_argument_expected(row, s8("`raw_string`"));
+ s8 expand = meta_entry_argument_expect(row, 0, MetaEntryArgumentKind_String).string;
- MetaExpansionPartList parts = meta_generate_expansion_set(ctx, &scratch, expand, t, row->location);
- s8 *variations = push_array(&scratch, s8, t->entry_count);
- for (u32 expansion = 0; expansion < t->entry_count; expansion++) {
+ MetaExpansionPartList parts = meta_generate_expansion_set(ctx, &scratch, expand, table, row->location);
+ s8 *variations = push_array(&scratch, s8, table->table.entry_count);
+ for (u32 expansion = 0; expansion < table->table.entry_count; expansion++) {
Stream sb = arena_stream(*ctx->arena);
for (iz part = 0; part < parts.count; part++) {
MetaExpansionPart *p = parts.data + part;
@@ -2436,7 +2624,7 @@ meta_expand(MetaContext *ctx, Arena scratch, MetaEntry *e, iz entry_count, MetaE
}
variations[expansion] = arena_stream_commit(ctx->arena, &sb);
}
- meta_extend_enumeration(ctx, kind, variations, t->entry_count);
+ meta_direct_enumeration(ctx, row->name, variations, table->table.entry_count, e->location);
}break;
error:
default:
@@ -2503,6 +2691,32 @@ meta_map_emit_lang(s8 lang, MetaEntry *e)
return result;
}
+function void
+meta_pack_constant(MetaContext *ctx, MetaEntry *e)
+{
+ assert(e->kind == MetaEntryKind_Constant);
+
+ MetaEntityID entity_id = meta_intern_entity(ctx, e->name, MetaEntityKind_Constant, meta_root_entity_id(ctx), e->location, 0);
+
+ meta_entry_argument_expected(e, s8("value"));
+ s8 value = meta_entry_argument_expect(e, 0, MetaEntryArgumentKind_String).string;
+
+ NumberConversion number = number_from_s8(value);
+ if (number.result != NumberConversionResult_Success || number.unparsed.len != 0) {
+ meta_compiler_error(e->location, "Invalid integer in definition of Constant '%.*s': %.*s\n",
+ (i32)e->name.len, e->name.data, (i32)value.len, value.data);
+ }
+
+ MetaEntity *entity = meta_entity(ctx, entity_id);
+ if (number.kind == NumberConversionKind_Float) {
+ entity->constant.kind = MetaConstantKind_Float;
+ entity->constant.F64 = number.F64;
+ } else {
+ entity->constant.kind = MetaConstantKind_Integer;
+ entity->constant.U64 = number.U64;
+ }
+}
+
function iz
meta_pack_emit(MetaContext *ctx, Arena scratch, MetaEntry *e, iz entry_count)
{
@@ -2561,27 +2775,6 @@ meta_pack_munion(MetaContext *ctx, MetaEntry *e, iz entry_count)
mu->sub_table_count = (u32)sub_tables.count;
}
-function iz
-meta_pack_table(MetaContext *ctx, MetaEntry *e, iz entry_count)
-{
- assert(e->kind == MetaEntryKind_Table);
-
- MetaTable *t = da_push(ctx->arena, &ctx->tables);
- iz table_name_id = meta_lookup_string_slow(ctx->table_names.data, ctx->table_names.count, e->name);
- if (table_name_id >= 0) meta_entry_error(e, "table redefined\n");
-
- s8 *t_name = da_push(ctx->arena, &ctx->table_names);
- t->table_name_id = (u32)da_index(t_name, &ctx->table_names);
- *t_name = e->name;
-
- meta_entry_argument_expected(e, s8("[field ...]"));
- MetaEntryArgument fields = meta_entry_argument_expect(e, 0, MetaEntryArgumentKind_Array);
- t->fields = fields.strings;
- t->field_count = (u32)fields.count;
-
- return meta_fill_table(ctx, e, entry_count, t);
-}
-
function CommandList
meta_extract_emit_file_dependencies(MetaContext *ctx, Arena *arena)
{
@@ -2663,8 +2856,8 @@ meta_expansion_part_conditional_argument(MetaExpansionConditionalArgument a, u32
case MetaExpansionConditionalArgumentKind_Reference:{
s8 string = a.strings[entry];
- IntegerConversion integer = integer_from_s8(string);
- if (integer.result != IntegerConversionResult_Success) {
+ NumberConversion integer = integer_from_s8(string);
+ if (integer.result != NumberConversionResult_Success) {
meta_compiler_error(loc, "Invalid integer in '%.*s' table expansion: %.*s\n",
(i32)table_name.len, table_name.data, (i32)string.len, string.data);
}
@@ -2693,8 +2886,7 @@ meta_expansion_part_conditional(MetaExpansionPart *p, u32 entry, s8 table_name,
}
function void
-metagen_run_emit(MetaprogramContext *m, MetaContext *ctx, MetaEmitOperationList *ops,
- MetaTableList *tables, s8 *evaluation_table)
+metagen_run_emit(MetaprogramContext *m, MetaContext *ctx, MetaEmitOperationList *ops, s8 *evaluation_table)
{
for (iz opcode = 0; opcode < ops->count; opcode++) {
MetaEmitOperation *op = ops->data + opcode;
@@ -2712,10 +2904,8 @@ metagen_run_emit(MetaprogramContext *m, MetaContext *ctx, MetaEmitOperationList
Arena scratch = m->scratch;
MetaEmitOperationExpansion *eop = &op->expansion_operation;
- MetaTable *t = tables->data + eop->table_id;
- // TODO(rnp): table_names should be stored with the in the table list
- s8 table_name = eop->table_id < ctx->table_names.count ? ctx->table_names.data[t->table_name_id]
- : s8("(Unamed Table)");
+ MetaTable *t = &ctx->entities.data[eop->table_entity_id].table;
+ s8 table_name = ctx->entity_names.data[eop->table_entity_id];
u32 alignment_count = 1;
u32 evaluation_count = 0;
@@ -2798,7 +2988,7 @@ metagen_run_emit_set(MetaprogramContext *m, MetaContext *ctx, MetaEmitOperationL
{
for (iz set = 0; set < emit_set->count; set++) {
MetaEmitOperationList *ops = emit_set->data + set;
- metagen_run_emit(m, ctx, ops, &ctx->tables, evaluation_table);
+ metagen_run_emit(m, ctx, ops, evaluation_table);
}
}
@@ -2819,6 +3009,23 @@ metagen_push_counted_enum_body(MetaprogramContext *m, s8 kind, s8 prefix, s8 mid
}
function void
+metagen_push_counted_enum_body_from_ids(MetaprogramContext *m, s8 kind, s8 prefix, s8 mid, s8 suffix,
+ da_count *ids, s8 *id_names, da_count ids_count)
+{
+ i64 max_id_length = 0;
+ for (i64 id = 0; id < ids_count; id++)
+ max_id_length = Max(max_id_length, id_names[ids[id]].len);
+
+ for (i64 id = 0; id < ids_count; id++) {
+ meta_begin_line(m, prefix, kind, id_names[ids[id]]);
+ meta_pad(m, ' ', 1 + (i32)(max_id_length - id_names[ids[id]].len));
+ meta_push(m, mid);
+ meta_push_i64(m, id);
+ meta_end_line(m, suffix);
+ }
+}
+
+function void
metagen_push_c_enum(MetaprogramContext *m, Arena scratch, s8 kind, s8 *ids, iz ids_count)
{
s8 kind_full = push_s8_from_parts(&scratch, s8(""), kind, s8("_"));
@@ -2829,12 +3036,29 @@ metagen_push_c_enum(MetaprogramContext *m, Arena scratch, s8 kind, s8 *ids, iz i
}
function void
-metagen_push_c_flag_enum(MetaprogramContext *m, Arena scratch, s8 kind, s8 *ids, iz ids_count)
+metagen_push_struct_body(MetaprogramContext *m, MetaTable *s, s8 *types, s8 *members, s8 *elements,
+ s8 prefix, s8 suffix, s8 str_elements_prefix)
{
- s8 kind_full = push_s8_from_parts(&scratch, s8(""), kind, s8("_"));
- meta_begin_scope(m, s8("typedef enum {"));
- metagen_push_counted_enum_body(m, kind_full, s8(""), s8("= (1 << "), s8("),"), ids, ids_count);
- meta_end_scope(m, s8("} "), kind, s8(";\n"));
+ i64 max_type_name_length = 0;
+ for (u32 member = 0; member < s->entry_count; member++) {
+ i32 id = s->struct_type_ids[member];
+ max_type_name_length = Max(max_type_name_length, types[id].len);
+ }
+
+ for (u32 member = 0; member < s->entry_count; member++) {
+ i32 id = s->struct_type_ids[member];
+ s8 kind = types[id];
+ i64 length = kind.len;
+
+ meta_begin_line(m, prefix, kind);
+ meta_pad(m, ' ', 1 + (i32)(max_type_name_length - length));
+ meta_push(m, members[member]);
+ if (elements && (elements[member].len > 1 || elements[member].data[0] != '1')) {
+ meta_push(m, s8("["), IsDigit(elements[member].data[0])? s8("") : str_elements_prefix,
+ elements[member], s8("]"));
+ }
+ meta_end_line(m, s8(";"), suffix);
+ }
}
function void
@@ -2842,134 +3066,146 @@ meta_push_shader_reload_info(MetaprogramContext *m, MetaContext *ctx)
{
///////////////////////////////
// NOTE(rnp): reloadable infos
- meta_begin_scope(m, s8("read_only global BeamformerShaderKind beamformer_reloadable_shader_kinds[] = {"));
- for (iz shader = 0; shader < ctx->base_shaders.count; shader++) {
- MetaShader *s = ctx->base_shaders.data[shader].shader;
- meta_push_line(m, s8("BeamformerShaderKind_"), ctx->shader_names.data[s->name_id], s8(","));
- }
- meta_end_scope(m, s8("};\n"));
+ meta_begin_scope(m, s8("read_only global " META_NAMESPACE_UPPER "ShaderKind " META_NAMESPACE_LOWER "_reloadable_shader_kinds[] = {"));
+ {
+ for (da_count shader = 0; shader < ctx->base_shader_count; shader++) {
+ da_count id = ctx->base_shader_ids[shader];
+ meta_push_line(m, s8(META_NAMESPACE_UPPER "ShaderKind_"), ctx->entity_names.data[id], s8(","));
+ }
+ } meta_end_scope(m, s8("};\n"));
- meta_begin_scope(m, s8("read_only global s8 beamformer_reloadable_shader_files[] = {"));
- for (iz shader = 0; shader < ctx->base_shaders.count; shader++) {
- meta_push_line(m, s8("s8_comp(\""), ctx->base_shaders.data[shader].file, s8("\"),"));
- }
- meta_end_scope(m, s8("};\n"));
+ meta_begin_scope(m, s8("read_only global s8 " META_NAMESPACE_LOWER "_reloadable_shader_files[] = {"));
+ {
+ for (da_count shader = 0; shader < ctx->base_shader_count; shader++) {
+ da_count id = ctx->base_shader_ids[shader];
+ MetaShader *s = &ctx->entities.data[id].shader;
+ meta_push_line(m, s8("s8_comp(\""), s->file, s8("\"),"));
+ }
+ } meta_end_scope(m, s8("};\n"));
+ meta_begin_scope(m, s8("read_only global i32 " META_NAMESPACE_LOWER "_shader_reloadable_index_by_shader[] = {"));
{
- meta_begin_scope(m, s8("read_only global i32 beamformer_shader_reloadable_index_by_shader[] = {"));
- for (iz shader = 0; shader < ctx->shaders.count; shader++) {
+ for (da_count shader = 0; shader < ctx->entity_kind_counts[MetaEntityKind_Shader]; shader++) {
meta_indent(m);
- meta_push_i64(m, ctx->shaders.data[shader].base_shader_id);
+ meta_push_i64(m, ctx->base_shader_id_map[shader]);
meta_end_line(m, s8(","));
}
- meta_end_scope(m, s8("};\n"));
- }
+ } meta_end_scope(m, s8("};\n"));
{
u32 info_index = 0;
- for (iz group = 0; group < ctx->shader_groups.count; group++) {
- MetaShaderGroup *sg = ctx->shader_groups.data + group;
- meta_begin_line(m, s8("read_only global i32 beamformer_reloadable"));
- for (iz i = 0; i < sg->name.len; i++) {
- if IsUpper(sg->name.data[i])
+ for (da_count group = 0; group < ctx->entity_kind_counts[MetaEntityKind_ShaderGroup]; group++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_ShaderGroup][group];
+ s8 name = ctx->entity_names.data[id];
+ meta_begin_line(m, s8("read_only global i32 " META_NAMESPACE_LOWER "_reloadable"));
+ for (i64 i = 0; i < name.len; i++) {
+ if IsUpper(name.data[i])
stream_append_byte(&m->stream, '_');
- stream_append_byte(&m->stream, ToLower(sg->name.data[i]));
+ stream_append_byte(&m->stream, ToLower(name.data[i]));
}
- meta_begin_scope(m, s8("_shader_info_indices[] = {"));
-
- for (iz shader = 0; shader < sg->shaders.count; shader++) {
- MetaShader *s = ctx->shaders.data + sg->shaders.data[shader];
- /* TODO(rnp): store base shader list in a better format */
- for (iz base_shader = 0; base_shader < ctx->base_shaders.count; base_shader++) {
- MetaBaseShader *bs = ctx->base_shaders.data + base_shader;
- if (bs->shader == s) {
- meta_indent(m);
- meta_push_u64(m, info_index++);
- meta_end_line(m, s8(","));
- break;
+
+ meta_begin_scope(m, s8("_shader_info_indices[] = {")); {
+ MetaEntityID child = ctx->entities.data[id].first_child;
+ do {
+ /* TODO(rnp): store base shader list in a better format */
+ for (da_count bs = 0; bs < ctx->base_shader_count; bs++) {
+ if (ctx->base_shader_ids[bs] == child.value) {
+ meta_indent(m);
+ meta_push_u64(m, info_index++);
+ meta_end_line(m, s8(","));
+ break;
+ }
}
- }
- }
- meta_end_scope(m, s8("};\n"));
+ child = ctx->entities.data[child.value].next_sibling;
+ } while (child.value != ctx->entities.data[id].first_child.value);
+ } meta_end_scope(m, s8("};\n"));
}
}
////////////////////////////////////
// NOTE(rnp): shader header strings
- meta_begin_scope(m, s8("read_only global s8 beamformer_shader_global_header_strings[] = {"));
- for (iz ref = 0; ref < ctx->shader_enumerations.count; ref++) {
- u32 kind = ctx->shader_enumerations.data[ref];
- s8_list *sub_list = ctx->enumeration_members.data + kind;
- s8 kind_name = push_s8_from_parts(&m->scratch, s8(""), ctx->enumeration_kinds.data[kind], s8("_"));
- meta_push_line(m, s8("s8_comp(\"\""));
- metagen_push_counted_enum_body(m, kind_name, s8("\"#define "), s8(""), s8("\\n\""),
- sub_list->data, sub_list->count);
- meta_push_line(m, s8("\"\\n\"),"));
- m->scratch = ctx->scratch;
- }
- meta_end_scope(m, s8("};\n"));
+ meta_begin_scope(m, s8("read_only global s8 " META_NAMESPACE_LOWER "_shader_global_header_strings[] = {"));
+ {
+ for (da_count ref = 0; ref < ctx->shader_entity_references.count; ref++) {
+ da_count entity_id = ctx->shader_entity_references.data[ref];
+ s8 entity_name = ctx->entity_names.data[entity_id];
+ MetaEntity *e = ctx->entities.data + entity_id;
- meta_begin_scope(m, s8("read_only global s8 *beamformer_shader_flag_strings[] = {"));
- for (iz shader = 0; shader < ctx->base_shaders.count; shader++) {
- MetaShader *s = ctx->base_shaders.data[shader].shader;
- s8_list *flag_list = ctx->flags_for_shader.data + s->flag_list_id;
+ switch (e->kind) {
- if (flag_list->count) {
- meta_begin_scope(m, s8("(s8 []){"));
- for (iz flag = 0; flag < flag_list->count; flag++)
- meta_push_line(m, s8("s8_comp(\""), flag_list->data[flag], s8("\"),"));
- meta_end_scope(m, s8("},"));
- } else {
- meta_push_line(m, s8("0,"));
- }
- }
- meta_end_scope(m, s8("};\n"));
+ case MetaEntityKind_Constant:{
+ meta_begin_line(m, s8("s8_comp(\"#define "), entity_name, s8(" ("));
+ switch(e->constant.kind) {
+ case MetaConstantKind_Integer:{ meta_push_u64(m, e->constant.U64); }break;
+ case MetaConstantKind_Float:{ meta_push_f64(m, e->constant.F64); }break;
+ InvalidDefaultCase;
+ }
+ meta_end_line(m, s8(")\\n\\n\"),"));
+ }break;
- meta_begin_scope(m, s8("read_only global u8 beamformer_shader_flag_strings_count[] = {"));
- for (iz shader = 0; shader < ctx->base_shaders.count; shader++) {
- MetaShader *s = ctx->base_shaders.data[shader].shader;
- u64 count = (u64)ctx->flags_for_shader.data[s->flag_list_id].count;
+ case MetaEntityKind_Struct:{
+ meta_push_line(m, s8("s8_comp(\"\""));
+ meta_push_line(m, s8("\"struct "), entity_name, s8(" {\\n\""));
+ metagen_push_struct_body(m, &e->table, meta_kind_glsl_types, e->table.entries[MetaStructField_Name],
+ e->table.entries[MetaStructField_Elements], s8("\" "), s8("\\n\""), s8(""));
+ meta_push_line(m, s8("\"};\\n\""));
+ meta_push_line(m, s8("\"\\n\"),"));
+ }break;
- meta_indent(m);
- meta_push_u64(m, count);
- meta_end_line(m, s8(","));
- }
- meta_end_scope(m, s8("};\n"));
+ case MetaEntityKind_PushConstants:{
+ meta_push_line(m, s8("s8_comp(\"\""));
+ meta_push_line(m, s8("\"layout(std140, binding = 0) uniform PushConstants {\\n\""));
+ metagen_push_struct_body(m, &e->table, meta_kind_glsl_types, e->table.entries[MetaStructField_Name],
+ e->table.entries[MetaStructField_Elements], s8("\" "), s8("\\n\""), s8(""));
+ meta_push_line(m, s8("\"};\\n\""));
+ meta_push_line(m, s8("\"\\n\"),"));
+ }break;
+
+ case MetaEntityKind_Enumeration:{
+ s8 kind_name = push_s8_from_parts(&m->scratch, s8(""), entity_name, s8("_"));
+ meta_push_line(m, s8("s8_comp(\"\""));
+ metagen_push_counted_enum_body(m, kind_name, s8("\"#define "), s8(""), s8("\\n\""),
+ e->table.entries[0], e->table.entry_count);
+ meta_push_line(m, s8("\"\\n\"),"));
+ }break;
+
+ InvalidDefaultCase;
+ }
+
+ m->scratch = ctx->scratch;
+ }
+ } meta_end_scope(m, s8("};\n"));
}
function void
meta_push_shader_bake(MetaprogramContext *m, MetaContext *ctx)
{
- for (iz shader = 0; shader < ctx->base_shaders.count; shader++) {
- MetaBaseShader *bs = ctx->base_shaders.data + shader;
- MetaShader *s = bs->shader;
+ for (da_count bs = 0; bs < ctx->base_shader_count; bs++) {
+ MetaShader *s = &ctx->entities.data[ctx->base_shader_ids[bs]].shader;
- s8 shader_name = ctx->shader_names.data[s->name_id];
+ s8 shader_name = ctx->entity_names.data[ctx->base_shader_ids[bs]];
- meta_begin_line(m, s8("read_only global u8 beamformer_shader_"));
- for (iz i = 0; i < shader_name.len; i++)
+ meta_begin_line(m, s8("read_only global u8 " META_NAMESPACE_LOWER "_shader_"));
+ for (i64 i = 0; i < shader_name.len; i++)
stream_append_byte(&m->stream, ToLower(shader_name.data[i]));
meta_begin_scope(m, s8("_bytes[] = {")); {
Arena scratch = m->scratch;
- s8 filename = push_s8_from_parts(&scratch, s8(OS_PATH_SEPARATOR), s8("shaders"), bs->file);
+ s8 filename = push_s8_from_parts(&scratch, s8(OS_PATH_SEPARATOR), s8("shaders"), s->file);
s8 file = read_entire_file((c8 *)filename.data, &scratch);
metagen_push_byte_array(m, file);
} meta_end_scope(m, s8("};\n"));
}
- meta_begin_scope(m, s8("read_only global s8 beamformer_shader_data[] = {")); {
- for (iz shader = 0; shader < ctx->base_shaders.count; shader++) {
- MetaBaseShader *bs = ctx->base_shaders.data + shader;
- MetaShader *s = bs->shader;
+ meta_begin_scope(m, s8("read_only global s8 " META_NAMESPACE_LOWER "_shader_data[] = {")); {
+ for (da_count bs = 0; bs < ctx->base_shader_count; bs++) {
+ s8 shader_name = ctx->entity_names.data[ctx->base_shader_ids[bs]];
- s8 shader_name = ctx->shader_names.data[s->name_id];
-
- meta_begin_line(m, s8("{.data = beamformer_shader_"));
+ meta_begin_line(m, s8("{.data = " META_NAMESPACE_LOWER "_shader_"));
for (iz i = 0; i < shader_name.len; i++)
stream_append_byte(&m->stream, ToLower(shader_name.data[i]));
- meta_push(m, s8("_bytes, .len = countof(beamformer_shader_"));
+ meta_push(m, s8("_bytes, .len = countof(" META_NAMESPACE_LOWER "_shader_"));
for (iz i = 0; i < shader_name.len; i++)
stream_append_byte(&m->stream, ToLower(shader_name.data[i]));
meta_end_line(m, s8("_bytes)},"));
@@ -3004,11 +3240,11 @@ metagen_emit_c_code(MetaContext *ctx, Arena arena)
// NOTE(rnp): shader baking
{
char *out_shaders = "generated" OS_PATH_SEPARATOR "beamformer_shaders.c";
- char **deps = push_array(&m->scratch, char *, 2 * ctx->base_shaders.count);
+ char **deps = push_array(&m->scratch, char *, 2 * ctx->base_shader_count);
u32 dep_count = 0;
- for (iz i = 0; i < ctx->base_shaders.count; i++) {
- MetaBaseShader *b = ctx->base_shaders.data + i;
- deps[dep_count++] = (c8 *)push_s8_from_parts(&m->scratch, s8(OS_PATH_SEPARATOR), s8("shaders"), b->file).data;
+ for (da_count bs = 0; bs < ctx->base_shader_count; bs++) {
+ MetaShader *s = &ctx->entities.data[ctx->base_shader_ids[bs]].shader;
+ deps[dep_count++] = (c8 *)push_s8_from_parts(&m->scratch, s8(OS_PATH_SEPARATOR), s8("shaders"), s->file).data;
}
if (needs_rebuild_(out_shaders, deps, dep_count)) {
build_log_generate("Bake Shaders");
@@ -3027,55 +3263,109 @@ metagen_emit_c_code(MetaContext *ctx, Arena arena)
meta_push(m, c_file_header);
/////////////////////////
- // NOTE(rnp): enumerants
- for (iz kind = 0; kind < ctx->enumeration_kinds.count; kind++) {
- s8 enum_name = push_s8_from_parts(&m->scratch, s8(""), s8("Beamformer"), ctx->enumeration_kinds.data[kind]);
- metagen_push_c_enum(m, m->scratch, enum_name, ctx->enumeration_members.data[kind].data,
- ctx->enumeration_members.data[kind].count);
+ // NOTE(rnp): constants
+ {
+ u32 integers = 0;
+ u32 floats = 0;
+
+ for (da_count constant = 0; constant < ctx->entity_kind_counts[MetaEntityKind_Constant]; constant++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_Constant][constant];
+ MetaEntity *e = ctx->entities.data + id;
+ if (e->constant.kind == MetaConstantKind_Integer) integers++;
+ if (e->constant.kind == MetaConstantKind_Float) floats++;
+ }
+
+ u32 row_alloc_count = Max(integers, floats);
+ s8 *columns[2];
+ columns[0] = push_array(&m->scratch, s8, row_alloc_count);
+ columns[1] = push_array(&m->scratch, s8, row_alloc_count);
+
+ u32 row_count;
+
+ row_count = 0;
+ meta_push_line(m, s8("// NOTE: Constants (Integer)"));
+ for (da_count constant = 0; constant < ctx->entity_kind_counts[MetaEntityKind_Constant]; constant++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_Constant][constant];
+ MetaEntity *e = ctx->entities.data + id;
+ if (e->constant.kind == MetaConstantKind_Integer) {
+ Stream sb = arena_stream(m->scratch);
+ stream_append_s8(&sb, s8("("));
+ stream_append_u64(&sb, e->constant.U64);
+ columns[0][row_count] = ctx->entity_names.data[id];
+ columns[1][row_count] = arena_stream_commit(&m->scratch, &sb);
+ row_count++;
+ }
+ }
+ metagen_push_table(m, m->scratch, s8("#define " META_NAMESPACE_UPPER), s8(")"), columns, row_count, 2);
+
+ row_count = 0;
+ meta_push_line(m, s8("\n// NOTE: Constants (Float)"));
+ for (da_count constant = 0; constant < ctx->entity_kind_counts[MetaEntityKind_Constant]; constant++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_Constant][constant];
+ MetaEntity *e = ctx->entities.data + id;
+ if (e->constant.kind == MetaConstantKind_Float) {
+ Stream sb = arena_stream(m->scratch);
+ stream_append_s8(&sb, s8("("));
+ stream_append_f64(&sb, e->constant.F64, 1000000);
+ columns[0][row_count] = ctx->entity_names.data[id];
+ columns[1][row_count] = arena_stream_commit(&m->scratch, &sb);
+ row_count++;
+ }
+ }
+ metagen_push_table(m, m->scratch, s8("#define " META_NAMESPACE_UPPER), s8(")"), columns, row_count, 2);
+
m->scratch = ctx->scratch;
}
+ meta_push(m, s8("\n"));
- for (iz shader = 0; shader < ctx->base_shaders.count; shader++) {
- MetaShader *s = ctx->base_shaders.data[shader].shader;
- s8_list *flag_list = ctx->flags_for_shader.data + s->flag_list_id;
- if (flag_list->count) {
- s8 enum_name = push_s8_from_parts(&m->scratch, s8(""), s8("BeamformerShader"),
- ctx->shader_names.data[s->name_id], s8("Flags"));
- metagen_push_c_flag_enum(m, m->scratch, enum_name, flag_list->data, flag_list->count);
- m->scratch = ctx->scratch;
- }
+ /////////////////////////
+ // NOTE(rnp): enumerants
+ for (da_count kind = 0; kind < ctx->entity_kind_counts[MetaEntityKind_Enumeration]; kind++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_Enumeration][kind];
+ MetaEntity *e = ctx->entities.data + id;
+
+ s8 enum_name = push_s8_from_parts(&m->scratch, s8(""), s8(META_NAMESPACE_UPPER),
+ ctx->entity_names.data[id]);
+ metagen_push_c_enum(m, m->scratch, enum_name, e->table.entries[0], e->table.entry_count);
+ m->scratch = ctx->scratch;
}
{
- s8 kind = s8("BeamformerShaderKind");
- s8 kind_full = s8("BeamformerShaderKind_");
+ s8 kind = s8(META_NAMESPACE_UPPER "ShaderKind");
+ s8 kind_full = s8(META_NAMESPACE_UPPER "ShaderKind_");
meta_begin_scope(m, s8("typedef enum {"));
- metagen_push_counted_enum_body(m, kind_full, s8(""), s8("= "), s8(","),
- ctx->shader_names.data, ctx->shader_names.count);
+ metagen_push_counted_enum_body_from_ids(m, kind_full, s8(""), s8("= "), s8(","),
+ ctx->entity_kind_ids[MetaEntityKind_Shader], ctx->entity_names.data,
+ ctx->entity_kind_counts[MetaEntityKind_Shader]);
meta_push_line(m, kind_full, s8("Count,\n"));
s8 *columns[2];
- columns[0] = push_array(&m->scratch, s8, ctx->shader_groups.count * 3);
- columns[1] = push_array(&m->scratch, s8, ctx->shader_groups.count * 3);
+ columns[0] = push_array(&m->scratch, s8, ctx->entity_kind_counts[MetaEntityKind_ShaderGroup] * 3);
+ columns[1] = push_array(&m->scratch, s8, ctx->entity_kind_counts[MetaEntityKind_ShaderGroup] * 3);
u32 rows = 0;
- for (iz group = 0; group < ctx->shader_groups.count; group++) {
- MetaShaderGroup *sg = ctx->shader_groups.data + group;
+ for (da_count group = 0; group < ctx->entity_kind_counts[MetaEntityKind_ShaderGroup]; group++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_ShaderGroup][group];
+ MetaEntityID child = ctx->entities.data[id].first_child;
+ s8 name = ctx->entity_names.data[id];
- if (sg->shaders.count > 0) {
- s8 first_name = ctx->shader_names.data[ctx->shaders.data[sg->shaders.data[0]].name_id];
- s8 last_name = ctx->shader_names.data[ctx->shaders.data[sg->shaders.data[sg->shaders.count - 1]].name_id];
+ da_count shader_count = meta_entity_children_count(ctx, (MetaEntityID){.value = id});
- columns[0][3 * group + 0] = push_s8_from_parts(&m->scratch, s8(""), kind, s8("_"), sg->name, s8("First"));
+ if (child.value != 0) {
+ // NOTE(rnp): childen pushed in LIFO order
+ s8 first_name = ctx->entity_names.data[ctx->entities.data[child.value].previous_sibling.value];
+ s8 last_name = ctx->entity_names.data[child.value];
+
+ columns[0][3 * group + 0] = push_s8_from_parts(&m->scratch, s8(""), kind, s8("_"), name, s8("First"));
columns[1][3 * group + 0] = push_s8_from_parts(&m->scratch, s8(""), s8("= "), kind, s8("_"), first_name);
- columns[0][3 * group + 1] = push_s8_from_parts(&m->scratch, s8(""), kind, s8("_"), sg->name, s8("Last"));
+ columns[0][3 * group + 1] = push_s8_from_parts(&m->scratch, s8(""), kind, s8("_"), name, s8("Last"));
columns[1][3 * group + 1] = push_s8_from_parts(&m->scratch, s8(""),s8("= "), kind, s8("_"), last_name);
- columns[0][3 * group + 2] = push_s8_from_parts(&m->scratch, s8(""), kind, s8("_"), sg->name, s8("Count"));
+ columns[0][3 * group + 2] = push_s8_from_parts(&m->scratch, s8(""), kind, s8("_"), name, s8("Count"));
Stream sb = arena_stream(m->scratch);
stream_append_s8(&sb, s8("= "));
- stream_append_u64(&sb, (u64)sg->shaders.count);
+ stream_append_i64(&sb, shader_count);
columns[1][3 * group + 2] = arena_stream_commit(&m->scratch, &sb);
rows += 3;
@@ -3089,204 +3379,142 @@ metagen_emit_c_code(MetaContext *ctx, Arena arena)
//////////////////////
// NOTE(rnp): structs
- for (u32 bake = 0; bake < ctx->shader_bake_parameters.count; bake++) {
- Arena tmp = m->scratch;
-
- // NOTE: Bake Parameters
- MetaShaderBakeParameters *b = ctx->shader_bake_parameters.data + bake;
- MetaShader *s = ctx->shaders.data + b->shader_id;
- s8 name = push_s8_from_parts(&m->scratch, s8(""), s8("BeamformerShader"),
- ctx->shader_names.data[s->name_id], s8("BakeParameters"));
- meta_begin_scope(m, s8("typedef struct {"));
- for (u32 entry = 0; entry < b->entry_count; entry++) {
- s8 kind = (b->floating_point & (1 << entry))? s8("f32 ") : s8("u32 ");
- meta_push_line(m, kind, b->names_lower[entry], s8(";"));
+ {
+ MetaEntityKind struct_kinds[] = {MetaEntityKind_Struct, MetaEntityKind_PushConstants, MetaEntityKind_BakeParameters};
+ da_count element_ids[] = {MetaStructField_Elements, MetaStructField_Elements, -1};
+ da_count name_ids[] = {MetaStructField_Name, MetaStructField_Name, MetaBakeField_NameLower};
+ for EachElement(struct_kinds, kind_it) {
+ for (da_count it = 0; it < ctx->entity_kind_counts[struct_kinds[kind_it]]; it++) {
+ da_count entity = ctx->entity_kind_ids[struct_kinds[kind_it]][it];
+
+ MetaEntity *e = ctx->entities.data + entity;
+ meta_begin_scope(m, s8("typedef struct {")); {
+ s8 *elements = element_ids[kind_it] < 0 ? 0 : e->table.entries[element_ids[kind_it]];
+
+ metagen_push_struct_body(m, &e->table, meta_kind_c_types, e->table.entries[name_ids[kind_it]],
+ elements, s8(""), s8(""), s8(META_NAMESPACE_UPPER));
+ } meta_end_scope(m, s8("} " META_NAMESPACE_UPPER), ctx->entity_names.data[entity], s8(";"));
+ meta_push(m, s8("\n"));
}
- meta_end_scope(m, s8("} "), name, s8(";\n"));
- m->scratch = tmp;
- }
-
-
- for (iz base_shader = 0; base_shader < ctx->base_shaders.count; base_shader++) {
- Arena tmp = m->scratch;
-
- // NOTE: Push Constants
- MetaShader *s = ctx->base_shaders.data[base_shader].shader;
- if (s->push_constants_id != (u32)-1) {
- MetaEmitOperationList ops[1] = {0};
- MetaTable *pc = ctx->push_constant_tables.data + s->push_constants_id;
-
- MetaEmitOperation *op = da_push(&m->scratch, ops);
- op->kind = MetaEmitOperationKind_String;
- op->string = s8("typedef struct {");
-
- s8 expr = s8(" $(%type)$(|)$(name);");
-
- MetaExpansionPartList parts = meta_generate_expansion_set(ctx, &m->scratch, expr, pc, META_CURRENT_LOCATION);
- op = da_push(&m->scratch, ops);
- op->kind = MetaEmitOperationKind_Expand;
- op->expansion_operation.parts = parts.data;
- op->expansion_operation.part_count = (u32)parts.count;
- op->expansion_operation.table_id = s->push_constants_id;
-
- op = da_push(&m->scratch, ops);
- op->kind = MetaEmitOperationKind_String;
- op->string = push_s8_from_parts(&m->scratch, s8(""), s8("} BeamformerShader"),
- ctx->shader_names.data[s->name_id], s8("PushConstants;"));
-
- metagen_run_emit(m, ctx, ops, &ctx->push_constant_tables, meta_kind_c_types);
}
-
- m->scratch = tmp;
}
- // shader bake parameter struct
- meta_begin_scope(m, s8("typedef struct {"));
+ // NOTE: shader bake parameter union
+ meta_begin_scope(m, s8("typedef union {"));
{
- meta_begin_scope(m, s8("union {"));
+ Arena scratch;
+ DeferLoop(scratch = m->scratch, m->scratch = scratch)
{
- Arena tmp = m->scratch;
s8 *columns[2];
- columns[0] = push_array(&m->scratch, s8, ctx->shader_bake_parameters.count);
- columns[1] = push_array(&m->scratch, s8, ctx->shader_bake_parameters.count);
- for (u32 bake = 0; bake < ctx->shader_bake_parameters.count; bake++) {
- MetaShaderBakeParameters *b = ctx->shader_bake_parameters.data + bake;
- MetaShader *s = ctx->shaders.data + b->shader_id;
- columns[0][bake] = push_s8_from_parts(&m->scratch, s8(""), s8("BeamformerShader"),
- ctx->shader_names.data[s->name_id], s8("BakeParameters"));
- columns[1][bake] = ctx->shader_names.data[s->name_id];
+ columns[0] = push_array(&m->scratch, s8, ctx->entity_kind_counts[MetaEntityKind_BakeParameters]);
+ columns[1] = push_array(&m->scratch, s8, ctx->entity_kind_counts[MetaEntityKind_BakeParameters]);
+
+ for (da_count bake = 0; bake < ctx->entity_kind_counts[MetaEntityKind_BakeParameters]; bake++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_BakeParameters][bake];
+
+ s8 bake_name = ctx->entity_names.data[id];
+ s8 shader_name = {.data = bake_name.data, .len = bake_name.len - s8("BakeParameters").len};
+
+ columns[0][bake] = push_s8_from_parts(&m->scratch, s8(""), s8(META_NAMESPACE_UPPER), bake_name);
+ columns[1][bake] = shader_name;
}
metagen_push_table(m, m->scratch, s8(""), s8(";"), columns,
- (uz)ctx->shader_bake_parameters.count, 2);
- m->scratch = tmp;
- } meta_end_scope(m, s8("};"));
- s8 names[] = {s8("data_kind"), s8("flags")};
- s8 types[] = {s8("u32"), s8("u32")};
- metagen_push_table(m, m->scratch, s8(""), s8(";"), (s8 *[]){types, names}, countof(names), 2);
- } meta_end_scope(m, s8("} BeamformerShaderBakeParameters;\n"));
+ ctx->entity_kind_counts[MetaEntityKind_BakeParameters], 2);
+ }
+ } meta_end_scope(m, s8("} " META_NAMESPACE_UPPER "ShaderBakeParameters;\n"));
metagen_run_emit_set(m, ctx, ctx->emit_sets + MetaEmitLang_C, meta_kind_c_types);
/////////////////////////////////
// NOTE(rnp): shader info tables
- meta_begin_scope(m, s8("read_only global s8 beamformer_shader_names[] = {"));
- metagen_push_table(m, m->scratch, s8("s8_comp(\""), s8("\"),"), &ctx->shader_names.data,
- (uz)ctx->shader_names.count, 1);
- meta_end_scope(m, s8("};\n"));
+ meta_begin_scope(m, s8("read_only global s8 " META_NAMESPACE_LOWER "_shader_names[] = {"));
+ for (da_count shader = 0; shader < ctx->entity_kind_counts[MetaEntityKind_Shader]; shader++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_Shader][shader];
+ meta_push_line(m, s8("s8_comp(\""), ctx->entity_names.data[id], s8("\"),"));
+ } meta_end_scope(m, s8("};\n"));
meta_push_shader_reload_info(m, ctx);
- meta_begin_scope(m, s8("read_only global i32 *beamformer_shader_header_vectors[] = {"));
- for (iz shader = 0; shader < ctx->base_shaders.count; shader++) {
- MetaShader *s = ctx->base_shaders.data[shader].shader;
- if (s->shader_enumeration_ids.count) {
- meta_begin_line(m, s8("(i32 []){"));
- for (iz id = 0; id < s->shader_enumeration_ids.count; id++) {
- if (id != 0) meta_push(m, s8(", "));
- meta_push_u64(m, s->shader_enumeration_ids.data[id]);
+ meta_begin_scope(m, s8("read_only global i32 *" META_NAMESPACE_LOWER "_shader_header_vectors[] = {"));
+ {
+ for (da_count bs = 0; bs < ctx->base_shader_count; bs++) {
+ da_count id = ctx->base_shader_ids[bs];
+ MetaShader *s = &ctx->entities.data[id].shader;
+ if (s->entity_reference_ids.count) {
+ meta_begin_line(m, s8("(i32 []){"));
+ for (da_count ref_id = 0; ref_id < s->entity_reference_ids.count; ref_id++) {
+ if (ref_id != 0) meta_push(m, s8(", "));
+ MetaEntityReference *r = &ctx->entities.data[s->entity_reference_ids.data[ref_id]].reference;
+ meta_push_i64(m, meta_lookup_id_slow(ctx->shader_entity_references.data,
+ ctx->shader_entity_references.count,
+ r->resolved_id.value));
+ }
+ meta_end_line(m, s8("},"));
+ } else {
+ meta_push_line(m, s8("0,"));
}
- meta_end_line(m, s8("},"));
- } else {
- meta_push_line(m, s8("0,"));
- }
- }
- meta_end_scope(m, s8("};\n"));
-
- meta_begin_scope(m, s8("read_only global i32 beamformer_shader_header_vector_lengths[] = {"));
- for (iz shader = 0; shader < ctx->base_shaders.count; shader++) {
- MetaShader *s = ctx->base_shaders.data[shader].shader;
- meta_indent(m);
- meta_push_u64(m, (u64)s->shader_enumeration_ids.count);
- meta_end_line(m, s8(","));
- }
- meta_end_scope(m, s8("};\n"));
-
- meta_begin_scope(m, s8("read_only global s8 *beamformer_shader_bake_parameter_names[] = {"));
- for (iz shader = 0; shader < ctx->base_shaders.count; shader++) {
- MetaShader *s = ctx->base_shaders.data[shader].shader;
- if (s->bake_parameters) {
- metagen_emit_c_s8_list(m, s->bake_parameters->names_upper, s->bake_parameters->entry_count);
- } else {
- meta_push_line(m, s8("0,"));
}
- }
- meta_end_scope(m, s8("};\n"));
-
- meta_begin_scope(m, s8("read_only global u32 beamformer_shader_bake_parameter_float_bits[] = {"));
- for (iz shader = 0; shader < ctx->base_shaders.count; shader++) {
- MetaShader *s = ctx->base_shaders.data[shader].shader;
- u32 hex = 0;
- if (s->bake_parameters)
- hex = s->bake_parameters->floating_point;
- meta_begin_line(m, s8("0x"));
- meta_push_u64_hex_width(m, hex, 8);
- meta_end_line(m, s8("UL,"));
- }
- meta_end_scope(m, s8("};\n"));
+ } meta_end_scope(m, s8("};\n"));
- meta_begin_scope(m, s8("read_only global i32 beamformer_shader_bake_parameter_counts[] = {"));
- for (iz shader = 0; shader < ctx->base_shaders.count; shader++) {
- MetaShader *s = ctx->base_shaders.data[shader].shader;
- if (s->bake_parameters) {
+ meta_begin_scope(m, s8("read_only global i32 " META_NAMESPACE_LOWER "_shader_header_vector_lengths[] = {"));
+ {
+ for (da_count bs= 0; bs < ctx->base_shader_count; bs++) {
+ da_count id = ctx->base_shader_ids[bs];
+ MetaShader *s = &ctx->entities.data[id].shader;
meta_indent(m);
- meta_push_u64(m, s->bake_parameters->entry_count);
+ meta_push_i64(m, s->entity_reference_ids.count);
meta_end_line(m, s8(","));
- } else {
- meta_push_line(m, s8("0,"));
}
- }
- meta_end_scope(m, s8("};\n"));
+ } meta_end_scope(m, s8("};\n"));
- meta_begin_scope(m, s8("read_only global s8 *beamformer_shader_push_constant_glsl_types[] = {"));
- for (iz shader = 0; shader < ctx->base_shaders.count; shader++) {
- MetaShader *s = ctx->base_shaders.data[shader].shader;
- if (s->push_constants_id != (u32)-1) {
- MetaTable *pc = ctx->push_constant_tables.data + s->push_constants_id;
- iz field = meta_lookup_string_slow(pc->fields, pc->field_count, s8("glsl_type"));
- metagen_emit_c_s8_list(m, pc->entries[field], pc->entry_count);
- } else {
- meta_push_line(m, s8("0,"));
+ meta_begin_scope(m, s8("read_only global s8 *" META_NAMESPACE_LOWER "_shader_bake_parameter_names[] = {"));
+ {
+ 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);
+ if (bp_id.value != 0) {
+ MetaEntity *bp = meta_entity(ctx, bp_id);
+ metagen_emit_c_s8_list(m, bp->table.entries[MetaBakeField_NameUpper], bp->table.entry_count);
+ } else {
+ meta_push_line(m, s8("0,"));
+ }
}
- }
- meta_end_scope(m, s8("};\n"));
+ } meta_end_scope(m, s8("};\n"));
- meta_begin_scope(m, s8("read_only global s8 *beamformer_shader_push_constant_names[] = {"));
- for (iz shader = 0; shader < ctx->base_shaders.count; shader++) {
- MetaShader *s = ctx->base_shaders.data[shader].shader;
- if (s->push_constants_id != (u32)-1) {
- MetaTable *pc = ctx->push_constant_tables.data + s->push_constants_id;
- iz field = meta_lookup_string_slow(pc->fields, pc->field_count, s8("name"));
- metagen_emit_c_s8_list(m, pc->entries[field], pc->entry_count);
- } else {
- meta_push_line(m, s8("0,"));
+ meta_begin_scope(m, s8("read_only global u32 " META_NAMESPACE_LOWER "_shader_bake_parameter_float_bits[] = {"));
+ {
+ 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;
+ for (u32 entry = 0; entry < t->entry_count; entry++)
+ if (t->struct_type_ids[entry] == MetaKind_F32)
+ hex |= 1 << entry;
+ }
+ meta_begin_line(m, s8("0x"));
+ meta_push_u64_hex_width(m, hex, 8);
+ meta_end_line(m, s8("UL,"));
}
- }
- meta_end_scope(m, s8("};\n"));
+ } meta_end_scope(m, s8("};\n"));
- meta_begin_scope(m, s8("read_only global u8 beamformer_shader_push_constant_counts[] = {"));
- for (iz shader = 0; shader < ctx->base_shaders.count; shader++) {
- MetaShader *s = ctx->base_shaders.data[shader].shader;
- if (s->push_constants_id != (u32)-1) {
+ meta_begin_scope(m, s8("read_only global u8 " META_NAMESPACE_LOWER "_shader_bake_parameter_counts[] = {"));
+ {
+ 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, ctx->push_constant_tables.data[s->push_constants_id].entry_count);
+ meta_push_u64(m, count);
meta_end_line(m, s8(","));
- } else {
- meta_push_line(m, s8("0,"));
}
- }
- meta_end_scope(m, s8("};\n"));
-
- meta_begin_scope(m, s8("read_only global u8 beamformer_shader_push_constant_sizes[] = {"));
- for (iz shader = 0; shader < ctx->base_shaders.count; shader++) {
- MetaShader *s = ctx->base_shaders.data[shader].shader;
- if (s->push_constants_id != (u32)-1) {
- meta_push_line(m, s8("sizeof(BeamformerShader"), ctx->shader_names.data[s->name_id],
- s8("PushConstants),"));
- } else {
- meta_push_line(m, s8("0,"));
- }
- }
- meta_end_scope(m, s8("};\n"));
+ } meta_end_scope(m, s8("};\n"));
//fprintf(stderr, "%.*s\n", (i32)m.stream.widx, m.stream.data);
@@ -3301,64 +3529,53 @@ metagen_matlab_union(MetaprogramContext *m, MetaContext *ctx, MetaMUnion *mu, s8
b32 result = 1;
Arena scratch = m->scratch;
- iz enumeration_id = meta_lookup_string_slow(ctx->enumeration_kinds.data, ctx->enumeration_kinds.count,
- mu->enumeration_name);
+ i32 enumeration_id = -1;
+ for (da_count it = 0; it < ctx->entity_kind_counts[MetaEntityKind_Enumeration]; it++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_Enumeration][it];
+ if (s8_equal(mu->enumeration_name, ctx->entity_names.data[id])) {
+ enumeration_id = id;
+ break;
+ }
+ }
+
if (enumeration_id < 0) {
meta_compiler_error(mu->location, "Kind Enumeration '%.*s' requested by @MUnion not defined\n",
(i32)mu->enumeration_name.len, mu->enumeration_name.data);
}
- s8_list *enumeration_members = ctx->enumeration_members.data + enumeration_id;
- if ((u32)enumeration_members->count != mu->sub_table_count) {
+ MetaTable *etable = &ctx->entities.data[enumeration_id].table;
+ if (etable->entry_count != mu->sub_table_count) {
meta_compiler_error(mu->location, "'%.*s' contains %u members but %u were requested by @MUnion\n",
(i32)mu->enumeration_name.len, mu->enumeration_name.data,
- (u32)enumeration_members->count, mu->sub_table_count);
+ etable->entry_count, mu->sub_table_count);
}
- struct table_match {
- MetaTable *table;
- MetaKind *kinds;
- u32 name_index;
- } *table_matches;
-
- table_matches = push_array(&scratch, struct table_match, mu->sub_table_count);
+ MetaTable **table_matches = push_array(&scratch, MetaTable *, mu->sub_table_count);
for (u32 index = 0; index < mu->sub_table_count; index++) {
s8 sub_table_name = mu->sub_table_names[index];
- MetaTable *t = ctx->tables.data + meta_lookup_string_slow(ctx->table_names.data,
- ctx->table_names.count, sub_table_name);
- if (t < ctx->tables.data) {
- meta_compiler_error(mu->location, "Parameter Table '%.*s' requested by @MUnion not defined\n",
- (i32)sub_table_name.len, sub_table_name.data);
+ da_count struct_id = -1;
+ for (da_count it = 0; it < ctx->entity_kind_counts[MetaEntityKind_Struct]; it++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_Struct][it];
+ if (s8_equal(sub_table_name, ctx->entity_names.data[id])) {
+ struct_id = it;
+ break;
+ }
}
- iz type_index = meta_lookup_string_slow(t->fields, t->field_count, s8("type"));
- iz name_index = meta_lookup_string_slow(t->fields, t->field_count, s8("name"));
- if (type_index < 0) {
- meta_compiler_error_message(mu->location, "'%.*s' missing fields required by @MUnion: type\n",
- (i32)sub_table_name.len, sub_table_name.data);
- }
- if (name_index < 0) {
- meta_compiler_error_message(mu->location, "'%.*s' missing fields required by @MUnion: name\n",
- (i32)sub_table_name.len, sub_table_name.data);
+ if (struct_id < 0) {
+ meta_compiler_error(mu->location, "Struct '%.*s' requested by @MUnion not defined\n",
+ (i32)sub_table_name.len, sub_table_name.data);
}
- if (type_index < 0 || name_index < 0) meta_error();
- table_matches[index].table = t;
- table_matches[index].kinds = push_array(&scratch, MetaKind, t->entry_count);
- table_matches[index].name_index = (u32)name_index;
-
- for (u32 entry = 0; entry < t->entry_count; entry++) {
- table_matches[index].kinds[entry] = meta_map_kind(t->entries[type_index][entry], sub_table_name,
- mu->location);
- }
+ table_matches[index] = &ctx->entities.data[struct_id].table;
}
u32 max_parameter_size = 0;
- for (iz member = 0; member < enumeration_members->count; member++) {
+ for (u32 member = 0; member < etable->entry_count; member++) {
u32 parameter_size = 0;
- for (u32 prop = 0; prop < table_matches[member].table->entry_count; prop++)
- parameter_size += meta_kind_byte_sizes[table_matches[member].kinds[prop]];
- max_parameter_size = MAX(parameter_size, max_parameter_size);
+ for (u32 prop = 0; prop < table_matches[member]->entry_count; prop++)
+ parameter_size += meta_kind_byte_sizes[table_matches[member]->struct_type_ids[prop]];
+ max_parameter_size = Max(parameter_size, max_parameter_size);
}
Arena scratch_temp = scratch;
@@ -3388,21 +3605,19 @@ metagen_matlab_union(MetaprogramContext *m, MetaContext *ctx, MetaMUnion *mu, s8
result &= meta_end_and_write_matlab(m, (c8 *)outfile.data);
scratch = scratch_temp;
- for (iz member = 0; member < enumeration_members->count; member++) {
- MetaTable *t = table_matches[member].table;
- MetaKind *kinds = table_matches[member].kinds;
+ for (u32 member = 0; member < etable->entry_count; member++) {
+ MetaTable *t = table_matches[member];
- s8 sub_name = enumeration_members->data[member];
+ s8 sub_name = etable->entries[0][member];
outfile = push_s8_from_parts(&scratch, s8(""), outdir, s8(OS_PATH_SEPARATOR), sub_name, s8(".m"));
- meta_begin_scope(m, s8("classdef "), sub_name, s8(" < OGLBeamformer"), namespace, s8(".Base"));
+ meta_begin_scope(m, s8("classdef "), sub_name, s8(" < OGL" META_NAMESPACE_UPPER), namespace, s8(".Base"));
{
meta_begin_scope(m, s8("properties"));
{
- u32 name_index = table_matches[member].name_index;
for (u32 prop = 0; prop < t->entry_count; prop++) {
- meta_begin_line(m, t->entries[name_index][prop], s8("(1,"));
- meta_push_u64(m, meta_kind_elements[kinds[prop]]);
- meta_end_line(m, s8(") "), meta_kind_matlab_types[kinds[prop]]);
+ meta_begin_line(m, t->entries[MetaStructField_Name][prop], s8("(1,"));
+ meta_push_u64(m, meta_kind_elements[t->struct_type_ids[prop]]);
+ meta_end_line(m, s8(") "), meta_kind_matlab_types[t->struct_type_ids[prop]]);
}
} meta_end_scope(m, s8("end"));
} meta_end_scope(m, s8("end"));
@@ -3452,35 +3667,52 @@ metagen_emit_matlab_code(MetaContext *ctx, Arena arena)
meta_begin_matlab_class(m, "OGLBeamformerShaderStage", "int32");
meta_begin_scope(m, s8("enumeration"));
{
- iz index = -1;
- for (iz group = 0; group < ctx->shader_groups.count; group++) {
- if (s8_equal(ctx->shader_groups.data[group].name, s8("Compute"))) {
- index = group;
+ da_count group_id = -1;
+ for (da_count group = 0; group < ctx->entity_kind_counts[MetaEntityKind_ShaderGroup]; group++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_ShaderGroup][group];
+ s8 group_name = ctx->entity_names.data[id];
+ if (s8_equal(group_name, s8("Compute"))) {
+ group_id = id;
break;
}
}
- if (index != -1) {
- MetaShaderGroup *sg = ctx->shader_groups.data + index;
- /* TODO(rnp): this assumes that the shaders are sequential */
- s8 *names = ctx->shader_names.data + ctx->shaders.data[0].name_id;
- metagen_push_counted_enum_body(m, s8(""), s8(""), s8("("), s8(")"), names, sg->shaders.count);
+ if (group_id != -1) {
+ da_count children = meta_entity_children_count(ctx, (MetaEntityID){.value = group_id});
+ if (children > 0) {
+ da_count *ids = push_array(&m->scratch, da_count, children);
+
+ // NOTE(rnp): children are pushed in LIFO order
+ da_count index = 0;
+ MetaEntityID child = ctx->entities.data[group_id].first_child;
+ do {
+ child = ctx->entities.data[child.value].previous_sibling;
+ ids[index++] = child.value;
+ } while (child.value != ctx->entities.data[group_id].first_child.value);
+
+ metagen_push_counted_enum_body_from_ids(m, s8(""), s8(""), s8("("), s8(")"), ids,
+ ctx->entity_names.data, children);
+ m->scratch = ctx->scratch;
+ }
} else {
build_log_failure("failed to find Compute shader group in meta info\n");
}
- result &= index != -1;
+ result &= group_id != -1;
}
result &= meta_end_and_write_matlab(m, OUTPUT("matlab/OGLBeamformerShaderStage.m"));
- for (iz kind = 0; kind < ctx->enumeration_kinds.count; kind++) {
+ for (da_count kind = 0; kind < ctx->entity_kind_counts[MetaEntityKind_Enumeration]; kind++) {
Arena scratch = ctx->scratch;
- s8 name = ctx->enumeration_kinds.data[kind];
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_Enumeration][kind];
+ s8 name = ctx->entity_names.data[id];
s8 output = push_s8_from_parts(&scratch, s8(""), s8(OUTPUT("matlab/OGLBeamformer")), name, s8(".m"));
- s8_list *kinds = ctx->enumeration_members.data + kind;
+
+ MetaTable *etable = &ctx->entities.data[id].table;
+ s8 *kinds = etable->entries[0];
meta_begin_scope(m, s8("classdef OGLBeamformer"), name, s8(" < int32"));
meta_begin_scope(m, s8("enumeration"));
s8 prefix = s8("");
- if (kinds->count > 0 && IsDigit(kinds->data[0].data[0])) prefix = s8("m");
- metagen_push_counted_enum_body(m, s8(""), prefix, s8("("), s8(")"), kinds->data, kinds->count);
+ if (etable->entry_count > 0 && IsDigit(kinds[0].data[0])) prefix = s8("m");
+ metagen_push_counted_enum_body(m, s8(""), prefix, s8("("), s8(")"), kinds, etable->entry_count);
result &= meta_end_and_write_matlab(m, (c8 *)output.data);
}
@@ -3488,14 +3720,14 @@ metagen_emit_matlab_code(MetaContext *ctx, Arena arena)
// NOTE: emit files
{
MetaEmitOperationListSet *emit_set = ctx->emit_sets + MetaEmitLang_MATLAB;
- for (u32 list = 0; list < emit_set->count; list++) {
+ for (da_count list = 0; list < emit_set->count; list++) {
MetaEmitOperationList *ops = emit_set->data + list;
Arena scratch = m->scratch;
s8 output = push_s8_from_parts(&m->scratch, s8(""),
s8(OUTPUT("matlab") OS_PATH_SEPARATOR "OGLBeamformer"),
ops->filename, s8(".m"));
meta_push_line(m, s8("% GENERATED CODE"));
- metagen_run_emit(m, ctx, ops, &ctx->tables, meta_kind_matlab_types);
+ metagen_run_emit(m, ctx, ops, meta_kind_matlab_types);
result &= meta_write_and_reset(m, (c8 *)output.data);
m->scratch = scratch;
}
@@ -3536,53 +3768,88 @@ metagen_emit_helper_library_header(MetaContext *ctx, Arena arena)
meta_push_line(m, s8("#include <stdint.h>\n"));
/////////////////////////
- // NOTE(rnp): enumarents
- for (iz kind = 0; kind < ctx->enumeration_kinds.count; kind++) {
- s8 enum_name = push_s8_from_parts(&m->scratch, s8(""), s8("Beamformer"), ctx->enumeration_kinds.data[kind]);
- metagen_push_c_enum(m, m->scratch, enum_name, ctx->enumeration_members.data[kind].data,
- ctx->enumeration_members.data[kind].count);
+ // NOTE(rnp): enumerents
+ {
+ u32 integers = 0;
+ for (da_count constant = 0; constant < ctx->entity_kind_counts[MetaEntityKind_Constant]; constant++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_Constant][constant];
+ MetaEntity *e = ctx->entities.data + id;
+ if (e->constant.kind == MetaConstantKind_Integer) integers++;
+ }
+
+ s8 *columns[2];
+ columns[0] = push_array(&m->scratch, s8, integers);
+ columns[1] = push_array(&m->scratch, s8, integers);
+
+ u32 row_count = 0;
+ meta_push_line(m, s8("// NOTE: Constants (Integer)"));
+ for (da_count constant = 0; constant < ctx->entity_kind_counts[MetaEntityKind_Constant]; constant++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_Constant][constant];
+ MetaEntity *e = ctx->entities.data + id;
+ if (e->constant.kind == MetaConstantKind_Integer) {
+ Stream sb = arena_stream(m->scratch);
+ stream_append_s8(&sb, s8("("));
+ stream_append_u64(&sb, e->constant.U64);
+ columns[0][row_count] = ctx->entity_names.data[id];
+ columns[1][row_count] = arena_stream_commit(&m->scratch, &sb);
+ row_count++;
+ }
+ }
+ metagen_push_table(m, m->scratch, s8("#define " META_NAMESPACE_UPPER), s8(")"), columns, row_count, 2);
+ }
+
+ /////////////////////////
+ // NOTE(rnp): enumerents
+ for (da_count kind = 0; kind < ctx->entity_kind_counts[MetaEntityKind_Enumeration]; kind++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_Enumeration][kind];
+ MetaEntity *e = ctx->entities.data + id;
+
+ s8 enum_name = push_s8_from_parts(&m->scratch, s8(""), s8(META_NAMESPACE_UPPER),
+ ctx->entity_names.data[id]);
+ metagen_push_c_enum(m, m->scratch, enum_name, e->table.entries[0], e->table.entry_count);
m->scratch = ctx->scratch;
}
{
- iz index = -1;
- for (iz group = 0; group < ctx->shader_groups.count; group++) {
- if (s8_equal(ctx->shader_groups.data[group].name, s8("Compute"))) {
- index = group;
+ da_count group_id = -1;
+ for (da_count group = 0; group < ctx->entity_kind_counts[MetaEntityKind_ShaderGroup]; group++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_ShaderGroup][group];
+ s8 group_name = ctx->entity_names.data[id];
+ if (s8_equal(group_name, s8("Compute"))) {
+ group_id = id;
break;
}
}
- if (index != -1) {
- u64 offset = 0;
- for (iz group = 0; group < index; group++)
- offset += (u64)ctx->shader_groups.data[group].shaders.count;
+ if (group_id != -1) {
+ da_count children = meta_entity_children_count(ctx, (MetaEntityID){.value = group_id});
+ if (children > 0) {
+ s8 kind = s8(META_NAMESPACE_UPPER "ShaderKind");
+ s8 kind_full = s8(META_NAMESPACE_UPPER "ShaderKind_");
- MetaShaderGroup *sg = ctx->shader_groups.data + index;
- s8 *columns[2];
- columns[0] = push_array(&m->scratch, s8, sg->shaders.count);
- columns[1] = push_array(&m->scratch, s8, sg->shaders.count);
+ da_count *ids = push_array(&m->scratch, da_count, children);
- Stream sb = arena_stream(m->scratch);
- for (iz id = 0; id < sg->shaders.count; id++) {
- stream_append_s8(&sb, s8("= "));
- stream_append_u64(&sb, offset + (u64)id);
-
- MetaShader *s = ctx->shaders.data + sg->shaders.data[id];
- columns[0][id] = ctx->shader_names.data[s->name_id];
- columns[1][id] = arena_stream_commit_and_reset(&m->scratch, &sb);
- }
+ // NOTE(rnp): children are pushed in LIFO order
+ da_count index = 0;
+ MetaEntityID child = ctx->entities.data[group_id].first_child;
+ do {
+ child = ctx->entities.data[child.value].previous_sibling;
+ ids[index++] = child.value;
+ } while (child.value != ctx->entities.data[group_id].first_child.value);
- meta_begin_scope(m, s8("typedef enum {"));
- metagen_push_table(m, m->scratch, s8("BeamformerShaderKind_"), s8(","), columns,
- (uz)sg->shaders.count, 2);
- meta_end_scope(m, s8("} BeamformerShaderKind;\n"));
+ meta_begin_scope(m, s8("typedef enum {"));
+ {
+ metagen_push_counted_enum_body_from_ids(m, kind_full, s8(""), s8("= "), s8(","), ids,
+ ctx->entity_names.data, children);
+ meta_push_line(m, kind_full, s8("Count,\n"));
+ } meta_end_scope(m, s8("} "), kind, s8(";\n"));
- m->scratch = ctx->scratch;
+ m->scratch = ctx->scratch;
- meta_begin_line(m, s8("#define BeamformerShaderKind_ComputeCount ("));
- meta_push_u64(m, (u64)sg->shaders.count);
- meta_end_line(m, s8(")\n"));
+ meta_begin_line(m, s8("#define "), kind_full, s8("ComputeCount ("));
+ meta_push_i64(m, children);
+ meta_end_line(m, s8(")\n"));
+ }
} else {
build_log_failure("failed to find Compute shader group in meta info\n");
}
@@ -3616,6 +3883,10 @@ metagen_load_context(Arena *arena, char *filename)
ctx->scratch = sub_arena(arena, MB(1), 16);
ctx->arena = arena;
+ // NOTE(rnp): nil entity
+ *da_push(ctx->arena, &ctx->entity_names) = s8("Nil");
+ da_push(ctx->arena, &ctx->entities);
+
MetaContext *result = ctx;
ctx->filename = c_str_to_s8(filename);
@@ -3626,43 +3897,39 @@ metagen_load_context(Arena *arena, char *filename)
Arena scratch = ctx->scratch;
MetaEntryStack entries = meta_entry_stack_from_file(ctx->arena, filename);
- i32 stack_items[32];
- struct { i32 *data; iz capacity; iz count; } stack = {stack_items, countof(stack_items), 0};
-
for (iz i = 0; i < entries.count; i++) {
MetaEntry *e = entries.data + i;
- //if (e->kind == MetaEntryKind_EndScope) depth--;
- //meta_entry_print(e, depth, -1);
- //if (e->kind == MetaEntryKind_BeginScope) depth++;
- //continue;
switch (e->kind) {
- case MetaEntryKind_BeginScope:{ *da_push(&scratch, &stack) = (i32)i; }break;
- case MetaEntryKind_EndScope:{ --stack.count; }break;
+ case MetaEntryKind_Constant:{
+ meta_pack_constant(ctx, e);
+ }break;
+
case MetaEntryKind_Emit:{
i += meta_pack_emit(ctx, scratch, e, entries.count - i);
}break;
- case MetaEntryKind_Enumeration:{
- meta_entry_argument_expected(e, s8("kind"), s8("[id ...]"));
- s8 kind = meta_entry_argument_expect(e, 0, MetaEntryArgumentKind_String).string;
- MetaEntryArgument ids = meta_entry_argument_expect(e, 1, MetaEntryArgumentKind_Array);
- for (u32 id = 0; id < ids.count; id++)
- meta_commit_enumeration(ctx, kind, ids.strings[id]);
- }break;
+
case MetaEntryKind_Embed:{
meta_embed(ctx, scratch, e, entries.count - i);
}break;
+
case MetaEntryKind_Expand:{
i += meta_expand(ctx, scratch, e, entries.count - i, 0);
}break;
+
case MetaEntryKind_MUnion:{
meta_pack_munion(ctx, e, entries.count - i);
}break;
+
case MetaEntryKind_ShaderGroup:{
i += meta_pack_shader_group(ctx, e, entries.count - i);
}break;
- case MetaEntryKind_Table:{
- i += meta_pack_table(ctx, e, entries.count - i);
+
+ case MetaEntryKind_Enumeration:
+ case MetaEntryKind_Struct:
+ case MetaEntryKind_Table:
+ {
+ i += meta_pack_table_entity(ctx, e, entries.count - i, e->name, meta_root_entity_id(ctx));
}break;
default:
@@ -3672,6 +3939,128 @@ metagen_load_context(Arena *arena, char *filename)
}
}
+ // NOTE(rnp): sort enitity ids into sub arrays
+ {
+ assert(ctx->entity_kind_counts[MetaEntityKind_Nil] == 0);
+
+ for EachNonZeroEnumValue(MetaEntityKind, it) {
+ if (ctx->entity_kind_counts[it]) {
+ ctx->entity_kind_ids[it] = push_array(ctx->arena, typeof(*ctx->entity_kind_ids[it]), ctx->entity_kind_counts[it]);
+ }
+ }
+
+ da_count entity_counts[MetaEntityKind_Count] = {0};
+ for (da_count entity = 1; entity < ctx->entities.count; entity++) {
+ MetaEntity *e = ctx->entities.data + entity;
+ da_count index = entity_counts[e->kind]++;
+ ctx->entity_kind_ids[e->kind][index] = da_index(e, &ctx->entities);
+ }
+ }
+
+ // NOTE(rnp): resolve reference entities
+ {
+ for (da_count entity = 0; entity < ctx->entity_kind_counts[MetaEntityKind_Reference]; entity++) {
+ MetaEntity *e = ctx->entities.data + ctx->entity_kind_ids[MetaEntityKind_Reference][entity];
+ da_count reference_id = meta_lookup_string_slow(ctx->entity_names.data, ctx->entity_names.count, e->reference.reference_name);
+ if (reference_id >= 0)
+ e->reference.resolved_id.value = reference_id;
+ }
+
+ b32 error = 0;
+ for (da_count entity = 0; entity < ctx->entity_kind_counts[MetaEntityKind_Reference]; entity++) {
+ MetaEntity *e = ctx->entities.data + ctx->entity_kind_ids[MetaEntityKind_Reference][entity];
+ MetaEntityReference *r = &e->reference;
+ if (e->reference.resolved_id.value == 0) {
+ meta_compiler_error_message(e->location, "undefined reference%s to '%.*s'\n",
+ r->reference_count > 1? "s" : "",
+ (i32)r->reference_name.len, r->reference_name.data);
+ if (r->reference_count > 1)
+ meta_compiler_message(" referenced in %d other places\n", r->reference_count - 1);
+ error = 1;
+ }
+ }
+ if (error) meta_error();
+ }
+
+ // NOTE(rnp): extract entities referenced by shaders
+ {
+ for (da_count shader = 0; shader < ctx->entity_kind_counts[MetaEntityKind_Shader]; shader++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_Shader][shader];
+ MetaShader *s = &ctx->entities.data[id].shader;
+ for (da_count ref = 0; ref < s->entity_reference_ids.count; ref++) {
+ MetaEntityReference *r = &ctx->entities.data[s->entity_reference_ids.data[ref]].reference;
+ meta_intern_id(ctx, &ctx->shader_entity_references, r->resolved_id.value);
+ }
+ }
+ }
+
+ // NOTE(rnp): finalize struct info
+ {
+ MetaEntityKind struct_kinds[] = {MetaEntityKind_Struct, MetaEntityKind_PushConstants, MetaEntityKind_BakeParameters};
+ u32 type_fields[] = {MetaStructField_Type, MetaStructField_Type, MetaBakeField_Type};
+ static_assert(countof(struct_kinds) == countof(type_fields), "");
+ for EachElement(struct_kinds, kind_it) {
+ for (da_count it = 0; it < ctx->entity_kind_counts[struct_kinds[kind_it]]; it++) {
+ da_count entity = ctx->entity_kind_ids[struct_kinds[kind_it]][it];
+ MetaEntity *e = ctx->entities.data + entity;
+ MetaTable *s = &e->table;
+ s8 *types = s->entries[type_fields[kind_it]];
+ for (u32 member = 0; member < s->entry_count; member++) {
+ s->struct_type_ids[member] = meta_lookup_string_slow(meta_kind_meta_types, MetaKind_Count, types[member]);
+ if (s->struct_type_ids[member] == -1) {
+ s8 name = ctx->entity_names.data[entity];
+ meta_compiler_error(e->location, "struct '%.*s' references undefined type '%.*s'\n",
+ (i32)name.len, name.data, (i32)types[member].len, types[member].data);
+ }
+ }
+ }
+ }
+ }
+
+ // NOTE(rnp): finalize base shader nonsense
+ {
+ for (da_count shader = 0; shader < ctx->entity_kind_counts[MetaEntityKind_Shader]; shader++) {
+ MetaEntity *e = ctx->entities.data + ctx->entity_kind_ids[MetaEntityKind_Shader][shader];
+ if (e->shader.file.len > 0)
+ ctx->base_shader_count++;
+ }
+
+ ctx->base_shader_ids = push_array(ctx->arena, da_count, ctx->base_shader_count);
+ ctx->base_shader_id_map = push_array(ctx->arena, da_count, ctx->entity_kind_counts[MetaEntityKind_Shader]);
+
+ da_count base_shader_ids_index = 0;
+ for (da_count shader = 0; shader < ctx->entity_kind_counts[MetaEntityKind_Shader]; shader++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_Shader][shader];
+ if (ctx->entities.data[id].shader.file.len > 0)
+ ctx->base_shader_ids[base_shader_ids_index++] = id;
+ }
+
+ // NOTE(rnp): first pass to resolve real shaders
+ for (da_count shader = 0; shader < ctx->entity_kind_counts[MetaEntityKind_Shader]; shader++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_Shader][shader];
+ if (ctx->entities.data[id].shader.file.len > 0) {
+ ctx->base_shader_id_map[shader] = meta_lookup_id_slow(ctx->base_shader_ids,
+ ctx->base_shader_count,
+ id);
+ } else {
+ ctx->base_shader_id_map[shader] = -1;
+ }
+ }
+
+ // NOTE(rnp): second pass to resolve aliases
+ for (da_count shader = 0; shader < ctx->entity_kind_counts[MetaEntityKind_Shader]; shader++) {
+ da_count id = ctx->entity_kind_ids[MetaEntityKind_Shader][shader];
+ if (ctx->base_shader_id_map[shader] == -1) {
+ if (ctx->entities.data[id].shader.kind == MetaShaderKind_Alias) {
+ ctx->base_shader_id_map[shader] = meta_lookup_id_slow(ctx->base_shader_ids,
+ ctx->base_shader_count,
+ ctx->entities.data[id].shader.alias_parent_id.value);
+ assert(ctx->base_shader_id_map[shader] != -1);
+ }
+ }
+ }
+ }
+
result->arena = 0;
return result;
}
@@ -3681,10 +4070,6 @@ metagen_file_direct(Arena arena, char *filename)
{
MetaContext *ctx = metagen_load_context(&arena, filename);
if (!ctx) return 0;
- if (ctx->shaders.count || ctx->base_shaders.count || ctx->shader_groups.count) {
- build_log_error("shaders not supported in file: %s\n", filename);
- return 0;
- }
b32 result = 1;
char *out;
diff --git a/generated/beamformer.meta.c b/generated/beamformer.meta.c
@@ -2,6 +2,17 @@
// GENERATED CODE
+// NOTE: Constants (Integer)
+#define BeamformerFilterSlots (4)
+#define BeamformerMaxBacklogFrames (16)
+#define BeamformerMaxChannelCount (256)
+#define BeamformerMaxEmmissionsCount (256)
+#define BeamformerMaxComputeShaderStages (16)
+#define BeamformerMaxParameterBlocks (16)
+#define BeamformerMaxRawDataFramesInFlight (3)
+
+// NOTE: Constants (Float)
+
typedef enum {
BeamformerDecodeMode_None = 0,
BeamformerDecodeMode_Hadamard = 1,
@@ -22,34 +33,6 @@ typedef enum {
} BeamformerSamplingMode;
typedef enum {
- BeamformerEmissionKind_Sine = 0,
- BeamformerEmissionKind_Chirp = 1,
- BeamformerEmissionKind_Count,
-} BeamformerEmissionKind;
-
-typedef enum {
- BeamformerAcquisitionKind_FORCES = 0,
- BeamformerAcquisitionKind_UFORCES = 1,
- BeamformerAcquisitionKind_HERCULES = 2,
- BeamformerAcquisitionKind_RCA_VLS = 3,
- BeamformerAcquisitionKind_RCA_TPW = 4,
- BeamformerAcquisitionKind_UHERCULES = 5,
- BeamformerAcquisitionKind_RACES = 6,
- BeamformerAcquisitionKind_EPIC_FORCES = 7,
- BeamformerAcquisitionKind_EPIC_UFORCES = 8,
- BeamformerAcquisitionKind_EPIC_UHERCULES = 9,
- BeamformerAcquisitionKind_Flash = 10,
- BeamformerAcquisitionKind_HERO_PA = 11,
- BeamformerAcquisitionKind_Count,
-} BeamformerAcquisitionKind;
-
-typedef enum {
- BeamformerContrastMode_None = 0,
- BeamformerContrastMode_A1S2 = 1,
- BeamformerContrastMode_Count,
-} BeamformerContrastMode;
-
-typedef enum {
BeamformerDataKind_Int16 = 0,
BeamformerDataKind_Int16Complex = 1,
BeamformerDataKind_Float32 = 2,
@@ -60,10 +43,16 @@ typedef enum {
} BeamformerDataKind;
typedef enum {
- BeamformerFilterKind_Kaiser = 0,
- BeamformerFilterKind_MatchedChirp = 1,
- BeamformerFilterKind_Count,
-} BeamformerFilterKind;
+ BeamformerContrastMode_None = 0,
+ BeamformerContrastMode_A1S2 = 1,
+ BeamformerContrastMode_Count,
+} BeamformerContrastMode;
+
+typedef enum {
+ BeamformerEmissionKind_Sine = 0,
+ BeamformerEmissionKind_Chirp = 1,
+ BeamformerEmissionKind_Count,
+} BeamformerEmissionKind;
typedef enum {
BeamformerInterpolationMode_Nearest = 0,
@@ -73,23 +62,26 @@ typedef enum {
} BeamformerInterpolationMode;
typedef enum {
- BeamformerShaderDecodeFlags_DilateOutput = (1 << 0),
- BeamformerShaderDecodeFlags_UseSharedMemory = (1 << 1),
-} BeamformerShaderDecodeFlags;
-
-typedef enum {
- BeamformerShaderFilterFlags_ComplexFilter = (1 << 0),
- BeamformerShaderFilterFlags_OutputFloats = (1 << 1),
- BeamformerShaderFilterFlags_Demodulate = (1 << 2),
-} BeamformerShaderFilterFlags;
+ BeamformerFilterKind_Kaiser = 0,
+ BeamformerFilterKind_MatchedChirp = 1,
+ BeamformerFilterKind_Count,
+} BeamformerFilterKind;
typedef enum {
- BeamformerShaderDASFlags_Fast = (1 << 0),
- BeamformerShaderDASFlags_Sparse = (1 << 1),
- BeamformerShaderDASFlags_CoherencyWeighting = (1 << 2),
- BeamformerShaderDASFlags_SingleFocus = (1 << 3),
- BeamformerShaderDASFlags_SingleOrientation = (1 << 4),
-} BeamformerShaderDASFlags;
+ BeamformerAcquisitionKind_FORCES = 0,
+ BeamformerAcquisitionKind_UFORCES = 1,
+ BeamformerAcquisitionKind_HERCULES = 2,
+ BeamformerAcquisitionKind_RCA_VLS = 3,
+ BeamformerAcquisitionKind_RCA_TPW = 4,
+ BeamformerAcquisitionKind_UHERCULES = 5,
+ BeamformerAcquisitionKind_RACES = 6,
+ BeamformerAcquisitionKind_EPIC_FORCES = 7,
+ BeamformerAcquisitionKind_EPIC_UFORCES = 8,
+ BeamformerAcquisitionKind_EPIC_UHERCULES = 9,
+ BeamformerAcquisitionKind_Flash = 10,
+ BeamformerAcquisitionKind_HERO_PA = 11,
+ BeamformerAcquisitionKind_Count,
+} BeamformerAcquisitionKind;
typedef enum {
BeamformerShaderKind_CudaDecode = 0,
@@ -112,6 +104,79 @@ typedef enum {
} BeamformerShaderKind;
typedef struct {
+ f32 cycles;
+ f32 frequency;
+} BeamformerSineParameters;
+
+typedef struct {
+ f32 duration;
+ f32 min_frequency;
+ f32 max_frequency;
+} BeamformerChirpParameters;
+
+typedef struct {
+ f32 cutoff_frequency;
+ f32 beta;
+ u32 length;
+} BeamformerKaiserFilterParameters;
+
+typedef struct {
+ f32 duration;
+ f32 min_frequency;
+ f32 max_frequency;
+} BeamformerChirpFilterParameters;
+
+typedef struct {
+ m4 das_voxel_transform;
+ m4 xdc_transform;
+ v2 xdc_element_pitch;
+ uv2 raw_data_dimensions;
+ v2 focal_vector;
+ u32 transmit_receive_orientation;
+ u32 sample_count;
+ u32 channel_count;
+ u32 acquisition_count;
+ u32 acquisition_kind;
+ f32 time_offset;
+ u8 single_focus;
+ u8 single_orientation;
+ u8 decode_mode;
+ u8 sampling_mode;
+} BeamformerParametersHead;
+
+typedef struct {
+ iv4 output_points;
+ f32 sampling_frequency;
+ f32 demodulation_frequency;
+ f32 speed_of_sound;
+ f32 f_number;
+ u32 interpolation_mode;
+ u32 coherency_weighting;
+ u32 decimation_rate;
+} BeamformerParametersUI;
+
+typedef struct {
+ i16 channel_mapping[256];
+ i16 sparse_elements[256];
+ u8 transmit_receive_orientations[256];
+ f32 steering_angles[256];
+ f32 focal_depths[256];
+ i32 compute_stages[16];
+ i32 compute_stage_parameters[16];
+ u32 compute_stages_count;
+ i32 data_kind;
+} BeamformerParametersSimple;
+
+typedef struct {
+ m4 xdc_transform;
+ m4 voxel_transform;
+ v2 xdc_element_pitch;
+} BeamformerDASPushConstants;
+
+typedef struct {
+ u32 data_kind;
+ u32 dilate_output;
+ u32 use_shared_memory;
u32 decode_mode;
u32 input_channel_stride;
u32 input_sample_stride;
@@ -121,9 +186,13 @@ typedef struct {
u32 output_transmit_stride;
u32 to_process;
u32 transmit_count;
-} BeamformerShaderDecodeBakeParameters;
+} BeamformerDecodeBakeParameters;
typedef struct {
+ u32 data_kind;
+ u32 demodulate;
+ u32 complex_filter;
+ u32 output_floats;
u32 decimation_rate;
u32 filter_length;
u32 input_channel_stride;
@@ -135,9 +204,15 @@ typedef struct {
u32 sample_count;
f32 demodulation_frequency;
f32 sampling_frequency;
-} BeamformerShaderFilterBakeParameters;
+} BeamformerFilterBakeParameters;
typedef struct {
+ u32 data_kind;
+ u32 coherency_weighting;
+ u32 single_focus;
+ u32 single_orientation;
+ u32 fast;
+ u32 sparse;
u32 acquisition_count;
u32 acquisition_kind;
u32 channel_count;
@@ -151,22 +226,12 @@ typedef struct {
f32 speed_of_sound;
f32 time_offset;
f32 transmit_angle;
-} BeamformerShaderDASBakeParameters;
+} BeamformerDASBakeParameters;
-typedef struct {
- m4 xdc_transform;
- m4 voxel_transform;
- v2 xdc_element_pitch;
-} BeamformerShaderDASPushConstants;
-
-typedef struct {
- union {
- BeamformerShaderDecodeBakeParameters Decode;
- BeamformerShaderFilterBakeParameters Filter;
- BeamformerShaderDASBakeParameters DAS;
- };
- u32 data_kind;
- u32 flags;
+typedef union {
+ BeamformerDecodeBakeParameters Decode;
+ BeamformerFilterBakeParameters Filter;
+ BeamformerDASBakeParameters DAS;
} BeamformerShaderBakeParameters;
typedef union {
@@ -211,24 +276,6 @@ typedef struct {
} BeamformerParameters;
typedef struct {
- m4 das_voxel_transform;
- m4 xdc_transform;
- v2 xdc_element_pitch;
- uv2 raw_data_dimensions;
- v2 focal_vector;
- u32 transmit_receive_orientation;
- u32 sample_count;
- u32 channel_count;
- u32 acquisition_count;
- u32 acquisition_kind;
- f32 time_offset;
- u8 single_focus;
- u8 single_orientation;
- u8 decode_mode;
- u8 sampling_mode;
-} BeamformerParametersHead;
-
-typedef struct {
iv4 output_points;
f32 sampling_frequency;
f32 demodulation_frequency;
@@ -474,43 +521,19 @@ read_only global s8 beamformer_shader_global_header_strings[] = {
"#define RCAOrientation_Rows 1\n"
"#define RCAOrientation_Columns 2\n"
"\n"),
-};
-
-read_only global s8 *beamformer_shader_flag_strings[] = {
- (s8 []){
- s8_comp("DilateOutput"),
- s8_comp("UseSharedMemory"),
- },
- (s8 []){
- s8_comp("ComplexFilter"),
- s8_comp("OutputFloats"),
- s8_comp("Demodulate"),
- },
- (s8 []){
- s8_comp("Fast"),
- s8_comp("Sparse"),
- s8_comp("CoherencyWeighting"),
- s8_comp("SingleFocus"),
- s8_comp("SingleOrientation"),
- },
- 0,
- 0,
- 0,
-};
-
-read_only global u8 beamformer_shader_flag_strings_count[] = {
- 2,
- 3,
- 5,
- 0,
- 0,
- 0,
+ s8_comp(""
+ "layout(std140, binding = 0) uniform PushConstants {\n"
+ " mat4 xdc_transform;\n"
+ " mat4 voxel_transform;\n"
+ " vec2 xdc_element_pitch;\n"
+ "};\n"
+ "\n"),
};
read_only global i32 *beamformer_shader_header_vectors[] = {
(i32 []){0, 1},
(i32 []){0},
- (i32 []){2, 0, 3, 4},
+ (i32 []){2, 0, 3, 4, 5},
0,
0,
0,
@@ -519,7 +542,7 @@ read_only global i32 *beamformer_shader_header_vectors[] = {
read_only global i32 beamformer_shader_header_vector_lengths[] = {
2,
1,
- 4,
+ 5,
0,
0,
0,
@@ -527,6 +550,9 @@ read_only global i32 beamformer_shader_header_vector_lengths[] = {
read_only global s8 *beamformer_shader_bake_parameter_names[] = {
(s8 []){
+ s8_comp("DataKind"),
+ s8_comp("DilateOutput"),
+ s8_comp("UseSharedMemory"),
s8_comp("DecodeMode"),
s8_comp("InputChannelStride"),
s8_comp("InputSampleStride"),
@@ -538,6 +564,10 @@ read_only global s8 *beamformer_shader_bake_parameter_names[] = {
s8_comp("TransmitCount"),
},
(s8 []){
+ s8_comp("DataKind"),
+ s8_comp("Demodulate"),
+ s8_comp("ComplexFilter"),
+ s8_comp("OutputFloats"),
s8_comp("DecimationRate"),
s8_comp("FilterLength"),
s8_comp("InputChannelStride"),
@@ -551,6 +581,12 @@ read_only global s8 *beamformer_shader_bake_parameter_names[] = {
s8_comp("SamplingFrequency"),
},
(s8 []){
+ s8_comp("DataKind"),
+ s8_comp("CoherencyWeighting"),
+ s8_comp("SingleFocus"),
+ s8_comp("SingleOrientation"),
+ s8_comp("Fast"),
+ s8_comp("Sparse"),
s8_comp("AcquisitionCount"),
s8_comp("AcquisitionKind"),
s8_comp("ChannelCount"),
@@ -572,61 +608,17 @@ read_only global s8 *beamformer_shader_bake_parameter_names[] = {
read_only global u32 beamformer_shader_bake_parameter_float_bits[] = {
0x00000000UL,
- 0x00000600UL,
- 0x00001fc0UL,
+ 0x00006000UL,
+ 0x0007f000UL,
0x00000000UL,
0x00000000UL,
0x00000000UL,
};
-read_only global i32 beamformer_shader_bake_parameter_counts[] = {
- 9,
- 11,
- 13,
- 0,
- 0,
- 0,
-};
-
-read_only global s8 *beamformer_shader_push_constant_glsl_types[] = {
- 0,
- 0,
- (s8 []){
- s8_comp("mat4"),
- s8_comp("mat4"),
- s8_comp("vec2"),
- },
- 0,
- 0,
- 0,
-};
-
-read_only global s8 *beamformer_shader_push_constant_names[] = {
- 0,
- 0,
- (s8 []){
- s8_comp("xdc_transform"),
- s8_comp("voxel_transform"),
- s8_comp("xdc_element_pitch"),
- },
- 0,
- 0,
- 0,
-};
-
-read_only global u8 beamformer_shader_push_constant_counts[] = {
- 0,
- 0,
- 3,
- 0,
- 0,
- 0,
-};
-
-read_only global u8 beamformer_shader_push_constant_sizes[] = {
- 0,
- 0,
- sizeof(BeamformerShaderDASPushConstants),
+read_only global u8 beamformer_shader_bake_parameter_counts[] = {
+ 12,
+ 15,
+ 19,
0,
0,
0,
diff --git a/lib/ogl_beamformer_lib.c b/lib/ogl_beamformer_lib.c
@@ -240,7 +240,7 @@ beamformer_reserve_parameter_blocks(uint32_t count)
{
b32 result = 0;
if (check_shared_memory() &&
- lib_error_check(count <= BeamformerMaxParameterBlockSlots, ParameterBlockOverflow))
+ lib_error_check(count <= BeamformerMaxParameterBlocks, ParameterBlockOverflow))
{
g_beamformer_library_context.bp->reserved_parameter_blocks = count;
result = 1;
@@ -365,7 +365,7 @@ beamformer_create_filter_base(BeamformerFilterParameters params, u8 filter_slot,
work->kind = BeamformerWorkKind_CreateFilter;
ctx->parameters = params;
ctx->filter_slot = filter_slot % BeamformerFilterSlots;
- ctx->parameter_block = parameter_block % BeamformerMaxParameterBlockSlots;
+ ctx->parameter_block = parameter_block % BeamformerMaxParameterBlocks;
beamform_work_queue_push_commit(&g_beamformer_library_context.bp->external_work_queue);
result = 1;
}
diff --git a/main_linux.c b/main_linux.c
@@ -42,9 +42,9 @@ typedef struct {
iptr handle;
s8 name;
- OSLinux_FileWatch * data;
- iz count;
- iz capacity;
+ OSLinux_FileWatch *data;
+ da_count count;
+ da_count capacity;
} OSLinux_FileWatchDirectory;
DA_STRUCT(OSLinux_FileWatchDirectory, OSLinux_FileWatchDirectory);
@@ -148,7 +148,7 @@ function OSLinux_FileWatchDirectory *
os_lookup_file_watch_directory(OSLinux_FileWatchDirectoryList *ctx, u64 hash)
{
OSLinux_FileWatchDirectory *result = 0;
- for (iz i = 0; !result && i < ctx->count; i++)
+ for (da_count i = 0; !result && i < ctx->count; i++)
if (ctx->data[i].hash == hash)
result = ctx->data + i;
return result;
@@ -265,14 +265,14 @@ dispatch_file_watch_events(BeamformerInput *input)
while ((rlen = read(os_linux_context.inotify_handle, mem, 4096)) > 0) {
for (u8 *data = mem; data < mem + rlen; data += sizeof(*event) + event->len) {
event = (struct inotify_event *)data;
- for (u32 i = 0; i < fwctx->count; i++) {
+ for (da_count i = 0; i < fwctx->count; i++) {
OSLinux_FileWatchDirectory *dir = fwctx->data + i;
if (event->wd != dir->handle)
continue;
s8 file = c_str_to_s8(event->name);
u64 hash = u64_hash_from_s8(file);
- for (u32 j = 0; j < dir->count; j++) {
+ for (da_count j = 0; j < dir->count; j++) {
OSLinux_FileWatch *fw = dir->data + j;
if (fw->hash == hash) {
// NOTE(rnp): avoid multiple updates in a single frame
diff --git a/main_w32.c b/main_w32.c
@@ -74,8 +74,8 @@ typedef struct {
s8 name;
OSW32_FileWatch *data;
- iz count;
- iz capacity;
+ da_count count;
+ da_count capacity;
w32_overlapped overlapped;
w32_io_completion_event event;
@@ -178,7 +178,7 @@ function OSW32_FileWatchDirectory *
os_lookup_file_watch_directory(OSW32_FileWatchDirectoryList *ctx, u64 hash)
{
OSW32_FileWatchDirectory *result = 0;
- for (iz i = 0; !result && i < ctx->count; i++)
+ for (da_count i = 0; !result && i < ctx->count; i++)
if (ctx->data[i].hash == hash)
result = ctx->data + i;
return result;
@@ -324,7 +324,7 @@ dispatch_file_watch(BeamformerInput *input, Arena arena, u64 current_time, OSW32
s8 file_name = s16_to_s8(&arena, (s16){.data = fni->filename, .len = fni->filename_size / 2});
u64 hash = u64_hash_from_s8(file_name);
- for (u32 i = 0; i < fw_dir->count; i++) {
+ for (da_count i = 0; i < fw_dir->count; i++) {
OSW32_FileWatch *fw = fw_dir->data + i;
if (fw->hash == hash) {
// NOTE(rnp): avoid multiple updates in a single frame
diff --git a/ui.c b/ui.c
@@ -498,8 +498,8 @@ typedef struct {
typedef struct Table {
TableRow *data;
- iz count;
- iz capacity;
+ da_count count;
+ da_count capacity;
/* NOTE(rnp): counted by columns */
TextAlignment *alignment;
@@ -525,8 +525,8 @@ typedef struct {
typedef struct {
TableStackFrame *data;
- iz count;
- iz capacity;
+ da_count count;
+ da_count capacity;
} TableStack;
typedef enum {
@@ -745,7 +745,7 @@ push_custom_view_title(Stream *s, Variable *var)
}break;
case BeamformerFrameViewKind_Indexed:{
stream_append_s8(s, s8(": Index {"));
- stream_append_u64(s, *bv->cycler->cycler.state % BeamformerMaxSavedFrames);
+ stream_append_u64(s, *bv->cycler->cycler.state % BeamformerMaxBacklogFrames);
stream_append_s8(s, s8("} ["));
}break;
case BeamformerFrameViewKind_3DXPlane:{ stream_append_s8(s, s8(": 3D X-Plane")); }break;
@@ -1397,7 +1397,7 @@ ui_beamformer_frame_view_convert(BeamformerUI *ui, Arena *arena, Variable *view,
}break;
case BeamformerFrameViewKind_Indexed:{
bv->cycler = add_variable_cycler(ui, menu, arena, 0, ui->small_font, s8("Index:"),
- &bv->cycler_state, 0, BeamformerMaxSavedFrames);
+ &bv->cycler_state, 0, BeamformerMaxBacklogFrames);
}break;
default:{}break;
}
@@ -2858,7 +2858,7 @@ draw_compute_stats_view(BeamformerUI *ui, Arena arena, Variable *view, Rect r, v
assert(view->type == VT_COMPUTE_STATS_VIEW);
read_only local_persist BeamformerComputePlan dummy_plan = {0};
- u32 selected_plan = ui->selected_parameter_block % BeamformerMaxParameterBlockSlots;
+ u32 selected_plan = ui->selected_parameter_block % BeamformerMaxParameterBlocks;
BeamformerComputePlan *cp = ui->beamformer_context->compute_context.compute_plans[selected_plan];
if (!cp) cp = &dummy_plan;
@@ -3299,9 +3299,9 @@ draw_ui_regions(BeamformerUI *ui, Rect window, v2 mouse)
struct {
struct region_frame *data;
- iz count;
- iz capacity;
- } stack = {init, 0, ARRAY_COUNT(init)};
+ da_count count;
+ da_count capacity;
+ } stack = {init, 0, countof(init)};
TempArena arena_savepoint = begin_temp_arena(&ui->arena);
@@ -3442,7 +3442,10 @@ function void
end_text_input(InputState *is, Variable *var)
{
f32 value = 0;
- if (is->numeric) value = (f32)parse_f64((s8){.len = is->count, .data = is->buf});
+ if (is->numeric) {
+ NumberConversion number = number_from_s8((s8){.len = is->count, .data = is->buf});
+ value = number.F64;
+ }
switch (var->type) {
case VT_SCALED_F32:{ var->scaled_real32.val = value; }break;
@@ -4093,7 +4096,7 @@ draw_ui(BeamformerCtx *ctx, BeamformerInput *input, BeamformerFrame *frame_to_dr
asan_poison_region(ui->arena.beg, ui->arena.end - ui->arena.beg);
- u32 selected_block = ui->selected_parameter_block % BeamformerMaxParameterBlockSlots;
+ u32 selected_block = ui->selected_parameter_block % BeamformerMaxParameterBlocks;
u32 selected_mask = 1 << selected_block;
if (ctx->ui_dirty_parameter_blocks & selected_mask) {
BeamformerParameterBlock *pb = beamformer_parameter_block_lock(ui->shared_memory, selected_block, 0);
diff --git a/util.c b/util.c
@@ -236,9 +236,9 @@ enum { DA_INITIAL_CAP = 16 };
: (s)->data + (s)->count++, 0, sizeof(*(s)->data)))
function void *
-da_reserve_(Arena *a, void *data, iz *capacity, iz needed, uz align, iz size)
+da_reserve_(Arena *a, void *data, da_count *capacity, da_count needed, u64 align, i64 size)
{
- iz cap = *capacity;
+ da_count cap = *capacity;
/* NOTE(rnp): handle both 0 initialized DAs and DAs that need to be moved (they started
* on the stack or someone allocated something in the middle of the arena during usage) */
@@ -783,7 +783,7 @@ cut_rect_vertical(Rect rect, f32 at, Rect *top, Rect *bot)
}
}
-function IntegerConversion
+function NumberConversion
integer_from_s8(s8 raw)
{
read_only local_persist alignas(64) i8 lut[64] = {
@@ -793,7 +793,7 @@ integer_from_s8(s8 raw)
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
};
- IntegerConversion result = {.unparsed = raw};
+ NumberConversion result = {.unparsed = raw};
iz i = 0;
i64 scale = 1;
@@ -813,7 +813,7 @@ integer_from_s8(s8 raw)
i64 value = lut[Min((u8)(raw.data[i] - (u8)'0'), clamp)];\
if (value >= 0) {\
if (result.U64 > (U64_MAX - (u64)value) / radix) {\
- result.result = IntegerConversionResult_OutOfRange;\
+ result.result = NumberConversionResult_OutOfRange;\
result.U64 = U64_MAX;\
return result;\
} else {\
@@ -831,27 +831,42 @@ integer_from_s8(s8 raw)
#undef integer_conversion_body
result.unparsed = (s8){.len = raw.len - i, .data = raw.data + i};
- result.result = IntegerConversionResult_Success;
+ result.result = i > 0 ? NumberConversionResult_Success : NumberConversionResult_Invalid;
+ result.kind = NumberConversionKind_Integer;
if (scale < 0) result.U64 = 0 - result.U64;
return result;
}
-function f64
-parse_f64(s8 s)
+function NumberConversion
+number_from_s8(s8 s)
{
- IntegerConversion integral = integer_from_s8(s);
+ NumberConversion result = {.unparsed = s};
+ NumberConversion integer = integer_from_s8(s);
+ if (integer.result == NumberConversionResult_Success) {
+ if (integer.unparsed.len != 0 && integer.unparsed.data[0] == '.') {
+ s = integer.unparsed;
+ s.data++;
+ s.len--;
- s = integral.unparsed;
- if (*s.data == '.') { s.data++; s.len--; }
- while (s.len > 0 && s.data[s.len - 1] == '0') s.len--;
+ while (s.len > 0 && s.data[s.len - 1] == '0') s.len--;
- IntegerConversion fractional = integer_from_s8(s);
+ NumberConversion fractional = integer_from_s8(s);
+ if (fractional.result == NumberConversionResult_Success || s.len == 0) {
+ result.F64 = (f64)fractional.U64;
- u64 power = (u64)(fractional.unparsed.data - s.data);
- f64 frac = (f64)fractional.U64;
- while (power > 0) { frac /= 10.0; power--; }
+ u64 divisor = (u64)(fractional.unparsed.data - s.data);
+ while (divisor > 0) { result.F64 /= 10.0; divisor--; }
- f64 result = (f64)integral.S64 + frac;
+ result.F64 += (f64)integer.S64;
+
+ result.result = NumberConversionResult_Success;
+ result.kind = NumberConversionKind_Float;
+ result.unparsed = fractional.unparsed;
+ }
+ } else {
+ result = integer;
+ }
+ }
return result;
}
diff --git a/util.h b/util.h
@@ -4,6 +4,8 @@
#include "compiler.h"
+#define da_count i32
+
#if COMPILER_MSVC
typedef unsigned __int64 u64;
typedef signed __int64 i64;
@@ -106,7 +108,6 @@ typedef u64 uptr;
#define str(...) str_(__VA_ARGS__)
#define countof(a) (iz)(sizeof(a) / sizeof(*a))
-#define ARRAY_COUNT(a) (sizeof(a) / sizeof(*a))
#define BETWEEN(x, a, b) ((x) >= (a) && (x) <= (b))
#define CLAMP(x, a, b) ((x) < (a) ? (a) : (x) > (b) ? (b) : (x))
#define CLAMP01(x) CLAMP(x, 0, 1)
@@ -145,9 +146,9 @@ typedef u64 uptr;
#define spin_wait(c) while ((c)) cpu_yield()
#define DA_STRUCT(kind, name) typedef struct { \
- kind *data; \
- iz count; \
- iz capacity; \
+ kind *data; \
+ da_count count; \
+ da_count capacity; \
} name ##List;
/* NOTE(rnp): no guarantees about actually getting an element */
@@ -217,19 +218,27 @@ typedef struct { iz len; u16 *data; } s16;
typedef struct { u32 cp, consumed; } UnicodeDecode;
typedef enum {
- IntegerConversionResult_Invalid,
- IntegerConversionResult_OutOfRange,
- IntegerConversionResult_Success,
-} IntegerConversionResult;
+ NumberConversionResult_Invalid,
+ NumberConversionResult_OutOfRange,
+ NumberConversionResult_Success,
+} NumberConversionResult;
+
+typedef enum {
+ NumberConversionKind_Invalid,
+ NumberConversionKind_Integer,
+ NumberConversionKind_Float,
+} NumberConversionKind;
typedef struct {
- IntegerConversionResult result;
+ NumberConversionResult result;
+ NumberConversionKind kind;
union {
u64 U64;
i64 S64;
+ f64 F64;
};
s8 unparsed;
-} IntegerConversion;
+} NumberConversion;
typedef struct { u64 start, stop; } RangeU64;