ogl_beamforming

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

main_w32.c (4181B)


      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_PIPE_NAME "\\\\.\\pipe\\beamformer_data_fifo"
     31 #define OS_SMEM_NAME "Local\\ogl_beamformer_parameters"
     32 
     33 #define OS_PATH_SEPERATOR "\\"
     34 
     35 #include "static.c"
     36 
     37 static void
     38 w32_wide_char_to_mb(Stream *s, u16 *wstr, u32 wide_char_length)
     39 {
     40 	/* NOTE(rnp): this assumes the wstr is strictly ASCII */
     41 	s->errors |= (s->cap - s->widx) < wide_char_length;
     42 	if (!s->errors) {
     43 		for (u32 i = 0; i < wide_char_length; i++)
     44 			s->data[s->widx++] = wstr[i] & 0xFF;
     45 	}
     46 }
     47 
     48 static void
     49 dispatch_file_watch(FileWatchDirectory *fw_dir, u8 *buf, Arena arena)
     50 {
     51 	i64 offset = 0;
     52 	Stream path = stream_alloc(&arena, 256);
     53 	w32_file_notify_info *fni = (w32_file_notify_info *)buf;
     54 	do {
     55 		if (fni->action != FILE_ACTION_MODIFIED) {
     56 			path.widx = 0;
     57 			stream_append_s8(&path, s8("unknown file watch event: "));
     58 			stream_append_u64(&path, fni->action);
     59 			stream_append_byte(&path, '\n');
     60 			os_write_err_msg(stream_to_s8(&path));
     61 		}
     62 
     63 		path.widx = 0;
     64 		stream_append_s8(&path, fw_dir->name);
     65 		stream_append_byte(&path, '\\');
     66 
     67 		s8 file_name = {.data = path.data + path.widx, .len = fni->filename_size / 2};
     68 		w32_wide_char_to_mb(&path, fni->filename, fni->filename_size / 2);
     69 		stream_append_byte(&path, 0);
     70 		path.widx--;
     71 
     72 		u64 hash = s8_hash(file_name);
     73 		for (u32 i = 0; i < fw_dir->file_watch_count; i++) {
     74 			FileWatch *fw = fw_dir->file_watches + i;
     75 			if (fw->hash == hash) {
     76 				fw->callback(stream_to_s8(&path),
     77 				             fw->user_data, arena);
     78 				break;
     79 			}
     80 		}
     81 
     82 		offset = fni->next_entry_offset;
     83 		fni    = (w32_file_notify_info *)((u8 *)fni + offset);
     84 	} while (offset);
     85 }
     86 
     87 static void
     88 clear_io_queue(Platform *platform, BeamformerInput *input, Arena arena)
     89 {
     90 	w32_context *ctx = (w32_context *)platform->os_context;
     91 
     92 	iptr handle = ctx->io_completion_handle;
     93 	w32_overlapped *overlapped;
     94 	u32  bytes_read;
     95 	uptr user_data;
     96 	while (GetQueuedCompletionStatus(handle, &bytes_read, &user_data, &overlapped, 0)) {
     97 		w32_io_completion_event *event = (w32_io_completion_event *)user_data;
     98 		switch (event->tag) {
     99 		case W32_IO_FILE_WATCH: {
    100 			FileWatchDirectory *dir = (FileWatchDirectory *)event->context;
    101 			dispatch_file_watch(dir, dir->buffer.beg, arena);
    102 			zero_struct(overlapped);
    103 			ReadDirectoryChangesW(dir->handle, dir->buffer.beg, 4096, 0,
    104 			                      FILE_NOTIFY_CHANGE_LAST_WRITE, 0, overlapped, 0);
    105 		} break;
    106 		case W32_IO_PIPE: break;
    107 		}
    108 	}
    109 }
    110 
    111 int
    112 main(void)
    113 {
    114 	BeamformerCtx   ctx   = {0};
    115 	BeamformerInput input = {.executable_reloaded = 1};
    116 	Arena temp_memory = os_alloc_arena((Arena){0}, 16 * MEGABYTE);
    117 	ctx.error_stream  = stream_alloc(&temp_memory, 1 * MEGABYTE);
    118 
    119 	ctx.ui_backing_store = sub_arena(&temp_memory, 2 * MEGABYTE, 4096);
    120 
    121 	Pipe data_pipe    = os_open_named_pipe(OS_PIPE_NAME);
    122 	input.pipe_handle = data_pipe.file;
    123 	ASSERT(data_pipe.file != INVALID_FILE);
    124 
    125 	#define X(name) ctx.platform.name = os_ ## name;
    126 	PLATFORM_FNS
    127 	#undef X
    128 
    129 	w32_context w32_ctx = {0};
    130 	w32_ctx.io_completion_handle = CreateIoCompletionPort(INVALID_FILE, 0, 0, 0);
    131 	ctx.platform.os_context = (iptr)&w32_ctx;
    132 
    133 	setup_beamformer(&ctx, &temp_memory);
    134 	debug_init(&ctx.platform, (iptr)&input, &temp_memory);
    135 
    136 	while (!(ctx.flags & SHOULD_EXIT)) {
    137 		clear_io_queue(&ctx.platform, &input, temp_memory);
    138 
    139 		input.last_mouse = input.mouse;
    140 		input.mouse.rl   = GetMousePosition();
    141 
    142 		i32 bytes_available = 0;
    143 		input.pipe_data_available = PeekNamedPipe(data_pipe.file, 0, 1 * MEGABYTE, 0,
    144 		                                          &bytes_available, 0) && bytes_available;
    145 
    146 		beamformer_frame_step(&ctx, &temp_memory, &input);
    147 
    148 		input.executable_reloaded = 0;
    149 	}
    150 }