ogl_beamforming

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

decode.glsl (3485B)


      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   DataKind == DataKind_Float32
     12 	#define INPUT_DATA_TYPE      float
     13 	#define SAMPLE_DATA_TYPE     float
     14 	#define SAMPLE_TYPE_CAST(x)  (x)
     15 #elif DataKind == DataKind_Float32Complex
     16 	#define INPUT_DATA_TYPE      vec2
     17 	#define SAMPLE_DATA_TYPE     vec2
     18 	#define SAMPLE_TYPE_CAST(x)  (x)
     19 #elif DataKind == DataKind_Int16Complex
     20 	#define INPUT_DATA_TYPE      int
     21 	#define SAMPLE_DATA_TYPE     vec2
     22 	#define SAMPLE_TYPE_CAST(x)  vec2(((x) << 16) >> 16, (x) >> 16)
     23 #elif DataKind == DataKind_Int16
     24 	#define INPUT_DATA_TYPE      int
     25 	#define RF_SAMPLES_PER_INDEX 2
     26 	#if (ShaderFlags & ShaderFlags_DilateOutput)
     27 		#define SAMPLE_DATA_TYPE    vec4
     28 		#define SAMPLE_TYPE_CAST(x) vec4(((x) << 16) >> 16, 0, (x) >> 16, 0)
     29 	#else
     30 		#define SAMPLE_DATA_TYPE    vec2
     31 		#define SAMPLE_TYPE_CAST(x) vec2(((x) << 16) >> 16, (x) >> 16)
     32 		#define OUTPUT_SAMPLES_PER_INDEX 2
     33 	#endif
     34 #else
     35 	#error unsupported data kind for Decode
     36 #endif
     37 
     38 #ifndef OUTPUT_SAMPLES_PER_INDEX
     39 	#define OUTPUT_SAMPLES_PER_INDEX 1
     40 #endif
     41 
     42 #ifndef RF_SAMPLES_PER_INDEX
     43 	#define RF_SAMPLES_PER_INDEX 1
     44 #endif
     45 
     46 layout(std430, binding = 1) readonly restrict buffer buffer_1 {
     47 	INPUT_DATA_TYPE rf_data[];
     48 };
     49 
     50 layout(std430, binding = 2) writeonly restrict buffer buffer_2 {
     51 	INPUT_DATA_TYPE out_rf_data[];
     52 };
     53 
     54 layout(std430, binding = 3) writeonly restrict buffer buffer_3 {
     55 	SAMPLE_DATA_TYPE out_data[];
     56 };
     57 
     58 layout(r8i,  binding = 0) readonly restrict uniform iimage2D hadamard;
     59 layout(r16i, binding = 1) readonly restrict uniform iimage1D channel_mapping;
     60 
     61 SAMPLE_DATA_TYPE sample_rf_data(uint index)
     62 {
     63 	SAMPLE_DATA_TYPE result = SAMPLE_TYPE_CAST(rf_data[index]);
     64 	return result;
     65 }
     66 
     67 void main()
     68 {
     69 	uint time_sample = gl_GlobalInvocationID.x * RF_SAMPLES_PER_INDEX;
     70 	uint channel     = gl_GlobalInvocationID.y;
     71 	uint transmit    = gl_GlobalInvocationID.z;
     72 
     73 	uint rf_offset = (input_channel_stride * channel + transmit_count * time_sample) / RF_SAMPLES_PER_INDEX;
     74 	if (u_first_pass) {
     75 		if (time_sample < input_transmit_stride) {
     76 			uint in_off = input_channel_stride  * imageLoad(channel_mapping, int(channel)).x +
     77 			              input_transmit_stride * transmit +
     78 			              input_sample_stride   * time_sample;
     79 			out_rf_data[rf_offset + transmit] = rf_data[in_off / RF_SAMPLES_PER_INDEX];
     80 		}
     81 	} else {
     82 		if (time_sample < output_transmit_stride) {
     83 			uint out_off = output_channel_stride  * channel +
     84 			               output_transmit_stride * transmit +
     85 			               output_sample_stride   * time_sample;
     86 
     87 			SAMPLE_DATA_TYPE result = SAMPLE_DATA_TYPE(0);
     88 			switch (decode_mode) {
     89 			case DecodeMode_None:{
     90 				result = sample_rf_data(rf_offset + transmit);
     91 			}break;
     92 			case DecodeMode_Hadamard:{
     93 				SAMPLE_DATA_TYPE sum = SAMPLE_DATA_TYPE(0);
     94 				for (int i = 0; i < imageSize(hadamard).x; i++)
     95 					sum += imageLoad(hadamard, ivec2(i, transmit)).x * sample_rf_data(rf_offset++);
     96 				result = sum / float(imageSize(hadamard).x);
     97 			}break;
     98 			}
     99 			out_data[out_off / OUTPUT_SAMPLES_PER_INDEX] = result;
    100 		}
    101 	}
    102 }