ogl_beamforming

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

Commit: 4dfa358da0ff2e22bc73e2ad4a52ae1e4ea978d1
Parent: 1643d83dfb2a08cea4f98c74a0064d8cbd5d08ea
Author: Randy Palamar
Date:   Thu,  5 Nov 2026 21:14:38 -0700

shaders/filter: constant propagate the cos/sin away

In theory this is faster:
Latency:            1653 -> 1631
Inverse Throughput: 169  -> 146

But it may not matter since the shader is usually overlapping with
DAS.

NOTE: the (index & 1u) == 0 selection is very powerful at least on
AMD GPUs. The -1.0, 1.0 are hardcoded into the instruction stream
but don't even add to the instruction footprint. The & 1u can be
hardcoded as a fixed 0x55... mask into a pair of scalar registers
making the whole operation (excluding mask loading) into a single
masked select on values that exist entirely in the instruction
encoding.

Diffstat:
Mshaders/filter.glsl | 10++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/shaders/filter.glsl b/shaders/filter.glsl @@ -52,8 +52,14 @@ f32vec2 complex_mul(f32vec2 a, f32vec2 b) #if Demodulate SAMPLE_TYPE rotate_iq(SAMPLE_TYPE iq, u32 index) { - f32 arg = radians(360) * index / SamplesPerWave; - SAMPLE_TYPE result = SAMPLE_TYPE(complex_mul(iq, f32vec2(cos(arg), -sin(arg)))); + f32 arg = radians(360) * index / SamplesPerWave; + vec2 cs = vec2(cos(arg), -sin(arg)); + if (SamplesPerWave == 2.f) { + cs = f32vec2(((index & 1u) == 0) ? 1.f : -1.f, 0.f); + } else if (SamplesPerWave == 1.f) { + cs = f32vec2(1.f, 0.f); + } + SAMPLE_TYPE result = SAMPLE_TYPE(complex_mul(iq, cs)); return result; } #endif