beamformer.h (6788B)
1 /* See LICENSE for license details. */ 2 #ifndef _BEAMFORMER_H_ 3 #define _BEAMFORMER_H_ 4 5 #include <glad.h> 6 7 #define GRAPHICS_API_OPENGL_43 8 #include <raylib_extended.h> 9 #include <rlgl.h> 10 11 #include "util.h" 12 13 enum gl_vendor_ids { 14 GL_VENDOR_AMD, 15 GL_VENDOR_ARM, 16 GL_VENDOR_INTEL, 17 GL_VENDOR_NVIDIA, 18 }; 19 20 typedef struct { 21 b32 executable_reloaded; 22 b32 pipe_data_available; 23 iptr pipe_handle; 24 25 v2 mouse; 26 v2 last_mouse; 27 } BeamformerInput; 28 29 #define INIT_CUDA_CONFIGURATION_FN(name) void name(u32 *input_dims, u32 *decoded_dims, u16 *channel_mapping) 30 typedef INIT_CUDA_CONFIGURATION_FN(init_cuda_configuration_fn); 31 INIT_CUDA_CONFIGURATION_FN(init_cuda_configuration_stub) {} 32 33 #define REGISTER_CUDA_BUFFERS_FN(name) void name(u32 *rf_data_ssbos, u32 rf_buffer_count, u32 raw_data_ssbo) 34 typedef REGISTER_CUDA_BUFFERS_FN(register_cuda_buffers_fn); 35 REGISTER_CUDA_BUFFERS_FN(register_cuda_buffers_stub) {} 36 37 #define CUDA_DECODE_FN(name) void name(size_t input_offset, u32 output_buffer_idx, u32 rf_channel_offset) 38 typedef CUDA_DECODE_FN(cuda_decode_fn); 39 CUDA_DECODE_FN(cuda_decode_stub) {} 40 41 #define CUDA_HILBERT_FN(name) void name(u32 input_buffer_idx, u32 output_buffer_idx) 42 typedef CUDA_HILBERT_FN(cuda_hilbert_fn); 43 CUDA_HILBERT_FN(cuda_hilbert_stub) {} 44 45 #define CUDA_LIB_FNS \ 46 X(cuda_decode) \ 47 X(cuda_hilbert) \ 48 X(init_cuda_configuration) \ 49 X(register_cuda_buffers) 50 51 typedef struct { 52 void *lib; 53 u64 timestamp; 54 #define X(name) name ## _fn *name; 55 CUDA_LIB_FNS 56 #undef X 57 } CudaLib; 58 59 #include "beamformer_parameters.h" 60 61 typedef struct { 62 BeamformerParameters raw; 63 ComputeShaderID compute_stages[16]; 64 u32 compute_stages_count; 65 b32 upload; 66 u32 raw_data_size; 67 b32 export_next_frame; 68 c8 export_pipe_name[1024]; 69 } BeamformerParametersFull; 70 71 #define CS_UNIFORMS \ 72 X(CS_DAS, voxel_offset) \ 73 X(CS_DAS, cycle_t) \ 74 X(CS_MIN_MAX, mips_level) \ 75 X(CS_SUM, sum_prescale) 76 77 typedef struct { 78 u32 programs[CS_LAST]; 79 80 /* NOTE: The raw data ssbo is not mapped on NVIDIA because their drivers _will_ store 81 * the buffer in the system memory. This doesn't happen for other vendors and 82 * mapping the buffer is preferred. In either case incoming data can be written to 83 * the arena. An additional BufferSubData is needed on NVIDIA to upload the data. */ 84 Arena raw_data_arena; 85 u32 raw_data_ssbo; 86 87 /* NOTE: Decoded data is only relevant in the context of a single frame. We use two 88 * buffers so that they can be swapped when chaining multiple compute stages */ 89 u32 rf_data_ssbos[2]; 90 u32 last_output_ssbo_index; 91 u32 hadamard_texture; 92 93 u32 shared_ubo; 94 95 f32 processing_progress; 96 b32 processing_compute; 97 98 uv4 dec_data_dim; 99 u32 rf_raw_size; 100 101 #define X(idx, name) i32 name ## _id; 102 CS_UNIFORMS 103 #undef X 104 } ComputeShaderCtx; 105 106 typedef struct { 107 Shader shader; 108 b32 updated; 109 i32 db_cutoff_id; 110 i32 threshold_id; 111 } FragmentShaderCtx; 112 113 typedef enum { 114 #define X(type, id, pretty, fixed_tx) DAS_ ##type = id, 115 DAS_TYPES 116 #undef X 117 DAS_LAST 118 } DASShaderID; 119 120 typedef struct { 121 /* TODO(rnp): there is assumption here that each shader will occur only once 122 * per compute. add an insertion index and change these to hold the max number 123 * of executed compute stages */ 124 u32 timer_ids[CS_LAST]; 125 f32 times[CS_LAST]; 126 b32 timer_active[CS_LAST]; 127 } ComputeShaderStats; 128 129 typedef struct BeamformFrame { 130 uv3 dim; 131 u32 texture; 132 133 /* NOTE: for use when displaying either prebeamformed frames or on the current frame 134 * when we intend to recompute on the next frame */ 135 v4 min_coordinate; 136 v4 max_coordinate; 137 138 u32 mips; 139 b32 in_flight; 140 b32 ready_to_present; 141 DASShaderID das_shader_id; 142 u32 compound_count; 143 u32 id; 144 145 struct BeamformFrame *next; 146 } BeamformFrame; 147 148 typedef struct { 149 enum gl_vendor_ids vendor_id; 150 i32 version_major; 151 i32 version_minor; 152 i32 max_2d_texture_dim; 153 i32 max_3d_texture_dim; 154 i32 max_ssbo_size; 155 i32 max_ubo_size; 156 i32 max_server_wait_time; 157 } GLParams; 158 159 enum beamform_work { 160 BW_COMPUTE, 161 BW_LOAD_RF_DATA, 162 BW_RELOAD_SHADER, 163 BW_SAVE_FRAME, 164 BW_SEND_FRAME, 165 }; 166 167 typedef struct { 168 void *beamformer_ctx; 169 s8 label; 170 s8 path; 171 ComputeShaderID shader; 172 b32 needs_header; 173 } ComputeShaderReloadContext; 174 175 typedef struct { 176 BeamformFrame *store; 177 ComputeShaderStats *stats; 178 } BeamformerWorkFrame; 179 180 typedef struct { 181 BeamformerWorkFrame frame; 182 iptr file_handle; 183 } BeamformOutputFrameContext; 184 185 /* NOTE: discriminated union based on type */ 186 typedef struct { 187 union { 188 iptr file_handle; 189 BeamformerWorkFrame frame; 190 BeamformOutputFrameContext output_frame_ctx; 191 ComputeShaderReloadContext *reload_shader_ctx; 192 }; 193 u32 type; 194 } BeamformWork; 195 196 typedef struct { 197 union { 198 u64 queue; 199 struct {u32 widx, ridx;}; 200 }; 201 BeamformWork work_items[1 << 6]; 202 } BeamformWorkQueue; 203 204 typedef struct { 205 BeamformFrame *frames; 206 u32 capacity; 207 u32 offset; 208 u32 cursor; 209 u32 needed_frames; 210 } BeamformFrameIterator; 211 212 typedef struct BeamformerCtx { 213 GLParams gl; 214 215 uv2 window_size; 216 b32 start_compute; 217 b32 should_exit; 218 219 /* TODO(rnp): is there a better way of tracking this? */ 220 b32 ready_for_rf; 221 222 Arena ui_backing_store; 223 void *ui; 224 /* TODO(rnp): this is nasty and should be removed */ 225 b32 ui_read_params; 226 227 BeamformFrame beamform_frames[MAX_BEAMFORMED_SAVED_FRAMES]; 228 ComputeShaderStats beamform_frame_compute_stats[MAX_BEAMFORMED_SAVED_FRAMES]; 229 u32 next_render_frame_index; 230 u32 display_frame_index; 231 232 /* NOTE: this will only be used when we are averaging */ 233 u32 averaged_frame_index; 234 BeamformFrame averaged_frames[2]; 235 ComputeShaderStats averaged_frame_compute_stats[2]; 236 237 ComputeShaderCtx csctx; 238 FragmentShaderCtx fsctx; 239 240 Arena export_buffer; 241 242 CudaLib cuda_lib; 243 OS os; 244 Stream error_stream; 245 246 BeamformWorkQueue *beamform_work_queue; 247 248 BeamformerParametersFull *params; 249 } BeamformerCtx; 250 251 #define LABEL_GL_OBJECT(type, id, s) {s8 _s = (s); glObjectLabel(type, id, _s.len, (c8 *)_s.data);} 252 253 #define BEAMFORMER_FRAME_STEP_FN(name) void name(BeamformerCtx *ctx, Arena *arena, \ 254 BeamformerInput *input) 255 typedef BEAMFORMER_FRAME_STEP_FN(beamformer_frame_step_fn); 256 257 #define BEAMFORMER_COMPLETE_COMPUTE_FN(name) void name(iptr user_context, Arena arena, iptr gl_context) 258 typedef BEAMFORMER_COMPLETE_COMPUTE_FN(beamformer_complete_compute_fn); 259 260 #define BEAMFORM_WORK_QUEUE_PUSH_FN(name) BeamformWork *name(BeamformWorkQueue *q) 261 typedef BEAMFORM_WORK_QUEUE_PUSH_FN(beamform_work_queue_push_fn); 262 263 #define BEAMFORM_WORK_QUEUE_PUSH_COMMIT_FN(name) void name(BeamformWorkQueue *q) 264 typedef BEAMFORM_WORK_QUEUE_PUSH_COMMIT_FN(beamform_work_queue_push_commit_fn); 265 266 #endif /*_BEAMFORMER_H_ */