decode.glsl (3073B)
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 #else 24 #define INPUT_DATA_TYPE int 25 #define RF_SAMPLES_PER_INDEX 2 26 #define RESULT_TYPE_CAST(x) (x) 27 #define SAMPLE_DATA_TYPE vec4 28 /* NOTE(rnp): for i16 rf_data we decode 2 samples at once */ 29 #define SAMPLE_TYPE_CAST(x) vec4(((x) << 16) >> 16, 0, (x) >> 16, 0) 30 #endif 31 32 layout(std430, binding = 1) readonly restrict buffer buffer_1 { 33 INPUT_DATA_TYPE rf_data[]; 34 }; 35 36 layout(std430, binding = 2) writeonly restrict buffer buffer_2 { 37 INPUT_DATA_TYPE out_rf_data[]; 38 }; 39 40 layout(std430, binding = 3) writeonly restrict buffer buffer_3 { 41 vec2 out_data[]; 42 }; 43 44 layout(r8i, binding = 0) readonly restrict uniform iimage2D hadamard; 45 layout(r16i, binding = 1) readonly restrict uniform iimage1D channel_mapping; 46 47 SAMPLE_DATA_TYPE sample_rf_data(uint index) 48 { 49 SAMPLE_DATA_TYPE result = SAMPLE_TYPE_CAST(rf_data[index]); 50 return result; 51 } 52 53 void main() 54 { 55 uint time_sample = gl_GlobalInvocationID.x * RF_SAMPLES_PER_INDEX; 56 uint channel = gl_GlobalInvocationID.y; 57 uint transmit = gl_GlobalInvocationID.z; 58 59 uint rf_offset = (channel * rf_raw_dim.x + time_sample * dec_data_dim.z) / RF_SAMPLES_PER_INDEX; 60 if (u_first_pass) { 61 int rf_channel = imageLoad(channel_mapping, int(channel)).x; 62 uint in_off = rf_channel * rf_raw_dim.x + transmit * dec_data_dim.x + time_sample; 63 out_rf_data[rf_offset + transmit] = rf_data[in_off / RF_SAMPLES_PER_INDEX]; 64 } else { 65 /* NOTE(rnp): stores output as a 3D matrix with ordering of {samples, channels, transmits} */ 66 uint out_off = dec_data_dim.x * dec_data_dim.y * transmit + dec_data_dim.x * channel + time_sample; 67 68 vec4 result = vec4(0); 69 switch (decode) { 70 case DECODE_MODE_NONE: { 71 result = RESULT_TYPE_CAST(sample_rf_data(rf_offset + transmit)); 72 } break; 73 case DECODE_MODE_HADAMARD: { 74 SAMPLE_DATA_TYPE sum = SAMPLE_DATA_TYPE(0); 75 for (int i = 0; i < dec_data_dim.z; i++) 76 sum += imageLoad(hadamard, ivec2(i, transmit)).x * sample_rf_data(rf_offset++); 77 result = RESULT_TYPE_CAST(sum) / float(dec_data_dim.z); 78 } break; 79 } 80 out_data[out_off + 0] = result.xy; 81 #if RF_SAMPLES_PER_INDEX == 2 82 out_data[out_off + 1] = result.zw; 83 #endif 84 } 85 }