ogl_beamforming

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

Commit: c880d8118d965d5898e6295a19aade47ca05e66c
Parent: cf2955efa08fba1c7f3541621bcb8cf12130cbe9
Author: Randy Palamar
Date:   Tue,  8 Sep 2026 21:25:06 -0700

decode/filter: cleanup over-complicated shared memory loading

This is much more idiomatic and is more likley to allow the
compiler to optimize to using instructions which use the local
tid "register" directly.

Diffstat:
Mshaders/decode.glsl | 11+----------
Mshaders/filter.glsl | 12++----------
2 files changed, 3 insertions(+), 20 deletions(-)

diff --git a/shaders/decode.glsl b/shaders/decode.glsl @@ -28,18 +28,9 @@ void run_decode_large(void) u32 channel = gl_GlobalInvocationID.y; u32 time_sample = gl_GlobalInvocationID.z; - const u32 samples_per_thread = TransmitCount / gl_WorkGroupSize.x; - const u32 leftover_samples = TransmitCount % gl_WorkGroupSize.x; - - u32 thread_index_x = gl_LocalInvocationID.x; - u32 samples_this_thread = samples_per_thread + u32(thread_index_x < leftover_samples); - u32 rf_offset = TransmitCount * ChunkChannelCount * gl_WorkGroupID.z + TransmitCount * channel; - - for (u32 i = 0; i < samples_this_thread; i++) { - u32 index = i * gl_WorkGroupSize.x + thread_index_x; + for (u32 index = gl_LocalInvocationID.x; index < TransmitCount; index += gl_WorkGroupSize.x) rf[gl_LocalInvocationID.y][index] = RF(rf_buffer).x[rf_offset + index]; - } barrier(); diff --git a/shaders/filter.glsl b/shaders/filter.glsl @@ -66,8 +66,6 @@ void main() uint channel = gl_GlobalInvocationID.y; uint transmit = gl_GlobalInvocationID.z; - uint thread_index = gl_LocalInvocationIndex; - uint thread_count = gl_WorkGroupSize.x * gl_WorkGroupSize.y * gl_WorkGroupSize.z; ///////////////////////// // NOTE: sample caching { @@ -86,14 +84,8 @@ void main() input_address += InputDataKindByteSize * (DecimationRate * gl_WorkGroupID.x * gl_WorkGroupSize.x); input_address -= InputDataKindByteSize * (FilterLength - 1); - uint total_samples = rf.length(); - uint samples_per_thread = total_samples / thread_count; - uint leftover_count = total_samples % thread_count; - uint samples_this_thread = samples_per_thread + uint(thread_index < leftover_count); - const SAMPLE_TYPE scale = SAMPLE_TYPE(bool(ComplexFilter) ? 1 : sqrt(2.0f)); - for (uint i = 0; i < samples_this_thread; i++) { - uint index = thread_count * i + thread_index; + for (u32 index = gl_LocalInvocationIndex; index < rf.length(); index += gl_WorkGroupSize.x) { SAMPLE_TYPE s = SAMPLE_TYPE(0); if (!offset_wraps || index >= FilterLength - 1) { s = SAMPLE_TYPE(Input(input_address).x[index]); @@ -109,7 +101,7 @@ void main() Filter f = Filter(HeapBase + FilterCoefficients); if (out_sample < SampleCount / DecimationRate) { RESULT_TYPE result = RESULT_TYPE(0); - u32 offset = DecimationRate * thread_index; + u32 offset = DecimationRate * gl_LocalInvocationIndex; for (u32 j = 0; j < FilterLength; j++) result += apply_filter(rf[offset + j], f.values[j]);