decode.glsl (2958B)
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 vec2 out_data[]; 38 }; 39 40 layout(r8i, binding = 0) readonly restrict uniform iimage2D hadamard; 41 layout(r16i, binding = 1) readonly restrict uniform iimage1D channel_mapping; 42 43 SAMPLE_DATA_TYPE sample_rf_data(int index) 44 { 45 SAMPLE_DATA_TYPE result = SAMPLE_TYPE_CAST(rf_data[index]); 46 return result; 47 } 48 49 void main() 50 { 51 int time_sample = int(gl_GlobalInvocationID.x); 52 int channel = int(gl_GlobalInvocationID.y); 53 int transmit = int(gl_GlobalInvocationID.z); 54 55 /* NOTE(rnp): stores output as a 3D matrix with ordering of {samples, channels, transmits} */ 56 uint out_off = dec_data_dim.x * dec_data_dim.y * transmit + dec_data_dim.x * channel; 57 out_off += RF_SAMPLES_PER_INDEX * time_sample; 58 59 int rf_channel = imageLoad(channel_mapping, channel).x; 60 61 /* NOTE(rnp): samples input as 2D matrix of {samples * transmits + padding, channels} */ 62 int rf_stride = int(dec_data_dim.x) / RF_SAMPLES_PER_INDEX; 63 int rf_offset = (int(rf_raw_dim.x) * rf_channel) / RF_SAMPLES_PER_INDEX + time_sample; 64 65 vec4 result = vec4(0); 66 switch (decode) { 67 case DECODE_MODE_NONE: { 68 result = RESULT_TYPE_CAST(sample_rf_data(rf_offset + rf_stride * transmit)); 69 } break; 70 case DECODE_MODE_HADAMARD: { 71 SAMPLE_DATA_TYPE sum = SAMPLE_DATA_TYPE(0); 72 for (int i = 0; i < dec_data_dim.z; i++) { 73 sum += imageLoad(hadamard, ivec2(i, transmit)).x * sample_rf_data(rf_offset); 74 rf_offset += rf_stride; 75 } 76 result = RESULT_TYPE_CAST(sum) / float(dec_data_dim.z); 77 } break; 78 } 79 out_data[out_off + 0] = result.xy; 80 #if RF_SAMPLES_PER_INDEX == 2 81 out_data[out_off + 1] = result.zw; 82 #endif 83 }