ogl_beamforming

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

main_w32.c (3896B)


      1 /* See LICENSE for license details. */
      2 #ifndef _WIN32
      3 #error This file is only meant to be compiled for Win32
      4 #endif
      5 
      6 #include "beamformer.h"
      7 
      8 typedef struct {
      9 	iptr io_completion_handle;
     10 } w32_context;
     11 
     12 enum w32_io_events {
     13 	W32_IO_FILE_WATCH,
     14 	W32_IO_PIPE,
     15 };
     16 
     17 typedef struct {
     18 	u64  tag;
     19 	iptr context;
     20 } w32_io_completion_event;
     21 
     22 #include "os_win32.c"
     23 
     24 #define OS_DEBUG_LIB_NAME      ".\\beamformer.dll"
     25 #define OS_DEBUG_LIB_TEMP_NAME ".\\beamformer_temp.dll"
     26 
     27 #define OS_CUDA_LIB_NAME       "external\\cuda_toolkit.dll"
     28 #define OS_CUDA_LIB_TEMP_NAME  "external\\cuda_toolkit_temp.dll"
     29 
     30 #define OS_RENDERDOC_SONAME    "renderdoc.dll"
     31 
     32 #define OS_SMEM_NAME           "Local\\ogl_beamformer_parameters"
     33 
     34 #define OS_PATH_SEPERATOR      "\\"
     35 
     36 #include "static.c"
     37 
     38 static void
     39 dispatch_file_watch(OS *os, FileWatchDirectory *fw_dir, u8 *buf, Arena arena)
     40 {
     41 	i64 offset = 0;
     42 	TempArena save_point = {0};
     43 	w32_file_notify_info *fni = (w32_file_notify_info *)buf;
     44 	do {
     45 		end_temp_arena(save_point);
     46 		save_point = begin_temp_arena(&arena);
     47 
     48 		Stream path = {.data = arena_commit(&arena, KB(1)), .cap = KB(1)};
     49 
     50 		if (fni->action != FILE_ACTION_MODIFIED) {
     51 			stream_append_s8(&path, s8("unknown file watch event: "));
     52 			stream_append_u64(&path, fni->action);
     53 			stream_append_byte(&path, '\n');
     54 			os->write_file(os->stderr, stream_to_s8(&path));
     55 			stream_reset(&path, 0);
     56 		}
     57 
     58 		stream_append_s8(&path, fw_dir->name);
     59 		stream_append_byte(&path, '\\');
     60 
     61 		s8 file_name = s16_to_s8(&arena, (s16){.data = fni->filename,
     62 		                                       .len  = fni->filename_size / 2});
     63 		stream_append_s8(&path, file_name);
     64 		stream_append_byte(&path, 0);
     65 		stream_commit(&path, -1);
     66 
     67 		u64 hash = s8_hash(file_name);
     68 		for (u32 i = 0; i < fw_dir->file_watch_count; i++) {
     69 			FileWatch *fw = fw_dir->file_watches + i;
     70 			if (fw->hash == hash) {
     71 				fw->callback(os, stream_to_s8(&path), fw->user_data, arena);
     72 				break;
     73 			}
     74 		}
     75 
     76 		offset = fni->next_entry_offset;
     77 		fni    = (w32_file_notify_info *)((u8 *)fni + offset);
     78 	} while (offset);
     79 }
     80 
     81 static void
     82 clear_io_queue(OS *os, BeamformerInput *input, Arena arena)
     83 {
     84 	w32_context *ctx = (w32_context *)os->context;
     85 
     86 	iptr handle = ctx->io_completion_handle;
     87 	w32_overlapped *overlapped;
     88 	u32  bytes_read;
     89 	uptr user_data;
     90 	while (GetQueuedCompletionStatus(handle, &bytes_read, &user_data, &overlapped, 0)) {
     91 		w32_io_completion_event *event = (w32_io_completion_event *)user_data;
     92 		switch (event->tag) {
     93 		case W32_IO_FILE_WATCH: {
     94 			FileWatchDirectory *dir = (FileWatchDirectory *)event->context;
     95 			dispatch_file_watch(os, dir, dir->buffer.beg, arena);
     96 			zero_struct(overlapped);
     97 			ReadDirectoryChangesW(dir->handle, dir->buffer.beg, 4096, 0,
     98 			                      FILE_NOTIFY_CHANGE_LAST_WRITE, 0, overlapped, 0);
     99 		} break;
    100 		case W32_IO_PIPE: break;
    101 		}
    102 	}
    103 }
    104 
    105 int
    106 main(void)
    107 {
    108 	BeamformerCtx   ctx   = {0};
    109 	BeamformerInput input = {.executable_reloaded = 1};
    110 	Arena temp_memory = os_alloc_arena((Arena){0}, MB(16));
    111 	ctx.error_stream  = stream_alloc(&temp_memory, MB(1));
    112 
    113 	ctx.ui_backing_store        = sub_arena(&temp_memory, MB(2), KB(4));
    114 	ctx.os.compute_worker.arena = sub_arena(&temp_memory, MB(2), KB(4));
    115 
    116 	#define X(name) ctx.os.name = os_ ## name;
    117 	OS_FNS
    118 	#undef X
    119 
    120 	w32_context w32_ctx = {0};
    121 	w32_ctx.io_completion_handle = CreateIoCompletionPort(INVALID_FILE, 0, 0, 0);
    122 
    123 	ctx.os.context               = (iptr)&w32_ctx;
    124 	ctx.os.compute_worker.asleep = 1;
    125 	ctx.os.stderr                = GetStdHandle(STD_ERROR_HANDLE);
    126 
    127 	debug_init(&ctx.os, (iptr)&input, &temp_memory);
    128 	setup_beamformer(&ctx, &temp_memory);
    129 	os_wake_waiters(&ctx.os.compute_worker.sync_variable);
    130 
    131 	while (!ctx.should_exit) {
    132 		clear_io_queue(&ctx.os, &input, temp_memory);
    133 
    134 		input.last_mouse = input.mouse;
    135 		input.mouse.rl   = GetMousePosition();
    136 
    137 		beamformer_frame_step(&ctx, &temp_memory, &input);
    138 
    139 		input.executable_reloaded = 0;
    140 	}
    141 }