Added add_transfer function to add a transfer to the current frame context(and resize if necessary)

main
noah metz 2024-10-28 14:48:36 -06:00
parent 22369f6385
commit 152635f14f
5 changed files with 91 additions and 25 deletions

@ -68,7 +68,7 @@ typedef struct SwapchainDetailsStruct {
} SwapchainDetails; } SwapchainDetails;
typedef struct TransferInfoStruct { typedef struct TransferInfoStruct {
VkDeviceSize dst_offset; VkDeviceSize offset;
VkDeviceSize size; VkDeviceSize size;
VkBuffer buffers[MAX_FRAMES_IN_FLIGHT]; VkBuffer buffers[MAX_FRAMES_IN_FLIGHT];
} TransferInfo; } TransferInfo;
@ -88,6 +88,11 @@ typedef struct FrameContextStruct {
VkBuffer transfer_buffer; VkBuffer transfer_buffer;
VmaAllocation transfer_memory; VmaAllocation transfer_memory;
void* transfer_mapped; void* transfer_mapped;
size_t transfer_written;
size_t transfer_max_size;
size_t transfer_max_count;
TransferInfo* transfer_infos; TransferInfo* transfer_infos;
uint32_t transfer_count; uint32_t transfer_count;
} FrameContext; } FrameContext;
@ -162,4 +167,11 @@ VkDeviceAddress buffer_address(
VkDevice device, VkDevice device,
VkBuffer buffer); VkBuffer buffer);
VkResult add_transfer(
void* data,
VkBuffer* buffers,
VkDeviceSize offset,
VkDeviceSize size,
RenderContext* gpu);
#endif #endif

@ -75,7 +75,7 @@ VkResult draw_frame(
context->frame[context->current_frame].transfer_buffer, context->frame[context->current_frame].transfer_buffer,
context->frame[context->current_frame].transfer_infos[j].buffers[i], context->frame[context->current_frame].transfer_infos[j].buffers[i],
src_offset, src_offset,
context->frame[context->current_frame].transfer_infos[j].dst_offset, context->frame[context->current_frame].transfer_infos[j].offset,
context->frame[context->current_frame].transfer_infos[j].size); context->frame[context->current_frame].transfer_infos[j].size);
src_offset += context->frame[context->current_frame].transfer_infos[j].size; src_offset += context->frame[context->current_frame].transfer_infos[j].size;
} }
@ -108,6 +108,7 @@ VkResult draw_frame(
VK_RESULT(vkQueueSubmit(context->transfer_queue.handle, 1, &submit_info, context->frame[context->current_frame].transfer_ready[i])); VK_RESULT(vkQueueSubmit(context->transfer_queue.handle, 1, &submit_info, context->frame[context->current_frame].transfer_ready[i]));
} }
context->frame[context->current_frame].transfer_count = 0; context->frame[context->current_frame].transfer_count = 0;
context->frame[context->current_frame].transfer_written = 0;
} }
uint32_t image_index; uint32_t image_index;

