Commit: efe2a5e361719985a9adf0233d8092a8584bea6e
Parent: 9130418de20f2674c3152ae6ef4bafaba43b6a00
Author: Randy Palamar
Date: Sun, 22 Jun 2025 21:26:41 -0600
core: don't flicker ui when frames are in progress
got a little too zealous and removed the gaurd against this.
instead of going back we can just push a pointer to the last frame
to complete beamforming into context
Diffstat:
5 files changed, 16 insertions(+), 25 deletions(-)
diff --git a/beamformer.c b/beamformer.c
@@ -160,20 +160,6 @@ push_compute_timing_info(ComputeTimingTable *t, ComputeTimingInfo info)
t->buffer[index] = info;
}
-function BeamformComputeFrame *
-beamformer_get_newest_frame(BeamformerCtx *ctx, b32 average_frame)
-{
- BeamformComputeFrame *result = 0;
- if (average_frame) {
- u32 a_index = !(ctx->averaged_frame_index % countof(ctx->averaged_frames));
- result = ctx->averaged_frames + a_index;
- } else {
- u32 index = (ctx->next_render_frame_index - 1) % countof(ctx->beamform_frames);
- result = ctx->beamform_frames + index;
- }
- return result;
-}
-
function b32
fill_frame_compute_work(BeamformerCtx *ctx, BeamformWork *work, ImagePlaneTag plane)
{
@@ -526,8 +512,7 @@ complete_queue(BeamformerCtx *ctx, BeamformWorkQueue *q, Arena arena, iptr gl_co
if (success && ctx->csctx.raw_data_ssbo) {
/* TODO(rnp): this check seems off */
can_commit = 0;
- BeamformComputeFrame *frame = beamformer_get_newest_frame(ctx, bp->output_points[3] > 1);
- fill_frame_compute_work(ctx, work, frame->image_plane_tag);
+ fill_frame_compute_work(ctx, work, ctx->latest_frame->image_plane_tag);
}
}break;
case BeamformerWorkKind_ExportBuffer:{
@@ -538,7 +523,7 @@ complete_queue(BeamformerCtx *ctx, BeamformWorkQueue *q, Arena arena, iptr gl_co
BeamformerExportContext *ec = &work->export_context;
switch (ec->kind) {
case BeamformerExportKind_BeamformedData:{
- BeamformComputeFrame *frame = beamformer_get_newest_frame(ctx, bp->output_points[3] > 1);
+ BeamformComputeFrame *frame = ctx->latest_frame;
assert(frame->ready_to_present);
u32 texture = frame->frame.texture;
uv3 dim = frame->frame.dim;
@@ -681,13 +666,16 @@ complete_queue(BeamformerCtx *ctx, BeamformWorkQueue *q, Arena arena, iptr gl_co
push_compute_timing_info(ctx->compute_timing_table, info);
}
+ frame->ready_to_present = 1;
if (did_sum_shader) {
u32 aframe_index = (ctx->averaged_frame_index % countof(ctx->averaged_frames));
ctx->averaged_frames[aframe_index].image_plane_tag = frame->image_plane_tag;
ctx->averaged_frames[aframe_index].ready_to_present = 1;
atomic_add_u32(&ctx->averaged_frame_index, 1);
+ atomic_store_u64((u64 *)&ctx->latest_frame, (u64)(ctx->averaged_frames + aframe_index));
+ } else {
+ atomic_store_u64((u64 *)&ctx->latest_frame, (u64)frame);
}
- frame->ready_to_present = 1;
cs->processing_compute = 0;
push_compute_timing_info(ctx->compute_timing_table,
@@ -823,12 +811,10 @@ DEBUG_EXPORT BEAMFORMER_FRAME_STEP_FN(beamformer_frame_step)
}
BeamformerSharedMemory *sm = ctx->shared_memory.region;
- BeamformerParameters *bp = &sm->parameters;
- b32 averaging = bp->output_points[3] > 1;
if (sm->locks[BeamformerSharedMemoryLockKind_DispatchCompute] && ctx->os.compute_worker.asleep) {
if (sm->start_compute_from_main) {
BeamformWork *work = beamform_work_queue_push(ctx->beamform_work_queue);
- ImagePlaneTag tag = beamformer_get_newest_frame(ctx, averaging)->image_plane_tag;
+ ImagePlaneTag tag = ctx->latest_frame->image_plane_tag;
if (fill_frame_compute_work(ctx, work, tag))
beamform_work_queue_push_commit(ctx->beamform_work_queue);
atomic_store_u32(&sm->start_compute_from_main, 0);
@@ -836,8 +822,8 @@ DEBUG_EXPORT BEAMFORMER_FRAME_STEP_FN(beamformer_frame_step)
ctx->os.wake_waiters(&ctx->os.compute_worker.sync_variable);
}
- BeamformComputeFrame *frame = beamformer_get_newest_frame(ctx, averaging);
- draw_ui(ctx, input, frame->ready_to_present? &frame->frame : 0, frame->image_plane_tag);
+ draw_ui(ctx, input, ctx->latest_frame->ready_to_present ? &ctx->latest_frame->frame : 0,
+ ctx->latest_frame->image_plane_tag);
ctx->frame_view_render_context.updated = 0;
diff --git a/beamformer.h b/beamformer.h
@@ -197,7 +197,9 @@ typedef struct {
b32 ui_read_params;
BeamformComputeFrame beamform_frames[MAX_BEAMFORMED_SAVED_FRAMES];
+ BeamformComputeFrame *latest_frame;
u32 next_render_frame_index;
+ u32 display_frame_index;
/* NOTE: this will only be used when we are averaging */
u32 averaged_frame_index;
diff --git a/intrinsics.c b/intrinsics.c
@@ -26,6 +26,7 @@
#define debugbreak() __debugbreak()
#define unreachable() __assume(0)
+ #define atomic_store_u64(ptr, n) *((volatile u64 *)(ptr)) = (n)
#define atomic_store_u32(ptr, n) *((volatile u32 *)(ptr)) = (n)
#define atomic_load_u64(ptr) *((volatile u64 *)(ptr))
#define atomic_load_u32(ptr) *((volatile u32 *)(ptr))
@@ -54,7 +55,7 @@
#endif
#define unreachable() __builtin_unreachable()
- #define atomic_store_u32(ptr, n) __atomic_store_n(ptr, n, __ATOMIC_RELEASE)
+ #define atomic_store_u64(ptr, n) __atomic_store_n(ptr, n, __ATOMIC_RELEASE)
#define atomic_load_u64(ptr) __atomic_load_n(ptr, __ATOMIC_ACQUIRE)
#define atomic_add_u64(ptr, n) __atomic_fetch_add(ptr, n, __ATOMIC_ACQ_REL)
#define atomic_and_u64(ptr, n) __atomic_and_fetch(ptr, n, __ATOMIC_RELEASE)
@@ -64,6 +65,7 @@
#define atomic_and_u32 atomic_and_u64
#define atomic_cas_u32 atomic_cas_u64
#define atomic_load_u32 atomic_load_u64
+ #define atomic_store_u32 atomic_store_u64
#define atan2_f32(y, x) __builtin_atan2f(y, x)
#define ceil_f32(a) __builtin_ceilf(a)
diff --git a/static.c b/static.c
@@ -277,6 +277,7 @@ setup_beamformer(BeamformerCtx *ctx, BeamformerInput *input, Arena *memory)
glfwMakeContextCurrent(raylib_window_handle);
+ ctx->latest_frame = ctx->beamform_frames;
ctx->beamform_work_queue = push_struct(memory, BeamformWorkQueue);
ctx->compute_shader_stats = push_struct(memory, ComputeShaderStats);
ctx->compute_timing_table = push_struct(memory, ComputeTimingTable);
diff --git a/ui.c b/ui.c
@@ -3019,7 +3019,7 @@ draw_ui(BeamformerCtx *ctx, BeamformerInput *input, BeamformFrame *frame_to_draw
b32 dispatch = ctx->os.shared_memory_region_lock(&ctx->shared_memory, sm->locks,
BeamformerSharedMemoryLockKind_DispatchCompute,
0);
- sm->start_compute_from_main |= dispatch & beamformer_get_newest_frame(ctx, 0)->ready_to_present;
+ sm->start_compute_from_main |= dispatch & ctx->latest_frame->ready_to_present;
ctx->os.shared_memory_region_unlock(&ctx->shared_memory, sm->locks, lock);
}
}