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 }