beamformer.h (14307B)
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 BEAMFORMER_IMPORT uint8_t * os_get_clipboard_text(int64_t *length); 113 BEAMFORMER_IMPORT void os_set_clipboard_text(uint8_t *data, int64_t length); 114 115 // NOTE(rnp): eventually logging will just be done internally 116 BEAMFORMER_IMPORT void os_console_log(uint8_t *data, int64_t length); 117 BEAMFORMER_IMPORT void os_fatal(uint8_t *data, int64_t length); 118 119 120 // NOTE(rnp): for vulkan cross API export on win32 (will be removed eventually) 121 BEAMFORMER_IMPORT void os_release_handle(OSHandle handle); 122 123 /* NOTE(rnp): this functionality is only needed on win32 to provide cross process 124 * synchronization. While posix has equivalent functionality there is no reason to 125 * use it over a value located in shared memory. */ 126 #if defined(_WIN32) 127 BEAMFORMER_IMPORT OSW32Semaphore os_w32_create_semaphore(const char *name, int32_t initial_count, int32_t maximum_count); 128 BEAMFORMER_IMPORT uint32_t os_w32_semaphore_wait(OSW32Semaphore, uint32_t timeout_ms); 129 BEAMFORMER_IMPORT void os_w32_semaphore_release(OSW32Semaphore, int32_t count); 130 #endif 131 132 ////////////////////////////// 133 // BEAMFORMER APPLICATION API 134 135 typedef enum { 136 BeamformerInputEventKind_ButtonPress, 137 BeamformerInputEventKind_ButtonRelease, 138 BeamformerInputEventKind_MouseScroll, 139 BeamformerInputEventKind_WindowResize, 140 BeamformerInputEventKind_ExecutableReload, 141 BeamformerInputEventKind_FileEvent, 142 } BeamformerInputEventKind; 143 144 typedef enum { 145 BeamformerButtonID_Space = ' ', 146 BeamformerButtonID_Apostrophe = '\'', 147 BeamformerButtonID_Comma = ',', 148 BeamformerButtonID_Minus = '-', 149 BeamformerButtonID_Period = '.', 150 BeamformerButtonID_Slash = '/', 151 BeamformerButtonID_0 = '0', 152 BeamformerButtonID_1 = '1', 153 BeamformerButtonID_2 = '2', 154 BeamformerButtonID_3 = '3', 155 BeamformerButtonID_4 = '4', 156 BeamformerButtonID_5 = '5', 157 BeamformerButtonID_6 = '6', 158 BeamformerButtonID_7 = '7', 159 BeamformerButtonID_8 = '8', 160 BeamformerButtonID_9 = '9', 161 BeamformerButtonID_Semicolon = ';', 162 BeamformerButtonID_Equal = '=', 163 BeamformerButtonID_A = 'A', 164 BeamformerButtonID_B = 'B', 165 BeamformerButtonID_C = 'C', 166 BeamformerButtonID_D = 'D', 167 BeamformerButtonID_E = 'E', 168 BeamformerButtonID_F = 'F', 169 BeamformerButtonID_G = 'G', 170 BeamformerButtonID_H = 'H', 171 BeamformerButtonID_I = 'I', 172 BeamformerButtonID_J = 'J', 173 BeamformerButtonID_K = 'K', 174 BeamformerButtonID_L = 'L', 175 BeamformerButtonID_M = 'M', 176 BeamformerButtonID_N = 'N', 177 BeamformerButtonID_O = 'O', 178 BeamformerButtonID_P = 'P', 179 BeamformerButtonID_Q = 'Q', 180 BeamformerButtonID_R = 'R', 181 BeamformerButtonID_S = 'S', 182 BeamformerButtonID_T = 'T', 183 BeamformerButtonID_U = 'U', 184 BeamformerButtonID_V = 'V', 185 BeamformerButtonID_W = 'W', 186 BeamformerButtonID_X = 'X', 187 BeamformerButtonID_Y = 'Y', 188 BeamformerButtonID_Z = 'Z', 189 BeamformerButtonID_LeftBracket = '[', 190 BeamformerButtonID_Backslash = '\\', 191 BeamformerButtonID_RightBracket = ']', 192 BeamformerButtonID_Grave = '`', 193 194 BeamformerButtonID_Escape, 195 BeamformerButtonID_Enter, 196 BeamformerButtonID_Tab, 197 BeamformerButtonID_Backspace, 198 BeamformerButtonID_Insert, 199 BeamformerButtonID_Delete, 200 BeamformerButtonID_Right, 201 BeamformerButtonID_Left, 202 BeamformerButtonID_Down, 203 BeamformerButtonID_Up, 204 BeamformerButtonID_PageUp, 205 BeamformerButtonID_PageDown, 206 BeamformerButtonID_Home, 207 BeamformerButtonID_End, 208 BeamformerButtonID_CapsLock, 209 BeamformerButtonID_ScrollLock, 210 BeamformerButtonID_NumLock, 211 BeamformerButtonID_PrintScreen, 212 BeamformerButtonID_Pause, 213 BeamformerButtonID_F1, 214 BeamformerButtonID_F2, 215 BeamformerButtonID_F3, 216 BeamformerButtonID_F4, 217 BeamformerButtonID_F5, 218 BeamformerButtonID_F6, 219 BeamformerButtonID_F7, 220 BeamformerButtonID_F8, 221 BeamformerButtonID_F9, 222 BeamformerButtonID_F10, 223 BeamformerButtonID_F11, 224 BeamformerButtonID_F12, 225 BeamformerButtonID_F13, 226 BeamformerButtonID_F14, 227 BeamformerButtonID_F15, 228 BeamformerButtonID_F16, 229 BeamformerButtonID_F17, 230 BeamformerButtonID_F18, 231 BeamformerButtonID_F19, 232 BeamformerButtonID_F20, 233 BeamformerButtonID_F21, 234 BeamformerButtonID_F22, 235 BeamformerButtonID_F23, 236 BeamformerButtonID_F24, 237 BeamformerButtonID_F25, 238 BeamformerButtonID_KP0, 239 BeamformerButtonID_KP1, 240 BeamformerButtonID_KP2, 241 BeamformerButtonID_KP3, 242 BeamformerButtonID_KP4, 243 BeamformerButtonID_KP5, 244 BeamformerButtonID_KP6, 245 BeamformerButtonID_KP7, 246 BeamformerButtonID_KP8, 247 BeamformerButtonID_KP9, 248 BeamformerButtonID_KPDecimal, 249 BeamformerButtonID_KPDivide, 250 BeamformerButtonID_KPMultiply, 251 BeamformerButtonID_KPSubtract, 252 BeamformerButtonID_KPAdd, 253 BeamformerButtonID_KPEnter, 254 BeamformerButtonID_KPEqual, 255 256 BeamformerButtonID_LeftShift, 257 BeamformerButtonID_LeftControl, 258 BeamformerButtonID_LeftAlt, 259 BeamformerButtonID_LeftSuper, 260 BeamformerButtonID_RightShift, 261 BeamformerButtonID_RightControl, 262 BeamformerButtonID_RightAlt, 263 BeamformerButtonID_RightSuper, 264 BeamformerButtonID_ModifierFirst = BeamformerButtonID_LeftShift, 265 BeamformerButtonID_ModifierLast = BeamformerButtonID_RightSuper, 266 267 BeamformerButtonID_Menu, 268 269 BeamformerButtonID_MouseLeft, 270 BeamformerButtonID_MouseRight, 271 BeamformerButtonID_MouseMiddle, 272 273 BeamformerButtonID_Count, 274 } BeamformerButtonID; 275 276 typedef enum { 277 BeamformerInputModifier_LeftAlt = (1 << 0), 278 BeamformerInputModifier_RightAlt = (1 << 1), 279 280 BeamformerInputModifier_LeftControl = (1 << 2), 281 BeamformerInputModifier_RightControl = (1 << 3), 282 283 BeamformerInputModifier_LeftShift = (1 << 4), 284 BeamformerInputModifier_RightShift = (1 << 5), 285 286 BeamformerInputModifier_LeftMeta = (1 << 6), 287 BeamformerInputModifier_RightMeta = (1 << 7), 288 289 BeamformerInputModifier_Alt = BeamformerInputModifier_LeftAlt|BeamformerInputModifier_RightAlt, 290 BeamformerInputModifier_Control = BeamformerInputModifier_LeftControl|BeamformerInputModifier_RightControl, 291 BeamformerInputModifier_Shift = BeamformerInputModifier_LeftShift|BeamformerInputModifier_RightShift, 292 BeamformerInputModifier_Meta = BeamformerInputModifier_LeftMeta|BeamformerInputModifier_RightMeta, 293 BeamformerInputModifier_Any = BeamformerInputModifier_Alt| 294 BeamformerInputModifier_Control| 295 BeamformerInputModifier_Shift| 296 BeamformerInputModifier_Meta, 297 } BeamformerInputModifiers; 298 299 typedef struct { 300 BeamformerInputEventKind kind; 301 BeamformerInputModifiers modifiers; 302 union { 303 struct { 304 BeamformerButtonID button_id; 305 // NOTE(rnp): if the button is not also an input key codepoint should be 0 306 uint32_t codepoint; 307 }; 308 struct {float x, y;} scroll; 309 310 struct { 311 uint32_t width, height; 312 OSWindow window; 313 } window_resize; 314 315 void *file_watch_user_context; 316 }; 317 } BeamformerInputEvent; 318 319 typedef struct { 320 /* NOTE(rnp): besides vulkan library code the beamformer will not allocate memory on its 321 * own. Recommended minimum size is 16MB. If shared memory is not provided it is recommended 322 * to increase this to at least 1GB to help facilitate loading of external data files (not yet 323 * implemented). */ 324 void * memory; 325 uint64_t memory_size; 326 327 /* NOTE(rnp): beamformer will use this to communicate with external processes. While it 328 * it won't be required in the future it is currently the only way to load data. 329 * Recommended size is 2-4GB. Currently this size will also limit the size of any data 330 * another process wishes to export. The name is required for listing in the UI so that 331 * users of external processes can open the region on their end. */ 332 void * shared_memory; 333 uint64_t shared_memory_size; 334 uint8_t * shared_memory_name; 335 uint32_t shared_memory_name_length; 336 337 float mouse_x; 338 float mouse_y; 339 340 uint32_t event_count; 341 342 BeamformerInputEvent event_queue[256]; 343 344 /* NOTE(rnp): the beamformer is not allowed to dynamically load libraries 345 * itself. Besides Vulkan, which is required, libraries are optional and 346 * the beamformer will not use features from libraries which have not 347 * been provided. */ 348 OSLibrary cuda_library_handle; 349 OSLibrary vulkan_library_handle; 350 351 #if BEAMFORMER_RENDERDOC_HOOKS 352 void *renderdoc_start_frame_capture; 353 void *renderdoc_end_frame_capture; 354 void *renderdoc_set_capture_file_path_template; 355 #endif 356 } BeamformerInput; 357 358 BEAMFORMER_EXPORT void beamformer_init(BeamformerInput *); 359 360 /* NOTE(rnp): while the platform can also decide to terminate the beamformer, 361 * the beamformer itself may indicate that it wants to terminate. If the 362 * beamformer itself decides to terminate it is unnecessary to call 363 * `beamformer_terminate()` but it will act as a NOP if you do. */ 364 BEAMFORMER_EXPORT uint32_t beamformer_should_close(BeamformerInput *); 365 366 /* IMPORTANT(rnp): since the beamformer may be interacting with external hardware 367 * it is critical that the platform calls this when it wishes to terminate the 368 * beamformer. Otherwise the external hardware may be left in a bad state and require 369 * a reboot. The beamformer will not waste time releasing resources unless it was 370 * compiled with BEAMFORMER_DEBUG enabled (useful for address sanitizer). */ 371 BEAMFORMER_EXPORT void beamformer_terminate(BeamformerInput *); 372 373 #if !BEAMFORMER_DEBUG 374 BEAMFORMER_EXPORT void beamformer_frame_step(BeamformerInput *); 375 #endif 376 377 #if BEAMFORMER_DEBUG 378 BEAMFORMER_EXPORT void beamformer_debug_hot_release(BeamformerInput *); 379 BEAMFORMER_EXPORT void beamformer_debug_hot_reload(OSLibrary new_library, BeamformerInput *); 380 #endif 381 382 #endif /*BEAMFORMER_H */