beamformer.h (11380B)
1 /* See LICENSE for license details. */ 2 #ifndef _BEAMFORMER_H_ 3 #define _BEAMFORMER_H_ 4 5 #include <raylib_extended.h> 6 #include <rlgl.h> 7 8 #include "util.h" 9 10 /////////////////// 11 // REQUIRED OS API 12 function OS_READ_WHOLE_FILE_FN(os_read_whole_file); 13 function OS_SHARED_MEMORY_LOCK_REGION_FN(os_shared_memory_region_lock); 14 function OS_SHARED_MEMORY_UNLOCK_REGION_FN(os_shared_memory_region_unlock); 15 function OS_WAKE_WAITERS_FN(os_wake_waiters); 16 function OS_WRITE_FILE_FN(os_write_file); 17 18 #include "opengl.h" 19 #include "util_gl.c" 20 21 enum gl_vendor_ids { 22 GL_VENDOR_AMD, 23 GL_VENDOR_ARM, 24 GL_VENDOR_INTEL, 25 GL_VENDOR_NVIDIA, 26 }; 27 28 typedef struct { 29 v2 mouse; 30 v2 last_mouse; 31 b32 executable_reloaded; 32 f32 dt; 33 } BeamformerInput; 34 35 #define CUDA_INIT_FN(name) void name(u32 *input_dims, u32 *decoded_dims) 36 typedef CUDA_INIT_FN(cuda_init_fn); 37 CUDA_INIT_FN(cuda_init_stub) {} 38 39 #define CUDA_REGISTER_BUFFERS_FN(name) void name(u32 *rf_data_ssbos, u32 rf_buffer_count, u32 raw_data_ssbo) 40 typedef CUDA_REGISTER_BUFFERS_FN(cuda_register_buffers_fn); 41 CUDA_REGISTER_BUFFERS_FN(cuda_register_buffers_stub) {} 42 43 #define CUDA_DECODE_FN(name) void name(size_t input_offset, u32 output_buffer_idx, u32 rf_channel_offset) 44 typedef CUDA_DECODE_FN(cuda_decode_fn); 45 CUDA_DECODE_FN(cuda_decode_stub) {} 46 47 #define CUDA_HILBERT_FN(name) void name(u32 input_buffer_idx, u32 output_buffer_idx) 48 typedef CUDA_HILBERT_FN(cuda_hilbert_fn); 49 CUDA_HILBERT_FN(cuda_hilbert_stub) {} 50 51 #define CUDA_SET_CHANNEL_MAPPING_FN(name) void name(i16 *channel_mapping) 52 typedef CUDA_SET_CHANNEL_MAPPING_FN(cuda_set_channel_mapping_fn); 53 CUDA_SET_CHANNEL_MAPPING_FN(cuda_set_channel_mapping_stub) {} 54 55 #define CUDA_LIB_FNS \ 56 X(decode, "cuda_decode") \ 57 X(hilbert, "cuda_hilbert") \ 58 X(init, "init_cuda_configuration") \ 59 X(register_buffers, "register_cuda_buffers") \ 60 X(set_channel_mapping, "cuda_set_channel_mapping") 61 62 typedef struct { 63 void *lib; 64 #define X(name, symname) cuda_ ## name ## _fn *name; 65 CUDA_LIB_FNS 66 #undef X 67 } CudaLib; 68 69 /* TODO(rnp): this should be a UBO */ 70 #define FRAME_VIEW_MODEL_MATRIX_LOC 0 71 #define FRAME_VIEW_VIEW_MATRIX_LOC 1 72 #define FRAME_VIEW_PROJ_MATRIX_LOC 2 73 #define FRAME_VIEW_DYNAMIC_RANGE_LOC 3 74 #define FRAME_VIEW_THRESHOLD_LOC 4 75 #define FRAME_VIEW_GAMMA_LOC 5 76 #define FRAME_VIEW_LOG_SCALE_LOC 6 77 #define FRAME_VIEW_BB_COLOUR_LOC 7 78 #define FRAME_VIEW_BB_FRACTION_LOC 8 79 #define FRAME_VIEW_SOLID_BB_LOC 10 80 81 #define FRAME_VIEW_BB_COLOUR 0.92, 0.88, 0.78, 1.0 82 #define FRAME_VIEW_BB_FRACTION 0.007f 83 84 #define FRAME_VIEW_RENDER_TARGET_SIZE 1024, 1024 85 86 typedef struct { 87 u32 shader; 88 u32 framebuffers[2]; /* [0] -> multisample target, [1] -> normal target for resolving */ 89 u32 renderbuffers[2]; /* only used for 3D views, size is fixed */ 90 b32 updated; 91 } FrameViewRenderContext; 92 93 #include "beamformer_parameters.h" 94 #include "beamformer_shared_memory.c" 95 96 typedef struct { 97 iptr elements_offset; 98 i32 elements; 99 u32 buffer; 100 u32 vao; 101 } BeamformerRenderModel; 102 103 typedef struct { 104 BeamformerFilterKind kind; 105 BeamformerFilterParameters parameters; 106 u32 texture; 107 } BeamformerFilter; 108 109 /* X(name, type, gltype) */ 110 #define BEAMFORMER_DEMOD_UBO_PARAM_LIST \ 111 X(input_channel_stride, u32, uint) \ 112 X(input_sample_stride, u32, uint) \ 113 X(input_transmit_stride, u32, uint) \ 114 X(output_channel_stride, u32, uint) \ 115 X(output_sample_stride, u32, uint) \ 116 X(output_transmit_stride, u32, uint) \ 117 X(decimation_rate, u32, uint) \ 118 X(map_channels, b32, bool) \ 119 X(demodulation_frequency, f32, float) \ 120 X(sampling_frequency, f32, float) 121 122 /* X(name, type, gltype) */ 123 #define BEAMFORMER_DECODE_UBO_PARAM_LIST \ 124 X(input_channel_stride, u32, uint) \ 125 X(input_sample_stride, u32, uint) \ 126 X(input_transmit_stride, u32, uint) \ 127 X(output_channel_stride, u32, uint) \ 128 X(output_sample_stride, u32, uint) \ 129 X(output_transmit_stride, u32, uint) \ 130 X(transmit_count, u32, uint) \ 131 X(decode_mode, u32, uint) 132 133 typedef alignas(16) struct { 134 #define X(name, type, ...) type name; 135 BEAMFORMER_DECODE_UBO_PARAM_LIST 136 #undef X 137 } BeamformerDecodeUBO; 138 static_assert((sizeof(BeamformerDecodeUBO) & 15) == 0, "UBO size must be a multiple of 16"); 139 140 typedef alignas(16) struct { 141 #define X(name, type, ...) type name; 142 BEAMFORMER_DEMOD_UBO_PARAM_LIST 143 #undef X 144 float _pad[2]; 145 } BeamformerDemodulateUBO; 146 static_assert((sizeof(BeamformerDemodulateUBO) & 15) == 0, "UBO size must be a multiple of 16"); 147 148 /* TODO(rnp): das should remove redundant info and add voxel transform */ 149 #define BEAMFORMER_COMPUTE_UBO_LIST \ 150 X(DAS, BeamformerParameters, das) \ 151 X(Decode, BeamformerDecodeUBO, decode) \ 152 X(Demodulate, BeamformerDemodulateUBO, demod) 153 154 #define X(k, ...) BeamformerComputeUBOKind_##k, 155 typedef enum {BEAMFORMER_COMPUTE_UBO_LIST BeamformerComputeUBOKind_Count} BeamformerComputeUBOKind; 156 #undef X 157 158 #define BEAMFORMER_COMPUTE_TEXTURE_LIST \ 159 X(ChannelMapping, GL_R16I) \ 160 X(FocalVectors, GL_RG32F) \ 161 X(SparseElements, GL_R16I) \ 162 X(Hadamard, GL_R8I) 163 164 typedef enum { 165 #define X(k, ...) BeamformerComputeTextureKind_##k, 166 BEAMFORMER_COMPUTE_TEXTURE_LIST 167 #undef X 168 BeamformerComputeTextureKind_Count 169 } BeamformerComputeTextureKind; 170 static_assert((BeamformerComputeTextureKind_Count - 1) == BeamformerComputeTextureKind_Hadamard, 171 "BeamformerComputeTextureKind_Hadamard must be end of TextureKinds"); 172 173 typedef struct BeamformerComputePlan BeamformerComputePlan; 174 struct BeamformerComputePlan { 175 BeamformerComputePipeline pipeline; 176 177 uv3 decode_dispatch; 178 uv3 demod_dispatch; 179 180 u32 rf_size; 181 i32 hadamard_order; 182 183 u32 textures[BeamformerComputeTextureKind_Count]; 184 u32 ubos[BeamformerComputeUBOKind_Count]; 185 186 BeamformerFilter filters[BeamformerFilterSlots]; 187 188 #define X(k, type, name) type name ##_ubo_data; 189 BEAMFORMER_COMPUTE_UBO_LIST 190 #undef X 191 192 BeamformerComputePlan *next; 193 }; 194 195 typedef struct { 196 GLsync upload_syncs[BeamformerMaxRawDataFramesInFlight]; 197 GLsync compute_syncs[BeamformerMaxRawDataFramesInFlight]; 198 199 u32 ssbo; 200 u32 size; 201 202 u32 data_timestamp_query; 203 204 u32 insertion_index; 205 u32 compute_index; 206 } BeamformerRFBuffer; 207 208 typedef struct { 209 u32 programs[BeamformerShaderKind_ComputeCount]; 210 BeamformerRFBuffer rf_buffer; 211 212 BeamformerComputePlan *compute_plans[BeamformerMaxParameterBlockSlots]; 213 BeamformerComputePlan *compute_plan_freelist; 214 215 /* NOTE(rnp): two interstage ssbos are allocated so that they may be used to 216 * ping pong data between compute stages */ 217 u32 ping_pong_ssbos[2]; 218 u32 last_output_ssbo_index; 219 220 u32 ping_pong_ssbo_size; 221 222 f32 processing_progress; 223 b32 processing_compute; 224 225 u32 shader_timer_ids[BeamformerMaxComputeShaderStages]; 226 227 BeamformerRenderModel unit_cube_model; 228 CudaLib cuda_lib; 229 } BeamformerComputeContext; 230 231 typedef enum { 232 #define X(type, id, pretty, fixed_tx) DASShaderKind_##type = id, 233 DAS_TYPES 234 #undef X 235 DASShaderKind_Count 236 } DASShaderKind; 237 238 typedef struct { 239 BeamformerComputeStatsTable table; 240 f32 average_times[BeamformerShaderKind_Count]; 241 242 u64 last_rf_timer_count; 243 f32 rf_time_delta_average; 244 245 u32 latest_frame_index; 246 u32 latest_rf_index; 247 } ComputeShaderStats; 248 249 /* TODO(rnp): maybe this also gets used for CPU timing info as well */ 250 typedef enum { 251 ComputeTimingInfoKind_ComputeFrameBegin, 252 ComputeTimingInfoKind_ComputeFrameEnd, 253 ComputeTimingInfoKind_Shader, 254 ComputeTimingInfoKind_RF_Data, 255 } ComputeTimingInfoKind; 256 257 typedef struct { 258 u64 timer_count; 259 ComputeTimingInfoKind kind; 260 union { 261 BeamformerShaderKind shader; 262 }; 263 } ComputeTimingInfo; 264 265 typedef struct { 266 u32 write_index; 267 u32 read_index; 268 b32 compute_frame_active; 269 ComputeTimingInfo buffer[4096]; 270 } ComputeTimingTable; 271 272 typedef struct { 273 BeamformerRFBuffer *rf_buffer; 274 SharedMemoryRegion *shared_memory; 275 ComputeTimingTable *compute_timing_table; 276 i32 *compute_worker_sync; 277 } BeamformerUploadThreadContext; 278 279 struct BeamformerFrame { 280 u32 texture; 281 b32 ready_to_present; 282 283 iv3 dim; 284 i32 mips; 285 286 /* NOTE: for use when displaying either prebeamformed frames or on the current frame 287 * when we intend to recompute on the next frame */ 288 v4 min_coordinate; 289 v4 max_coordinate; 290 291 // metadata 292 u32 id; 293 u32 compound_count; 294 DASShaderKind das_shader_kind; 295 BeamformerViewPlaneTag view_plane_tag; 296 297 BeamformerFrame *next; 298 }; 299 300 #define GL_PARAMETERS \ 301 X(MAJOR_VERSION, version_major, "") \ 302 X(MINOR_VERSION, version_minor, "") \ 303 X(MIN_MAP_BUFFER_ALIGNMENT, min_map_buffer_alignment, "") \ 304 X(TEXTURE_BUFFER_OFFSET_ALIGNMENT, texture_buffer_offset_alignment, "") \ 305 X(MAX_TEXTURE_BUFFER_SIZE, max_texture_buffer_size, "") \ 306 X(MAX_TEXTURE_SIZE, max_2d_texture_dim, "") \ 307 X(MAX_3D_TEXTURE_SIZE, max_3d_texture_dim, "") \ 308 X(MAX_SHADER_STORAGE_BLOCK_SIZE, max_ssbo_size, "") \ 309 X(MAX_COMPUTE_SHARED_MEMORY_SIZE, max_shared_memory_size, "") \ 310 X(MAX_UNIFORM_BLOCK_SIZE, max_ubo_size, "") \ 311 X(MAX_SERVER_WAIT_TIMEOUT, max_server_wait_time, " [ns]") 312 313 typedef struct { 314 enum gl_vendor_ids vendor_id; 315 #define X(glname, name, suffix) i32 name; 316 GL_PARAMETERS 317 #undef X 318 } GLParams; 319 320 typedef struct { 321 GLParams gl; 322 323 iv2 window_size; 324 b32 should_exit; 325 326 Arena ui_backing_store; 327 void *ui; 328 u32 ui_dirty_parameter_blocks; 329 330 BeamformerComputeContext compute_context; 331 332 /* TODO(rnp): ideally this would go in the UI but its hard to manage with the UI 333 * destroying itself on hot-reload */ 334 FrameViewRenderContext frame_view_render_context; 335 336 OS os; 337 Stream error_stream; 338 339 BeamformWorkQueue *beamform_work_queue; 340 341 ComputeShaderStats *compute_shader_stats; 342 ComputeTimingTable *compute_timing_table; 343 344 SharedMemoryRegion shared_memory; 345 346 BeamformerFrame beamform_frames[BeamformerMaxSavedFrames]; 347 BeamformerFrame *latest_frame; 348 u32 next_render_frame_index; 349 u32 display_frame_index; 350 351 /* NOTE: this will only be used when we are averaging */ 352 u32 averaged_frame_index; 353 BeamformerFrame averaged_frames[2]; 354 } BeamformerCtx; 355 356 struct ShaderReloadContext { 357 BeamformerCtx *beamformer_context; 358 s8 path; 359 s8 name; 360 s8 header; 361 u32 *shader; 362 ShaderReloadContext *link; 363 GLenum gl_type; 364 BeamformerShaderKind kind; 365 }; 366 367 #define BEAMFORMER_FRAME_STEP_FN(name) void name(BeamformerCtx *ctx, BeamformerInput *input) 368 typedef BEAMFORMER_FRAME_STEP_FN(beamformer_frame_step_fn); 369 370 #define BEAMFORMER_COMPLETE_COMPUTE_FN(name) void name(iptr user_context, Arena *arena, iptr gl_context) 371 typedef BEAMFORMER_COMPLETE_COMPUTE_FN(beamformer_complete_compute_fn); 372 373 #define BEAMFORMER_RF_UPLOAD_FN(name) void name(BeamformerUploadThreadContext *ctx, Arena arena) 374 typedef BEAMFORMER_RF_UPLOAD_FN(beamformer_rf_upload_fn); 375 376 #define BEAMFORMER_RELOAD_SHADER_FN(name) b32 name(OS *os, BeamformerCtx *ctx, \ 377 ShaderReloadContext *src, Arena arena, s8 shader_name) 378 typedef BEAMFORMER_RELOAD_SHADER_FN(beamformer_reload_shader_fn); 379 380 #define BEAMFORMER_DEBUG_UI_DEINIT_FN(name) void name(BeamformerCtx *ctx) 381 typedef BEAMFORMER_DEBUG_UI_DEINIT_FN(beamformer_debug_ui_deinit_fn); 382 383 #endif /*_BEAMFORMER_H_ */