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