diff --git a/client/include/gpu.h b/client/include/gpu.h index ffa3c1a..30c8478 100644 --- a/client/include/gpu.h +++ b/client/include/gpu.h @@ -68,7 +68,7 @@ typedef struct SwapchainDetailsStruct { } SwapchainDetails; typedef struct TransferInfoStruct { - VkDeviceSize dst_offset; + VkDeviceSize offset; VkDeviceSize size; VkBuffer buffers[MAX_FRAMES_IN_FLIGHT]; } TransferInfo; @@ -88,6 +88,11 @@ typedef struct FrameContextStruct { VkBuffer transfer_buffer; VmaAllocation transfer_memory; void* transfer_mapped; + size_t transfer_written; + + size_t transfer_max_size; + size_t transfer_max_count; + TransferInfo* transfer_infos; uint32_t transfer_count; } FrameContext; @@ -162,4 +167,11 @@ VkDeviceAddress buffer_address( VkDevice device, VkBuffer buffer); +VkResult add_transfer( + void* data, + VkBuffer* buffers, + VkDeviceSize offset, + VkDeviceSize size, + RenderContext* gpu); + #endif diff --git a/client/src/draw.c b/client/src/draw.c index 3225600..5761cc1 100644 --- a/client/src/draw.c +++ b/client/src/draw.c @@ -75,7 +75,7 @@ VkResult draw_frame( context->frame[context->current_frame].transfer_buffer, context->frame[context->current_frame].transfer_infos[j].buffers[i], 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); 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])); } context->frame[context->current_frame].transfer_count = 0; + context->frame[context->current_frame].transfer_written = 0; } uint32_t image_index; diff --git a/client/src/gpu.c b/client/src/gpu.c index 2a6984e..1319fe7 100644 --- a/client/src/gpu.c +++ b/client/src/gpu.c @@ -789,10 +789,12 @@ VkResult create_frame_context(VkDevice device, VmaAllocator allocator, VkCommand }; VK_RESULT(vkAllocateCommandBuffers(device, &command_info, frame->transfer_commands)); - // TODO: temp size values, add dynamic resizing - VK_RESULT(create_transfer_buffer(allocator, 1024, &frame->transfer_buffer, &frame->transfer_memory, &frame->transfer_mapped)); + // TODO: better defaults + 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_infos = malloc(sizeof(TransferInfo)*10); + frame->transfer_infos = malloc(sizeof(TransferInfo)*frame->transfer_max_count); 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); } + +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; +} diff --git a/client/src/main.c b/client/src/main.c index d4a7e93..0bb0f36 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -161,7 +161,9 @@ void* network_thread(void* data) { return NULL; } -int main_thread(ClientContext* context) { +VkResult main_thread(ClientContext* context) { + VkResult result; + GPUString fps_string = { .pos = {0, 32}, .size = 32, @@ -186,32 +188,21 @@ int main_thread(ClientContext* context) { create_container(&fps_container, &context->render, &context->ui); + // double last_draw = -1; double draw_interval = 1; 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) { glfwPollEvents(); 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) { - 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)); map_string(str, mapped_codes, 0, 0, &context->ui); mapped_string->size = 32; @@ -227,6 +218,19 @@ int main_thread(ClientContext* context) { last_draw = frame_time; 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)); } // diff --git a/client/src/ui.c b/client/src/ui.c index 97168dc..9847fbe 100644 --- a/client/src/ui.c +++ b/client/src/ui.c @@ -387,7 +387,6 @@ VkResult create_layer( container->layers[index].data.max_drawables = max_drawables + max_codes; 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.container = container->address; memcpy(mapped, &container->layers[index].data, sizeof(GPULayer));