Commit: 266448a5f5056b5cc502040a21f560bf1df35f75
Parent: 62b6d4a0d8638c532d4933a570f92e702bdf50c6
Author: Randy Palamar
Date: Mon, 7 Oct 2024 13:10:12 -0600
remove many *printf calls and move remaining to util.c
Diffstat:
M | main.c | | | 56 | +++++++++++++++++++++++++++++++++++--------------------- |
M | os_unix.c | | | 6 | ++++++ |
M | os_win32.c | | | 17 | +++++++++++++++-- |
M | ui.c | | | 87 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
M | util.c | | | 103 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------- |
M | util.h | | | 8 | ++++++++ |
6 files changed, 195 insertions(+), 82 deletions(-)
diff --git a/main.c b/main.c
@@ -46,16 +46,20 @@ static void
gl_debug_logger(u32 src, u32 type, u32 id, u32 lvl, i32 len, const char *msg, const void *userctx)
{
(void)src; (void)type; (void)id; (void)userctx;
- fputs("[GL DEBUG ", stderr);
+
+ u8 buf[128];
+ Stream s = {.data = buf, .cap = ARRAY_COUNT(buf)};
+ stream_append_s8(&s, s8("[GL DEBUG "));
switch (lvl) {
- case GL_DEBUG_SEVERITY_HIGH: fputs("HIGH]: ", stderr); break;
- case GL_DEBUG_SEVERITY_MEDIUM: fputs("MEDIUM]: ", stderr); break;
- case GL_DEBUG_SEVERITY_LOW: fputs("LOW]: ", stderr); break;
- case GL_DEBUG_SEVERITY_NOTIFICATION: fputs("NOTIFICATION]: ", stderr); break;
- default: fputs("INVALID]: ", stderr); break;
+ case GL_DEBUG_SEVERITY_HIGH: stream_append_s8(&s, s8("HIGH]: ")); break;
+ case GL_DEBUG_SEVERITY_MEDIUM: stream_append_s8(&s, s8("MEDIUM]: ")); break;
+ case GL_DEBUG_SEVERITY_LOW: stream_append_s8(&s, s8("LOW]: ")); break;
+ case GL_DEBUG_SEVERITY_NOTIFICATION: stream_append_s8(&s, s8("NOTIFICATION]: ")); break;
+ default: stream_append_s8(&s, s8("INVALID]: ")); break;
}
- fwrite(msg, 1, len, stderr);
- fputc('\n', stderr);
+ os_write_err_msg(stream_to_s8(s));
+ os_write_err_msg((s8){.len = len, .data = (u8 *)msg});
+ os_write_err_msg(s8("\n"));
}
static void
@@ -88,22 +92,32 @@ validate_gl_requirements(GLParams *gl)
}
static void
-dump_gl_params(GLParams *gl)
+dump_gl_params(GLParams *gl, Arena a)
{
- (void)gl;
+ (void)gl; (void)a;
#ifdef _DEBUG
- fputs("---- GL Parameters ----\n", stdout);
+ Stream s = stream_alloc(&a, 1 * MEGABYTE);
+ stream_append_s8(&s, s8("---- GL Parameters ----\n"));
switch (gl->vendor_id) {
- case GL_VENDOR_AMD: fputs("Vendor: AMD\n", stdout); break;
- case GL_VENDOR_INTEL: fputs("Vendor: Intel\n", stdout); break;
- case GL_VENDOR_NVIDIA: fputs("Vendor: nVidia\n", stdout); break;
+ case GL_VENDOR_AMD: stream_append_s8(&s, s8("Vendor: AMD\n")); break;
+ case GL_VENDOR_INTEL: stream_append_s8(&s, s8("Vendor: Intel\n")); break;
+ case GL_VENDOR_NVIDIA: stream_append_s8(&s, s8("Vendor: nVidia\n")); break;
}
- printf("Version: %d.%d\n", gl->version_major, gl->version_minor);
- printf("Max 1D/2D Texture Dimension: %d\n", gl->max_2d_texture_dim);
- printf("Max 3D Texture Dimension: %d\n", gl->max_3d_texture_dim);
- printf("Max SSBO Size: %d\n", gl->max_ssbo_size);
- printf("Max UBO Size: %d\n", gl->max_ubo_size);
- fputs("-----------------------\n", stdout);
+ stream_append_s8(&s, s8("Version: "));
+ stream_append_i64(&s, gl->version_major);
+ stream_append_s8(&s, s8("."));
+ stream_append_i64(&s, gl->version_minor);
+ stream_append_s8(&s, s8("\nMax 1D/2D Texture Dimension: "));
+ stream_append_i64(&s, gl->max_2d_texture_dim);
+ stream_append_s8(&s, s8("\nMax 3D Texture Dimension: "));
+ stream_append_i64(&s, gl->max_3d_texture_dim);
+ stream_append_s8(&s, s8("\nMax SSBO Size: "));
+ stream_append_i64(&s, gl->max_ssbo_size);
+ stream_append_s8(&s, s8("\nMax UBO Size: "));
+ stream_append_i64(&s, gl->max_ubo_size);
+ stream_append_s8(&s, s8("\n-----------------------\n"));
+ if (!s.errors)
+ os_write_err_msg(stream_to_s8(s));
#endif
}
@@ -238,7 +252,7 @@ main(void)
/* NOTE: Gather information about the GPU */
get_gl_params(&ctx.gl);
- dump_gl_params(&ctx.gl);
+ dump_gl_params(&ctx.gl, temp_memory);
validate_gl_requirements(&ctx.gl);
/* TODO: build these into the binary */
diff --git a/os_unix.c b/os_unix.c
@@ -14,6 +14,12 @@ typedef struct {
typedef void *os_library_handle;
+static void
+os_write_err_msg(s8 msg)
+{
+ write(STDERR_FILENO, msg.data, msg.len);
+}
+
static Arena
os_alloc_arena(Arena a, size capacity)
{
diff --git a/os_win32.c b/os_win32.c
@@ -1,6 +1,9 @@
/* See LICENSE for license details. */
#include "util.h"
+#define STD_OUTPUT_HANDLE -11
+#define STD_ERROR_HANDLE -12
+
#define PAGE_READWRITE 0x04
#define MEM_COMMIT 0x1000
#define MEM_RESERVE 0x2000
@@ -56,6 +59,7 @@ W32(b32) FreeLibrary(void *);
W32(b32) GetFileInformationByHandle(void *, void *);
W32(i32) GetLastError(void);
W32(void *) GetProcAddress(void *, c8 *);
+W32(void *) GetStdHandle(i32);
W32(void) GetSystemInfo(void *);
W32(void *) LoadLibraryA(c8 *);
W32(void *) MapViewOfFile(void *, u32, u32, u32, u64);
@@ -74,6 +78,15 @@ typedef struct {
typedef void *os_library_handle;
+static void
+os_write_err_msg(s8 msg)
+{
+ if (!win32_stderr_handle)
+ win32_stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
+ i32 wlen;
+ WriteFile(win32_stderr_handle, msg.data, msg.len, &wlen, 0);
+}
+
static Arena
os_alloc_arena(Arena a, size capacity)
{
@@ -122,7 +135,7 @@ static b32
os_write_file(char *fname, s8 raw)
{
if (raw.len > (size)U32_MAX) {
- fputs("os_write_file: writing files > 4GB is not yet support on win32\n", stderr);
+ os_write_err_msg(s8("os_write_file: writing files > 4GB is not yet support on win32\n"));
return 0;
}
@@ -146,7 +159,7 @@ os_get_file_stats(char *fname)
w32_file_info fileinfo;
if (!GetFileInformationByHandle(h, &fileinfo)) {
- fputs("os_get_file_stats: couldn't get file info\n", stderr);
+ os_write_err_msg(s8("os_get_file_stats: couldn't get file info\n"));
CloseHandle(h);
return ERROR_FILE_STATS;
}
diff --git a/ui.c b/ui.c
@@ -173,23 +173,17 @@ bmv_store_value(BeamformerCtx *ctx, BPModifiableValue *bmv, f32 new_val, b32 fro
ctx->flags |= GEN_MIPMAPS;
}
-static s8
-bmv_sprint(BPModifiableValue *bmv, s8 buf)
+static void
+bmv_sprint(BPModifiableValue *bmv, Stream *s)
{
- s8 result = buf;
if (bmv->flags & MV_FLOAT) {
f32 *value = bmv->value;
- size len = snprintf((char *)buf.data, buf.len, "%0.02f", *value * bmv->scale);
- ASSERT(len <= buf.len);
- result.len = len;
+ stream_append_f32(s, *value * bmv->scale);
} else {
ASSERT(bmv->flags & MV_INT);
i32 *value = bmv->value;
- size len = snprintf((char *)buf.data, buf.len, "%d", (i32)(*value * bmv->scale));
- ASSERT(len <= buf.len);
- result.len = len;
+ stream_append_i64(s, *value * bmv->scale);
}
- return result;
}
static void
@@ -313,8 +307,11 @@ set_text_input_idx(BeamformerCtx *ctx, BPModifiableValue bmv, Rect r, v2 mouse)
if (ctx->is.store.value == NULL)
return;
- s8 ibuf = bmv_sprint(&bmv, (s8){.data = (u8 *)ctx->is.buf, .len = ARRAY_COUNT(ctx->is.buf)});
- ctx->is.buf_len = ibuf.len;
+ Stream s = {.cap = ARRAY_COUNT(ctx->is.buf), .data = (u8 *)ctx->is.buf};
+ bmv_sprint(&bmv, &s);
+ ASSERT(!s.errors);
+ ctx->is.buf_len = s.widx;
+ ctx->is.buf[ctx->is.buf_len] = 0;
ASSERT(CheckCollisionPointRec(mouse.rl, r.rl));
ctx->is.cursor_hover_p = CLAMP01((mouse.x - r.pos.x) / r.size.w);
@@ -344,13 +341,13 @@ do_value_listing(s8 prefix, s8 suffix, f32 value, Font font, Arena a, Rect r)
v2 suffix_s = measure_text(font, suffix);
v2 suffix_p = {.x = r.pos.x + r.size.w - suffix_s.w, .y = r.pos.y};
- s8 txt = s8alloc(&a, 64);
- txt.len = snprintf((char *)txt.data, txt.len, "%0.02f", value);
+ Stream buf = stream_alloc(&a, 64);
+ stream_append_f32(&buf, value);
v2 txt_p = {.x = r.pos.x + LISTING_LEFT_COLUMN_WIDTH, .y = r.pos.y};
- draw_text(font, prefix, r.pos, 0, colour_from_normalized(FG_COLOUR));
- draw_text(font, txt, txt_p, 0, colour_from_normalized(FG_COLOUR));
- draw_text(font, suffix, suffix_p, 0, colour_from_normalized(FG_COLOUR));
+ draw_text(font, prefix, r.pos, 0, colour_from_normalized(FG_COLOUR));
+ draw_text(font, stream_to_s8(buf), txt_p, 0, colour_from_normalized(FG_COLOUR));
+ draw_text(font, suffix, suffix_p, 0, colour_from_normalized(FG_COLOUR));
r.pos.y += suffix_s.h + LISTING_LINE_PAD;
r.size.y -= suffix_s.h + LISTING_LINE_PAD;
@@ -361,8 +358,7 @@ static Rect
do_text_input_listing(s8 prefix, s8 suffix, BPModifiableValue bmv, BeamformerCtx *ctx, Arena a,
Rect r, v2 mouse, f32 *hover_t)
{
- s8 buf = s8alloc(&a, 64);
- s8 txt = buf;
+ Stream buf = stream_alloc(&a, 68);
v2 txt_s;
b32 bmv_active = bmv_equal(&bmv, &ctx->is.store);
@@ -370,8 +366,8 @@ do_text_input_listing(s8 prefix, s8 suffix, BPModifiableValue bmv, BeamformerCtx
txt_s = measure_text(ctx->font, (s8){.len = ctx->is.buf_len,
.data = (u8 *)ctx->is.buf});
} else {
- txt = bmv_sprint(&bmv, buf);
- txt_s = measure_text(ctx->font, txt);
+ bmv_sprint(&bmv, &buf);
+ txt_s = measure_text(ctx->font, stream_to_s8(buf));
}
Rect edit_rect = {
@@ -387,13 +383,15 @@ do_text_input_listing(s8 prefix, s8 suffix, BPModifiableValue bmv, BeamformerCtx
set_text_input_idx(ctx, (BPModifiableValue){0}, (Rect){0}, mouse);
f32 old_val = bmv_scaled_value(&bmv);
bmv_store_value(ctx, &bmv, old_val + mouse_scroll, 1);
- txt = bmv_sprint(&bmv, buf);
+ buf.widx = 0;
+ bmv_sprint(&bmv, &buf);
}
}
if (!hovering && bmv_equal(&bmv, &ctx->is.store) && IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
set_text_input_idx(ctx, (BPModifiableValue){0}, (Rect){0}, mouse);
- txt = bmv_sprint(&bmv, buf);
+ buf.widx = 0;
+ bmv_sprint(&bmv, &buf);
}
if (hovering && IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
@@ -402,7 +400,7 @@ do_text_input_listing(s8 prefix, s8 suffix, BPModifiableValue bmv, BeamformerCtx
Color colour = colour_from_normalized(lerp_v4(FG_COLOUR, HOVERED_COLOUR, *hover_t));
if (!bmv_equal(&bmv, &ctx->is.store)) {
- draw_text(ctx->font, txt, edit_rect.pos, 0, colour);
+ draw_text(ctx->font, stream_to_s8(buf), edit_rect.pos, 0, colour);
} else {
do_text_input(ctx, 7, edit_rect, colour);
}
@@ -596,8 +594,8 @@ draw_debug_overlay(BeamformerCtx *ctx, Arena arena, Rect r)
ComputeShaderCtx *cs = &ctx->csctx;
- s8 txt_buf = s8alloc(&arena, 64);
- v2 pos = {.x = 20, .y = ws.h - 10};
+ Stream buf = stream_alloc(&arena, 64);
+ v2 pos = {.x = 20, .y = ws.h - 10};
f32 compute_time_sum = 0;
u32 stages = ctx->params->compute_stages_count;
@@ -606,12 +604,12 @@ draw_debug_overlay(BeamformerCtx *ctx, Arena arena, Rect r)
pos.y -= measure_text(ctx->font, labels[index]).y;
draw_text(ctx->font, labels[index], pos, 0, colour_from_normalized(FG_COLOUR));
- s8 tmp = txt_buf;
- tmp.len = snprintf((char *)txt_buf.data, txt_buf.len, "%0.02e [s]",
- cs->last_frame_time[index]);
- v2 txt_fs = measure_text(ctx->font, tmp);
+ buf.widx = 0;
+ stream_append_f32_e(&buf, cs->last_frame_time[index]);
+ stream_append_s8(&buf, s8(" [s]"));
+ v2 txt_fs = measure_text(ctx->font, stream_to_s8(buf));
v2 rpos = {.x = r.pos.x + r.size.w - txt_fs.w, .y = pos.y};
- draw_text(ctx->font, tmp, rpos, 0, colour_from_normalized(FG_COLOUR));
+ draw_text(ctx->font, stream_to_s8(buf), rpos, 0, colour_from_normalized(FG_COLOUR));
compute_time_sum += cs->last_frame_time[index];
}
@@ -622,11 +620,12 @@ draw_debug_overlay(BeamformerCtx *ctx, Arena arena, Rect r)
pos.y -= measure_text(ctx->font, totals[i]).y;
draw_text(ctx->font, totals[i], pos, 0, colour_from_normalized(FG_COLOUR));
- s8 tmp = txt_buf;
- tmp.len = snprintf((char *)txt_buf.data, txt_buf.len, "%0.02e [s]", times[i]);
- v2 txt_fs = measure_text(ctx->font, tmp);
+ buf.widx = 0;
+ stream_append_f32_e(&buf, times[i]);
+ stream_append_s8(&buf, s8(" [s]"));
+ v2 txt_fs = measure_text(ctx->font, stream_to_s8(buf));
v2 rpos = {.x = r.pos.x + r.size.w - txt_fs.w, .y = pos.y};
- draw_text(ctx->font, tmp, rpos, 0, colour_from_normalized(FG_COLOUR));
+ draw_text(ctx->font, stream_to_s8(buf), rpos, 0, colour_from_normalized(FG_COLOUR));
}
{
@@ -683,10 +682,10 @@ draw_ui(BeamformerCtx *ctx, Arena arena)
rr.pos.x = lr.pos.x + lr.size.w;
if (output_dim.x > 1e-6 && output_dim.y > 1e-6) {
- s8 txt = s8alloc(&arena, 64);
- s8 tmp = txt;
- tmp.len = snprintf((char *)txt.data, txt.len, "%+0.01f mm", -188.8f);
- v2 txt_s = measure_text(ctx->small_font, tmp);
+ Stream buf = stream_alloc(&arena, 64);
+ stream_append_f32(&buf, -188.88f);
+ stream_append_s8(&buf, s8(" mm"));
+ v2 txt_s = measure_text(ctx->small_font, stream_to_s8(buf));
rr.pos.x += 0.02 * rr.size.w;
rr.pos.y += 0.02 * rr.size.h;
@@ -761,13 +760,15 @@ draw_ui(BeamformerCtx *ctx, Arena arena)
Color txt_colour = colour_from_normalized(lerp_v4(FG_COLOUR, HOVERED_COLOUR,
txt_colour_t[i]));
- char *fmt[2] = {"%+0.01f mm", "%0.01f mm"};
f32 rot[2] = {90, 0};
for (u32 j = 0; j <= line_count; j++) {
DrawLineEx(start_pos.rl, end_pos.rl, 3, colour_from_normalized(FG_COLOUR));
- s8 tmp = txt;
- tmp.len = snprintf((char *)txt.data, txt.len, fmt[i], mm);
- draw_text(ctx->small_font, tmp, txt_pos, rot[i], txt_colour);
+ buf.widx = 0;
+ if (i == 0 && mm > 0) stream_append_s8(&buf, s8("+"));
+ stream_append_f32(&buf, mm);
+ stream_append_s8(&buf, s8(" mm"));
+ draw_text(ctx->small_font, stream_to_s8(buf), txt_pos,
+ rot[i], txt_colour);
start_pos.E[i] += inc;
end_pos.E[i] += inc;
txt_pos.E[i] += inc;
diff --git a/util.c b/util.c
@@ -3,18 +3,6 @@
#include <stdio.h>
#include <stdlib.h>
-static void __attribute__((noreturn))
-die(char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-
- exit(1);
-}
-
static void *
mem_clear(u8 *p, u8 c, size len)
{
@@ -35,16 +23,99 @@ alloc_(Arena *a, size len, size align, size count)
{
size padding = -(uintptr_t)a->beg & (align - 1);
size available = a->end - a->beg - padding;
- if (available < 0 || count > available / len) {
- ASSERT(0);
- die("arena OOM\n");
- }
+ if (available < 0 || count > available / len)
+ ASSERT(0 && "arena OOM\n");
void *p = a->beg + padding;
a->beg += padding + count * len;
/* TODO: Performance? */
return mem_clear(p, 0, count * len);
}
+static Stream
+stream_alloc(Arena *a, size cap)
+{
+ Stream result = {.cap = cap};
+ result.data = alloc(a, u8, cap);
+ return result;
+}
+
+static s8
+stream_to_s8(Stream s)
+{
+ ASSERT(!s.errors);
+ s8 result = {.len = s.widx, .data = s.data};
+ return result;
+}
+
+static void
+stream_append_s8(Stream *s, s8 str)
+{
+ s->errors |= (s->cap - s->widx) <= str.len;
+ for (size i = 0; !s->errors && i < str.len; i++)
+ s->data[s->widx++] = str.data[i];
+}
+
+static void
+stream_append_u64(Stream *s, u64 n)
+{
+ u8 tmp[64];
+ u8 *end = tmp + sizeof(tmp);
+ u8 *beg = end;
+ do { *--beg = '0' + (n % 10); } while (n /= 10);
+ stream_append_s8(s, (s8){.len = end - beg, .data = beg});
+}
+
+static void
+stream_append_i64(Stream *s, i64 n)
+{
+ if (n < 0) {
+ stream_append_s8(s, s8("-"));
+ n *= -1;
+ }
+ stream_append_u64(s, n);
+}
+
+static void
+stream_append_f32(Stream *s, f32 f)
+{
+ if (f < 0) {
+ stream_append_s8(s, s8("-"));
+ f *= -1;
+ }
+ /* TODO */
+ size remaining = s->cap - s->widx;
+ s->errors |= remaining <= snprintf(0, 0, "%0.02f", f);
+ if (!s->errors)
+ s->widx += snprintf((char *)(s->data + s->widx), remaining, "%0.02f", f);
+}
+
+static void
+stream_append_f32_e(Stream *s, f32 f)
+{
+ if (f < 0) {
+ stream_append_s8(s, s8("-"));
+ f *= -1;
+ }
+ /* TODO */
+ size remaining = s->cap - s->widx;
+ s->errors |= remaining <= snprintf(0, 0, "%0.02e", f);
+ if (!s->errors)
+ s->widx += snprintf((char *)(s->data + s->widx), remaining, "%0.02e", f);
+}
+
+
+static void __attribute__((noreturn))
+die(char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ exit(1);
+}
+
static s8
s8alloc(Arena *a, size len)
{
diff --git a/util.h b/util.h
@@ -45,6 +45,7 @@ typedef int16_t i16;
typedef uint16_t u16;
typedef int32_t i32;
typedef uint32_t u32;
+typedef int64_t i64;
typedef uint64_t u64;
typedef uint32_t b32;
typedef float f32;
@@ -112,6 +113,13 @@ typedef struct {
} FileStats;
#define ERROR_FILE_STATS (FileStats){.filesize = -1}
+typedef struct {
+ size widx;
+ u8 *data;
+ size cap;
+ b32 errors;
+} Stream;
+
#include "beamformer_parameters.h"
typedef struct {
BeamformerParameters raw;