ogl_beamforming

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

decode.glsl (3844B)


      1 /* See LICENSE for license details. */
      2 
      3 /* NOTE(rnp): invoked with samples x channels x transmits
      4  * Each instance extracts a single time sample from a single channel for all transmits
      5  * and does a dot product with the appropriate row of the bound hadamard matrix
      6  * (unless decode_mode == DECODE_MODE_NONE). The result of this dot product is stored in the
      7  * output. In bulk this has the effect of computing a matrix multiply of the
      8  * sample-transmit plane with the bound hadamard matrix.
      9  */
     10 
     11 #if   defined(INPUT_DATA_TYPE_FLOAT)
     12 	#define INPUT_DATA_TYPE      float
     13 	#define RF_SAMPLES_PER_INDEX 1
     14 	#define RESULT_TYPE_CAST(x)  vec4((x), 0, 0, 0)
     15 	#define SAMPLE_DATA_TYPE     float
     16 	#define SAMPLE_TYPE_CAST(x)  (x)
     17 #elif defined(INPUT_DATA_TYPE_FLOAT_COMPLEX)
     18 	#define INPUT_DATA_TYPE      vec2
     19 	#define RF_SAMPLES_PER_INDEX 1
     20 	#define RESULT_TYPE_CAST(x)  vec4((x), 0, 0)
     21 	#define SAMPLE_DATA_TYPE     vec2
     22 	#define SAMPLE_TYPE_CAST(x)  (x)
     23 #elif defined(INPUT_DATA_TYPE_INT16_COMPLEX)
     24 	#define INPUT_DATA_TYPE      int
     25 	#define RF_SAMPLES_PER_INDEX 1
     26 	#define RESULT_TYPE_CAST(x)  vec4((x), 0, 0)
     27 	#define SAMPLE_DATA_TYPE     vec2
     28 	#define SAMPLE_TYPE_CAST(x)  vec2(((x) << 16) >> 16, (x) >> 16)
     29 #else
     30 	#define INPUT_DATA_TYPE      int
     31 	#define RESULT_TYPE_CAST(x)  (x)
     32 	/* NOTE(rnp): for i16 rf_data we decode 2 samples at once */
     33 	#define RF_SAMPLES_PER_INDEX 2
     34 	#define SAMPLE_DATA_TYPE     vec4
     35 	#if defined(OUTPUT_DATA_TYPE_FLOAT)
     36 		#define SAMPLE_TYPE_CAST(x)  vec4(((x) << 16) >> 16, (x) >> 16, 0, 0)
     37 	#else
     38 		#define SAMPLE_TYPE_CAST(x)  vec4(((x) << 16) >> 16, 0, (x) >> 16, 0)
     39 	#endif
     40 #endif
     41 
     42 layout(std430, binding = 1) readonly restrict buffer buffer_1 {
     43 	INPUT_DATA_TYPE rf_data[];
     44 };
     45 
     46 layout(std430, binding = 2) writeonly restrict buffer buffer_2 {
     47 	INPUT_DATA_TYPE out_rf_data[];
     48 };
     49 
     50 layout(std430, binding = 3) writeonly restrict buffer buffer_3 {
     51 	vec2 out_data[];
     52 };
     53 
     54 layout(r8i,  binding = 0) readonly restrict uniform iimage2D hadamard;
     55 layout(r16i, binding = 1) readonly restrict uniform iimage1D channel_mapping;
     56 
     57 SAMPLE_DATA_TYPE sample_rf_data(uint index)
     58 {
     59 	SAMPLE_DATA_TYPE result = SAMPLE_TYPE_CAST(rf_data[index]);
     60 	return result;
     61 }
     62 
     63 void main()
     64 {
     65 	uint time_sample = gl_GlobalInvocationID.x * RF_SAMPLES_PER_INDEX;
     66 	uint channel     = gl_GlobalInvocationID.y;
     67 	uint transmit    = gl_GlobalInvocationID.z;
     68 
     69 	uint rf_offset = (input_channel_stride * channel + transmit_count * time_sample) / RF_SAMPLES_PER_INDEX;
     70 	if (u_first_pass) {
     71 		if (time_sample < input_transmit_stride) {
     72 			uint in_off = input_channel_stride  * imageLoad(channel_mapping, int(channel)).x +
     73 			              input_transmit_stride * transmit +
     74 			              input_sample_stride   * time_sample;
     75 			out_rf_data[rf_offset + transmit] = rf_data[in_off / RF_SAMPLES_PER_INDEX];
     76 		}
     77 	} else {
     78 		#if defined(OUTPUT_DATA_TYPE_FLOAT)
     79 		/* NOTE(rnp): when outputting floats do not dilate the out time sample;
     80 		 * output should end up densely packed */
     81 		time_sample = gl_GlobalInvocationID.x;
     82 		#endif
     83 		if (time_sample < output_transmit_stride) {
     84 			uint out_off = output_channel_stride  * channel +
     85 			               output_transmit_stride * transmit +
     86 			               output_sample_stride   * time_sample;
     87 
     88 			vec4 result = vec4(0);
     89 			switch (decode_mode) {
     90 			case DECODE_MODE_NONE: {
     91 				result = RESULT_TYPE_CAST(sample_rf_data(rf_offset + transmit));
     92 			} break;
     93 			case DECODE_MODE_HADAMARD: {
     94 				SAMPLE_DATA_TYPE sum = SAMPLE_DATA_TYPE(0);
     95 				for (int i = 0; i < imageSize(hadamard).x; i++)
     96 					sum += imageLoad(hadamard, ivec2(i, transmit)).x * sample_rf_data(rf_offset++);
     97 				result = RESULT_TYPE_CAST(sum) / float(imageSize(hadamard).x);
     98 			} break;
     99 			}
    100 			out_data[out_off + 0] = result.xy;
    101 			#if RF_SAMPLES_PER_INDEX == 2 && !defined(OUTPUT_DATA_TYPE_FLOAT)
    102 			out_data[out_off + 1] = result.zw;
    103 			#endif
    104 		}
    105 	}
    106 }