util.h (7672B)
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 #ifndef asm 9 #define asm __asm__ 10 #endif 11 12 #ifndef typeof 13 #define typeof __typeof__ 14 #endif 15 16 #define alignof _Alignof 17 18 #ifdef _DEBUG 19 #ifdef OS_WINDOWS 20 #define DEBUG_EXPORT __declspec(dllexport) 21 #else 22 #define DEBUG_EXPORT 23 #endif 24 #define DEBUG_DECL(a) a 25 #define assert(c) do { if (!(c)) debugbreak(); } while (0) 26 #else 27 #define DEBUG_EXPORT function 28 #define DEBUG_DECL(a) 29 #define assert(c) (void)(c) 30 #endif 31 32 #define InvalidCodePath assert(0) 33 #define InvalidDefaultCase default: assert(0); break 34 35 #define arg_list(type, ...) (type []){__VA_ARGS__}, sizeof((type []){__VA_ARGS__}) / sizeof(type) 36 37 #define function static 38 #define global static 39 #define local_persist static 40 41 #define static_assert _Static_assert 42 43 /* NOTE: garbage to get the prepocessor to properly stringize the value of a macro */ 44 #define str_(...) #__VA_ARGS__ 45 #define str(...) str_(__VA_ARGS__) 46 47 #define countof(a) (sizeof(a) / sizeof(*a)) 48 #define ABS(x) ((x) < 0 ? (-x) : (x)) 49 #define BETWEEN(x, a, b) ((x) >= (a) && (x) <= (b)) 50 #define CLAMP(x, a, b) ((x) < (a) ? (a) : (x) > (b) ? (b) : (x)) 51 #define CLAMP01(x) CLAMP(x, 0, 1) 52 #define ISPOWEROF2(a) (((a) & ((a) - 1)) == 0) 53 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 54 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 55 #define ORONE(x) ((x)? (x) : 1) 56 #define SIGN(x) ((x) < 0? -1 : 1) 57 #define swap(a, b) {typeof(a) __tmp = (a); (a) = (b); (b) = __tmp;} 58 59 #define EachElement(array, it) (u64 it = 0; it < countof(array); it += 1) 60 #define EachEnumValue(type, it) (type it = (type)0; it < type##_Count; it = (type)(it + 1)) 61 #define EachNonZeroEnumValue(type, it) (type it = (type)1; it < type##_Count; it = (type)(it + 1)) 62 63 /* NOTE(rnp): no guarantees about actually getting an element */ 64 #define SLLPop(list) list; list = list ? list->next : 0 65 #define SLLPush(v, list) do { \ 66 (v)->next = (list); \ 67 (list) = v; \ 68 } while (0) 69 70 #define DLLPushDown(v, list) do { \ 71 (v)->next = (list); \ 72 if ((v)->next) (v)->next->prev = (v); \ 73 (list) = (v); \ 74 } while (0) 75 76 #define DLLRemove(v) do { \ 77 if ((v)->next) (v)->next->prev = (v)->prev; \ 78 if ((v)->prev) (v)->prev->next = (v)->next; \ 79 } while (0) 80 81 #define KB(a) ((u64)(a) << 10ull) 82 #define MB(a) ((u64)(a) << 20ull) 83 #define GB(a) ((u64)(a) << 30ull) 84 85 #define S32_MAX (0x7fffffffl) 86 #define U32_MAX (0xfffffffful) 87 #define U64_MAX (0xffffffffffffffffull) 88 #define F32_INFINITY (__builtin_inff()) 89 90 #define PI (3.14159265358979323846) 91 92 #define INVALID_FILE (-1) 93 94 typedef char c8; 95 typedef uint8_t u8; 96 typedef int16_t s16; 97 typedef uint16_t u16; 98 typedef int32_t s32; 99 typedef uint32_t u32; 100 typedef int64_t s64; 101 typedef uint64_t u64; 102 typedef uint32_t b32; 103 typedef float f32; 104 typedef double f64; 105 typedef ptrdiff_t sz; 106 typedef size_t uz; 107 typedef ptrdiff_t sptr; 108 typedef size_t uptr; 109 110 #include "intrinsics.c" 111 112 typedef struct { u8 *beg, *end; } Arena; 113 114 typedef struct { sz len; u8 *data; } str8; 115 #define str8(s) (str8){.len = countof(s) - 1, .data = (u8 *)s} 116 117 typedef struct { sz len; u16 *data; } str16; 118 119 typedef struct { u32 cp, consumed; } UnicodeDecode; 120 121 typedef union { 122 struct { s32 x, y; }; 123 struct { s32 w, h; }; 124 s32 E[2]; 125 } sv2; 126 127 typedef union { 128 struct { s32 x, y, z; }; 129 struct { s32 w, h, d; }; 130 sv2 xy; 131 s32 E[3]; 132 } sv3; 133 134 typedef union { 135 struct { u32 x, y; }; 136 struct { u32 w, h; }; 137 u32 E[2]; 138 } uv2; 139 140 typedef union { 141 struct { u32 x, y, z; }; 142 struct { u32 w, h, d; }; 143 uv2 xy; 144 u32 E[3]; 145 } uv3; 146 147 typedef union { 148 struct { u32 x, y, z, w; }; 149 struct { uv3 xyz; u32 _w; }; 150 u32 E[4]; 151 } uv4; 152 153 typedef union { 154 struct { f32 x, y; }; 155 struct { f32 w, h; }; 156 f32 E[2]; 157 } v2; 158 159 typedef union { 160 struct { f32 x, y, z; }; 161 struct { f32 w, h, d; }; 162 f32 E[3]; 163 } v3; 164 165 typedef union { 166 struct { f32 x, y, z, w; }; 167 struct { f32 r, g, b, a; }; 168 struct { v3 xyz; f32 _1; }; 169 struct { f32 _2; v3 yzw; }; 170 struct { v2 xy, zw; }; 171 f32 E[4]; 172 } v4; 173 174 #define XZ(v) (v2){.x = v.x, .y = v.z} 175 #define YZ(v) (v2){.x = v.y, .y = v.z} 176 #define XY(v) (v2){.x = v.x, .y = v.y} 177 178 typedef union { 179 struct { v4 x, y, z, w; }; 180 v4 c[4]; 181 f32 E[16]; 182 } m4; 183 184 typedef struct { v2 pos, size; } Rect; 185 #define INVERTED_INFINITY_RECT (Rect){.pos = {.x = -F32_INFINITY, .y = -F32_INFINITY}, \ 186 .size = {.x = -F32_INFINITY, .y = -F32_INFINITY}} 187 188 typedef struct { 189 u8 *data; 190 u32 widx; 191 u32 cap; 192 b32 errors; 193 } Stream; 194 195 typedef struct OS OS; 196 197 #define FILE_WATCH_CALLBACK_FN(name) b32 name(OS *os, str8 path, sptr user_data, Arena arena) 198 typedef FILE_WATCH_CALLBACK_FN(file_watch_callback); 199 200 typedef struct { 201 sptr user_data; 202 u64 hash; 203 file_watch_callback *callback; 204 } FileWatch; 205 206 typedef struct { 207 u64 hash; 208 sptr handle; 209 str8 name; 210 211 FileWatch *data; 212 sz count; 213 sz capacity; 214 Arena buffer; 215 } FileWatchDirectory; 216 217 typedef struct { 218 FileWatchDirectory *data; 219 sz count; 220 sz capacity; 221 sptr handle; 222 } FileWatchContext; 223 224 #define OS_ALLOC_ARENA_FN(name) Arena name(sz capacity) 225 #define OS_ADD_FILE_WATCH_FN(name) void name(OS *os, Arena *a, str8 path, \ 226 file_watch_callback *callback, sptr user_data) 227 #define OS_READ_WHOLE_FILE_FN(name) str8 name(Arena *arena, char *file) 228 #define OS_WRITE_NEW_FILE_FN(name) b32 name(char *fname, str8 raw) 229 #define OS_WRITE_FILE_FN(name) b32 name(sptr file, str8 raw) 230 231 struct OS { 232 FileWatchContext file_watch_context; 233 sptr context; 234 sptr error_handle; 235 }; 236 237 #include "vulkan.h" 238 239 #define MAX_RENDER_FRAMES_IN_FLIGHT 2 240 #define MAX_COMPUTE_FRAMES_IN_FLIGHT 3 241 242 typedef struct { 243 VkSurfaceFormatKHR surface_format; 244 VkExtent2D surface_extent; 245 u32 queue_index; 246 b32 exclusive_queue; 247 VkSurfaceKHR surface; 248 VkSwapchainKHR swap_chain; 249 VkFramebuffer *framebuffers; 250 VkImage *images; 251 VkImageView *image_views; 252 VkSemaphore *render_complete_semaphores; 253 VkSemaphore image_available_semaphores[MAX_RENDER_FRAMES_IN_FLIGHT]; 254 u32 image_count; 255 u32 framebuffer_index; 256 u32 current_frame_index; 257 b32 framebuffer_resize; 258 } VulkanSwapChain; 259 260 typedef enum { 261 VulkanPipelineKind_Render, 262 VulkanPipelineKind_Compute, 263 VulkanPipelineKind_Count, 264 } VulkanPipelineKind; 265 266 typedef struct { 267 VkRenderPass render_pass; 268 VkCommandBuffer command_buffers[MAX_RENDER_FRAMES_IN_FLIGHT]; 269 VkFence command_buffer_fences[MAX_RENDER_FRAMES_IN_FLIGHT]; 270 } VulkanRenderPipeline; 271 272 typedef struct { 273 VkCommandBuffer command_buffers[MAX_COMPUTE_FRAMES_IN_FLIGHT]; 274 VkFence command_buffer_fences[MAX_COMPUTE_FRAMES_IN_FLIGHT]; 275 } VulkanComputePipeline; 276 277 typedef struct { 278 VulkanPipelineKind kind; 279 union { 280 VulkanRenderPipeline render; 281 VulkanComputePipeline compute; 282 }; 283 284 VkPipeline pipeline; 285 VkPipelineLayout pipeline_layout; 286 } VulkanPipeline; 287 288 typedef struct { 289 VkInstance handle; 290 VkDevice device; 291 VkPhysicalDevice physical_device; 292 VkQueue queue; 293 294 VkCommandPool command_pool; 295 296 VulkanPipeline render_pipeline; 297 VulkanSwapChain swap_chain; 298 } VulkanContext; 299 300 typedef struct { 301 Arena arena; 302 OS os; 303 304 sv2 window_size; 305 306 u32 output_frames_count; 307 308 f32 last_time; 309 b32 do_update; 310 311 b32 should_exit; 312 313 void *window; 314 315 VulkanContext vulkan; 316 } ViewerContext; 317 318 #include "util.c" 319 #include "math.c" 320 321 #endif /* _UTIL_H_ */