@ -789,10 +789,12 @@ VkResult create_frame_context(VkDevice device, VmaAllocator allocator, VkCommand
}; };
VK_RESULT(vkAllocateCommandBuffers(device, &command_info, frame->transfer_commands)); VK_RESULT(vkAllocateCommandBuffers(device, &command_info, frame->transfer_commands));
// TODO: temp size values, add dynamic resizing // TODO: better defaults
VK_RESULT(create_transfer_buffer(allocator, 1024, &frame->transfer_buffer, &frame->transfer_memory, &frame->transfer_mapped)); frame->transfer_max_size = 1;
frame->transfer_max_count = 1;
VK_RESULT(create_transfer_buffer(allocator, frame->transfer_max_size, &frame->transfer_buffer, &frame->transfer_memory, &frame->transfer_mapped));
frame->transfer_count = 0; frame->transfer_count = 0;
frame->transfer_infos = malloc(sizeof(TransferInfo)*10); frame->transfer_infos = malloc(sizeof(TransferInfo)*frame->transfer_max_count);
return VK_SUCCESS; return VK_SUCCESS;
} }
@ -1090,3 +1092,51 @@ VkResult command_transition_image_layout(VkDevice device, VkCommandPool transfer
return command_end_single(device, command_buffer, transfer_pool, transfer_queue); return command_end_single(device, command_buffer, transfer_pool, transfer_queue);
} }
VkResult add_transfer(
void* data,
VkBuffer* buffers,
VkDeviceSize offset,
VkDeviceSize size,
RenderContext* gpu) {
VkResult result;
FrameContext* frame = &gpu->frame[gpu->current_frame];
while(frame->transfer_written + size >= frame->transfer_max_size) {
VkBuffer new_transfer;
VmaAllocation new_transfer_memory;
void* new_transfer_data;
VK_RESULT(create_transfer_buffer(gpu->allocator, 2*frame->transfer_max_size, &new_transfer, &new_transfer_memory, &new_transfer_data));
memcpy(new_transfer_data, frame->transfer_mapped, frame->transfer_written);
destroy_transfer_buffer(gpu->allocator, frame->transfer_buffer, frame->transfer_memory);
frame->transfer_buffer = new_transfer;
frame->transfer_memory = new_transfer_memory;
frame->transfer_mapped = new_transfer_data;
frame->transfer_max_size *= 2;
}
if(frame->transfer_count + 1 >= frame->transfer_max_count) {
void* new_infos = malloc(sizeof(TransferInfo)*2*frame->transfer_max_count);
if(new_infos == NULL) {
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
memcpy(new_infos, frame->transfer_infos, sizeof(TransferInfo)*frame->transfer_count);
free(frame->transfer_infos);
frame->transfer_infos = new_infos;
frame->transfer_max_count *= 2;
}
memcpy(frame->transfer_mapped + frame->transfer_written, data, size);
frame->transfer_infos[frame->transfer_count].size = size;
for(uint32_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
frame->transfer_infos[frame->transfer_count].buffers[i] = buffers[i];
}
frame->transfer_infos[frame->transfer_count].offset = offset;
frame->transfer_written += size;
frame->transfer_count += 1;
return VK_SUCCESS;
}

@ -161,7 +161,9 @@ void* network_thread(void* data) {
return NULL; return NULL;
} }
int main_thread(ClientContext* context) { VkResult main_thread(ClientContext* context) {
VkResult result;
GPUString fps_string = { GPUString fps_string = {
.pos = {0, 32}, .pos = {0, 32},
.size = 32, .size = 32,
@ -186,32 +188,21 @@ int main_thread(ClientContext* context) {
create_container(&fps_container, &context->render, &context->ui); create_container(&fps_container, &context->render, &context->ui);
//
double last_draw = -1; double last_draw = -1;
double draw_interval = 1; double draw_interval = 1;
double frame_count = 0; double frame_count = 0;
uint32_t* mapped_codes = context->ui.containers[0].layers[0].codes_buffer;
GPUString* mapped_string = &context->ui.containers[0].layers[0].strings_buffer[0];
char str[11];
//
while(glfwWindowShouldClose(context->window) == 0) { while(glfwWindowShouldClose(context->window) == 0) {
glfwPollEvents(); glfwPollEvents();
double frame_time = glfwGetTime(); double frame_time = glfwGetTime();
// TODO: replace with API calls to add these structures to the per-frame transfer and update CPU structures //
if(frame_time - last_draw > draw_interval) { if(frame_time - last_draw > draw_interval) {
context->render.frame[context->render.current_frame].transfer_count = 2;
TransferInfo* transfer_infos = context->render.frame[context->render.current_frame].transfer_infos;
transfer_infos[0].size = 10*sizeof(uint32_t);
transfer_infos[0].dst_offset = 0;
transfer_infos[0].buffers[0] = context->ui.containers[0].layers[0].codes[0];
transfer_infos[0].buffers[1] = context->ui.containers[0].layers[0].codes[1];
transfer_infos[1].size = sizeof(GPUString);
transfer_infos[1].dst_offset = 0;
transfer_infos[1].buffers[0] = context->ui.containers[0].layers[0].strings[0];
transfer_infos[1].buffers[1] = context->ui.containers[0].layers[0].strings[1];
void* mapped = context->render.frame[context->render.current_frame].transfer_mapped;
uint32_t* mapped_codes = (uint32_t*)mapped;
GPUString* mapped_string = (GPUString*)(mapped + 10*sizeof(uint32_t));
char str[11];
snprintf(str, 11, "%3.2f", frame_count/(frame_time-last_draw)); snprintf(str, 11, "%3.2f", frame_count/(frame_time-last_draw));
map_string(str, mapped_codes, 0, 0, &context->ui); map_string(str, mapped_codes, 0, 0, &context->ui);
mapped_string->size = 32; mapped_string->size = 32;
@ -227,6 +218,19 @@ int main_thread(ClientContext* context) {
last_draw = frame_time; last_draw = frame_time;
frame_count = 0; frame_count = 0;
VK_RESULT(add_transfer(
context->ui.containers[0].layers[0].codes_buffer,
context->ui.containers[0].layers[0].codes,
0,
10*sizeof(uint32_t),
&context->render));
VK_RESULT(add_transfer(
context->ui.containers[0].layers[0].strings_buffer,
context->ui.containers[0].layers[0].strings,
0,
sizeof(GPUString),
&context->render));
} }
// //

@ -387,7 +387,6 @@ VkResult create_layer(
container->layers[index].data.max_drawables = max_drawables + max_codes; container->layers[index].data.max_drawables = max_drawables + max_codes;
container->layers[index].data.max_strings = max_strings; container->layers[index].data.max_strings = max_strings;
container->layers[index].data.max_codes = max_codes;
container->layers[index].data.num_drawables = max_drawables; container->layers[index].data.num_drawables = max_drawables;
container->layers[index].data.container = container->address; container->layers[index].data.container = container->address;
memcpy(mapped, &container->layers[index].data, sizeof(GPULayer)); memcpy(mapped, &container->layers[index].data, sizeof(GPULayer));