util.h (9875B)
1 /* See LICENSE for license details. */ 2 #ifndef _UTIL_H_ 3 #define _UTIL_H_ 4 5 #include <stddef.h> 6 #include <stdint.h> 7 8 #include "compiler.h" 9 10 #ifndef asm 11 #define asm __asm__ 12 #endif 13 14 #ifndef typeof 15 #define typeof __typeof__ 16 #endif 17 18 #ifdef _DEBUG 19 #if OS_WINDOWS 20 #define DEBUG_EXPORT __declspec(dllexport) 21 #ifdef _BEAMFORMER_DLL 22 #define DEBUG_IMPORT __declspec(dllimport) 23 #else 24 #define DEBUG_IMPORT __declspec(dllexport) 25 #endif 26 #else 27 #ifdef _BEAMFORMER_DLL 28 #define DEBUG_IMPORT extern 29 #else 30 #define DEBUG_IMPORT 31 #endif 32 #define DEBUG_EXPORT 33 #endif 34 #define DEBUG_DECL(a) a 35 #define assert(c) do { if (!(c)) debugbreak(); } while (0) 36 #else 37 #define DEBUG_IMPORT global 38 #define DEBUG_EXPORT function 39 #define DEBUG_DECL(a) 40 #define assert(c) (void)(c) 41 #endif 42 #define ASSERT assert 43 44 #if ASAN_ACTIVE 45 void __asan_poison_memory_region(void *, ptrdiff_t); 46 void __asan_unpoison_memory_region(void *, ptrdiff_t); 47 #define asan_poison_region(region, size) __asan_poison_memory_region((region), (size)) 48 #define asan_unpoison_region(region, size) __asan_unpoison_memory_region((region), (size)) 49 #else 50 #define asan_poison_region(...) 51 #define asan_unpoison_region(...) 52 #endif 53 54 #define INVALID_CODE_PATH ASSERT(0) 55 #define INVALID_DEFAULT_CASE default: ASSERT(0); break 56 #define InvalidCodePath assert(0) 57 #define InvalidDefaultCase default: assert(0); break 58 59 #define arg_list(type, ...) (type []){__VA_ARGS__}, sizeof((type []){__VA_ARGS__}) / sizeof(type) 60 61 #define function static 62 #define global static 63 #define local_persist static 64 65 #define alignof _Alignof 66 #define static_assert _Static_assert 67 68 /* NOTE: garbage to get the prepocessor to properly stringize the value of a macro */ 69 #define str_(...) #__VA_ARGS__ 70 #define str(...) str_(__VA_ARGS__) 71 72 #define countof(a) (iz)(sizeof(a) / sizeof(*a)) 73 #define ARRAY_COUNT(a) (sizeof(a) / sizeof(*a)) 74 #define ABS(x) ((x) < 0 ? (-x) : (x)) 75 #define BETWEEN(x, a, b) ((x) >= (a) && (x) <= (b)) 76 #define CLAMP(x, a, b) ((x) < (a) ? (a) : (x) > (b) ? (b) : (x)) 77 #define CLAMP01(x) CLAMP(x, 0, 1) 78 #define ISPOWEROF2(a) (((a) & ((a) - 1)) == 0) 79 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 80 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 81 #define ORONE(x) ((x)? (x) : 1) 82 #define SIGN(x) ((x) < 0? -1 : 1) 83 #define swap(a, b) do {typeof(a) __tmp = (a); (a) = (b); (b) = __tmp;} while(0) 84 85 #define f32_cmp(x, y) (ABS((x) - (y)) <= F32_EPSILON * MAX(1.0f, MAX(ABS(x), ABS(y)))) 86 87 #define EachElement(array, it) (u64 it = 0; it < countof(array); it += 1) 88 #define EachEnumValue(type, it) (type it = (type)0; it < type##_Count; it = (type)(it + 1)) 89 #define EachNonZeroEnumValue(type, it) (type it = (type)1; it < type##_Count; it = (type)(it + 1)) 90 91 #define spin_wait(c) while ((c)) 92 93 /* NOTE(rnp): no guarantees about actually getting an element */ 94 #define SLLPop(list) list; list = list ? list->next : 0 95 #define SLLPush(v, list) do { \ 96 (v)->next = (list); \ 97 (list) = v; \ 98 } while (0) 99 100 #define SLLPopFreelist(list) list; do { \ 101 asan_unpoison_region((list), sizeof(*(list))); \ 102 (void)SLLPop((list)); \ 103 } while(0) 104 105 #define SLLPushFreelist(v, list) do { \ 106 SLLPush((v), (list)); \ 107 asan_poison_region((v), sizeof(*(v))); \ 108 } while(0) 109 110 #define DLLPushDown(v, list) do { \ 111 (v)->next = (list); \ 112 if ((v)->next) (v)->next->prev = (v); \ 113 (list) = (v); \ 114 } while (0) 115 116 #define DLLRemove(v) do { \ 117 if ((v)->next) (v)->next->prev = (v)->prev; \ 118 if ((v)->prev) (v)->prev->next = (v)->next; \ 119 } while (0) 120 121 #define KB(a) ((u64)(a) << 10ULL) 122 #define MB(a) ((u64)(a) << 20ULL) 123 #define GB(a) ((u64)(a) << 30ULL) 124 125 #define I32_MAX (0x7FFFFFFFL) 126 #define U32_MAX (0xFFFFFFFFUL) 127 #define F32_INFINITY (1e+300*1e+300) 128 #define F32_EPSILON (1e-6f) 129 #ifndef PI 130 #define PI (3.14159265358979323846f) 131 #endif 132 133 typedef char c8; 134 typedef uint8_t u8; 135 typedef int16_t i16; 136 typedef uint16_t u16; 137 typedef int32_t i32; 138 typedef uint32_t u32; 139 typedef int64_t i64; 140 typedef uint64_t u64; 141 typedef uint32_t b32; 142 typedef float f32; 143 typedef double f64; 144 typedef ptrdiff_t iz; 145 typedef size_t uz; 146 typedef ptrdiff_t iptr; 147 typedef size_t uptr; 148 149 #include "intrinsics.c" 150 151 typedef struct { u8 *beg, *end; } Arena; 152 typedef struct { Arena *arena; u8 *old_beg; } TempArena; 153 154 typedef struct { iz len; u8 *data; } s8; 155 #define s8(s) (s8){.len = countof(s) - 1, .data = (u8 *)s} 156 #define s8_comp(s) {sizeof(s) - 1, (u8 *)s} 157 158 typedef struct { iz len; u16 *data; } s16; 159 160 typedef struct { u32 cp, consumed; } UnicodeDecode; 161 162 /* NOTE: raylib stubs */ 163 #ifndef RAYLIB_H 164 typedef struct { f32 x, y; } Vector2; 165 typedef struct { f32 x, y, w, h; } Rectangle; 166 #endif 167 168 typedef union { 169 struct { i32 x, y; }; 170 struct { i32 w, h; }; 171 i32 E[2]; 172 } iv2; 173 174 typedef union { 175 struct { i32 x, y, z; }; 176 struct { i32 w, h, d; }; 177 iv2 xy; 178 i32 E[3]; 179 } iv3; 180 181 typedef union { 182 struct { u32 x, y; }; 183 struct { u32 w, h; }; 184 u32 E[2]; 185 } uv2; 186 187 typedef union { 188 struct { u32 x, y, z; }; 189 struct { u32 w, h, d; }; 190 uv2 xy; 191 u32 E[3]; 192 } uv3; 193 194 typedef union { 195 struct { u32 x, y, z, w; }; 196 struct { uv3 xyz; u32 _w; }; 197 u32 E[4]; 198 } uv4; 199 200 typedef union { 201 struct { f32 x, y; }; 202 struct { f32 w, h; }; 203 Vector2 rl; 204 f32 E[2]; 205 } v2; 206 207 typedef union { 208 struct { f32 x, y, z; }; 209 struct { f32 w, h, d; }; 210 f32 E[3]; 211 } v3; 212 213 typedef union { 214 struct { f32 x, y, z, w; }; 215 struct { f32 r, g, b, a; }; 216 struct { v3 xyz; f32 _1; }; 217 struct { f32 _2; v3 yzw; }; 218 struct { v2 xy, zw; }; 219 f32 E[4]; 220 } v4; 221 222 #define XZ(v) (v2){.x = v.x, .y = v.z} 223 #define YZ(v) (v2){.x = v.y, .y = v.z} 224 #define XY(v) (v2){.x = v.x, .y = v.y} 225 226 typedef union { 227 struct { v4 x, y, z, w; }; 228 v4 c[4]; 229 f32 E[16]; 230 } m4; 231 232 /* TODO(rnp): delete raylib */ 233 typedef struct { 234 v3 origin; 235 v3 direction; 236 } ray; 237 238 typedef union { 239 struct { v2 pos, size; }; 240 Rectangle rl; 241 } Rect; 242 #define INVERTED_INFINITY_RECT (Rect){.pos = {.x = -F32_INFINITY, .y = -F32_INFINITY}, \ 243 .size = {.x = -F32_INFINITY, .y = -F32_INFINITY}} 244 245 typedef struct { 246 u8 *data; 247 i32 widx; 248 i32 cap; 249 b32 errors; 250 } Stream; 251 252 #define INVALID_FILE (-1) 253 254 typedef struct OS OS; 255 256 typedef struct { 257 Arena arena; 258 iptr handle; 259 iptr window_handle; 260 iptr gl_context; 261 iptr user_context; 262 i32 sync_variable; 263 b32 asleep; 264 } GLWorkerThreadContext; 265 266 #define FILE_WATCH_CALLBACK_FN(name) b32 name(OS *os, s8 path, iptr user_data, Arena arena) 267 typedef FILE_WATCH_CALLBACK_FN(file_watch_callback); 268 269 typedef struct { 270 iptr user_data; 271 u64 hash; 272 file_watch_callback *callback; 273 } FileWatch; 274 275 typedef struct { 276 u64 hash; 277 iptr handle; 278 s8 name; 279 280 FileWatch *data; 281 iz count; 282 iz capacity; 283 Arena buffer; 284 } FileWatchDirectory; 285 286 typedef struct { 287 FileWatchDirectory *data; 288 iz count; 289 iz capacity; 290 iptr handle; 291 } FileWatchContext; 292 293 typedef struct { 294 void *region; 295 iptr os_context; 296 } SharedMemoryRegion; 297 298 #define OS_ALLOC_ARENA_FN(name) Arena name(iz capacity) 299 typedef OS_ALLOC_ARENA_FN(os_alloc_arena_fn); 300 301 #define OS_ADD_FILE_WATCH_FN(name) void name(OS *os, Arena *a, s8 path, \ 302 file_watch_callback *callback, iptr user_data) 303 typedef OS_ADD_FILE_WATCH_FN(os_add_file_watch_fn); 304 305 #define OS_WAKE_WORKER_FN(name) void name(GLWorkerThreadContext *ctx) 306 typedef OS_WAKE_WORKER_FN(os_wake_worker_fn); 307 308 #define OS_READ_WHOLE_FILE_FN(name) s8 name(Arena *arena, char *file) 309 typedef OS_READ_WHOLE_FILE_FN(os_read_whole_file_fn); 310 311 #define OS_WAIT_ON_VALUE_FN(name) b32 name(i32 *value, i32 current, u32 timeout_ms) 312 typedef OS_WAIT_ON_VALUE_FN(os_wait_on_value_fn); 313 314 #define OS_WAKE_WAITERS_FN(name) void name(i32 *sync) 315 typedef OS_WAKE_WAITERS_FN(os_wake_waiters_fn); 316 317 #define OS_WRITE_NEW_FILE_FN(name) b32 name(char *fname, s8 raw) 318 typedef OS_WRITE_NEW_FILE_FN(os_write_new_file_fn); 319 320 #define OS_WRITE_FILE_FN(name) b32 name(iptr file, s8 raw) 321 typedef OS_WRITE_FILE_FN(os_write_file_fn); 322 323 #define OS_THREAD_ENTRY_POINT_FN(name) iptr name(iptr _ctx) 324 typedef OS_THREAD_ENTRY_POINT_FN(os_thread_entry_point_fn); 325 326 #define OS_SHARED_MEMORY_LOCK_REGION_FN(name) b32 name(SharedMemoryRegion *sm, i32 *locks, i32 lock_index, u32 timeout_ms) 327 typedef OS_SHARED_MEMORY_LOCK_REGION_FN(os_shared_memory_region_lock_fn); 328 329 #define OS_SHARED_MEMORY_UNLOCK_REGION_FN(name) void name(SharedMemoryRegion *sm, i32 *locks, i32 lock_index) 330 typedef OS_SHARED_MEMORY_UNLOCK_REGION_FN(os_shared_memory_region_unlock_fn); 331 332 #define RENDERDOC_GET_API_FN(name) b32 name(u32 version, void **out_api) 333 typedef RENDERDOC_GET_API_FN(renderdoc_get_api_fn); 334 335 #define RENDERDOC_START_FRAME_CAPTURE_FN(name) void name(iptr gl_context, iptr window_handle) 336 typedef RENDERDOC_START_FRAME_CAPTURE_FN(renderdoc_start_frame_capture_fn); 337 338 #define RENDERDOC_END_FRAME_CAPTURE_FN(name) b32 name(iptr gl_context, iptr window_handle) 339 typedef RENDERDOC_END_FRAME_CAPTURE_FN(renderdoc_end_frame_capture_fn); 340 341 typedef alignas(16) u8 RenderDocAPI[216]; 342 #define RENDERDOC_API_FN_ADDR(a, offset) (*(iptr *)((*a) + offset)) 343 #define RENDERDOC_START_FRAME_CAPTURE(a) (renderdoc_start_frame_capture_fn *)RENDERDOC_API_FN_ADDR(a, 152) 344 #define RENDERDOC_END_FRAME_CAPTURE(a) (renderdoc_end_frame_capture_fn *) RENDERDOC_API_FN_ADDR(a, 168) 345 346 struct OS { 347 FileWatchContext file_watch_context; 348 iptr context; 349 iptr error_handle; 350 351 GLWorkerThreadContext compute_worker; 352 GLWorkerThreadContext upload_worker; 353 354 DEBUG_DECL(renderdoc_start_frame_capture_fn *start_frame_capture;) 355 DEBUG_DECL(renderdoc_end_frame_capture_fn *end_frame_capture;) 356 }; 357 358 #define LABEL_GL_OBJECT(type, id, s) {s8 _s = (s); glObjectLabel(type, id, (i32)_s.len, (c8 *)_s.data);} 359 360 #include "util.c" 361 #include "math.c" 362 363 #endif /* _UTIL_H_ */