Commit: 57358dab72f75f60ffbe7362a6c80c8f63654d87
Parent: 7a81806f8d70ccd79c06c3170c2644eddfe56207
Author: Randy Palamar
Date: Sun, 9 Nov 2025 09:32:51 -0700
os: make os struct a platform specific global
Diffstat:
12 files changed, 146 insertions(+), 147 deletions(-)
diff --git a/beamformer.c b/beamformer.c
@@ -748,7 +748,7 @@ load_compute_shader(BeamformerCtx *ctx, BeamformerComputePlan *cp, u32 shader_sl
BeamformerShaderKind base_shader = beamformer_reloadable_shader_kinds[reloadable_index];
s8 path;
if (!BakeShaders)
- path = push_s8_from_parts(&arena, ctx->os.path_separator, s8("shaders"),
+ path = push_s8_from_parts(&arena, os_path_separator(), s8("shaders"),
beamformer_reloadable_shader_files[reloadable_index]);
Stream shader_stream = arena_stream(arena);
@@ -812,7 +812,7 @@ load_compute_shader(BeamformerCtx *ctx, BeamformerComputePlan *cp, u32 shader_sl
/* TODO(rnp): instance name */
s8 shader_name = beamformer_shader_names[shader];
- program = load_shader(&ctx->os, arena, &shader_text, (u32 []){GL_COMPUTE_SHADER}, 1, shader_name);
+ program = load_shader(arena, &shader_text, (u32 []){GL_COMPUTE_SHADER}, 1, shader_name);
}
glDeleteProgram(cp->programs[shader_slot]);
@@ -1134,7 +1134,7 @@ DEBUG_EXPORT BEAMFORMER_RELOAD_SHADER_FN(beamformer_reload_shader)
u32 *shader = &ctx->frame_view_render_context.shader;
glDeleteProgram(*shader);
- *shader = load_shader(&ctx->os, arena, shader_texts, shader_types, shader_count, shader_name);
+ *shader = load_shader(arena, shader_texts, shader_types, shader_count, shader_name);
ctx->frame_view_render_context.updated = 1;
return 1;
@@ -1480,15 +1480,15 @@ DEBUG_EXPORT BEAMFORMER_FRAME_STEP_FN(beamformer_frame_step)
if (input->executable_reloaded) {
ui_init(ctx, ctx->ui_backing_store);
- DEBUG_DECL(start_frame_capture = ctx->os.start_frame_capture);
- DEBUG_DECL(end_frame_capture = ctx->os.end_frame_capture);
+ DEBUG_DECL(start_frame_capture = ctx->start_frame_capture);
+ DEBUG_DECL(end_frame_capture = ctx->end_frame_capture);
}
BeamformerSharedMemory *sm = ctx->shared_memory.region;
if (atomic_load_u32(sm->locks + BeamformerSharedMemoryLockKind_UploadRF))
- os_wake_waiters(&ctx->os.upload_worker.sync_variable);
+ os_wake_waiters(&ctx->upload_worker.sync_variable);
if (atomic_load_u32(sm->locks + BeamformerSharedMemoryLockKind_DispatchCompute))
- os_wake_waiters(&ctx->os.compute_worker.sync_variable);
+ os_wake_waiters(&ctx->compute_worker.sync_variable);
BeamformerFrame *frame = ctx->latest_frame;
BeamformerViewPlaneTag tag = frame? frame->view_plane_tag : 0;
diff --git a/beamformer.h b/beamformer.h
@@ -13,6 +13,8 @@
///////////////////
// REQUIRED OS API
+function iptr os_error_handle(void);
+function s8 os_path_separator(void);
function OS_READ_WHOLE_FILE_FN(os_read_whole_file);
function OS_SHARED_MEMORY_LOCK_REGION_FN(os_shared_memory_region_lock);
function OS_SHARED_MEMORY_UNLOCK_REGION_FN(os_shared_memory_region_unlock);
@@ -325,7 +327,6 @@ typedef struct {
* destroying itself on hot-reload */
FrameViewRenderContext frame_view_render_context;
- OS os;
Stream error_stream;
BeamformWorkQueue *beamform_work_queue;
@@ -343,6 +344,13 @@ typedef struct {
/* NOTE: this will only be used when we are averaging */
u32 averaged_frame_index;
BeamformerFrame averaged_frames[2];
+
+ FileWatchDirectoryList file_watch_list;
+ GLWorkerThreadContext upload_worker;
+ GLWorkerThreadContext compute_worker;
+
+ DEBUG_DECL(renderdoc_start_frame_capture_fn *start_frame_capture;)
+ DEBUG_DECL(renderdoc_end_frame_capture_fn *end_frame_capture;)
} BeamformerCtx;
typedef struct ShaderReloadContext ShaderReloadContext;
@@ -363,7 +371,7 @@ typedef BEAMFORMER_COMPLETE_COMPUTE_FN(beamformer_complete_compute_fn);
#define BEAMFORMER_RF_UPLOAD_FN(name) void name(BeamformerUploadThreadContext *ctx, Arena arena)
typedef BEAMFORMER_RF_UPLOAD_FN(beamformer_rf_upload_fn);
-#define BEAMFORMER_RELOAD_SHADER_FN(name) b32 name(OS *os, s8 path, ShaderReloadContext *src, \
+#define BEAMFORMER_RELOAD_SHADER_FN(name) b32 name(s8 path, ShaderReloadContext *src, \
Arena arena, s8 shader_name)
typedef BEAMFORMER_RELOAD_SHADER_FN(beamformer_reload_shader_fn);
diff --git a/main_linux.c b/main_linux.c
@@ -35,15 +35,14 @@ os_gl_proc_address(char *name)
#include "static.c"
function void
-dispatch_file_watch_events(OS *os, Arena arena)
+dispatch_file_watch_events(FileWatchDirectoryList *fwctx, Arena arena)
{
- FileWatchContext *fwctx = &os->file_watch_context;
u8 *mem = arena_alloc(&arena, 4096, 16, 1);
Stream path = stream_alloc(&arena, 256);
struct inotify_event *event;
iz rlen;
- while ((rlen = read((i32)fwctx->handle, mem, 4096)) > 0) {
+ while ((rlen = read(os_linux_context.inotify_handle, mem, 4096)) > 0) {
for (u8 *data = mem; data < mem + rlen; data += sizeof(*event) + event->len) {
event = (struct inotify_event *)data;
for (u32 i = 0; i < fwctx->count; i++) {
@@ -59,8 +58,7 @@ dispatch_file_watch_events(OS *os, Arena arena)
stream_append_s8s(&path, dir->name, s8("/"), file);
stream_append_byte(&path, 0);
stream_commit(&path, -1);
- fw->callback(os, stream_to_s8(&path),
- fw->user_data, arena);
+ fw->callback(stream_to_s8(&path), fw->user_data, arena);
stream_reset(&path, 0);
break;
}
@@ -78,18 +76,19 @@ main(void)
BeamformerCtx *ctx = 0;
BeamformerInput *input = 0;
+ os_linux_context.inotify_handle = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
+
setup_beamformer(&program_memory, &ctx, &input);
- os_wake_waiters(&ctx->os.compute_worker.sync_variable);
struct pollfd fds[1] = {{0}};
- fds[0].fd = (i32)ctx->os.file_watch_context.handle;
+ fds[0].fd = os_linux_context.inotify_handle;
fds[0].events = POLLIN;
u64 last_time = os_get_timer_counter();
while (!ctx->should_exit) {
poll(fds, countof(fds), 0);
if (fds[0].revents & POLLIN)
- dispatch_file_watch_events(&ctx->os, program_memory);
+ dispatch_file_watch_events(&ctx->file_watch_list, program_memory);
u64 now = os_get_timer_counter();
input->last_mouse = input->mouse;
diff --git a/main_w32.c b/main_w32.c
@@ -33,7 +33,7 @@ os_gl_proc_address(char *name)
#include "static.c"
function void
-dispatch_file_watch(OS *os, FileWatchDirectory *fw_dir, u8 *buf, Arena arena)
+dispatch_file_watch(FileWatchDirectory *fw_dir, u8 *buf, Arena arena)
{
i64 offset = 0;
TempArena save_point = {0};
@@ -48,7 +48,7 @@ dispatch_file_watch(OS *os, FileWatchDirectory *fw_dir, u8 *buf, Arena arena)
stream_append_s8(&path, s8("unknown file watch event: "));
stream_append_u64(&path, fni->action);
stream_append_byte(&path, '\n');
- os_write_file(os->error_handle, stream_to_s8(&path));
+ os_write_file(os_error_handle(), stream_to_s8(&path));
stream_reset(&path, 0);
}
@@ -65,7 +65,7 @@ dispatch_file_watch(OS *os, FileWatchDirectory *fw_dir, u8 *buf, Arena arena)
for (u32 i = 0; i < fw_dir->count; i++) {
FileWatch *fw = fw_dir->data + i;
if (fw->hash == hash) {
- fw->callback(os, stream_to_s8(&path), fw->user_data, arena);
+ fw->callback(stream_to_s8(&path), fw->user_data, arena);
break;
}
}
@@ -76,11 +76,9 @@ dispatch_file_watch(OS *os, FileWatchDirectory *fw_dir, u8 *buf, Arena arena)
}
function void
-clear_io_queue(OS *os, BeamformerInput *input, Arena arena)
+clear_io_queue(BeamformerInput *input, Arena arena)
{
- w32_context *ctx = (w32_context *)os->context;
-
- iptr handle = ctx->io_completion_handle;
+ iptr handle = os_w32_context.io_completion_handle;
w32_overlapped *overlapped;
u32 bytes_read;
uptr user_data;
@@ -89,7 +87,7 @@ clear_io_queue(OS *os, BeamformerInput *input, Arena arena)
switch (event->tag) {
case W32_IO_FILE_WATCH: {
FileWatchDirectory *dir = (FileWatchDirectory *)event->context;
- dispatch_file_watch(os, dir, dir->buffer.beg, arena);
+ dispatch_file_watch(dir, dir->buffer.beg, arena);
zero_struct(overlapped);
ReadDirectoryChangesW(dir->handle, dir->buffer.beg, 4096, 0,
FILE_NOTIFY_CHANGE_LAST_WRITE, 0, overlapped, 0);
@@ -107,18 +105,20 @@ main(void)
BeamformerCtx *ctx = 0;
BeamformerInput *input = 0;
+ os_w32_context.error_handle = GetStdHandle(STD_ERROR_HANDLE);
+ os_w32_context.io_completion_handle = CreateIoCompletionPort(INVALID_FILE, 0, 0, 0);
+ os_w32_context.timer_frequency = os_get_timer_frequency();
+
setup_beamformer(&program_memory, &ctx, &input);
- os_wake_waiters(&ctx->os.compute_worker.sync_variable);
- w32_context *w32_ctx = (w32_context *)ctx->os.context;
u64 last_time = os_get_timer_counter();
while (!ctx->should_exit) {
- clear_io_queue(&ctx->os, input, program_memory);
+ clear_io_queue(input, program_memory);
u64 now = os_get_timer_counter();
input->last_mouse = input->mouse;
input->mouse.rl = GetMousePosition();
- input->dt = (f32)((f64)(now - last_time) / (f64)w32_ctx->timer_frequency);
+ input->dt = (f32)((f64)(now - last_time) / (f64)os_w32_context.timer_frequency);
last_time = now;
beamformer_frame_step(ctx, input);
diff --git a/os_linux.c b/os_linux.c
@@ -21,6 +21,11 @@
#include <sys/syscall.h>
#include <unistd.h>
+typedef struct {
+ i32 inotify_handle;
+} OS_LinuxContext;
+global OS_LinuxContext os_linux_context;
+
/* NOTE(rnp): hidden behind feature flags -> screw compiler/standards idiots */
#ifndef CLOCK_MONOTONIC
#define CLOCK_MONOTONIC 1
@@ -67,6 +72,18 @@ os_fatal(s8 msg)
unreachable();
}
+function iptr
+os_error_handle(void)
+{
+ return STDERR_FILENO;
+}
+
+function s8
+os_path_separator(void)
+{
+ return s8("/");
+}
+
function u64
os_get_timer_frequency(void)
{
@@ -223,19 +240,18 @@ os_unload_library(void *h)
function OS_ADD_FILE_WATCH_FN(os_add_file_watch)
{
s8 directory = path;
- directory.len = s8_scan_backwards(path, OS_PATH_SEPARATOR_CHAR);
+ directory.len = s8_scan_backwards(path, '/');
assert(directory.len > 0);
u64 hash = u64_hash_from_s8(directory);
- FileWatchContext *fwctx = &os->file_watch_context;
FileWatchDirectory *dir = lookup_file_watch_directory(fwctx, hash);
if (!dir) {
- assert(path.data[directory.len] == OS_PATH_SEPARATOR_CHAR);
+ assert(path.data[directory.len] == '/');
dir = da_push(a, fwctx);
dir->hash = hash;
dir->name = push_s8(a, directory);
u32 mask = IN_MOVED_TO|IN_CLOSE_WRITE;
- dir->handle = inotify_add_watch((i32)fwctx->handle, (c8 *)dir->name.data, mask);
+ dir->handle = inotify_add_watch(os_linux_context.inotify_handle, (c8 *)dir->name.data, mask);
}
FileWatch *fw = da_push(a, dir);
@@ -293,10 +309,3 @@ function OS_SHARED_MEMORY_UNLOCK_REGION_FN(os_shared_memory_region_unlock)
atomic_store_u32(lock, 0);
os_wake_waiters(lock);
}
-
-function void
-os_init(OS *os, Arena *program_memory)
-{
- os->file_watch_context.handle = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
- os->error_handle = STDERR_FILENO;
-}
diff --git a/os_win32.c b/os_win32.c
@@ -66,11 +66,6 @@ typedef struct {
iptr event_handle;
} w32_overlapped;
-typedef struct {
- iptr io_completion_handle;
- u64 timer_frequency;
-} w32_context;
-
typedef enum {
W32_IO_FILE_WATCH,
W32_IO_PIPE,
@@ -120,6 +115,13 @@ W32(iptr) wglGetProcAddress(c8 *);
W32(b32) WriteFile(iptr, u8 *, i32, i32 *, void *);
W32(void *) VirtualAlloc(u8 *, iz, u32, u32);
+typedef struct {
+ iptr error_handle;
+ iptr io_completion_handle;
+ u64 timer_frequency;
+} OS_W32Context;
+global OS_W32Context os_w32_context;
+
#ifdef _DEBUG
function void *
os_get_module(char *name, Stream *e)
@@ -156,6 +158,18 @@ os_fatal(s8 msg)
unreachable();
}
+function iptr
+os_error_handle(void)
+{
+ return os_w32_context.error_handle;
+}
+
+function s8
+os_path_separator(void)
+{
+ return s8("\\");
+}
+
function u64
os_get_timer_frequency(void)
{
@@ -338,14 +352,13 @@ os_unload_library(void *h)
function OS_ADD_FILE_WATCH_FN(os_add_file_watch)
{
s8 directory = path;
- directory.len = s8_scan_backwards(path, OS_PATH_SEPARATOR_CHAR);
+ directory.len = s8_scan_backwards(path, '\\');
assert(directory.len > 0);
u64 hash = u64_hash_from_s8(directory);
- FileWatchContext *fwctx = &os->file_watch_context;
FileWatchDirectory *dir = lookup_file_watch_directory(fwctx, hash);
if (!dir) {
- assert(path.data[directory.len] == OS_PATH_SEPARATOR_CHAR);
+ assert(path.data[directory.len] == '\\');
dir = da_push(a, fwctx);
dir->hash = hash;
@@ -354,11 +367,10 @@ function OS_ADD_FILE_WATCH_FN(os_add_file_watch)
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, 0);
- w32_context *ctx = (w32_context *)os->context;
w32_io_completion_event *event = push_struct(a, typeof(*event));
event->tag = W32_IO_FILE_WATCH;
event->context = (iptr)dir;
- CreateIoCompletionPort(dir->handle, ctx->io_completion_handle, (uptr)event, 0);
+ CreateIoCompletionPort(dir->handle, os_w32_context.io_completion_handle, (uptr)event, 0);
dir->buffer = sub_arena(a, 4096 + sizeof(w32_overlapped), 64);
w32_overlapped *overlapped = (w32_overlapped *)(dir->buffer.beg + 4096);
@@ -410,14 +422,3 @@ function OS_SHARED_MEMORY_UNLOCK_REGION_FN(os_shared_memory_region_unlock)
os_wake_waiters(locks + lock_index);
ReleaseSemaphore(ctx->semaphores[lock_index], 1, 0);
}
-
-function void
-os_init(OS *os, Arena *program_memory)
-{
- w32_context *ctx = push_struct(program_memory, typeof(*ctx));
- ctx->io_completion_handle = CreateIoCompletionPort(INVALID_FILE, 0, 0, 0);
- ctx->timer_frequency = os_get_timer_frequency();
-
- os->error_handle = GetStdHandle(STD_ERROR_HANDLE);
- os->context = (iptr)ctx;
-}
diff --git a/static.c b/static.c
@@ -24,15 +24,21 @@ global void *debug_lib;
DEBUG_ENTRY_POINTS
#undef X
+struct debug_context {
+ BeamformerInput *input;
+ b32 *compute_worker_asleep;
+ b32 *upload_worker_asleep;
+};
+
function FILE_WATCH_CALLBACK_FN(debug_reload)
{
- BeamformerInput *input = (BeamformerInput *)user_data;
- Stream err = arena_stream(arena);
+ struct debug_context *ctx = (struct debug_context *)user_data;
+ Stream err = arena_stream(arena);
/* NOTE(rnp): spin until compute thread finishes its work (we will probably
* never reload while compute is in progress but just incase). */
- spin_wait(!atomic_load_u32(&os->compute_worker.asleep));
- spin_wait(!atomic_load_u32(&os->upload_worker.asleep));
+ spin_wait(!atomic_load_u32(ctx->compute_worker_asleep));
+ spin_wait(!atomic_load_u32(ctx->upload_worker_asleep));
os_unload_library(debug_lib);
debug_lib = os_load_library(OS_DEBUG_LIB_NAME, OS_DEBUG_LIB_TEMP_NAME, &err);
@@ -42,18 +48,22 @@ function FILE_WATCH_CALLBACK_FN(debug_reload)
#undef X
stream_append_s8(&err, s8("Reloaded Main Executable\n"));
- os_write_file(os->error_handle, stream_to_s8(&err));
+ os_write_file(os_error_handle(), stream_to_s8(&err));
- input->executable_reloaded = 1;
+ ctx->input->executable_reloaded = 1;
return 1;
}
function void
-debug_init(OS *os, iptr input, Arena *arena)
+debug_init(BeamformerCtx *ctx, BeamformerInput *input, Arena *arena)
{
- os_add_file_watch(os, arena, s8(OS_DEBUG_LIB_NAME), debug_reload, input);
- debug_reload(os, s8(""), input, *arena);
+ struct debug_context *dctx = push_struct(arena, struct debug_context);
+ dctx->input = input;
+ dctx->compute_worker_asleep = &ctx->compute_worker.asleep;
+ dctx->upload_worker_asleep = &ctx->upload_worker.asleep;
+ os_add_file_watch(&ctx->file_watch_list, arena, s8(OS_DEBUG_LIB_NAME), debug_reload, (iptr)dctx);
+ debug_reload(s8(""), (iptr)dctx, *arena);
Stream err = arena_stream(*arena);
void *rdoc = os_get_module(OS_RENDERDOC_SONAME, 0);
@@ -62,30 +72,24 @@ debug_init(OS *os, iptr input, Arena *arena)
if (get_api) {
RenderDocAPI *api = 0;
if (get_api(10600, (void **)&api)) {
- os->start_frame_capture = RENDERDOC_START_FRAME_CAPTURE(api);
- os->end_frame_capture = RENDERDOC_END_FRAME_CAPTURE(api);
+ ctx->start_frame_capture = RENDERDOC_START_FRAME_CAPTURE(api);
+ ctx->end_frame_capture = RENDERDOC_END_FRAME_CAPTURE(api);
stream_append_s8(&err, s8("loaded: " OS_RENDERDOC_SONAME "\n"));
}
}
}
- os_write_file(os->error_handle, stream_to_s8(&err));
+ os_write_file(os_error_handle(), stream_to_s8(&err));
}
#endif /* _DEBUG */
-struct gl_debug_ctx {
- Stream stream;
- iptr os_error_handle;
-};
-
function void
gl_debug_logger(u32 src, u32 type, u32 id, u32 lvl, i32 len, const char *msg, const void *userctx)
{
- struct gl_debug_ctx *ctx = (struct gl_debug_ctx *)userctx;
- Stream *e = &ctx->stream;
+ Stream *e = (Stream *)userctx;
stream_append_s8s(e, s8("[OpenGL] "), (s8){.len = len, .data = (u8 *)msg}, s8("\n"));
- os_write_file(ctx->os_error_handle, stream_to_s8(e));
+ os_write_file(os_error_handle(), stream_to_s8(e));
stream_reset(e, 0);
}
@@ -135,7 +139,7 @@ validate_gl_requirements(GLParams *gl, Arena a)
}
function void
-dump_gl_params(GLParams *gl, Arena a, OS *os)
+dump_gl_params(GLParams *gl, Arena a)
{
#ifdef _DEBUG
s8 vendor = s8("vendor:");
@@ -164,7 +168,7 @@ dump_gl_params(GLParams *gl, Arena a, OS *os)
GL_PARAMETERS
#undef X
stream_append_s8(&s, s8("-----------------------\n"));
- os_write_file(os->error_handle, stream_to_s8(&s));
+ os_write_file(os_error_handle(), stream_to_s8(&s));
#endif
}
@@ -172,7 +176,7 @@ function FILE_WATCH_CALLBACK_FN(reload_shader)
{
ShaderReloadContext *ctx = (typeof(ctx))user_data;
BeamformerShaderKind kind = beamformer_reloadable_shader_kinds[ctx->reloadable_info_index];
- return beamformer_reload_shader(os, path, ctx, arena, beamformer_shader_names[kind]);
+ return beamformer_reload_shader(path, ctx, arena, beamformer_shader_names[kind]);
}
typedef struct {
@@ -189,7 +193,7 @@ function FILE_WATCH_CALLBACK_FN(reload_shader_indirect)
work->kind = BeamformerWorkKind_ReloadShader,
work->reload_shader = rsi->shader;
beamform_work_queue_push_commit(ctx->beamform_work_queue);
- os_wake_waiters(&os->compute_worker.sync_variable);
+ os_wake_waiters(&ctx->compute_worker.sync_variable);
}
return 1;
}
@@ -213,7 +217,7 @@ function FILE_WATCH_CALLBACK_FN(load_cuda_library)
CUDALibraryProcedureList
#undef X
- os_write_file(os->error_handle, stream_to_s8(&err));
+ os_write_file(os_error_handle(), stream_to_s8(&err));
}
#define X(name, symname) if (!cuda_## name) cuda_## name = cuda_ ## name ## _stub;
@@ -343,14 +347,12 @@ setup_beamformer(Arena *memory, BeamformerCtx **o_ctx, BeamformerInput **o_input
ctx->ui_backing_store = ui_arena;
input->executable_reloaded = 1;
- os_init(&ctx->os, memory);
- ctx->os.path_separator = s8(OS_PATH_SEPARATOR);
- ctx->os.compute_worker.arena = compute_arena;
- ctx->os.compute_worker.asleep = 1;
- ctx->os.upload_worker.arena = upload_arena;
- ctx->os.upload_worker.asleep = 1;
+ ctx->compute_worker.arena = compute_arena;
+ ctx->compute_worker.asleep = 1;
+ ctx->upload_worker.arena = upload_arena;
+ ctx->upload_worker.asleep = 1;
- debug_init(&ctx->os, (iptr)input, memory);
+ debug_init(ctx, input, memory);
SetConfigFlags(FLAG_VSYNC_HINT|FLAG_WINDOW_ALWAYS_RUN);
InitWindow(ctx->window_size.w, ctx->window_size.h, "OGL Beamformer");
@@ -366,7 +368,7 @@ setup_beamformer(Arena *memory, BeamformerCtx **o_ctx, BeamformerInput **o_input
#undef X
/* NOTE: Gather information about the GPU */
get_gl_params(&ctx->gl, &ctx->error_stream);
- dump_gl_params(&ctx->gl, *memory, &ctx->os);
+ dump_gl_params(&ctx->gl, *memory);
validate_gl_requirements(&ctx->gl, *memory);
ctx->beamform_work_queue = push_struct(memory, BeamformWorkQueue);
@@ -387,34 +389,34 @@ setup_beamformer(Arena *memory, BeamformerCtx **o_ctx, BeamformerInput **o_input
BeamformerComputeContext *cs = &ctx->compute_context;
- GLWorkerThreadContext *worker = &ctx->os.compute_worker;
+ GLWorkerThreadContext *worker = &ctx->compute_worker;
/* TODO(rnp): we should lock this down after we have something working */
worker->user_context = (iptr)ctx;
worker->window_handle = glfwCreateWindow(1, 1, "", 0, raylib_window_handle);
worker->handle = os_create_thread(*memory, (iptr)worker, s8("[compute]"),
compute_worker_thread_entry_point);
- GLWorkerThreadContext *upload = &ctx->os.upload_worker;
+ GLWorkerThreadContext *upload = &ctx->upload_worker;
BeamformerUploadThreadContext *upctx = push_struct(memory, typeof(*upctx));
upload->user_context = (iptr)upctx;
upctx->rf_buffer = &cs->rf_buffer;
upctx->shared_memory = &ctx->shared_memory;
upctx->compute_timing_table = ctx->compute_timing_table;
- upctx->compute_worker_sync = &ctx->os.compute_worker.sync_variable;
+ upctx->compute_worker_sync = &ctx->compute_worker.sync_variable;
upload->window_handle = glfwCreateWindow(1, 1, "", 0, raylib_window_handle);
upload->handle = os_create_thread(*memory, (iptr)upload, s8("[upload]"),
upload_worker_thread_entry_point);
glfwMakeContextCurrent(raylib_window_handle);
- if (load_cuda_library(&ctx->os, s8(OS_CUDA_LIB_NAME), (iptr)&ctx->gl, *memory))
- os_add_file_watch(&ctx->os, memory, s8(OS_CUDA_LIB_NAME), load_cuda_library, (iptr)&ctx->gl);
+ if (load_cuda_library(s8(OS_CUDA_LIB_NAME), (iptr)&ctx->gl, *memory))
+ os_add_file_watch(&ctx->file_watch_list, memory, s8(OS_CUDA_LIB_NAME),
+ load_cuda_library, (iptr)&ctx->gl);
/* NOTE: set up OpenGL debug logging */
- struct gl_debug_ctx *gl_debug_ctx = push_struct(memory, typeof(*gl_debug_ctx));
- gl_debug_ctx->stream = stream_alloc(memory, 1024);
- gl_debug_ctx->os_error_handle = ctx->os.error_handle;
- glDebugMessageCallback(gl_debug_logger, gl_debug_ctx);
+ Stream *gl_error_stream = push_struct(memory, Stream);
+ *gl_error_stream = stream_alloc(memory, 1024);
+ glDebugMessageCallback(gl_debug_logger, gl_error_stream);
#ifdef _DEBUG
glEnable(GL_DEBUG_OUTPUT);
#endif
@@ -430,8 +432,8 @@ setup_beamformer(Arena *memory, BeamformerCtx **o_ctx, BeamformerInput **o_input
BeamformerShaderReloadIndirectContext *rsi = push_struct(memory, typeof(*rsi));
rsi->beamformer = ctx;
rsi->shader = beamformer_reloadable_shader_kinds[index];
- os_add_file_watch(&ctx->os, memory, file, reload_shader_indirect, (iptr)rsi);
- reload_shader_indirect(&ctx->os, file, (iptr)rsi, *memory);
+ os_add_file_watch(&ctx->file_watch_list, memory, file, reload_shader_indirect, (iptr)rsi);
+ reload_shader_indirect(file, (iptr)rsi, *memory);
}
os_wake_waiters(&worker->sync_variable);
}
@@ -506,9 +508,9 @@ setup_beamformer(Arena *memory, BeamformerCtx **o_ctx, BeamformerInput **o_input
if (!BakeShaders) {
render_file = push_s8_from_parts(&scratch, s8(OS_PATH_SEPARATOR), s8("shaders"),
beamformer_reloadable_shader_files[render_rsi_index]);
- os_add_file_watch(&ctx->os, memory, render_file, reload_shader, (iptr)render_3d);
+ os_add_file_watch(&ctx->file_watch_list, memory, render_file, reload_shader, (iptr)render_3d);
}
- reload_shader(&ctx->os, render_file, (iptr)render_3d, *memory);
+ reload_shader(render_file, (iptr)render_3d, *memory);
f32 unit_cube_vertices[] = {
0.5f, 0.5f, -0.5f,
diff --git a/tests/throughput.c b/tests/throughput.c
@@ -111,18 +111,16 @@ os_read_file_simp(char *fname)
#elif OS_WINDOWS
-global w32_context os_context;
-
function void
os_init_timer(void)
{
- os_context.timer_frequency = os_get_timer_frequency();
+ os_w32_context.timer_frequency = os_get_timer_frequency();
}
function f64
os_get_time(void)
{
- f64 result = (f64)os_get_timer_counter() / (f64)os_context.timer_frequency;
+ f64 result = (f64)os_get_timer_counter() / (f64)os_w32_context.timer_frequency;
return result;
}
diff --git a/ui.c b/ui.c
@@ -4017,7 +4017,7 @@ draw_ui(BeamformerCtx *ctx, BeamformerInput *input, BeamformerFrame *frame_to_dr
if (fill_frame_compute_work(ctx, work, tag, selected_block, 0))
beamform_work_queue_push_commit(ctx->beamform_work_queue);
}
- os_wake_waiters(&ctx->os.compute_worker.sync_variable);
+ os_wake_waiters(&ctx->compute_worker.sync_variable);
}
}
}
diff --git a/util.c b/util.c
@@ -74,12 +74,6 @@ arena_alloc(Arena *a, iz len, uz align, iz count)
enum { DA_INITIAL_CAP = 16 };
-#define DA_STRUCT(kind, name) typedef struct { \
- kind *data; \
- iz count; \
- iz capacity; \
-} name ##List;
-
#define da_index(it, s) ((it) - (s)->data)
#define da_reserve(a, s, n) \
(s)->data = da_reserve_((a), (s)->data, &(s)->capacity, (s)->count + n, \
@@ -685,7 +679,7 @@ parse_f64(s8 s)
}
function FileWatchDirectory *
-lookup_file_watch_directory(FileWatchContext *ctx, u64 hash)
+lookup_file_watch_directory(FileWatchDirectoryList *ctx, u64 hash)
{
FileWatchDirectory *result = 0;
for (u32 i = 0; i < ctx->count; i++) {
diff --git a/util.h b/util.h
@@ -99,6 +99,12 @@
#define spin_wait(c) while ((c)) cpu_yield()
+#define DA_STRUCT(kind, name) typedef struct { \
+ kind *data; \
+ iz count; \
+ iz capacity; \
+} name ##List;
+
/* NOTE(rnp): no guarantees about actually getting an element */
#define SLLPop(list) list; list = list ? list->next : 0
#define SLLPush(v, list) do { \
@@ -282,7 +288,7 @@ typedef struct {
b32 asleep;
} GLWorkerThreadContext;
-#define FILE_WATCH_CALLBACK_FN(name) b32 name(OS *os, s8 path, iptr user_data, Arena arena)
+#define FILE_WATCH_CALLBACK_FN(name) b32 name(s8 path, iptr user_data, Arena arena)
typedef FILE_WATCH_CALLBACK_FN(file_watch_callback);
typedef struct {
@@ -301,13 +307,7 @@ typedef struct {
iz capacity;
Arena buffer;
} FileWatchDirectory;
-
-typedef struct {
- FileWatchDirectory *data;
- iz count;
- iz capacity;
- iptr handle;
-} FileWatchContext;
+DA_STRUCT(FileWatchDirectory, FileWatchDirectory);
typedef struct {
void *region;
@@ -317,7 +317,7 @@ typedef struct {
#define OS_ALLOC_ARENA_FN(name) Arena name(iz capacity)
typedef OS_ALLOC_ARENA_FN(os_alloc_arena_fn);
-#define OS_ADD_FILE_WATCH_FN(name) void name(OS *os, Arena *a, s8 path, \
+#define OS_ADD_FILE_WATCH_FN(name) void name(FileWatchDirectoryList *fwctx, Arena *a, s8 path, \
file_watch_callback *callback, iptr user_data)
typedef OS_ADD_FILE_WATCH_FN(os_add_file_watch_fn);
@@ -362,18 +362,6 @@ typedef alignas(16) u8 RenderDocAPI[216];
#define RENDERDOC_START_FRAME_CAPTURE(a) (renderdoc_start_frame_capture_fn *)RENDERDOC_API_FN_ADDR(a, 152)
#define RENDERDOC_END_FRAME_CAPTURE(a) (renderdoc_end_frame_capture_fn *) RENDERDOC_API_FN_ADDR(a, 168)
-struct OS {
- FileWatchContext file_watch_context;
- iptr context;
- iptr error_handle;
- s8 path_separator;
-
- GLWorkerThreadContext compute_worker;
- GLWorkerThreadContext upload_worker;
-
- DEBUG_DECL(renderdoc_start_frame_capture_fn *start_frame_capture;)
- DEBUG_DECL(renderdoc_end_frame_capture_fn *end_frame_capture;)
-};
#define LABEL_GL_OBJECT(type, id, s) {s8 _s = (s); glObjectLabel(type, id, (i32)_s.len, (c8 *)_s.data);}
diff --git a/util_gl.c b/util_gl.c
@@ -1,6 +1,6 @@
/* See LICENSE for license details. */
function u32
-compile_shader(OS *os, Arena a, u32 type, s8 shader, s8 name)
+compile_shader(Arena a, u32 type, s8 shader, s8 name)
{
u32 sid = glCreateShader(type);
glShaderSource(sid, 1, (const char **)&shader.data, (int *)&shader.len);
@@ -18,7 +18,7 @@ compile_shader(OS *os, Arena a, u32 type, s8 shader, s8 name)
glGetShaderInfoLog(sid, len, &out_len, (char *)(buf.data + buf.widx));
stream_commit(&buf, out_len);
glDeleteShader(sid);
- os_write_file(os->error_handle, stream_to_s8(&buf));
+ os_write_file(os_error_handle(), stream_to_s8(&buf));
sid = 0;
}
@@ -27,7 +27,7 @@ compile_shader(OS *os, Arena a, u32 type, s8 shader, s8 name)
}
function u32
-link_program(OS *os, Arena a, u32 *shader_ids, i32 shader_id_count)
+link_program(Arena a, u32 *shader_ids, i32 shader_id_count)
{
i32 success = 0;
u32 result = glCreateProgram();
@@ -42,7 +42,7 @@ link_program(OS *os, Arena a, u32 *shader_ids, i32 shader_id_count)
glGetProgramInfoLog(result, buf.cap - buf.widx, &len, (c8 *)(buf.data + buf.widx));
stream_reset(&buf, len);
stream_append_byte(&buf, '\n');
- os_write_file(os->error_handle, stream_to_s8(&buf));
+ os_write_file(os_error_handle(), stream_to_s8(&buf));
glDeleteProgram(result);
result = 0;
}
@@ -50,17 +50,17 @@ link_program(OS *os, Arena a, u32 *shader_ids, i32 shader_id_count)
}
function u32
-load_shader(OS *os, Arena arena, s8 *shader_texts, u32 *shader_types, i32 count, s8 name)
+load_shader(Arena arena, s8 *shader_texts, u32 *shader_types, i32 count, s8 name)
{
u32 result = 0;
u32 *ids = push_array(&arena, u32, count);
b32 valid = 1;
for (i32 i = 0; i < count; i++) {
- ids[i] = compile_shader(os, arena, shader_types[i], shader_texts[i], name);
+ ids[i] = compile_shader(arena, shader_types[i], shader_texts[i], name);
valid &= ids[i] != 0;
}
- if (valid) result = link_program(os, arena, ids, count);
+ if (valid) result = link_program(arena, ids, count);
for (i32 i = 0; i < count; i++) glDeleteShader(ids[i]);
if (result) glObjectLabel(GL_PROGRAM, result, (i32)name.len, (c8 *)name.data);