diff --git a/client/include/draw.h b/client/include/draw.h index 95b638f..687dbeb 100644 --- a/client/include/draw.h +++ b/client/include/draw.h @@ -5,6 +5,9 @@ #include "ui.h" VkResult draw_frame( + RenderContext* context); + +VkResult record_draw_commands( RenderContext* context, UIContextStorage* ui_context); diff --git a/client/src/draw.c b/client/src/draw.c index b02e407..1da6445 100644 --- a/client/src/draw.c +++ b/client/src/draw.c @@ -1,6 +1,7 @@ #include "draw.h" +#include "gpu.h" -VkResult record_ui_compute(VkCommandBuffer command_buffer, UIContextStorage* ui_context) { +void record_ui_compute(VkCommandBuffer command_buffer, UIContextStorage* ui_context) { VkDeviceAddress push[2] = {ui_context->address, 0}; vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, ui_context->string_pipeline.pipeline); @@ -51,11 +52,9 @@ VkResult record_ui_compute(VkCommandBuffer command_buffer, UIContextStorage* ui_ } } } - - return VK_SUCCESS; } -VkResult record_ui_draw(VkCommandBuffer command_buffer, UIContextStorage* ui_context) { +void record_ui_draw(VkCommandBuffer command_buffer, UIContextStorage* ui_context) { VkDeviceAddress push[2] = {ui_context->address, 0}; vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.pipeline); @@ -72,14 +71,61 @@ VkResult record_ui_draw(VkCommandBuffer command_buffer, UIContextStorage* ui_con } } } +} + +VkResult record_draw_commands( + RenderContext* context, + UIContextStorage* ui_context) { + VkResult result; + for(uint32_t image_index = 0; image_index < context->swapchain_image_count; image_index++) { + VkCommandBuffer command_buffer = context->swapchain_command_buffers[image_index]; + VK_RESULT(vkResetCommandBuffer(command_buffer, 0)); + + VkCommandBufferBeginInfo begin_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + }; + VK_RESULT(vkBeginCommandBuffer(command_buffer, &begin_info)); + + VkViewport viewport = { + .width = context->swapchain_extent.width, + .height = context->swapchain_extent.height, + .maxDepth = 1.0f, + .minDepth = 0.0f, + }; + vkCmdSetViewport(command_buffer, 0, 1, &viewport); + + VkRect2D scissor = { + .extent = context->swapchain_extent, + }; + vkCmdSetScissor(command_buffer, 0, 1, &scissor); + + VkClearValue clear_values[2] = {{.color={{0.0f, 0.0f, 0.0f, 0.0f}}}, {.depthStencil={1.0f, 0.0f}}}; + + VkRenderPassBeginInfo render_pass_begin = { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .renderPass = context->render_pass, + .framebuffer = context->swapchain_framebuffers[image_index], + .renderArea.offset = {0, 0}, + .renderArea.extent = context->swapchain_extent, + .clearValueCount = 2, + .pClearValues = clear_values, + }; + + record_ui_compute(command_buffer, ui_context); + vkCmdBeginRenderPass(command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); + vkCmdNextSubpass(command_buffer, VK_SUBPASS_CONTENTS_INLINE); + record_ui_draw(command_buffer, ui_context); + vkCmdEndRenderPass(command_buffer); + + VK_RESULT(vkEndCommandBuffer(command_buffer)); + } return VK_SUCCESS; } VkResult draw_frame( - RenderContext* context, - UIContextStorage* ui_context) { + RenderContext* context) { VkResult result; result = vkWaitForFences(context->device, 1, &context->in_flight_fences[context->current_frame], VK_TRUE, UINT64_MAX); @@ -93,61 +139,11 @@ VkResult draw_frame( } uint32_t image_index; - VkCommandBuffer command_buffer = context->swapchain_command_buffers[context->current_frame]; result = vkAcquireNextImageKHR(context->device, context->swapchain, UINT64_MAX, context->image_available_semaphores[context->current_frame], VK_NULL_HANDLE, &image_index); if(result != VK_SUCCESS) { return result; } - result = vkResetCommandBuffer(command_buffer, 0); - if(result != VK_SUCCESS) { - return result; - } - - VkCommandBufferBeginInfo begin_info = { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - }; - result = vkBeginCommandBuffer(command_buffer, &begin_info); - if(result != VK_SUCCESS) { - return result; - } - - VkViewport viewport = { - .width = context->swapchain_extent.width, - .height = context->swapchain_extent.height, - .maxDepth = 1.0f, - .minDepth = 0.0f, - }; - vkCmdSetViewport(command_buffer, 0, 1, &viewport); - - VkRect2D scissor = { - .extent = context->swapchain_extent, - }; - vkCmdSetScissor(command_buffer, 0, 1, &scissor); - - VkClearValue clear_values[2] = {{.color={{0.0f, 0.0f, 0.0f, 0.0f}}}, {.depthStencil={1.0f, 0.0f}}}; - - VkRenderPassBeginInfo render_pass_begin = { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = context->render_pass, - .framebuffer = context->swapchain_framebuffers[image_index], - .renderArea.offset = {0, 0}, - .renderArea.extent = context->swapchain_extent, - .clearValueCount = 2, - .pClearValues = clear_values, - }; - - record_ui_compute(command_buffer, ui_context); - vkCmdBeginRenderPass(command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); - vkCmdNextSubpass(command_buffer, VK_SUBPASS_CONTENTS_INLINE); - record_ui_draw(command_buffer, ui_context); - vkCmdEndRenderPass(command_buffer); - - result = vkEndCommandBuffer(command_buffer); - if(result != VK_SUCCESS) { - return result; - } - VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; VkSubmitInfo submit_info = { .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, @@ -155,7 +151,7 @@ VkResult draw_frame( .pWaitSemaphores = &context->image_available_semaphores[context->current_frame], .pWaitDstStageMask = wait_stages, .commandBufferCount = 1, - .pCommandBuffers = &command_buffer, + .pCommandBuffers = &context->swapchain_command_buffers[image_index], .signalSemaphoreCount = 1, .pSignalSemaphores = &context->render_finished_semaphores[context->current_frame], }; diff --git a/client/src/gpu.c b/client/src/gpu.c index 92f027c..4bc7bed 100644 --- a/client/src/gpu.c +++ b/client/src/gpu.c @@ -910,11 +910,6 @@ VkResult init_vulkan(GLFWwindow* window, RenderContext* context) { return result; } - context->swapchain_command_buffers = create_command_buffers(context->device, context->graphics_pool, MAX_FRAMES_IN_FLIGHT); - if(context->swapchain_command_buffers == NULL) { - return VK_ERROR_UNKNOWN; - } - context->image_available_semaphores = create_semaphores(context->device, 0, MAX_FRAMES_IN_FLIGHT); if(context->image_available_semaphores == NULL) { return VK_ERROR_UNKNOWN; @@ -949,6 +944,11 @@ VkResult init_vulkan(GLFWwindow* window, RenderContext* context) { return result; } + context->swapchain_command_buffers = create_command_buffers(context->device, context->graphics_pool, context->swapchain_image_count); + if(context->swapchain_command_buffers == NULL) { + return VK_ERROR_UNKNOWN; + } + result = create_image_views(context->device, context->swapchain_image_count, context->swapchain_images, context->swapchain_format, &context->swapchain_image_views); if(result != VK_SUCCESS) { return result; diff --git a/client/src/main.c b/client/src/main.c index 32a4bbd..92eb71f 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -89,10 +89,12 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render) { VK_RESULT(create_container(&container_info, render, &ui)); + VK_RESULT(record_draw_commands(render, &ui)); + while(glfwWindowShouldClose(window) == 0) { glfwPollEvents(); - result = draw_frame(render, &ui); + result = draw_frame(render); if(result != VK_SUCCESS) { fprintf(stderr, "draw_frame error: %s\n", string_VkResult(result)); return result;