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