beamformer.h (11126B)
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(ChannelMapping, GL_R16I, GL_RED_INTEGER, GL_SHORT) \ 136 X(FocalVectors, GL_RG32F, GL_RG, GL_FLOAT) \ 137 X(SparseElements, GL_R16I, GL_RED_INTEGER, GL_SHORT) \ 138 X(TransmitReceiveOrientations, GL_R8I, GL_RED_INTEGER, GL_BYTE) 139 140 #define BEAMFORMER_COMPUTE_TEXTURE_LIST_FULL \ 141 BEAMFORMER_COMPUTE_TEXTURE_LIST \ 142 X(Hadamard, GL_R32F) 143 144 typedef enum { 145 #define X(k, ...) BeamformerComputeTextureKind_##k, 146 BEAMFORMER_COMPUTE_TEXTURE_LIST_FULL 147 #undef X 148 BeamformerComputeTextureKind_Count 149 } BeamformerComputeTextureKind; 150 static_assert((BeamformerComputeTextureKind_Count - 1) == BeamformerComputeTextureKind_Hadamard, 151 "BeamformerComputeTextureKind_Hadamard must be end of TextureKinds"); 152 153 typedef struct { 154 uv3 layout; 155 uv3 dispatch; 156 BeamformerShaderBakeParameters bake; 157 } BeamformerShaderDescriptor; 158 159 typedef struct BeamformerComputePlan BeamformerComputePlan; 160 struct BeamformerComputePlan { 161 BeamformerComputePipeline pipeline; 162 163 u32 programs[BeamformerMaxComputeShaderStages]; 164 165 u32 dirty_programs; 166 167 BeamformerAcquisitionKind acquisition_kind; 168 u32 acquisition_count; 169 170 u32 rf_size; 171 i32 hadamard_order; 172 b32 iq_pipeline; 173 174 v3 min_coordinate; 175 v3 max_coordinate; 176 iv3 output_points; 177 i32 average_frames; 178 179 u32 textures[BeamformerComputeTextureKind_Count]; 180 u32 ubos[BeamformerComputeUBOKind_Count]; 181 182 BeamformerFilter filters[BeamformerFilterSlots]; 183 184 #define X(k, type, name) type name ##_ubo_data; 185 BEAMFORMER_COMPUTE_UBO_LIST 186 #undef X 187 188 u128 shader_hashes[BeamformerMaxComputeShaderStages]; 189 BeamformerShaderDescriptor shader_descriptors[BeamformerMaxComputeShaderStages]; 190 191 BeamformerComputePlan *next; 192 }; 193 194 typedef struct { 195 GLsync upload_syncs[BeamformerMaxRawDataFramesInFlight]; 196 GLsync compute_syncs[BeamformerMaxRawDataFramesInFlight]; 197 198 u32 ssbo; 199 u32 size; 200 u32 active_rf_size; 201 202 u32 data_timestamp_query; 203 204 u32 insertion_index; 205 u32 compute_index; 206 } BeamformerRFBuffer; 207 208 typedef struct { 209 BeamformerRFBuffer rf_buffer; 210 211 BeamformerComputePlan *compute_plans[BeamformerMaxParameterBlockSlots]; 212 BeamformerComputePlan *compute_plan_freelist; 213 214 /* NOTE(rnp): two interstage ssbos are allocated so that they may be used to 215 * ping pong data between compute stages */ 216 u32 ping_pong_ssbos[2]; 217 u32 last_output_ssbo_index; 218 219 u32 ping_pong_ssbo_size; 220 221 f32 processing_progress; 222 b32 processing_compute; 223 224 u32 shader_timer_ids[BeamformerMaxComputeShaderStages]; 225 226 BeamformerRenderModel unit_cube_model; 227 } BeamformerComputeContext; 228 229 typedef struct { 230 BeamformerComputeStatsTable table; 231 f32 average_times[BeamformerShaderKind_Count]; 232 233 u64 last_rf_timer_count; 234 f32 rf_time_delta_average; 235 236 u32 latest_frame_index; 237 u32 latest_rf_index; 238 } ComputeShaderStats; 239 240 /* TODO(rnp): maybe this also gets used for CPU timing info as well */ 241 typedef enum { 242 ComputeTimingInfoKind_ComputeFrameBegin, 243 ComputeTimingInfoKind_ComputeFrameEnd, 244 ComputeTimingInfoKind_Shader, 245 ComputeTimingInfoKind_RF_Data, 246 } ComputeTimingInfoKind; 247 248 typedef struct { 249 u64 timer_count; 250 ComputeTimingInfoKind kind; 251 union { 252 BeamformerShaderKind shader; 253 }; 254 } ComputeTimingInfo; 255 256 typedef struct { 257 u32 write_index; 258 u32 read_index; 259 b32 compute_frame_active; 260 ComputeTimingInfo buffer[4096]; 261 } ComputeTimingTable; 262 263 typedef struct { 264 BeamformerRFBuffer *rf_buffer; 265 SharedMemoryRegion *shared_memory; 266 ComputeTimingTable *compute_timing_table; 267 i32 *compute_worker_sync; 268 } BeamformerUploadThreadContext; 269 270 struct BeamformerFrame { 271 u32 texture; 272 b32 ready_to_present; 273 274 iv3 dim; 275 i32 mips; 276 277 /* NOTE: for use when displaying either prebeamformed frames or on the current frame 278 * when we intend to recompute on the next frame */ 279 v3 min_coordinate; 280 v3 max_coordinate; 281 282 // metadata 283 GLenum gl_kind; 284 u32 id; 285 u32 compound_count; 286 u32 parameter_block; 287 BeamformerAcquisitionKind acquisition_kind; 288 BeamformerViewPlaneTag view_plane_tag; 289 290 BeamformerFrame *next; 291 }; 292 293 #define GL_PARAMETERS \ 294 X(MAJOR_VERSION, version_major, "") \ 295 X(MINOR_VERSION, version_minor, "") \ 296 X(MIN_MAP_BUFFER_ALIGNMENT, min_map_buffer_alignment, "") \ 297 X(TEXTURE_BUFFER_OFFSET_ALIGNMENT, texture_buffer_offset_alignment, "") \ 298 X(MAX_TEXTURE_BUFFER_SIZE, max_texture_buffer_size, "") \ 299 X(MAX_TEXTURE_SIZE, max_2d_texture_dim, "") \ 300 X(MAX_3D_TEXTURE_SIZE, max_3d_texture_dim, "") \ 301 X(MAX_SHADER_STORAGE_BLOCK_SIZE, max_ssbo_size, "") \ 302 X(MAX_COMPUTE_SHARED_MEMORY_SIZE, max_shared_memory_size, "") \ 303 X(MAX_UNIFORM_BLOCK_SIZE, max_ubo_size, "") \ 304 X(MAX_SERVER_WAIT_TIMEOUT, max_server_wait_time, " [ns]") 305 306 typedef struct { 307 enum gl_vendor_ids vendor_id; 308 #define X(glname, name, suffix) i32 name; 309 GL_PARAMETERS 310 #undef X 311 } GLParams; 312 313 typedef struct { 314 GLParams gl; 315 316 iv2 window_size; 317 b32 should_exit; 318 319 Arena ui_backing_store; 320 void *ui; 321 u32 ui_dirty_parameter_blocks; 322 323 BeamformerComputeContext compute_context; 324 325 /* TODO(rnp): ideally this would go in the UI but its hard to manage with the UI 326 * destroying itself on hot-reload */ 327 FrameViewRenderContext frame_view_render_context; 328 329 OS os; 330 Stream error_stream; 331 332 BeamformWorkQueue *beamform_work_queue; 333 334 ComputeShaderStats *compute_shader_stats; 335 ComputeTimingTable *compute_timing_table; 336 337 SharedMemoryRegion shared_memory; 338 339 BeamformerFrame beamform_frames[BeamformerMaxSavedFrames]; 340 BeamformerFrame *latest_frame; 341 u32 next_render_frame_index; 342 u32 display_frame_index; 343 344 /* NOTE: this will only be used when we are averaging */ 345 u32 averaged_frame_index; 346 BeamformerFrame averaged_frames[2]; 347 } BeamformerCtx; 348 349 typedef struct ShaderReloadContext ShaderReloadContext; 350 struct ShaderReloadContext { 351 BeamformerCtx *beamformer_context; 352 ShaderReloadContext *link; 353 s8 header; 354 GLenum gl_type; 355 i32 reloadable_info_index; 356 }; 357 358 #define BEAMFORMER_FRAME_STEP_FN(name) void name(BeamformerCtx *ctx, BeamformerInput *input) 359 typedef BEAMFORMER_FRAME_STEP_FN(beamformer_frame_step_fn); 360 361 #define BEAMFORMER_COMPLETE_COMPUTE_FN(name) void name(iptr user_context, Arena *arena, iptr gl_context) 362 typedef BEAMFORMER_COMPLETE_COMPUTE_FN(beamformer_complete_compute_fn); 363 364 #define BEAMFORMER_RF_UPLOAD_FN(name) void name(BeamformerUploadThreadContext *ctx, Arena arena) 365 typedef BEAMFORMER_RF_UPLOAD_FN(beamformer_rf_upload_fn); 366 367 #define BEAMFORMER_RELOAD_SHADER_FN(name) b32 name(OS *os, s8 path, ShaderReloadContext *src, \ 368 Arena arena, s8 shader_name) 369 typedef BEAMFORMER_RELOAD_SHADER_FN(beamformer_reload_shader_fn); 370 371 #define BEAMFORMER_DEBUG_UI_DEINIT_FN(name) void name(BeamformerCtx *ctx) 372 typedef BEAMFORMER_DEBUG_UI_DEINIT_FN(beamformer_debug_ui_deinit_fn); 373 374 #endif /*_BEAMFORMER_H_ */