ogl_beamforming

Ultrasound Beamforming Implemented with OpenGL
git clone anongit@rnpnr.xyz:ogl_beamforming.git
Log | Files | Refs | Feed | Submodules | README | LICENSE

beamformer.h (10076B)


      1 /* See LICENSE for license details. */
      2 #ifndef BEAMFORMER_H
      3 #define BEAMFORMER_H
      4 
      5 #include <stdint.h>
      6 
      7 #define BEAMFORMER_NAME_STRING "OGL Beamformer"
      8 
      9 ///////////////////////////////
     10 // COMPILE TIME CONFIGURATION
     11 
     12 /* NOTE(rnp): By design the beamformer has very little compile time configuration.
     13  * The few options it does have are documented here.
     14  *
     15  * BEAMFORMER_IMPORT
     16  * BEAMFORMER_EXPORT
     17  *   The symbol markup for imported and exported symbols. In a typical
     18  *   release unity build these are both defined to `static`.
     19  *
     20  * BEAMFORMER_DEBUG
     21  *   Compile the beamformer with handling for hot reloading at runtime.
     22  *   This requires compiling `beamformer_core.c` as a dynamic library which the
     23  *   platform is required to load at runtime.
     24  *   IMPORTANT: When the platform wants to reload the library at runtime it
     25  *   MUST NOT unload the old library immediately; the beamformer may still
     26  *   be executing code in old library. Instead the platform must first call
     27  *   `beamformer_debug_hot_release` with the program's memory, then it may close the
     28  *   old handle. Then `beamformer_debug_hot_reload` should be called with the new handle
     29  *   so that the beamformer may resume operation.
     30  *
     31  * BEAMFORMER_RENDERDOC_HOOKS
     32  *   Add RenderDoc API calls to capture complete compute frames. As compute is performed
     33  *   asynchronously from normal rendering it is not possible to capture normally. In this
     34  *   configuration the beamformer will use the function pointers provided in the
     35  *   BeamformerInput to make these calls.
     36  *   IMPORTANT: The renderdoc library will only be visible when the application is started
     37  *   through RenderDoc. Furthermore the library has startup code which will halt the program
     38  *   if loaded normally. It must be loaded using platform module loading APIs. For example
     39  *   GetModuleHandle or dlopen with the RTLD_NOLOAD flag set.
     40  *
     41  */
     42 
     43 #ifndef BEAMFORMER_IMPORT
     44  #define BEAMFORMER_IMPORT
     45 #endif
     46 
     47 #ifndef BEAMFORMER_EXPORT
     48  #define BEAMFORMER_EXPORT
     49 #endif
     50 
     51 #ifdef BEAMFORMER_DEBUG
     52   #undef BEAMFORMER_DEBUG
     53   #define BEAMFORMER_DEBUG (1)
     54 #else
     55   #define BEAMFORMER_DEBUG (0)
     56 #endif
     57 
     58 #ifdef BEAMFORMER_RENDERDOC_HOOKS
     59   #undef BEAMFORMER_RENDERDOC_HOOKS
     60   #define BEAMFORMER_RENDERDOC_HOOKS (1)
     61 #else
     62   #define BEAMFORMER_RENDERDOC_HOOKS (0)
     63 #endif
     64 
     65 ///////////////////
     66 // REQUIRED OS API
     67 #define OSInvalidHandleValue ((u64)-1)
     68 typedef struct { uint64_t value[1]; } OSBarrier;
     69 typedef struct { uint64_t value[1]; } OSHandle;
     70 typedef struct { uint64_t value[1]; } OSLibrary;
     71 typedef struct { uint64_t value[1]; } OSThread;
     72 typedef struct { uint64_t value[1]; } OSWindow;
     73 typedef struct { uint64_t value[1]; } OSW32Semaphore;
     74 
     75 typedef uint64_t os_thread_entry_point_fn(void *user_context);
     76 
     77 typedef struct {
     78 	uint64_t timer_frequency;
     79 
     80 	uint32_t logical_processor_count;
     81 	uint32_t page_size;
     82 
     83 	uint8_t  path_separator_byte;
     84 } OSSystemInfo;
     85 
     86 BEAMFORMER_IMPORT OSSystemInfo * os_system_info(void);
     87 
     88 BEAMFORMER_IMPORT OSThread       os_create_thread(const char *name, void *user_context, os_thread_entry_point_fn *fn);
     89 BEAMFORMER_IMPORT OSBarrier      os_barrier_alloc(uint32_t thread_count);
     90 BEAMFORMER_IMPORT void           os_barrier_enter(OSBarrier);
     91 
     92 /* NOTE(rnp): since the beamformer may spawn threads, which may need to keep time,
     93  * passing in a single timer value with the rest of the input is insufficient. */
     94 BEAMFORMER_IMPORT uint64_t       os_timer_count(void);
     95 
     96 BEAMFORMER_IMPORT void           os_add_file_watch(const char *path, int64_t path_length, void *user_context);
     97 BEAMFORMER_IMPORT int64_t        os_read_entire_file(const char *file, void *buffer, int64_t buffer_capacity);
     98 
     99 BEAMFORMER_IMPORT void *         os_lookup_symbol(OSLibrary library, const char *symbol);
    100 
    101 /* NOTE(rnp): memory watch timed waiting functions. (-1) is an infinite timeout. the beamformer
    102  * will use these with the intention of yielding the thread back to the OS. */
    103 BEAMFORMER_IMPORT uint32_t       os_wait_on_address(int32_t *lock, int32_t current, uint32_t timeout_ms);
    104 BEAMFORMER_IMPORT void           os_wake_all_waiters(int32_t *lock);
    105 
    106 // NOTE(rnp): currently beamformer will only create one window.
    107 // once raylib is removed it may request multiple
    108 BEAMFORMER_IMPORT OSWindow       os_window_create(uint8_t *title, int64_t title_length, int32_t width, int32_t height);
    109 //BEAMFORMER_IMPORT void           os_window_title(OSWindow window, uint8_t *title, int64_t title_length);
    110 //BEAMFORMER_IMPORT void           os_window_destroy(OSWindow window);
    111 
    112 // NOTE(rnp): eventually logging will just be done internally
    113 BEAMFORMER_IMPORT void           os_console_log(uint8_t *data, int64_t length);
    114 BEAMFORMER_IMPORT void           os_fatal(uint8_t *data, int64_t length);
    115 
    116 
    117 // NOTE(rnp): for vulkan cross API export on win32 (will be removed eventually)
    118 BEAMFORMER_IMPORT void           os_release_handle(OSHandle handle);
    119 
    120 /* NOTE(rnp): this functionality is only needed on win32 to provide cross process
    121  * synchronization. While posix has equivalent functionality there is no reason to
    122  * use it over a value located in shared memory. */
    123 #if defined(_WIN32)
    124 BEAMFORMER_IMPORT OSW32Semaphore os_w32_create_semaphore(const char *name, int32_t initial_count, int32_t maximum_count);
    125 BEAMFORMER_IMPORT uint32_t       os_w32_semaphore_wait(OSW32Semaphore, uint32_t timeout_ms);
    126 BEAMFORMER_IMPORT void           os_w32_semaphore_release(OSW32Semaphore, int32_t count);
    127 #endif
    128 
    129 //////////////////////////////
    130 // BEAMFORMER APPLICATION API
    131 
    132 typedef enum {
    133 	BeamformerInputEventKind_ButtonPress,
    134 	BeamformerInputEventKind_ButtonRelease,
    135 	BeamformerInputEventKind_MouseScroll,
    136 	BeamformerInputEventKind_WindowResize,
    137 	BeamformerInputEventKind_ExecutableReload,
    138 	BeamformerInputEventKind_FileEvent,
    139 } BeamformerInputEventKind;
    140 
    141 // TODO: not yet used
    142 typedef enum {
    143 	BeamformerButtonID_MouseLeft,
    144 	BeamformerButtonID_MouseRight,
    145 	BeamformerButtonID_MouseMiddle,
    146 	BeamformerButtonID_Count,
    147 } BeamformerButtonID;
    148 
    149 typedef enum {
    150 	BeamformerInputModifier_LeftAlt      = (1 << 0),
    151 	BeamformerInputModifier_RightAlt     = (1 << 1),
    152 
    153 	BeamformerInputModifier_LeftControl  = (1 << 2),
    154 	BeamformerInputModifier_RightControl = (1 << 3),
    155 
    156 	BeamformerInputModifier_LeftShift    = (1 << 4),
    157 	BeamformerInputModifier_RightShift   = (1 << 5),
    158 
    159 	BeamformerInputModifier_LeftMeta     = (1 << 6),
    160 	BeamformerInputModifier_RightMeta    = (1 << 7),
    161 
    162 	BeamformerInputModifier_Alt     = BeamformerInputModifier_LeftAlt|BeamformerInputModifier_RightAlt,
    163 	BeamformerInputModifier_Control = BeamformerInputModifier_LeftControl|BeamformerInputModifier_RightControl,
    164 	BeamformerInputModifier_Shift   = BeamformerInputModifier_LeftShift|BeamformerInputModifier_RightShift,
    165 	BeamformerInputModifier_Meta    = BeamformerInputModifier_LeftMeta|BeamformerInputModifier_RightMeta,
    166 	BeamformerInputModifier_Any     = BeamformerInputModifier_Alt|
    167 	                                  BeamformerInputModifier_Control|
    168 	                                  BeamformerInputModifier_Shift|
    169 	                                  BeamformerInputModifier_Meta,
    170 } BeamformerInputModifiers;
    171 
    172 typedef struct {
    173 	BeamformerInputEventKind kind;
    174 	union {
    175 		BeamformerButtonID  button_id;
    176 
    177 		struct {
    178 			uint32_t width, height;
    179 			OSWindow window;
    180 		} window_resize;
    181 
    182 		void *file_watch_user_context;
    183 	};
    184 } BeamformerInputEvent;
    185 
    186 typedef struct {
    187 	/* NOTE(rnp): besides vulkan library code the beamformer will not allocate memory on its
    188 	 * own. Recommended minimum size is 16MB. If shared memory is not provided it is recommended
    189 	 * to increase this to at least 1GB to help facilitate loading of external data files (not yet
    190 	 * implemented). */
    191 	void *      memory;
    192 	uint64_t    memory_size;
    193 
    194 	/* NOTE(rnp): beamformer will use this to communicate with external processes. While it
    195 	 * it won't be required in the future it is currently the only way to load data.
    196 	 * Recommended size is 2-4GB. Currently this size will also limit the size of any data
    197 	 * another process wishes to export. The name is required for listing in the UI so that
    198 	 * users of external processes can open the region on their end. */
    199 	void *      shared_memory;
    200 	uint64_t    shared_memory_size;
    201 	uint8_t *   shared_memory_name;
    202 	uint32_t    shared_memory_name_length;
    203 
    204 	float       mouse_x;
    205 	float       mouse_y;
    206 
    207 	uint32_t    event_count;
    208 
    209 	BeamformerInputModifiers input_modifiers;
    210 	BeamformerInputEvent     event_queue[256];
    211 
    212 	/* NOTE(rnp): the beamformer is not allowed to dynamically load libraries
    213 	 * itself. Besides Vulkan, which is required, libraries are optional and
    214 	 * the beamformer will not use features from libraries which have not
    215 	 * been provided. */
    216 	OSLibrary cuda_library_handle;
    217 	OSLibrary vulkan_library_handle;
    218 
    219 	#if BEAMFORMER_RENDERDOC_HOOKS
    220 	void *renderdoc_start_frame_capture;
    221 	void *renderdoc_end_frame_capture;
    222 	void *renderdoc_set_capture_file_path_template;
    223 	#endif
    224 } BeamformerInput;
    225 
    226 BEAMFORMER_EXPORT void beamformer_init(BeamformerInput *);
    227 
    228 /* NOTE(rnp): while the platform can also decide to terminate the beamformer,
    229  * the beamformer itself may indicate that it wants to terminate. If the
    230  * beamformer itself decides to terminate it is unnecessary to call
    231  * `beamformer_terminate()` but it will act as a NOP if you do. */
    232 BEAMFORMER_EXPORT uint32_t beamformer_should_close(BeamformerInput *);
    233 
    234 /* IMPORTANT(rnp): since the beamformer may be interacting with external hardware
    235  * it is critical that the platform calls this when it wishes to terminate the
    236  * beamformer. Otherwise the external hardware may be left in a bad state and require
    237  * a reboot. The beamformer will not waste time releasing resources unless it was
    238  * compiled with BEAMFORMER_DEBUG enabled (useful for address sanitizer). */
    239 BEAMFORMER_EXPORT void beamformer_terminate(BeamformerInput *);
    240 
    241 #if !BEAMFORMER_DEBUG
    242 BEAMFORMER_EXPORT void beamformer_frame_step(BeamformerInput *);
    243 #endif
    244 
    245 #if BEAMFORMER_DEBUG
    246 BEAMFORMER_EXPORT void beamformer_debug_hot_release(BeamformerInput *);
    247 BEAMFORMER_EXPORT void beamformer_debug_hot_reload(OSLibrary new_library, BeamformerInput *);
    248 #endif
    249 
    250 #endif /*BEAMFORMER_H */