Commit: 3520f866131d4d0aaa74ba7babc5e5e5ea58982f
Parent: d9d790381f3f551e0a11f837e5d77d8c0b76da98
Author: Randy Palamar
Date: Sat, 25 Jul 2026 20:37:06 -0700
core: use vulkan specialization constants for bake parameters
This is slightly nicer for debugging as it gives human readable
values (particularly for f32s) in renderdoc. However, they are
much more limited than my form of baking and so anything that
changes the types of variables, enabled shader extensions, or
other more complicated things still requires extra preprocessing.
I have dumped shader assembly before and after this and it is
identical, the only difference being the pipeline hash. So this
can not in any way change the shader performance.
Diffstat:
10 files changed, 220 insertions(+), 150 deletions(-)
diff --git a/beamformer.meta b/beamformer.meta
@@ -271,6 +271,28 @@
[transmit_receive_orientations U16 MaxChannelCount]
}
+@Flags FilterCompileFlags
+{
+ ComplexFilter
+ Demodulate
+}
+
+@Flags DecodeCompileFlags
+{
+ CooperativeMatrix
+}
+
+@Flags DASCompileFlags
+{
+ CoherencyWeighting
+}
+
+@Flags ReshapeCompileFlags
+{
+ Deinterleave
+ Interleave
+}
+
@Emit
{
`read_only global u8 beamformer_data_kind_element_size[] = {`
@@ -336,6 +358,8 @@
{
@Enumeration DecodeMode
+ @Flags DecodeCompileFlags
+
@Bake
{
[UseSharedMemory use_shared_memory B32]
@@ -346,7 +370,6 @@
[ToProcess to_process U32]
[TransmitCount transmit_count U32]
[ChunkChannelCount chunk_channel_count U32]
- [CooperativeMatrix cooperative_matrix B32]
[CooperativeMatrixM cooperative_matrix_m U32]
[CooperativeMatrixN cooperative_matrix_n U32]
[CooperativeMatrixK cooperative_matrix_k U32]
@@ -365,12 +388,12 @@
@Enumeration ShaderBufferSlot
@Enumeration ShaderResourceKind
+ @Flags FilterCompileFlags
+
@ShaderAlias Demodulate
@Bake
{
- [Demodulate demodulate U32]
- [ComplexFilter complex_filter U32]
[DecimationRate decimation_rate U32]
[FilterLength filter_length U32]
[InputChannelStride input_channel_stride U32]
@@ -404,20 +427,21 @@
@Enumeration ShaderBufferSlot
@Enumeration ShaderResourceKind
+ @Flags DASCompileFlags
+
@Struct DASArrayParameters
@Bake
{
- [CoherencyWeighting coherency_weighting U32]
- [SingleFocus single_focus U32]
- [SingleOrientation single_orientation U32]
- [Sparse sparse U32]
- [AcquisitionCount acquisition_count U32]
+ [SingleFocus single_focus B32]
+ [SingleOrientation single_orientation B32]
+ [Sparse sparse B32]
+ [AcquisitionCount acquisition_count S32]
[AcquisitionKind acquisition_kind U32]
- [ChannelCount channel_count U32]
- [ChunkChannelCount chunk_channel_count U32]
+ [ChannelCount channel_count S32]
+ [ChunkChannelCount chunk_channel_count S32]
[InterpolationMode interpolation_mode U32]
- [SampleCount sample_count U32]
+ [SampleCount sample_count S32]
[TransmitReceiveOrientation transmit_receive_orientation U32]
[DemodulationFrequency demodulation_frequency F32]
@@ -481,6 +505,7 @@
@Shader(reshape.glsl) Reshape
{
+ @Flags ReshapeCompileFlags
@Bake
{
[SizeX size_x U32]
@@ -492,8 +517,6 @@
[OutputStrideX output_stride_x U32]
[OutputStrideY output_stride_y U32]
[OutputStrideZ output_stride_z U32]
- [Interleave interleave B32]
- [Deinterleave deinterleave B32]
}
@PushConstants
diff --git a/beamformer_core.c b/beamformer_core.c
@@ -632,7 +632,7 @@ plan_compute_pipeline(BeamformerComputePlan *cp, BeamformerParameterBlock *pb, A
if (demodulate)
decode_sample_count *= 2;
- db->cooperative_matrix = 1;
+ sd->compile_flags |= BeamformerDecodeCompileFlags_CooperativeMatrix;
db->cooperative_matrix_m = 16;
db->cooperative_matrix_n = 16;
db->cooperative_matrix_k = 16;
@@ -672,12 +672,13 @@ plan_compute_pipeline(BeamformerComputePlan *cp, BeamformerParameterBlock *pb, A
b32 demod = node->kind == BeamformerShaderKind_Demodulate;
BeamformerFilter *f = cp->filters + sp->filter_slot;
+ sd->compile_flags |= BeamformerFilterCompileFlags_Demodulate * demod;
+ sd->compile_flags |= BeamformerFilterCompileFlags_ComplexFilter * f->parameters.complex;
+
time_offset += f->time_delay;
BeamformerFilterBakeParameters *fb = &sd->bake.Filter;
fb->filter_length = (u32)f->length;
- fb->demodulate = demod;
- fb->complex_filter = f->parameters.complex;
fb->sample_count = input_sample_count;
fb->decimation_rate = demod ? decimation_rate : 1;
@@ -749,8 +750,8 @@ plan_compute_pipeline(BeamformerComputePlan *cp, BeamformerParameterBlock *pb, A
db->sparse = id == BeamformerAcquisitionKind_UFORCES || id == BeamformerAcquisitionKind_UHERCULES;
db->single_focus = pb->parameters.single_focus;
db->single_orientation = pb->parameters.single_orientation;
- db->coherency_weighting = pb->parameters.coherency_weighting;
+ sd->compile_flags |= BeamformerDASCompileFlags_CoherencyWeighting * pb->parameters.coherency_weighting;
sd->layout = layout_for_output(cp->output_points);
sd->dispatch = dispatch_for_output(sd->layout, cp->output_points);
}break;
@@ -762,11 +763,13 @@ plan_compute_pipeline(BeamformerComputePlan *cp, BeamformerParameterBlock *pb, A
case BeamformerShaderKind_Reshape:{
BeamformerReshapeBakeParameters *rb = &sd->bake.Reshape;
- rb->deinterleave = beamformer_data_kind_complex[node->input_data_kind] &&
+ b32 deinterleave = beamformer_data_kind_complex[node->input_data_kind] &&
!beamformer_data_kind_complex[node->output_data_kind];
- rb->interleave = !beamformer_data_kind_complex[node->input_data_kind] &&
+ b32 interleave = !beamformer_data_kind_complex[node->input_data_kind] &&
beamformer_data_kind_complex[node->output_data_kind];
- assert(rb->interleave == 0 || (rb->interleave != rb->deinterleave));
+ assert(interleave == 0 || (interleave != deinterleave));
+ sd->compile_flags |= BeamformerReshapeCompileFlags_Deinterleave * deinterleave;
+ sd->compile_flags |= BeamformerReshapeCompileFlags_Interleave * interleave;
rb->input_stride_x = node->input_stride.x;
rb->input_stride_y = node->input_stride.y;
@@ -877,19 +880,20 @@ stream_append_shader_header(Stream *s, i32 reloadable_index, BeamformerShaderDes
}
stream_append_byte(s, '\n');
+ stream_append_str8(s, str8("#define CompileFlags (0x"));
+ stream_append_hex_u64_width(s, sd->compile_flags, 8);
+ stream_append_str8(s, str8(")\n"));
+
i32 struct_id = beamformer_base_shader_to_bake_struct_id[reloadable_index];
if (struct_id != -1) {
- u32 *parameters = (u32 *)&sd->bake;
- str8 *names = beamformer_shader_bake_parameter_names[reloadable_index];
- MetaStructInfo *si = meta_struct_info_by_id + struct_id;
- MetaStructMember *sm = meta_struct_members_by_id[struct_id];
-
+ str8 *names = beamformer_shader_bake_parameter_names[reloadable_index];
+ MetaStructInfo *si = meta_struct_info_by_id + struct_id;
+ MetaStructMember *sm = meta_struct_members_by_id[struct_id];
for (u32 index = 0; index < si->member_count; index++) {
- b32 is_float = sm[index].type_id == MetaKind_F32;
- stream_append_str8s(s, str8("#define "), names[index],
- is_float ? str8(" uintBitsToFloat") : str8(" "), str8("(0x"));
- stream_append_hex_u64(s, parameters[index]);
- stream_append_str8(s, str8(")\n"));
+ str8 type = meta_kind_glsl_types[sm[index].type_id];
+ stream_append_str8(s, str8("layout(constant_id = "));
+ stream_append_u64(s, index);
+ stream_append_str8s(s, str8(") const "), type, str8(" "), names[index], str8(" = "), type, str8("(1);\n"));
}
}
}
@@ -930,15 +934,17 @@ beamformer_reload_pipeline(VulkanHandle *pipeline, BeamformerShaderReloadInfo *s
infos[i].kind = sris[i].shader_kind;
infos[i].text = arena_stream_commit_zero(&arena, &shader_stream);
infos[i].name = beamformer_shader_names[sris[i].shader];
-
- //s8 line = s8("---------------\n");
- //s8 nl = s8("\n");
- //os_console_log(line.data, line.len);
- //os_console_log(infos[i].name.data, infos[i].name.len);
- //os_console_log(nl.data, nl.len);
- //os_console_log(line.data, line.len);
- //os_console_log(infos[i].text.data, infos[i].text.len);
- //os_console_log(line.data, line.len);
+ infos[i].specialization_data = sris[i].shader_descriptor ? &sris[i].shader_descriptor->bake : 0;
+ infos[i].specialization_struct_id = beamformer_base_shader_to_bake_struct_id[reloadable_index];
+
+ //str8 line = str8("---------------\n");
+ //str8 nl = str8("\n");
+ //os_console_log(line.data, line.length);
+ //os_console_log(infos[i].name.data, infos[i].name.length);
+ //os_console_log(nl.data, nl.length);
+ //os_console_log(line.data, line.length);
+ //os_console_log(infos[i].text.data, infos[i].text.length);
+ //os_console_log(line.data, line.length);
}
vk_pipeline_release(*pipeline);
@@ -1232,7 +1238,7 @@ do_compute_shader(BeamformerCtx *ctx, VulkanHandle cmd, BeamformerComputePlan *c
memory_copy(pc.voxel_transform.E, cp->das_voxel_transform.E, sizeof(pc.voxel_transform));
memory_copy(pc.xdc_transform.E, cp->xdc_transform.E, sizeof(pc.xdc_transform));
- b32 coherent = cp->shader_descriptors[shader_slot].bake.DAS.coherency_weighting;
+ b32 coherent = (cp->shader_descriptors[shader_slot].compile_flags & BeamformerDASCompileFlags_CoherencyWeighting) != 0;
GPUMemoryBarrierInfo memory_barriers[] = {
// NOTE(rnp): last stage data output barrier
@@ -1484,7 +1490,9 @@ complete_queue(BeamformerCtx *ctx, BeamformWorkQueue *q, Arena *arena)
das_index = (i32)i;
}
- b32 das_coherent = das_index >= 0 && cp->shader_descriptors[das_index].bake.DAS.coherency_weighting;
+ b32 das_coherent = das_index >= 0 &&
+ (cp->shader_descriptors[das_index].compile_flags &
+ BeamformerDASCompileFlags_CoherencyWeighting) != 0;
u64 reserved_frame_size = 0;
if (has_sum)
diff --git a/beamformer_internal.h b/beamformer_internal.h
@@ -56,6 +56,8 @@ typedef enum {
typedef struct {
VulkanShaderKind kind;
+ i32 specialization_struct_id;
+ void *specialization_data;
str8 text;
str8 name;
} VulkanPipelineCreateInfo;
@@ -285,6 +287,7 @@ typedef struct {BEAMFORMER_COMPUTE_ARRAY_PARAMETERS_LIST} BeamformerComputeArray
typedef struct {
uv3 layout;
uv3 dispatch;
+ u32 compile_flags;
BeamformerDataKind input_data_kind;
BeamformerDataKind output_data_kind;
BeamformerShaderBakeParameters bake;
diff --git a/build.c b/build.c
@@ -1067,12 +1067,6 @@ typedef enum {
#include "meta.h"
-read_only global u8 meta_kind_byte_sizes[] = {
- #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, _g, _b, _m, _by, elements, ...) elements,
META_KIND_LIST
@@ -1097,12 +1091,6 @@ read_only global str8 meta_kind_base_c_types[] = {
#undef X
};
-read_only global str8 meta_kind_glsl_types[] = {
- #define X(_k, _c, glsl, ...) str8_comp(#glsl),
- META_KIND_LIST
- #undef X
-};
-
read_only global str8 meta_kind_c_types[] = {
#define X(_k, c, ...) str8_comp(#c),
META_KIND_LIST
@@ -3695,6 +3683,13 @@ meta_push_shader_reload_info(MetaprogramContext *m, MetaContext *ctx)
meta_push_line(m, str8("\"\\n\"),"));
}break;
+ case MetaEntityKind_Flags:{
+ meta_push_line(m, str8("str8_comp(\"\""));
+ metagen_push_counted_enum_body(m, str8(""), str8("\"#define "), str8("((CompileFlags & (1 << "),
+ str8(")) != 0)\\n\""), e->table.entries[0], e->table.entry_count);
+ meta_push_line(m, str8("\"\\n\"),"));
+ }break;
+
case MetaEntityKind_Enumeration:{
str8 kind_name = push_str8_from_parts(&m->scratch, str8(""), entity_name, str8("_"));
meta_push_line(m, str8("str8_comp(\"\""));
diff --git a/generated/beamformer.c b/generated/beamformer.c
@@ -124,6 +124,24 @@ typedef enum {
} BeamformerLiveImagingDirtyFlags;
typedef enum {
+ BeamformerFilterCompileFlags_ComplexFilter = 1 << 0,
+ BeamformerFilterCompileFlags_Demodulate = 1 << 1,
+} BeamformerFilterCompileFlags;
+
+typedef enum {
+ BeamformerDecodeCompileFlags_CooperativeMatrix = 1 << 0,
+} BeamformerDecodeCompileFlags;
+
+typedef enum {
+ BeamformerDASCompileFlags_CoherencyWeighting = 1 << 0,
+} BeamformerDASCompileFlags;
+
+typedef enum {
+ BeamformerReshapeCompileFlags_Deinterleave = 1 << 0,
+ BeamformerReshapeCompileFlags_Interleave = 1 << 1,
+} BeamformerReshapeCompileFlags;
+
+typedef enum {
BeamformerShaderKind_Decode = 0,
BeamformerShaderKind_Filter = 1,
BeamformerShaderKind_Demodulate = 2,
@@ -156,15 +174,12 @@ typedef struct {
u32 to_process;
u32 transmit_count;
u32 chunk_channel_count;
- b32 cooperative_matrix;
u32 cooperative_matrix_m;
u32 cooperative_matrix_n;
u32 cooperative_matrix_k;
} BeamformerDecodeBakeParameters;
typedef struct {
- u32 demodulate;
- u32 complex_filter;
u32 decimation_rate;
u32 filter_length;
u32 input_channel_stride;
@@ -180,16 +195,15 @@ typedef struct {
} BeamformerFilterBakeParameters;
typedef struct {
- u32 coherency_weighting;
- u32 single_focus;
- u32 single_orientation;
- u32 sparse;
- u32 acquisition_count;
+ b32 single_focus;
+ b32 single_orientation;
+ b32 sparse;
+ i32 acquisition_count;
u32 acquisition_kind;
- u32 channel_count;
- u32 chunk_channel_count;
+ i32 channel_count;
+ i32 chunk_channel_count;
u32 interpolation_mode;
- u32 sample_count;
+ i32 sample_count;
u32 transmit_receive_orientation;
f32 demodulation_frequency;
f32 f_number;
@@ -210,8 +224,6 @@ typedef struct {
u32 output_stride_x;
u32 output_stride_y;
u32 output_stride_z;
- b32 interleave;
- b32 deinterleave;
} BeamformerReshapeBakeParameters;
typedef struct {
@@ -581,10 +593,9 @@ read_only global MetaStructMember *meta_struct_members_by_id[] = {
{18, 20, 1, 0},
{18, 24, 1, 0},
{18, 28, 1, 0},
- {14, 32, 1, 0},
+ {18, 32, 1, 0},
{18, 36, 1, 0},
{18, 40, 1, 0},
- {18, 44, 1, 0},
},
(MetaStructMember []){
{18, 0, 1, 0},
@@ -597,30 +608,27 @@ read_only global MetaStructMember *meta_struct_members_by_id[] = {
{18, 28, 1, 0},
{18, 32, 1, 0},
{18, 36, 1, 0},
- {18, 40, 1, 0},
- {18, 44, 1, 0},
- {8, 48, 1, 0},
- {8, 52, 1, 0},
+ {8, 40, 1, 0},
+ {8, 44, 1, 0},
},
(MetaStructMember []){
- {18, 0, 1, 0},
- {18, 4, 1, 0},
- {18, 8, 1, 0},
- {18, 12, 1, 0},
+ {14, 0, 1, 0},
+ {14, 4, 1, 0},
+ {14, 8, 1, 0},
+ {10, 12, 1, 0},
{18, 16, 1, 0},
- {18, 20, 1, 0},
- {18, 24, 1, 0},
+ {10, 20, 1, 0},
+ {10, 24, 1, 0},
{18, 28, 1, 0},
- {18, 32, 1, 0},
+ {10, 32, 1, 0},
{18, 36, 1, 0},
- {18, 40, 1, 0},
+ {8, 40, 1, 0},
{8, 44, 1, 0},
{8, 48, 1, 0},
{8, 52, 1, 0},
{8, 56, 1, 0},
{8, 60, 1, 0},
{8, 64, 1, 0},
- {8, 68, 1, 0},
},
(MetaStructMember []){
{18, 0, 1, 0},
@@ -632,8 +640,6 @@ read_only global MetaStructMember *meta_struct_members_by_id[] = {
{18, 24, 1, 0},
{18, 28, 1, 0},
{18, 32, 1, 0},
- {14, 36, 1, 0},
- {14, 40, 1, 0},
},
};
@@ -647,14 +653,11 @@ read_only global str8 *meta_struct_member_names_by_id[] = {
str8_comp("to_process"),
str8_comp("transmit_count"),
str8_comp("chunk_channel_count"),
- str8_comp("cooperative_matrix"),
str8_comp("cooperative_matrix_m"),
str8_comp("cooperative_matrix_n"),
str8_comp("cooperative_matrix_k"),
},
(str8 []){
- str8_comp("demodulate"),
- str8_comp("complex_filter"),
str8_comp("decimation_rate"),
str8_comp("filter_length"),
str8_comp("input_channel_stride"),
@@ -669,7 +672,6 @@ read_only global str8 *meta_struct_member_names_by_id[] = {
str8_comp("sampling_frequency"),
},
(str8 []){
- str8_comp("coherency_weighting"),
str8_comp("single_focus"),
str8_comp("single_orientation"),
str8_comp("sparse"),
@@ -698,16 +700,14 @@ read_only global str8 *meta_struct_member_names_by_id[] = {
str8_comp("output_stride_x"),
str8_comp("output_stride_y"),
str8_comp("output_stride_z"),
- str8_comp("interleave"),
- str8_comp("deinterleave"),
},
};
read_only global MetaStructInfo meta_struct_info_by_id[] = {
- {str8_comp("DecodeBakeParameters"), 12, 48, 0},
- {str8_comp("FilterBakeParameters"), 14, 56, 0},
- {str8_comp("DASBakeParameters"), 18, 72, 0},
- {str8_comp("ReshapeBakeParameters"), 11, 44, 0},
+ {str8_comp("DecodeBakeParameters"), 11, 44, 0},
+ {str8_comp("FilterBakeParameters"), 12, 48, 0},
+ {str8_comp("DASBakeParameters"), 17, 68, 0},
+ {str8_comp("ReshapeBakeParameters"), 9, 36, 0},
};
read_only global str8 beamformer_shader_names[] = {
@@ -781,6 +781,9 @@ read_only global str8 beamformer_shader_global_header_strings[] = {
"#define DecodeMode_Hadamard 1\n"
"\n"),
str8_comp(""
+ "#define CooperativeMatrix ((CompileFlags & (1 << 0)) != 0)\n"
+ "\n"),
+ str8_comp(""
"layout(push_constant, std430) uniform PushConstants {\n"
" uint64_t hadamard_buffer;\n"
" uint64_t rf_buffer;\n"
@@ -795,6 +798,10 @@ read_only global str8 beamformer_shader_global_header_strings[] = {
"#define ShaderResourceKind_Buffer 0\n"
"\n"),
str8_comp(""
+ "#define ComplexFilter ((CompileFlags & (1 << 0)) != 0)\n"
+ "#define Demodulate ((CompileFlags & (1 << 1)) != 0)\n"
+ "\n"),
+ str8_comp(""
"layout(push_constant, std430) uniform PushConstants {\n"
" uint64_t input_data;\n"
" uint64_t filter_coefficients;\n"
@@ -828,6 +835,9 @@ read_only global str8 beamformer_shader_global_header_strings[] = {
"#define RCAOrientation_Columns 2\n"
"\n"),
str8_comp(""
+ "#define CoherencyWeighting ((CompileFlags & (1 << 0)) != 0)\n"
+ "\n"),
+ str8_comp(""
"struct DASArrayParameters {\n"
" f32vec2 focal_vectors[MaxChannelCount];\n"
" int16_t sparse_elements[MaxChannelCount];\n"
@@ -869,6 +879,10 @@ read_only global str8 beamformer_shader_global_header_strings[] = {
"};\n"
"\n"),
str8_comp(""
+ "#define Deinterleave ((CompileFlags & (1 << 0)) != 0)\n"
+ "#define Interleave ((CompileFlags & (1 << 1)) != 0)\n"
+ "\n"),
+ str8_comp(""
"layout(push_constant, std430) uniform PushConstants {\n"
" uint64_t output_buffer;\n"
" uint64_t left_input_buffer;\n"
@@ -917,24 +931,24 @@ read_only global b8 beamformer_shader_primitive_is_vertex[] = {
};
read_only global i32 *beamformer_shader_header_vectors[] = {
- (i32 []){0, 1},
- (i32 []){2, 3, 4},
- (i32 []){5, 6, 7, 8, 2, 3, 9, 10},
- (i32 []){11},
- 0,
- (i32 []){12},
- (i32 []){13},
+ (i32 []){0, 1, 2},
+ (i32 []){3, 4, 5, 6},
+ (i32 []){7, 8, 9, 10, 3, 4, 11, 12, 13},
(i32 []){14},
+ 0,
+ (i32 []){15},
+ (i32 []){16, 17},
+ (i32 []){18},
};
read_only global i32 beamformer_shader_header_vector_lengths[] = {
- 2,
3,
- 8,
+ 4,
+ 9,
1,
0,
1,
- 1,
+ 2,
1,
};
@@ -948,14 +962,11 @@ read_only global str8 *beamformer_shader_bake_parameter_names[] = {
str8_comp("ToProcess"),
str8_comp("TransmitCount"),
str8_comp("ChunkChannelCount"),
- str8_comp("CooperativeMatrix"),
str8_comp("CooperativeMatrixM"),
str8_comp("CooperativeMatrixN"),
str8_comp("CooperativeMatrixK"),
},
(str8 []){
- str8_comp("Demodulate"),
- str8_comp("ComplexFilter"),
str8_comp("DecimationRate"),
str8_comp("FilterLength"),
str8_comp("InputChannelStride"),
@@ -970,7 +981,6 @@ read_only global str8 *beamformer_shader_bake_parameter_names[] = {
str8_comp("SamplingFrequency"),
},
(str8 []){
- str8_comp("CoherencyWeighting"),
str8_comp("SingleFocus"),
str8_comp("SingleOrientation"),
str8_comp("Sparse"),
@@ -1002,8 +1012,6 @@ read_only global str8 *beamformer_shader_bake_parameter_names[] = {
str8_comp("OutputStrideX"),
str8_comp("OutputStrideY"),
str8_comp("OutputStrideZ"),
- str8_comp("Interleave"),
- str8_comp("Deinterleave"),
},
0,
};
diff --git a/meta.h b/meta.h
@@ -23,6 +23,18 @@
X(U8, u8, uint8_t, uint8_t, uint8, 1, 1) \
X(STR, str8, error, error, error, 16, 1) \
+read_only global str8 meta_kind_glsl_types[] = {
+ #define X(_k, _c, glsl, ...) str8_comp(#glsl),
+ META_KIND_LIST
+ #undef X
+};
+
+read_only global u8 meta_kind_byte_sizes[] = {
+ #define X(_k, _c, _g, _b, _m, bytes, ...) bytes,
+ META_KIND_LIST
+ #undef X
+};
+
typedef enum {
#define X(k, ...) MetaKind_## k,
META_KIND_LIST
diff --git a/shaders/das.glsl b/shaders/das.glsl
@@ -248,8 +248,8 @@ RESULT_TYPE HERCULES(const vec3 world_point)
RESULT_TYPE result = RESULT_TYPE(0);
for (f32 chunk_channel = 0; chunk_channel < f32(ChunkChannelCount); chunk_channel += 1.0f) {
f32 rx_channel = f32(channel_offset) + chunk_channel;
- int rf_offset = int(rf_element_offset) + int(chunk_channel) * SampleCount * AcquisitionCount + Sparse * SampleCount;
- rf_offset -= int(InterpolationMode == InterpolationMode_Cubic);
+ s32 rf_offset = s32(rf_element_offset) + s32(chunk_channel) * SampleCount * AcquisitionCount + s32(Sparse) * SampleCount;
+ rf_offset -= s32(InterpolationMode == InterpolationMode_Cubic);
// NOTE(rnp): this wouldn't be so messy if we just forced an orientation like with FORCES
vec2 element_receive_delta_squared = xy_world_point;
@@ -259,9 +259,9 @@ RESULT_TYPE HERCULES(const vec3 world_point)
if (rx_cols) element_receive_delta_squared.x *= element_receive_delta_squared.x;
else element_receive_delta_squared.y *= element_receive_delta_squared.y;
- for (int transmit = Sparse; transmit < AcquisitionCount; transmit++) {
- int tx_channel = bool(Sparse) ? ArrayParameters(array_parameters).data.sparse_elements[transmit - Sparse]
- : transmit;
+ for (s32 transmit = s32(Sparse); transmit < AcquisitionCount; transmit++) {
+ s32 tx_channel = Sparse ? ArrayParameters(array_parameters).data.sparse_elements[transmit - s32(Sparse)]
+ : transmit;
if (rx_cols) element_receive_delta_squared.y = xy_world_point.y - tx_channel * xdc_element_pitch.y;
else element_receive_delta_squared.x = xy_world_point.x - tx_channel * xdc_element_pitch.x;
@@ -300,14 +300,14 @@ RESULT_TYPE FORCES(const vec3 xdc_world_point)
float a_arg = abs(FNumber * receive_x_delta / xdc_world_point.z);
if (a_arg < 0.5f) {
- int rf_offset = int(rf_element_offset) + int(chunk_channel) * SampleCount * AcquisitionCount + Sparse * SampleCount;
- rf_offset -= int(InterpolationMode == InterpolationMode_Cubic);
+ s32 rf_offset = s32(rf_element_offset) + s32(chunk_channel) * SampleCount * AcquisitionCount + s32(Sparse) * SampleCount;
+ rf_offset -= s32(InterpolationMode == InterpolationMode_Cubic);
float receive_index = sample_index(sqrt(receive_x_delta * receive_x_delta + z_delta_squared));
float apodization = apodize(a_arg);
- for (int transmit = Sparse; transmit < AcquisitionCount; transmit++) {
- int tx_channel = bool(Sparse) ? ArrayParameters(array_parameters).data.sparse_elements[transmit - Sparse]
- : transmit;
+ for (s32 transmit = s32(Sparse); transmit < AcquisitionCount; transmit++) {
+ s32 tx_channel = Sparse ? ArrayParameters(array_parameters).data.sparse_elements[transmit - s32(Sparse)]
+ : transmit;
float transmit_x_delta = xdc_world_point.x - xdc_element_pitch.x * tx_channel;
float transmit_index = sqrt(transmit_yz_squared + transmit_x_delta * transmit_x_delta) * SamplingFrequency / SpeedOfSound;
diff --git a/shaders/decode.glsl b/shaders/decode.glsl
@@ -23,8 +23,6 @@ OutputDataType sample_rf_data(u32 index)
return result;
}
-#if UseSharedMemory
-
shared InputDataType rf[gl_WorkGroupSize.y][TransmitCount];
void run_decode_large(void)
{
@@ -74,15 +72,14 @@ void run_decode_large(void)
Output(output_buffer).x[out_off] = result[i];
}
}
-#endif
#if CooperativeMatrix
+void run_decode_coop_shmem(void)
+{
+}
void run_decode_coop(void)
{
- #if UseSharedMemory
- #else
-
u32vec2 tile_index = gl_WorkGroupID.xy;
u32 time_sample = gl_WorkGroupID.z;
@@ -117,7 +114,6 @@ void run_decode_coop(void)
Output out_buffer = Output(output_buffer);
coopMatStore(result, out_buffer.x, offset + TransmitCount * result_row + result_col,
TransmitCount, gl_CooperativeMatrixLayoutRowMajor);
- #endif
}
#endif
@@ -158,11 +154,11 @@ void main()
switch (DecodeMode) {
case DecodeMode_Hadamard:{
#if CooperativeMatrix
- run_decode_coop();
- #elif UseSharedMemory
- run_decode_large();
+ if (UseSharedMemory) run_decode_coop_shmem();
+ else run_decode_coop();
#else
- run_decode_small();
+ if (UseSharedMemory) run_decode_large();
+ else run_decode_small();
#endif
}break;
}
diff --git a/shaders/filter.glsl b/shaders/filter.glsl
@@ -1,7 +1,7 @@
/* See LICENSE for license details. */
-#if (InputDataKind == DataKind_Int16Complex || \
- (InputDataKind == DataKind_Int16 && Demodulate) || \
- (InputDataKind == DataKind_Float16 && Demodulate))
+#if (InputDataKind == DataKind_Int16Complex || \
+ (InputDataKind == DataKind_Int16 && Demodulate) || \
+ (InputDataKind == DataKind_Float16 && Demodulate))
#define SAMPLE_TYPE f16vec2
#elif InputDataKind == DataKind_Int16
#define SAMPLE_TYPE f16
@@ -83,7 +83,7 @@ void main()
// input strides were specified in terms of a single element. therefore we
// must divide this by two. by doing this here we can gracefully handle
// the case where there are an odd number of samples (this drops the last one).
- if (Demodulate != 0)
+ if (Demodulate)
in_offset /= 2;
// NOTE(rnp): broken out to avoid overflow from the subtraction
@@ -122,13 +122,13 @@ void main()
OutputSampleStride * out_sample +
output_element_offset;
- #if BatchSampleCount
- // NOTE(rnp): deinterleave
- output_data[out_offset] = OutputDataType(result.x);
- out_offset += BatchSampleCount;
- output_data[out_offset] = OutputDataType(result.y);
- #else
- output_data[out_offset] = OutputDataType(result);
- #endif
+ if (BatchSampleCount != 0) {
+ // NOTE(rnp): deinterleave
+ output_data[out_offset] = OutputDataType(result.x);
+ out_offset += BatchSampleCount;
+ output_data[out_offset] = OutputDataType(result.y);
+ } else {
+ output_data[out_offset] = OutputDataType(result);
+ }
}
}
diff --git a/vulkan.c b/vulkan.c
@@ -591,11 +591,26 @@ vk_stage_flags_from_shader_kind(VulkanShaderKind kind)
return result;
}
+function VkSpecializationMapEntry *
+vk_specialization_map_from_struct_id(Arena *arena, i32 struct_id)
+{
+ assert(struct_id >= 0);
+ MetaStructInfo *si = meta_struct_info_by_id + struct_id;
+ MetaStructMember *sm = meta_struct_members_by_id[struct_id];
+ VkSpecializationMapEntry *result = push_array(arena, VkSpecializationMapEntry, si->member_count);
+ for EachIndex(si->member_count, it) {
+ result[it].constantID = it;
+ result[it].offset = sm[it].offset;
+ result[it].size = meta_kind_byte_sizes[sm[it].type_id];
+ }
+ return result;
+}
+
function VulkanPipeline
-vk_compute_pipeline_from_shader_text(Arena arena, str8 text, str8 name, u32 push_constants_size)
+vk_compute_pipeline_from_info(Arena arena, VulkanPipelineCreateInfo *info, u32 push_constants_size)
{
VulkanPipeline result = {.stage_flags = VK_SHADER_STAGE_COMPUTE_BIT};
- VkShaderModule module = vk_compile_shader_module(arena, VK_SHADER_STAGE_COMPUTE_BIT, text, name);
+ VkShaderModule module = vk_compile_shader_module(arena, VK_SHADER_STAGE_COMPUTE_BIT, info->text, info->name);
if (module) {
VkPushConstantRange push_constant_range = {
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
@@ -624,11 +639,21 @@ vk_compute_pipeline_from_shader_text(Arena arena, str8 text, str8 name, u32 push
},
};
+ VkSpecializationInfo specialization_info = {0};
+ if (info->specialization_data && info->specialization_struct_id >= 0) {
+ MetaStructInfo *si = meta_struct_info_by_id + info->specialization_struct_id;
+ pipeline_create_info.stage.pSpecializationInfo = &specialization_info;
+ specialization_info.pMapEntries = vk_specialization_map_from_struct_id(&arena, info->specialization_struct_id);
+ specialization_info.mapEntryCount = si->member_count;
+ specialization_info.dataSize = si->size;
+ specialization_info.pData = info->specialization_data;
+ }
+
vkCreateComputePipelines(vulkan_context->device, 0, 1, &pipeline_create_info, 0, &result.pipeline);
- vk_label_object(PIPELINE, result.pipeline, name, str8("Pipeline"));
- vk_label_object(PIPELINE_LAYOUT, result.layout, name, str8("Pipeline Layout"));
- vk_label_object(SHADER_MODULE, module, name, str8("Module"));
+ vk_label_object(PIPELINE, result.pipeline, info->name, str8("Pipeline"));
+ vk_label_object(PIPELINE_LAYOUT, result.layout, info->name, str8("Pipeline Layout"));
+ vk_label_object(SHADER_MODULE, module, info->name, str8("Module"));
vkDestroyShaderModule(vulkan_context->device, module, 0);
}
@@ -1880,8 +1905,8 @@ vk_load(OSLibrary vulkan_library_handle, Arena *memory, Stream *err)
"layout(push_constant) uniform pc { uint data[256 / 4]; };\n"
"void main() {}\n"
"\n");
- vk->default_compute_pipeline = vk_compute_pipeline_from_shader_text(vk->arena, default_compute_shader,
- str8("error_compute_shader"), 256);
+ VulkanPipelineCreateInfo compute_create_info = {.text = default_compute_shader, .name = str8("error_compute_shader")};
+ vk->default_compute_pipeline = vk_compute_pipeline_from_info(vk->arena, &compute_create_info, 256);
read_only local_persist str8 default_vertex_shader = str8(""
"#version 430 core\n"
@@ -2355,7 +2380,7 @@ vk_pipeline(VulkanPipelineCreateInfo *infos, u32 count, u32 push_constants_size)
result = (VulkanHandle){(u64)e};
if (count == 2) e->as.pipeline = vk_graphics_pipeline_from_infos(arena, infos, count, push_constants_size);
- else e->as.pipeline = vk_compute_pipeline_from_shader_text(arena, infos[0].text, infos[0].name, push_constants_size);
+ else e->as.pipeline = vk_compute_pipeline_from_info(arena, infos, push_constants_size);
}
return result;
}