Commit: f7518ff88f916cfd61c95b307910fae2fb16a9ca
Parent: c6f25ad89a2e480feae755d19978ccee18133dc9
Author: Randy Palamar
Date: Fri, 12 Sep 2025 12:43:19 -0600
core/das: upload array of transmit/receive orientations for RCA methods
each acquistion event could utilize a different orientation pair in these methods
Diffstat:
10 files changed, 82 insertions(+), 75 deletions(-)
diff --git a/beamformer.c b/beamformer.c
@@ -96,11 +96,11 @@ beamformer_compute_plan_for_block(BeamformerComputeContext *cc, u32 block, Arena
#undef X
#define X(_k, t, ...) t,
- GLenum gl_kind[] = {BEAMFORMER_COMPUTE_TEXTURE_LIST};
+ GLenum gl_kind[] = {BEAMFORMER_COMPUTE_TEXTURE_LIST_FULL};
#undef X
read_only local_persist s8 tex_prefix[] = {
#define X(k, ...) s8_comp(#k "["),
- BEAMFORMER_COMPUTE_TEXTURE_LIST
+ BEAMFORMER_COMPUTE_TEXTURE_LIST_FULL
#undef X
};
glCreateTextures(GL_TEXTURE_1D, BeamformerComputeTextureKind_Count - 1, result->textures);
@@ -455,10 +455,6 @@ das_ubo_from_beamformer_parameters(BeamformerDASUBO *du, BeamformerParameters *b
du->shader_flags = 0;
if (bp->coherency_weighting) du->shader_flags |= BeamformerShaderDASFlags_CoherencyWeighting;
- if (bp->transmit_mode == BeamformerRCAOrientation_Columns)
- du->shader_flags |= BeamformerShaderDASFlags_TxColumns;
- if (bp->receive_mode == BeamformerRCAOrientation_Columns)
- du->shader_flags |= BeamformerShaderDASFlags_RxColumns;
}
function void
@@ -713,35 +709,28 @@ beamformer_commit_parameter_block(BeamformerCtx *ctx, BeamformerComputePlan *cp,
alloc_beamform_frame(&ctx->gl, ctx->averaged_frames + 1, cp->output_points, gl_kind, s8("Averaged Frame"), arena);
}
}break;
- case BeamformerParameterBlockRegion_ChannelMapping:
+ case BeamformerParameterBlockRegion_ChannelMapping:{
+ cuda_set_channel_mapping(pb->channel_mapping);
+ } /* FALLTHROUGH */
case BeamformerParameterBlockRegion_FocalVectors:
case BeamformerParameterBlockRegion_SparseElements:
+ case BeamformerParameterBlockRegion_TransmitReceiveOrientations:
{
BeamformerComputeTextureKind texture_kind = 0;
- u32 texture_type = 0, texture_format = 0;
- /* TODO(rnp): this whole thing could be a table */
+ u32 pixel_type = 0, texture_format = 0;
switch (region) {
- case BeamformerParameterBlockRegion_ChannelMapping:{
- texture_kind = BeamformerComputeTextureKind_ChannelMapping;
- texture_type = GL_SHORT;
- texture_format = GL_RED_INTEGER;
- /* TODO(rnp): cuda lib */
- cuda_set_channel_mapping(pb->channel_mapping);
- }break;
- case BeamformerParameterBlockRegion_FocalVectors:{
- texture_kind = BeamformerComputeTextureKind_FocalVectors;
- texture_type = GL_FLOAT;
- texture_format = GL_RG;
- }break;
- case BeamformerParameterBlockRegion_SparseElements:{
- texture_kind = BeamformerComputeTextureKind_SparseElements;
- texture_type = GL_SHORT;
- texture_format = GL_RED_INTEGER;
+ #define X(kind, _gl, tf, pt, ...) \
+ case BeamformerParameterBlockRegion_## kind:{ \
+ texture_kind = BeamformerComputeTextureKind_## kind; \
+ texture_format = tf; \
+ pixel_type = pt; \
}break;
+ BEAMFORMER_COMPUTE_TEXTURE_LIST
+ #undef X
InvalidDefaultCase;
}
glTextureSubImage1D(cp->textures[texture_kind], 0, 0, BeamformerMaxChannelCount,
- texture_format, texture_type,
+ texture_format, pixel_type,
(u8 *)pb + BeamformerParameterBlockRegionOffsets[region]);
}break;
}
@@ -858,6 +847,7 @@ do_compute_shader(BeamformerCtx *ctx, BeamformerComputePlan *cp, BeamformerFrame
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 1, cc->ping_pong_ssbos[input_ssbo_idx], 0, cp->rf_size);
glBindImageTexture(1, sparse_texture, 0, 0, 0, GL_READ_ONLY, GL_R16I);
glBindImageTexture(2, cp->textures[BeamformerComputeTextureKind_FocalVectors], 0, 0, 0, GL_READ_ONLY, GL_RG32F);
+ glBindImageTexture(3, cp->textures[BeamformerComputeTextureKind_TransmitReceiveOrientations], 0, 0, 0, GL_READ_ONLY, GL_R8I);
glProgramUniform1ui(program, DAS_CYCLE_T_UNIFORM_LOC, das_cycle_t++);
diff --git a/beamformer.h b/beamformer.h
@@ -180,15 +180,20 @@ static_assert((sizeof(BeamformerDASUBO) & 15) == 0, "UBO size must be a multiple
typedef enum {BEAMFORMER_COMPUTE_UBO_LIST BeamformerComputeUBOKind_Count} BeamformerComputeUBOKind;
#undef X
+// X(kind, gl_kind, texture_format, pixel_type)
#define BEAMFORMER_COMPUTE_TEXTURE_LIST \
- X(ChannelMapping, GL_R16I) \
- X(FocalVectors, GL_RG32F) \
- X(SparseElements, GL_R16I) \
+ X(ChannelMapping, GL_R16I, GL_RED_INTEGER, GL_SHORT) \
+ X(FocalVectors, GL_RG32F, GL_RG, GL_FLOAT) \
+ X(SparseElements, GL_R16I, GL_RED_INTEGER, GL_SHORT) \
+ X(TransmitReceiveOrientations, GL_R8I, GL_RED_INTEGER, GL_BYTE)
+
+#define BEAMFORMER_COMPUTE_TEXTURE_LIST_FULL \
+ BEAMFORMER_COMPUTE_TEXTURE_LIST \
X(Hadamard, GL_R8I)
typedef enum {
#define X(k, ...) BeamformerComputeTextureKind_##k,
- BEAMFORMER_COMPUTE_TEXTURE_LIST
+ BEAMFORMER_COMPUTE_TEXTURE_LIST_FULL
#undef X
BeamformerComputeTextureKind_Count
} BeamformerComputeTextureKind;
diff --git a/beamformer.meta b/beamformer.meta
@@ -45,7 +45,7 @@
@Enumeration(RCAOrientation)
- @Flags([CoherencyWeighting RxColumns TxColumns])
+ @Flags([CoherencyWeighting])
}
@Shader(min_max.glsl) MinMax
diff --git a/beamformer_parameters.h b/beamformer_parameters.h
@@ -84,10 +84,8 @@ typedef enum {BEAMFORMER_CONSTANTS_LIST} BeamformerConstants;
X(acquisition_count, uint32_t, , uint32, 1, "") \
X(das_shader_id, uint32_t, , uint32, 1, "") \
X(time_offset, float, , single, 1, "pulse length correction time [s]") \
- X(decode, uint8_t, , uint8, 1, "Decode or just reshape data") \
- X(transmit_mode, uint8_t, , uint8, 1, "Method/Orientation of Transmit") \
- X(receive_mode, uint8_t, , uint8, 1, "Method/Orientation of Receive") \
- X(sampling_mode, uint8_t, , uint8, 1, "")
+ X(decode, uint16_t, , uint16, 1, "Decode or just reshape data") \
+ X(sampling_mode, uint16_t, , uint16, 1, "")
#define BEAMFORMER_UI_PARAMS \
X(output_min_coordinate, float, [3], single, 3, "[m] Back-Top-Left corner of output region") \
@@ -104,14 +102,15 @@ typedef enum {BEAMFORMER_CONSTANTS_LIST} BeamformerConstants;
X(decimation_rate, uint32_t, , uint32, 1, "Number of times to decimate")
#define BEAMFORMER_SIMPLE_PARAMS \
- X(channel_mapping, int16_t, [BeamformerMaxChannelCount], int16, BeamformerMaxChannelCount) \
- X(sparse_elements, int16_t, [BeamformerMaxChannelCount], int16, BeamformerMaxChannelCount) \
- X(steering_angles, float, [BeamformerMaxChannelCount], single, BeamformerMaxChannelCount) \
- X(focal_depths, float, [BeamformerMaxChannelCount], single, BeamformerMaxChannelCount) \
- X(compute_stages, int32_t, [BeamformerMaxComputeShaderStages], int32, BeamformerMaxComputeShaderStages) \
- X(compute_stage_parameters, int16_t, [BeamformerMaxComputeShaderStages], int16, BeamformerMaxComputeShaderStages) \
- X(compute_stages_count, uint32_t, , uint32, 1) \
- X(data_kind, int32_t, , int32, 1)
+ X(channel_mapping, int16_t, [BeamformerMaxChannelCount], int16, BeamformerMaxChannelCount) \
+ X(sparse_elements, int16_t, [BeamformerMaxChannelCount], int16, BeamformerMaxChannelCount) \
+ X(transmit_receive_orientations, uint8_t, [BeamformerMaxChannelCount], uint8, BeamformerMaxChannelCount) \
+ X(steering_angles, float, [BeamformerMaxChannelCount], single, BeamformerMaxChannelCount) \
+ X(focal_depths, float, [BeamformerMaxChannelCount], single, BeamformerMaxChannelCount) \
+ X(compute_stages, int32_t, [BeamformerMaxComputeShaderStages], int32, BeamformerMaxComputeShaderStages) \
+ X(compute_stage_parameters, int16_t, [BeamformerMaxComputeShaderStages], int16, BeamformerMaxComputeShaderStages) \
+ X(compute_stages_count, uint32_t, , uint32, 1) \
+ X(data_kind, int32_t, , int32, 1)
#define X(name, type, size, ...) type name size;
typedef struct {BEAMFORMER_PARAMS_HEAD} BeamformerParametersHead;
diff --git a/beamformer_shared_memory.c b/beamformer_shared_memory.c
@@ -1,5 +1,5 @@
/* See LICENSE for license details. */
-#define BEAMFORMER_SHARED_MEMORY_VERSION (14UL)
+#define BEAMFORMER_SHARED_MEMORY_VERSION (15UL)
typedef struct BeamformerFrame BeamformerFrame;
typedef struct ShaderReloadContext ShaderReloadContext;
@@ -96,11 +96,12 @@ typedef enum {BEAMFORMER_LIVE_IMAGING_DIRTY_FLAG_LIST} BeamformerLiveImagingDirt
#undef X
#define BEAMFORMER_PARAMETER_BLOCK_REGION_LIST \
- X(ComputePipeline, pipeline) \
- X(ChannelMapping, channel_mapping) \
- X(FocalVectors, focal_vectors) \
- X(Parameters, parameters) \
- X(SparseElements, sparse_elements)
+ X(ComputePipeline, pipeline) \
+ X(ChannelMapping, channel_mapping) \
+ X(FocalVectors, focal_vectors) \
+ X(Parameters, parameters) \
+ X(SparseElements, sparse_elements) \
+ X(TransmitReceiveOrientations, transmit_receive_orientations)
typedef enum {
#define X(k, ...) BeamformerParameterBlockRegion_##k,
@@ -138,6 +139,7 @@ typedef struct {
alignas(16) i16 channel_mapping[BeamformerMaxChannelCount];
alignas(16) i16 sparse_elements[BeamformerMaxChannelCount];
+ alignas(16) u8 transmit_receive_orientations[BeamformerMaxChannelCount];
/* NOTE(rnp): interleaved transmit angle, focal depth pairs */
alignas(16) v2 focal_vectors[BeamformerMaxChannelCount];
} BeamformerParameterBlock;
diff --git a/generated/beamformer.meta.c b/generated/beamformer.meta.c
@@ -43,8 +43,6 @@ typedef enum {
BeamformerShaderDASFlags_Sparse = (1 << 1),
BeamformerShaderDASFlags_Interpolate = (1 << 2),
BeamformerShaderDASFlags_CoherencyWeighting = (1 << 3),
- BeamformerShaderDASFlags_RxColumns = (1 << 4),
- BeamformerShaderDASFlags_TxColumns = (1 << 5),
} BeamformerShaderDASFlags;
typedef enum {
@@ -245,8 +243,6 @@ read_only global s8 beamformer_shader_local_header_strings[] = {
"#define ShaderFlags_Sparse (1 << 1)\n"
"#define ShaderFlags_Interpolate (1 << 2)\n"
"#define ShaderFlags_CoherencyWeighting (1 << 3)\n"
- "#define ShaderFlags_RxColumns (1 << 4)\n"
- "#define ShaderFlags_TxColumns (1 << 5)\n"
"\n"),
{0},
{0},
diff --git a/helpers/ogl_beamformer_lib.c b/helpers/ogl_beamformer_lib.c
@@ -410,9 +410,10 @@ beamformer_wait_for_compute_dispatch(i32 timeout_ms)
}
#define BEAMFORMER_UPLOAD_FNS \
- X(channel_mapping, i16, 1, ChannelMapping) \
- X(sparse_elements, i16, 1, SparseElements) \
- X(focal_vectors, f32, 2, FocalVectors)
+ X(channel_mapping, i16, 1, ChannelMapping) \
+ X(focal_vectors, f32, 2, FocalVectors) \
+ X(sparse_elements, i16, 1, SparseElements) \
+ X(transmit_receive_orientations, u8, 1, TransmitReceiveOrientations)
#define X(name, dtype, elements, region_name) \
b32 beamformer_push_##name ##_at(dtype *data, u32 count, u32 block) { \
@@ -493,17 +494,20 @@ beamformer_push_simple_parameters_at(BeamformerSimpleParameters *bp, u32 block)
{
b32 result = validate_simple_parameters(bp);
if (result) {
+ alignas(64) v2 focal_vectors[countof(bp->steering_angles)];
+ for (u32 i = 0; i < countof(bp->steering_angles); i++)
+ focal_vectors[i] = (v2){{bp->steering_angles[i], bp->focal_depths[i]}};
+
result &= beamformer_push_parameters_at((BeamformerParameters *)bp, block);
result &= beamformer_push_pipeline_at(bp->compute_stages, bp->compute_stages_count, (BeamformerDataKind)bp->data_kind, block);
result &= beamformer_push_channel_mapping_at(bp->channel_mapping, bp->channel_count, block);
+ result &= beamformer_push_focal_vectors_at((f32 *)focal_vectors, countof(focal_vectors), block);
+ result &= beamformer_push_transmit_receive_orientations_at(bp->transmit_receive_orientations,
+ bp->acquisition_count, block);
+
if (bp->das_shader_id == BeamformerDASKind_UFORCES || bp->das_shader_id == BeamformerDASKind_UHERCULES)
result &= beamformer_push_sparse_elements_at(bp->sparse_elements, bp->acquisition_count, block);
- alignas(64) v2 focal_vectors[countof(bp->steering_angles)];
- for (u32 i = 0; i < countof(bp->steering_angles); i++)
- focal_vectors[i] = (v2){{bp->steering_angles[i], bp->focal_depths[i]}};
- result &= beamformer_push_focal_vectors_at((f32 *)focal_vectors, countof(focal_vectors), block);
-
for (u32 stage = 0; stage < bp->compute_stages_count; stage++)
result &= beamformer_set_pipeline_stage_parameters_at(stage, bp->compute_stage_parameters[stage], block);
}
diff --git a/helpers/ogl_beamformer_lib_base.h b/helpers/ogl_beamformer_lib_base.h
@@ -112,6 +112,9 @@ LIB_FN uint32_t beamformer_push_sparse_elements_at(int16_t *elements, uint32_t c
LIB_FN uint32_t beamformer_push_focal_vectors(float *vectors, uint32_t count);
LIB_FN uint32_t beamformer_push_focal_vectors_at(float *vectors, uint32_t count, uint32_t parameter_slot);
+LIB_FN uint32_t beamformer_push_transmit_receive_orientations(uint8_t *values, uint32_t count);
+LIB_FN uint32_t beamformer_push_transmit_receive_orientations_at(uint8_t *values, uint32_t count, uint32_t parameter_slot);
+
////////////////////
// Filter Creation
diff --git a/shaders/das.glsl b/shaders/das.glsl
@@ -40,6 +40,10 @@ layout(TEXTURE_KIND, binding = 0) writeonly restrict uniform image3D u_out_data
layout(r16i, binding = 1) readonly restrict uniform iimage1D sparse_elements;
layout(rg32f, binding = 2) readonly restrict uniform image1D focal_vectors;
+layout(r8i, binding = 3) readonly restrict uniform iimage1D transmit_receive_orientations;
+
+#define RX_ORIENTATION_MASK (1 << 0)
+#define TX_ORIENTATION_MASK (1 << 1)
#define C_SPLINE 0.5
@@ -139,8 +143,8 @@ float cylindrical_wave_transmit_distance(vec3 point, float focal_depth, float tr
#if (ShaderFlags & ShaderFlags_Fast)
RESULT_TYPE RCA(vec3 world_point)
{
- bool tx_rows = bool((shader_flags & ShaderFlags_TxColumns) == 0);
- bool rx_rows = bool((shader_flags & ShaderFlags_RxColumns) == 0);
+ bool tx_rows = (imageLoad(transmit_receive_orientations, u_channel).x & TX_ORIENTATION_MASK) == 0;
+ bool rx_rows = (imageLoad(transmit_receive_orientations, u_channel).x & RX_ORIENTATION_MASK) == 0;
vec2 xdc_world_point = rca_plane_projection((xdc_transform * vec4(world_point, 1)).xyz, rx_rows);
vec2 focal_vector = imageLoad(focal_vectors, u_channel).xy;
float transmit_angle = radians(focal_vector.x);
@@ -170,15 +174,14 @@ RESULT_TYPE RCA(vec3 world_point)
#else
RESULT_TYPE RCA(vec3 world_point)
{
- bool tx_rows = bool((shader_flags & ShaderFlags_TxColumns) == 0);
- bool rx_rows = bool((shader_flags & ShaderFlags_RxColumns) == 0);
- vec2 xdc_world_point = rca_plane_projection((xdc_transform * vec4(world_point, 1)).xyz, rx_rows);
-
RESULT_TYPE result = RESULT_TYPE(0);
for (int transmit = 0; transmit < acquisition_count; transmit++) {
vec2 focal_vector = imageLoad(focal_vectors, transmit).xy;
float transmit_angle = radians(focal_vector.x);
float focal_depth = focal_vector.y;
+ bool tx_rows = (imageLoad(transmit_receive_orientations, u_channel).x & TX_ORIENTATION_MASK) == 0;
+ bool rx_rows = (imageLoad(transmit_receive_orientations, u_channel).x & RX_ORIENTATION_MASK) == 0;
+ vec2 xdc_world_point = rca_plane_projection((xdc_transform * vec4(world_point, 1)).xyz, rx_rows);
float transmit_distance;
if (isinf(focal_depth)) {
@@ -208,8 +211,8 @@ RESULT_TYPE RCA(vec3 world_point)
RESULT_TYPE HERCULES(vec3 world_point)
{
vec3 xdc_world_point = (xdc_transform * vec4(world_point, 1)).xyz;
- bool tx_rows = bool((shader_flags & ShaderFlags_TxColumns) == 0);
- bool rx_cols = bool((shader_flags & ShaderFlags_RxColumns));
+ bool tx_rows = (imageLoad(transmit_receive_orientations, 0).x & TX_ORIENTATION_MASK) == 0;
+ bool rx_cols = (imageLoad(transmit_receive_orientations, 0).x & RX_ORIENTATION_MASK) != 0;
vec2 focal_vector = imageLoad(focal_vectors, 0).xy;
float transmit_angle = radians(focal_vector.x);
float focal_depth = focal_vector.y;
@@ -245,8 +248,8 @@ RESULT_TYPE HERCULES(vec3 world_point)
RESULT_TYPE HERCULES(vec3 world_point)
{
vec3 xdc_world_point = (xdc_transform * vec4(world_point, 1)).xyz;
- bool tx_rows = bool((shader_flags & ShaderFlags_TxColumns) == 0);
- bool rx_cols = bool((shader_flags & ShaderFlags_RxColumns));
+ bool tx_rows = (imageLoad(transmit_receive_orientations, 0).x & TX_ORIENTATION_MASK) == 0;
+ bool rx_cols = (imageLoad(transmit_receive_orientations, 0).x & RX_ORIENTATION_MASK) != 0;
vec2 focal_vector = imageLoad(focal_vectors, 0).xy;
float transmit_angle = radians(focal_vector.x);
float focal_depth = focal_vector.y;
diff --git a/tests/throughput.c b/tests/throughput.c
@@ -205,8 +205,6 @@ beamformer_parameters_from_zemp_bp_v1(zemp_bp_v1 *zbp, BeamformerParameters *out
out->sample_count = zbp->decoded_data_dim[0];
out->channel_count = zbp->decoded_data_dim[1];
out->acquisition_count = zbp->decoded_data_dim[2];
- out->transmit_mode = (u8)((zbp->transmit_mode & 2) >> 1);
- out->receive_mode = (u8)((zbp->transmit_mode & 1) >> 0);
out->decode = (u8)zbp->decode_mode;
out->das_shader_id = zbp->beamform_mode;
out->time_offset = zbp->time_offset;
@@ -354,11 +352,18 @@ execute_study(s8 study, Arena arena, Stream path, Options *options)
}
{
- alignas(64) v2 focal_vectors[countof(zbp->focal_depths)];
- for (u32 i = 0; i < countof(zbp->focal_depths); i++)
+ alignas(64) v2 focal_vectors[BeamformerMaxChannelCount];
+ for (u32 i = 0; i < countof(focal_vectors); i++)
focal_vectors[i] = (v2){{zbp->transmit_angles[i], zbp->focal_depths[i]}};
beamformer_push_focal_vectors((f32 *)focal_vectors, countof(focal_vectors));
}
+ {
+ alignas(64) u8 transmit_receive_orientations[BeamformerMaxChannelCount];
+ for (u32 i = 0; i < countof(transmit_receive_orientations); i++)
+ transmit_receive_orientations[i] = (u8)zbp->transmit_mode;
+ beamformer_push_transmit_receive_orientations(transmit_receive_orientations,
+ countof(transmit_receive_orientations));
+ }
beamformer_push_channel_mapping(zbp->channel_mapping, countof(zbp->channel_mapping));
beamformer_push_sparse_elements(zbp->sparse_elements, countof(zbp->sparse_elements));