beamformer.h (11056B)
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 OS_READ_WHOLE_FILE_FN(os_read_whole_file); 17 function OS_SHARED_MEMORY_LOCK_REGION_FN(os_shared_memory_region_lock); 18 function OS_SHARED_MEMORY_UNLOCK_REGION_FN(os_shared_memory_region_unlock); 19 function OS_WAKE_WAITERS_FN(os_wake_waiters); 20 function OS_WRITE_FILE_FN(os_write_file); 21 22 #include "util_gl.c" 23 24 enum gl_vendor_ids { 25 GL_VENDOR_AMD, 26 GL_VENDOR_ARM, 27 GL_VENDOR_INTEL, 28 GL_VENDOR_NVIDIA, 29 }; 30 31 typedef struct { 32 v2 mouse; 33 v2 last_mouse; 34 b32 executable_reloaded; 35 f32 dt; 36 } BeamformerInput; 37 38 #define CUDA_INIT_FN(name) void name(u32 *input_dims, u32 *decoded_dims) 39 typedef CUDA_INIT_FN(cuda_init_fn); 40 CUDA_INIT_FN(cuda_init_stub) {} 41 42 #define CUDA_REGISTER_BUFFERS_FN(name) void name(u32 *rf_data_ssbos, u32 rf_buffer_count, u32 raw_data_ssbo) 43 typedef CUDA_REGISTER_BUFFERS_FN(cuda_register_buffers_fn); 44 CUDA_REGISTER_BUFFERS_FN(cuda_register_buffers_stub) {} 45 46 #define CUDA_DECODE_FN(name) void name(size_t input_offset, u32 output_buffer_idx, u32 rf_channel_offset) 47 typedef CUDA_DECODE_FN(cuda_decode_fn); 48 CUDA_DECODE_FN(cuda_decode_stub) {} 49 50 #define CUDA_HILBERT_FN(name) void name(u32 input_buffer_idx, u32 output_buffer_idx) 51 typedef CUDA_HILBERT_FN(cuda_hilbert_fn); 52 CUDA_HILBERT_FN(cuda_hilbert_stub) {} 53 54 #define CUDA_SET_CHANNEL_MAPPING_FN(name) void name(i16 *channel_mapping) 55 typedef CUDA_SET_CHANNEL_MAPPING_FN(cuda_set_channel_mapping_fn); 56 CUDA_SET_CHANNEL_MAPPING_FN(cuda_set_channel_mapping_stub) {} 57 58 #define CUDALibraryProcedureList \ 59 X(decode, "cuda_decode") \ 60 X(hilbert, "cuda_hilbert") \ 61 X(init, "init_cuda_configuration") \ 62 X(register_buffers, "register_cuda_buffers") \ 63 X(set_channel_mapping, "cuda_set_channel_mapping") 64 65 #define X(name, ...) DEBUG_IMPORT cuda_## name ##_fn *cuda_## name; 66 CUDALibraryProcedureList 67 #undef X 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 f32 time_delay; 107 i32 length; 108 u32 ssbo; 109 } BeamformerFilter; 110 111 /* X(name, type, gltype) */ 112 #define BEAMFORMER_DAS_UBO_PARAM_LIST \ 113 X(voxel_transform, m4, mat4) \ 114 X(xdc_transform, m4, mat4) \ 115 X(xdc_element_pitch, v2, vec2) 116 117 typedef alignas(16) struct { 118 #define X(name, type, ...) type name; 119 BEAMFORMER_DAS_UBO_PARAM_LIST 120 #undef X 121 float _pad[2]; 122 } BeamformerDASUBO; 123 static_assert((sizeof(BeamformerDASUBO) & 15) == 0, "UBO size must be a multiple of 16"); 124 125 /* TODO(rnp): need 1 UBO per filter slot */ 126 #define BEAMFORMER_COMPUTE_UBO_LIST \ 127 X(DAS, BeamformerDASUBO, das) 128 129 #define X(k, ...) BeamformerComputeUBOKind_##k, 130 typedef enum {BEAMFORMER_COMPUTE_UBO_LIST BeamformerComputeUBOKind_Count} BeamformerComputeUBOKind; 131 #undef X 132 133 // X(kind, gl_kind, texture_format, pixel_type) 134 #define BEAMFORMER_COMPUTE_TEXTURE_LIST \ 135 X(FocalVectors, GL_RG32F, GL_RG, GL_FLOAT) \ 136 X(SparseElements, GL_R16I, GL_RED_INTEGER, GL_SHORT) \ 137 X(TransmitReceiveOrientations, GL_R8I, GL_RED_INTEGER, GL_BYTE) 138 139 #define BEAMFORMER_COMPUTE_TEXTURE_LIST_FULL \ 140 BEAMFORMER_COMPUTE_TEXTURE_LIST \ 141 X(Hadamard, GL_R32F) 142 143 typedef enum { 144 #define X(k, ...) BeamformerComputeTextureKind_##k, 145 BEAMFORMER_COMPUTE_TEXTURE_LIST_FULL 146 #undef X 147 BeamformerComputeTextureKind_Count 148 } BeamformerComputeTextureKind; 149 static_assert((BeamformerComputeTextureKind_Count - 1) == BeamformerComputeTextureKind_Hadamard, 150 "BeamformerComputeTextureKind_Hadamard must be end of TextureKinds"); 151 152 typedef struct { 153 uv3 layout; 154 uv3 dispatch; 155 BeamformerShaderBakeParameters bake; 156 } BeamformerShaderDescriptor; 157 158 typedef struct BeamformerComputePlan BeamformerComputePlan; 159 struct BeamformerComputePlan { 160 BeamformerComputePipeline pipeline; 161 162 u32 programs[BeamformerMaxComputeShaderStages]; 163 164 u32 dirty_programs; 165 166 BeamformerAcquisitionKind acquisition_kind; 167 u32 acquisition_count; 168 169 u32 rf_size; 170 i32 hadamard_order; 171 b32 iq_pipeline; 172 173 v3 min_coordinate; 174 v3 max_coordinate; 175 iv3 output_points; 176 i32 average_frames; 177 178 u32 textures[BeamformerComputeTextureKind_Count]; 179 u32 ubos[BeamformerComputeUBOKind_Count]; 180 181 BeamformerFilter filters[BeamformerFilterSlots]; 182 183 #define X(k, type, name) type name ##_ubo_data; 184 BEAMFORMER_COMPUTE_UBO_LIST 185 #undef X 186 187 u128 shader_hashes[BeamformerMaxComputeShaderStages]; 188 BeamformerShaderDescriptor shader_descriptors[BeamformerMaxComputeShaderStages]; 189 190 BeamformerComputePlan *next; 191 }; 192 193 typedef struct { 194 GLsync upload_syncs[BeamformerMaxRawDataFramesInFlight]; 195 GLsync compute_syncs[BeamformerMaxRawDataFramesInFlight]; 196 197 u32 ssbo; 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 #define GL_PARAMETERS \ 293 X(MAJOR_VERSION, version_major, "") \ 294 X(MINOR_VERSION, version_minor, "") \ 295 X(MIN_MAP_BUFFER_ALIGNMENT, min_map_buffer_alignment, "") \ 296 X(TEXTURE_BUFFER_OFFSET_ALIGNMENT, texture_buffer_offset_alignment, "") \ 297 X(MAX_TEXTURE_BUFFER_SIZE, max_texture_buffer_size, "") \ 298 X(MAX_TEXTURE_SIZE, max_2d_texture_dim, "") \ 299 X(MAX_3D_TEXTURE_SIZE, max_3d_texture_dim, "") \ 300 X(MAX_SHADER_STORAGE_BLOCK_SIZE, max_ssbo_size, "") \ 301 X(MAX_COMPUTE_SHARED_MEMORY_SIZE, max_shared_memory_size, "") \ 302 X(MAX_UNIFORM_BLOCK_SIZE, max_ubo_size, "") \ 303 X(MAX_SERVER_WAIT_TIMEOUT, max_server_wait_time, " [ns]") 304 305 typedef struct { 306 enum gl_vendor_ids vendor_id; 307 #define X(glname, name, suffix) i32 name; 308 GL_PARAMETERS 309 #undef X 310 } GLParams; 311 312 typedef struct { 313 GLParams gl; 314 315 iv2 window_size; 316 b32 should_exit; 317 318 Arena ui_backing_store; 319 void *ui; 320 u32 ui_dirty_parameter_blocks; 321 322 BeamformerComputeContext compute_context; 323 324 /* TODO(rnp): ideally this would go in the UI but its hard to manage with the UI 325 * destroying itself on hot-reload */ 326 FrameViewRenderContext frame_view_render_context; 327 328 OS os; 329 Stream error_stream; 330 331 BeamformWorkQueue *beamform_work_queue; 332 333 ComputeShaderStats *compute_shader_stats; 334 ComputeTimingTable *compute_timing_table; 335 336 SharedMemoryRegion shared_memory; 337 338 BeamformerFrame beamform_frames[BeamformerMaxSavedFrames]; 339 BeamformerFrame *latest_frame; 340 u32 next_render_frame_index; 341 u32 display_frame_index; 342 343 /* NOTE: this will only be used when we are averaging */ 344 u32 averaged_frame_index; 345 BeamformerFrame averaged_frames[2]; 346 } BeamformerCtx; 347 348 typedef struct ShaderReloadContext ShaderReloadContext; 349 struct ShaderReloadContext { 350 BeamformerCtx *beamformer_context; 351 ShaderReloadContext *link; 352 s8 header; 353 GLenum gl_type; 354 i32 reloadable_info_index; 355 }; 356 357 #define BEAMFORMER_FRAME_STEP_FN(name) void name(BeamformerCtx *ctx, BeamformerInput *input) 358 typedef BEAMFORMER_FRAME_STEP_FN(beamformer_frame_step_fn); 359 360 #define BEAMFORMER_COMPLETE_COMPUTE_FN(name) void name(iptr user_context, Arena *arena, iptr gl_context) 361 typedef BEAMFORMER_COMPLETE_COMPUTE_FN(beamformer_complete_compute_fn); 362 363 #define BEAMFORMER_RF_UPLOAD_FN(name) void name(BeamformerUploadThreadContext *ctx, Arena arena) 364 typedef BEAMFORMER_RF_UPLOAD_FN(beamformer_rf_upload_fn); 365 366 #define BEAMFORMER_RELOAD_SHADER_FN(name) b32 name(OS *os, s8 path, ShaderReloadContext *src, \ 367 Arena arena, s8 shader_name) 368 typedef BEAMFORMER_RELOAD_SHADER_FN(beamformer_reload_shader_fn); 369 370 #define BEAMFORMER_DEBUG_UI_DEINIT_FN(name) void name(BeamformerCtx *ctx) 371 typedef BEAMFORMER_DEBUG_UI_DEINIT_FN(beamformer_debug_ui_deinit_fn); 372 373 #endif /*_BEAMFORMER_H_ */