beamformer.h (8271B)
1 /* See LICENSE for license details. */ 2 #ifndef _BEAMFORMER_H_ 3 #define _BEAMFORMER_H_ 4 5 #include <glad.h> 6 7 #define GRAPHICS_API_OPENGL_43 8 #include <raylib.h> 9 #include <rlgl.h> 10 11 #include "util.h" 12 13 #define BG_COLOUR (v4){.r = 0.15, .g = 0.12, .b = 0.13, .a = 1.0} 14 #define FG_COLOUR (v4){.r = 0.92, .g = 0.88, .b = 0.78, .a = 1.0} 15 #define FOCUSED_COLOUR (v4){.r = 0.86, .g = 0.28, .b = 0.21, .a = 1.0} 16 #define HOVERED_COLOUR (v4){.r = 0.11, .g = 0.50, .b = 0.59, .a = 1.0} 17 #define RULER_COLOUR (v4){.r = 1.00, .g = 0.70, .b = 0.00, .a = 1.0} 18 19 #define INFO_COLUMN_WIDTH 560 20 /* NOTE: extra space used for allowing mouse clicks after end of text */ 21 #define TEXT_BOX_EXTRA_X 10.0f 22 23 #define TEXT_HOVER_SPEED 5.0f 24 25 #define RULER_TEXT_PAD 10.0f 26 #define RULER_TICK_LENGTH 20.0f 27 28 #define RECT_BTN_COLOUR (Color){.r = 0x43, .g = 0x36, .b = 0x3a, .a = 0xff} 29 #define RECT_BTN_BORDER_COLOUR (Color){.r = 0x00, .g = 0x00, .b = 0x00, .a = 0xCC} 30 #define RECT_BTN_ROUNDNESS 0.3f 31 #define RECT_BTN_BORDER_WIDTH 6.0f 32 33 /* TODO: multiple views */ 34 #define MAX_DISPLAYS 1 35 36 enum program_flags { 37 SHOULD_EXIT = 1 << 0, 38 START_COMPUTE = 1 << 1, 39 }; 40 41 enum gl_vendor_ids { 42 GL_VENDOR_AMD, 43 GL_VENDOR_ARM, 44 GL_VENDOR_INTEL, 45 GL_VENDOR_NVIDIA, 46 }; 47 48 typedef struct { 49 u8 buf[64]; 50 i32 buf_len; 51 i32 cursor; 52 f32 cursor_blink_t; 53 f32 cursor_blink_scale; 54 } InputState; 55 56 enum variable_flags { 57 V_CAUSES_COMPUTE = 1 << 29, 58 V_GEN_MIPMAPS = 1 << 30, 59 }; 60 61 enum interaction_states { 62 IS_NONE, 63 IS_NOP, 64 IS_SET, 65 IS_DRAG, 66 IS_SCROLL, 67 IS_TEXT, 68 69 IS_DISPLAY, 70 IS_SCALE_BAR, 71 }; 72 73 enum ruler_state { 74 RS_NONE, 75 RS_START, 76 RS_HOLD, 77 }; 78 79 enum scale_bar_directions { 80 SB_LATERAL, 81 SB_AXIAL, 82 }; 83 84 typedef struct { 85 Variable hot; 86 Variable next_hot; 87 Variable active; 88 u32 hot_state; 89 u32 state; 90 } InteractionState; 91 92 typedef struct v2_sll { 93 struct v2_sll *next; 94 v2 v; 95 } v2_sll; 96 97 typedef struct { 98 f32 *min_value, *max_value; 99 v2_sll *savepoint_stack; 100 v2 zoom_starting_point; 101 v2 screen_offset; 102 v2 screen_space_to_value; 103 f32 hover_t; 104 b32 scroll_both; 105 } ScaleBar; 106 107 typedef struct { 108 TempArena frame_temporary_arena; 109 Arena arena_for_frame; 110 111 Font font; 112 Font small_font; 113 f32 font_height; 114 f32 small_font_height; 115 116 InteractionState interaction; 117 InputState text_input_state; 118 119 ScaleBar scale_bars[MAX_DISPLAYS][2]; 120 v2_sll *scale_bar_savepoint_freelist; 121 122 v2 ruler_start_p; 123 v2 ruler_stop_p; 124 u32 ruler_state; 125 } BeamformerUI; 126 127 #define MAX_FRAMES_IN_FLIGHT 3 128 129 #define INIT_CUDA_CONFIGURATION_FN(name) void name(u32 *input_dims, u32 *decoded_dims, u16 *channel_mapping) 130 typedef INIT_CUDA_CONFIGURATION_FN(init_cuda_configuration_fn); 131 INIT_CUDA_CONFIGURATION_FN(init_cuda_configuration_stub) {} 132 133 #define REGISTER_CUDA_BUFFERS_FN(name) void name(u32 *rf_data_ssbos, u32 rf_buffer_count, u32 raw_data_ssbo) 134 typedef REGISTER_CUDA_BUFFERS_FN(register_cuda_buffers_fn); 135 REGISTER_CUDA_BUFFERS_FN(register_cuda_buffers_stub) {} 136 137 #define CUDA_DECODE_FN(name) void name(size_t input_offset, u32 output_buffer_idx, u32 rf_channel_offset) 138 typedef CUDA_DECODE_FN(cuda_decode_fn); 139 CUDA_DECODE_FN(cuda_decode_stub) {} 140 141 #define CUDA_HILBERT_FN(name) void name(u32 input_buffer_idx, u32 output_buffer_idx) 142 typedef CUDA_HILBERT_FN(cuda_hilbert_fn); 143 CUDA_HILBERT_FN(cuda_hilbert_stub) {} 144 145 #define CUDA_LIB_FNS \ 146 X(cuda_decode) \ 147 X(cuda_hilbert) \ 148 X(init_cuda_configuration) \ 149 X(register_cuda_buffers) 150 151 typedef struct { 152 void *lib; 153 u64 timestamp; 154 #define X(name) name ## _fn *name; 155 CUDA_LIB_FNS 156 #undef X 157 } CudaLib; 158 159 #include "beamformer_parameters.h" 160 typedef struct { 161 BeamformerParameters raw; 162 enum compute_shaders compute_stages[16]; 163 u32 compute_stages_count; 164 b32 upload; 165 b32 export_next_frame; 166 c8 export_pipe_name[1024]; 167 } BeamformerParametersFull; 168 169 #define CS_UNIFORMS \ 170 X(CS_DAS, volume_export_dim_offset) \ 171 X(CS_DAS, volume_export_pass) \ 172 X(CS_DAS, cycle_t) \ 173 X(CS_MIN_MAX, mips_level) \ 174 X(CS_SUM, sum_prescale) 175 176 typedef struct { 177 u32 programs[CS_LAST]; 178 179 u32 timer_index; 180 u32 timer_ids[MAX_FRAMES_IN_FLIGHT][CS_LAST]; 181 b32 timer_active[MAX_FRAMES_IN_FLIGHT][CS_LAST]; 182 GLsync timer_fences[MAX_FRAMES_IN_FLIGHT]; 183 f32 last_frame_time[CS_LAST]; 184 185 /* NOTE: the raw_data_ssbo is allocated at 3x the required size to allow for tiled 186 * transfers when the GPU is running behind the CPU. It is not mapped on NVIDIA because 187 * their drivers _will_ store the buffer in the system memory. This doesn't happen 188 * for Intel or AMD and mapping the buffer is preferred. In either case incoming data can 189 * be written to the arena at the appropriate offset for the current raw_data_index. An 190 * additional BufferSubData is needed on NVIDIA to upload the data. */ 191 GLsync raw_data_fences[MAX_FRAMES_IN_FLIGHT]; 192 Arena raw_data_arena; 193 u32 raw_data_ssbo; 194 u32 raw_data_index; 195 196 /* NOTE: Decoded data is only relevant in the context of a single frame. We use two 197 * buffers so that they can be swapped when chaining multiple compute stages */ 198 u32 rf_data_ssbos[2]; 199 u32 last_output_ssbo_index; 200 u32 hadamard_texture; 201 202 u32 shared_ubo; 203 204 uv4 dec_data_dim; 205 uv2 rf_raw_dim; 206 207 #define X(idx, name) i32 name ## _id; 208 CS_UNIFORMS 209 #undef X 210 } ComputeShaderCtx; 211 212 typedef struct { 213 Shader shader; 214 RenderTexture2D output; 215 /* TODO: cleanup: X macro? */ 216 i32 db_cutoff_id; 217 i32 threshold_id; 218 f32 db; 219 f32 threshold; 220 b32 gen_mipmaps; 221 } FragmentShaderCtx; 222 223 typedef struct { 224 uv3 dim; 225 u32 texture; 226 227 /* NOTE: for use when displaying either prebeamformed frames or on the current frame 228 * when we intend to recompute on the next frame */ 229 v4 min_coordinate; 230 v4 max_coordinate; 231 232 u32 mips; 233 } BeamformFrame; 234 235 typedef struct { 236 BeamformFrame frame; 237 u32 timer_ids[2]; 238 f32 runtime; 239 u32 rf_data_ssbo; 240 u32 shader; 241 u32 dispatch_index; 242 b32 timer_active; 243 } PartialComputeCtx; 244 245 typedef struct { 246 enum gl_vendor_ids vendor_id; 247 i32 version_major; 248 i32 version_minor; 249 i32 max_2d_texture_dim; 250 i32 max_3d_texture_dim; 251 i32 max_ssbo_size; 252 i32 max_ubo_size; 253 } GLParams; 254 255 enum beamform_work { 256 BW_FULL_COMPUTE, 257 BW_RECOMPUTE, 258 BW_PARTIAL_COMPUTE, 259 BW_SAVE_FRAME, 260 BW_SEND_FRAME, 261 BW_SSBO_COPY, 262 }; 263 264 typedef struct { 265 u32 source_ssbo; 266 u32 dest_ssbo; 267 } BeamformSSBOCopy; 268 269 typedef struct { 270 BeamformFrame *frame; 271 iptr export_handle; 272 u32 raw_data_ssbo_index; 273 b32 first_pass; 274 } BeamformCompute; 275 276 typedef struct { 277 BeamformFrame *frame; 278 iptr output_handle; 279 } BeamformOutputFrame; 280 281 /* NOTE: discriminated union based on type */ 282 typedef struct BeamformWork { 283 struct BeamformWork *next; 284 union { 285 BeamformSSBOCopy ssbo_copy_ctx; 286 BeamformCompute compute_ctx; 287 BeamformOutputFrame output_frame_ctx; 288 }; 289 u32 type; 290 } BeamformWork; 291 292 typedef struct { 293 BeamformWork *first; 294 BeamformWork *last; 295 BeamformWork *next_free; 296 i32 compute_in_flight; 297 b32 did_compute_this_frame; 298 } BeamformWorkQueue; 299 300 typedef struct { 301 BeamformFrame *frames; 302 u32 capacity; 303 u32 offset; 304 u32 cursor; 305 u32 needed_frames; 306 } BeamformFrameIterator; 307 308 typedef struct BeamformerCtx { 309 GLParams gl; 310 311 uv2 window_size; 312 u32 flags; 313 314 Arena ui_backing_store; 315 BeamformerUI *ui; 316 317 BeamformFrame beamform_frames[MAX_BEAMFORMED_SAVED_FRAMES]; 318 u32 displayed_frame_index; 319 320 /* NOTE: this will only be used when we are averaging */ 321 BeamformFrame averaged_frame; 322 ComputeShaderCtx csctx; 323 FragmentShaderCtx fsctx; 324 PartialComputeCtx partial_compute_ctx; 325 326 Arena export_buffer; 327 328 CudaLib cuda_lib; 329 Platform platform; 330 Stream error_stream; 331 332 BeamformWorkQueue beamform_work_queue; 333 334 BeamformerParametersFull *params; 335 } BeamformerCtx; 336 337 #define LABEL_GL_OBJECT(type, id, s) {s8 _s = (s); glObjectLabel(type, id, _s.len, (c8 *)_s.data);} 338 339 #define BEAMFORMER_FRAME_STEP_FN(name) void name(BeamformerCtx *ctx, Arena *arena, \ 340 BeamformerInput *input) 341 typedef BEAMFORMER_FRAME_STEP_FN(beamformer_frame_step_fn); 342 343 #endif /*_BEAMFORMER_H_ */