Commit: 90790434f2477ba72cb42794ccbe45ee03883dc5
Parent: 226ad51e3007ba8efc9af3bfb5cd9bc88b6d95d1
Author: Randy Palamar
Date: Sat, 15 Aug 2026 06:36:23 -0700
core: store gpu pointer instead of offset in frame
this will be needed to hook up output from recursive imaging to ui
Diffstat:
3 files changed, 37 insertions(+), 18 deletions(-)
diff --git a/beamformer_core.c b/beamformer_core.c
@@ -20,6 +20,11 @@
* - that queue isn't really considered hot so a lock is probably fine
* [ ]: bug: reinit cuda on hot-reload
*
+ * [ ]: export for special frames/data
+ * - Color Map Data
+ * - Recursive Imaging Result
+ * - Incoherent sum
+ *
* [ ]: Tiled Array Handling
* [ ]: add tile count uv2
* [ ]: make xdc_transform an array
@@ -313,6 +318,21 @@ beamformer_update_hadamard(BeamformerComputePlan *cp, BeamformerComputeArrayPara
}
}
+function GPUBuffer *
+beamformer_gpu_buffer_from_frame(BeamformerFrame *frame)
+{
+ GPUBuffer *result = beamformer_context->compute_context.backlog.buffer;
+ if (!Between(frame->gpu_pointer, result->gpu_pointer, result->gpu_pointer + result->size)) {
+ result = 0;
+ BeamformerComputePlan *cp = beamformer_context->compute_context.compute_plans[frame->parameter_block];
+ if (cp) {
+ result = &cp->gpu_temp_arena;
+ assert(Between(frame->gpu_pointer, result->gpu_pointer, result->gpu_pointer + result->size));
+ }
+ }
+ return result;
+}
+
function u64
beamformer_frame_byte_size(iv3 points, BeamformerDataKind kind)
{
@@ -347,7 +367,7 @@ beamformer_frame_next(BeamformerComputeContext *cc, iv3 output_points, b32 compl
BeamformerFrame *result = bl->frames + (id % countof(bl->frames));
atomic_store_u64(&result->timeline_valid_value, -1ULL);
result->id = id & U32_MAX;
- result->buffer_offset = bl->next_offset;
+ result->gpu_pointer = bl->buffer->gpu_pointer + bl->next_offset;
result->points = output_points;
result->data_kind = kind;
@@ -1259,14 +1279,12 @@ do_compute_shader(BeamformerCtx *ctx, GPUCommandList cmd, BeamformerComputePlan
}break;
case BeamformerShaderKind_DAS:{
- GPUBuffer *b = cc->backlog.buffer;
-
u64 element_size = beamformer_data_kind_byte_size[cp->shader_descriptors[shader_slot].input_data_kind];
BeamformerDASPushConstants pc = {
.xdc_element_pitch = cp->xdc_element_pitch,
.rf_element_offset = das_output_index * pp_size / element_size,
- .output_frame = b->gpu_pointer + frame->buffer_offset,
+ .output_frame = frame->gpu_pointer,
.channel_offset = channel_offset,
.readi_group = cp->readi_group,
};
@@ -1279,9 +1297,7 @@ do_compute_shader(BeamformerCtx *ctx, GPUCommandList cmd, BeamformerComputePlan
}break;
case BeamformerShaderKind_CoherencyWeighting:{
- BeamformerCoherencyWeightingPushConstants pc = {
- .coherent_sum = cc->backlog.buffer->gpu_pointer + frame->buffer_offset,
- };
+ BeamformerCoherencyWeightingPushConstants pc = {.coherent_sum = frame->gpu_pointer};
gpu_command_pipeline_barrier(cmd);
gpu_command_push_constants(cmd, 0, sizeof(pc), &pc);
gpu_command_dispatch_compute(cmd, dispatch);
@@ -1397,8 +1413,9 @@ complete_queue(BeamformerCtx *ctx, BeamformWorkQueue *q, Arena *arena)
// so we either need to count the total size of all requested frames first or
// just fill up as much as possible.
if (exported_size + frame_size <= ec->size) {
+ u64 offset = f->gpu_pointer - bl->buffer->gpu_pointer;
gpu_host_wait_timeline(GPUTimeline_Compute, f->timeline_valid_value, -1ULL);
- gpu_buffer_range_download(sm_output + exported_size, bl->buffer, f->buffer_offset, frame_size, 1);
+ gpu_buffer_range_download(sm_output + exported_size, bl->buffer, offset, frame_size, 1);
exported_size += frame_size;
}
}
@@ -1483,9 +1500,10 @@ complete_queue(BeamformerCtx *ctx, BeamformWorkQueue *q, Arena *arena)
gpu_command_timestamp(cmd);
if (das_index >= 0) {
- u64 frame_size = beamformer_frame_byte_size(frame->points, frame->data_kind);
- GPUBuffer *backlog = cs->backlog.buffer;
- gpu_command_clear_buffer(cmd, backlog, frame->buffer_offset, frame_size, 0);
+ GPUBuffer *backlog = cs->backlog.buffer;
+ u64 frame_size = beamformer_frame_byte_size(frame->points, frame->data_kind);
+ u64 offset = frame->gpu_pointer - backlog->gpu_pointer;
+ gpu_command_clear_buffer(cmd, backlog, offset, frame_size, 0);
}
if (coherency_weighting >= 0) {
diff --git a/beamformer_internal.h b/beamformer_internal.h
@@ -393,7 +393,7 @@ typedef struct {
} BeamformerUploadThreadContext;
typedef struct {
- u64 buffer_offset;
+ u64 gpu_pointer;
u64 timeline_valid_value;
/* NOTE: for use when displaying either prebeamformed frames or on the current frame
diff --git a/ui.c b/ui.c
@@ -853,10 +853,13 @@ beamformer_ui_frame_view_copy_frame(BeamformerFrameView *new, BeamformerFrameVie
};
gpu_buffer_allocate(&new->copy_buffer, &allocate_info);
- GPUBuffer *backlog = beamformer_context->compute_context.backlog.buffer;
+ GPUBuffer *buffer = beamformer_gpu_buffer_from_frame(&old->frame);
+ assert(buffer);
+
GPUCommandList cmd = gpu_command_list_begin(GPUTimeline_Compute);
gpu_command_wait_timeline(cmd, GPUTimeline_Compute, old->frame.timeline_valid_value);
- gpu_command_copy_buffer(cmd, &new->copy_buffer, backlog, old->frame.buffer_offset, frame_size);
+ u64 offset = old->frame.gpu_pointer - buffer->gpu_pointer;
+ gpu_command_copy_buffer(cmd, &new->copy_buffer, buffer, offset, frame_size);
new->frame.timeline_valid_value = gpu_command_list_end(cmd, (VulkanHandle){0}, (VulkanHandle){0});
}
@@ -1003,8 +1006,7 @@ function void
render_single_xplane(BeamformerFrameView *view, BeamformerFrame *frame, v3 translate, f32 rotation_turns,
GPUCommandList command, BeamformerRenderBeamformedPushConstants *pc, m4 vp_m, b32 drag_plane)
{
- GPUBuffer *beamformed_buffer = beamformer_context->compute_context.backlog.buffer;
- pc->input_data = frame->timeline_valid_value ? beamformed_buffer->gpu_pointer + frame->buffer_offset : 0;
+ pc->input_data = frame->timeline_valid_value ? frame->gpu_pointer : 0;
pc->input_size_x = frame->points.x;
pc->input_size_y = frame->points.y;
pc->input_size_z = frame->points.z;
@@ -1074,9 +1076,8 @@ render_2d_plane(BeamformerFrameView *view, GPUCommandList command, BeamformerRen
m4 model = m4_scale((v3){{2.0f, 2.0f, 0.0f}});
m4 projection = orthographic_projection(0, 1, 1, 1);
- GPUBuffer *beamformed_buffer = beamformer_context->compute_context.backlog.buffer;
pc->mvp_matrix = m4_mul(m4_mul(model, view_m), projection);
- pc->input_data = beamformed_buffer->gpu_pointer + view->frame.buffer_offset;
+ pc->input_data = view->frame.gpu_pointer;
pc->input_size_x = view->frame.points.x;
pc->input_size_y = view->frame.points.y;
pc->input_size_z = view->frame.points.z;