From e14be07f0fab02d8c7742fc0232d96b56bc32361 Mon Sep 17 00:00:00 2001 From: Frederico Linhares Date: Fri, 21 Oct 2022 11:52:48 -0300 Subject: feat Skip frame if image is not available. --- src/vk/renderer.cpp | 288 ++++++++++++++++++++++++++++------------------------ 1 file changed, 153 insertions(+), 135 deletions(-) diff --git a/src/vk/renderer.cpp b/src/vk/renderer.cpp index 7492cce..8d82b00 100644 --- a/src/vk/renderer.cpp +++ b/src/vk/renderer.cpp @@ -164,153 +164,171 @@ Renderer::~Renderer() void Renderer::draw() { - vkWaitForFences(cg_core.vk_device_with_swapchain->device, 1, + auto fence_status = vkGetFenceStatus( + cg_core.vk_device_with_swapchain->device, + cg_core.vk_swapchain->in_flight_fences[ + cg_core.vk_swapchain->current_frame]); + + if(fence_status == VK_SUCCESS) + { + auto next_frame = cg_core.vk_swapchain->current_frame + 1; + if(next_frame == Swapchain::max_frames_in_flight) next_frame = 0; + + vkResetFences(cg_core.vk_device_with_swapchain->device, 1, &cg_core.vk_swapchain->in_flight_fences[ - cg_core.vk_swapchain->current_frame], VK_TRUE, - std::numeric_limits::max()); - vkResetFences(cg_core.vk_device_with_swapchain->device, 1, - &cg_core.vk_swapchain->in_flight_fences[ - cg_core.vk_swapchain->current_frame]); + cg_core.vk_swapchain->current_frame]); - uint32_t image_index; - vkAcquireNextImageKHR( + uint32_t image_index; + vkAcquireNextImageKHR( cg_core.vk_device_with_swapchain->device, cg_core.vk_swapchain->swapchain, std::numeric_limits::max(), cg_core.vk_swapchain->image_available_semaphores[ cg_core.vk_swapchain->current_frame], VK_NULL_HANDLE, &image_index); - VkCommandBuffer draw_command_buffer = - this->draw_command_buffers[cg_core.vk_swapchain->current_frame]; - vkResetCommandBuffer(draw_command_buffer, 0); - - auto next_frame = cg_core.vk_swapchain->current_frame + 1; - if(next_frame == Swapchain::max_frames_in_flight) next_frame = 0; - - // Begin command buffer. - { - VkCommandBufferBeginInfo begin_info{}; - begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - begin_info.flags = 0; - begin_info.pInheritanceInfo = nullptr; - if (vkBeginCommandBuffer(draw_command_buffer, &begin_info) != VK_SUCCESS) - throw std::runtime_error{"Failed to beggin draw command buffer."}; - } - - // 3D drawing. - { - // Dark gray blue. - std::array clear_values{}; - clear_values[0].color = {0.12f, 0.12f, 0.18f, 1.0f}; - clear_values[1].depthStencil = {1.0f, 0}; - - VkRenderPassBeginInfo render_pass_begin{}; - render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - render_pass_begin.pNext = nullptr; - render_pass_begin.renderPass = - cg_core.vk_graphics_pipeline_3d_layout->render_pass; - render_pass_begin.framebuffer = - cg_core.vk_graphics_pipeline_3d->swapchain_framebuffers[image_index]; - render_pass_begin.renderArea.offset = {0, 0}; - render_pass_begin.renderArea.extent = { - static_cast(cg_core.display_width), - static_cast(cg_core.display_height)}; - render_pass_begin.clearValueCount = clear_values.size(); - render_pass_begin.pClearValues = clear_values.data(); - - vkCmdBeginRenderPass( - draw_command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); - - for(auto &view: this->views_3d) - cg_core.vk_graphics_pipeline_3d->draw( - view, draw_command_buffer, cg_core.vk_swapchain->current_frame, - image_index); - - vkCmdEndRenderPass(draw_command_buffer); + VkCommandBuffer draw_command_buffer = + this->draw_command_buffers[cg_core.vk_swapchain->current_frame]; + vkResetCommandBuffer(draw_command_buffer, 0); + + // Begin command buffer. + { + VkCommandBufferBeginInfo begin_info{}; + begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + begin_info.flags = 0; + begin_info.pInheritanceInfo = nullptr; + if (vkBeginCommandBuffer(draw_command_buffer, &begin_info) != VK_SUCCESS) + throw std::runtime_error{"Failed to beggin draw command buffer."}; + } + + // 3D drawing. + { + // Dark gray blue. + std::array clear_values{}; + clear_values[0].color = {0.12f, 0.12f, 0.18f, 1.0f}; + clear_values[1].depthStencil = {1.0f, 0}; + + VkRenderPassBeginInfo render_pass_begin{}; + render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + render_pass_begin.pNext = nullptr; + render_pass_begin.renderPass = + cg_core.vk_graphics_pipeline_3d_layout->render_pass; + render_pass_begin.framebuffer = + cg_core.vk_graphics_pipeline_3d->swapchain_framebuffers[image_index]; + render_pass_begin.renderArea.offset = {0, 0}; + render_pass_begin.renderArea.extent = { + static_cast(cg_core.display_width), + static_cast(cg_core.display_height)}; + render_pass_begin.clearValueCount = clear_values.size(); + render_pass_begin.pClearValues = clear_values.data(); + + vkCmdBeginRenderPass( + draw_command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); + + for(auto &view: this->views_3d) + cg_core.vk_graphics_pipeline_3d->draw( + view, draw_command_buffer, cg_core.vk_swapchain->current_frame, + image_index); + + vkCmdEndRenderPass(draw_command_buffer); + } + + // 2D drawing + { + VkRenderPassBeginInfo render_pass_begin{}; + render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + render_pass_begin.pNext = nullptr; + render_pass_begin.renderPass = + cg_core.vk_graphics_pipeline_2d_layout->render_pass; + render_pass_begin.framebuffer = + cg_core.vk_graphics_pipeline_2d->swapchain_framebuffers[image_index]; + render_pass_begin.renderArea.offset = {0, 0}; + render_pass_begin.renderArea.extent = { + static_cast(cg_core.display_width), + static_cast(cg_core.display_height)}; + render_pass_begin.clearValueCount = 0; + render_pass_begin.pClearValues = nullptr; + + vkCmdBeginRenderPass( + draw_command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); + + for(auto &view: this->views_2d) + cg_core.vk_graphics_pipeline_2d->draw( + view, draw_command_buffer, cg_core.vk_swapchain->current_frame, + next_frame, image_index); + + for(auto &view: this->views_3d) + cg_core.vk_graphics_pipeline_2d->draw( + view, draw_command_buffer, cg_core.vk_swapchain->current_frame, + next_frame, image_index); + + vkCmdEndRenderPass(draw_command_buffer); + } + + // End command buffer. + if(vkEndCommandBuffer(draw_command_buffer) != VK_SUCCESS) + throw std::runtime_error{"Failed to end draw command buffer."}; + + // Submit drawing command. + { + auto queue{this->queue_family->get_queue()}; + + VkSemaphore wait_semaphores[]{ + cg_core.vk_swapchain->image_available_semaphores[ + cg_core.vk_swapchain->current_frame]}; + VkPipelineStageFlags wait_stages[] = + {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; + VkSemaphore signal_semaphores[]{ + cg_core.vk_swapchain->render_finished_semaphores[ + cg_core.vk_swapchain->current_frame]}; + + VkSubmitInfo submit_info{}; + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.pNext = nullptr; + submit_info.waitSemaphoreCount = 1; + submit_info.pWaitSemaphores = wait_semaphores; + submit_info.pWaitDstStageMask = wait_stages; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &draw_command_buffer; + submit_info.signalSemaphoreCount = 1; + submit_info.pSignalSemaphores = signal_semaphores; + + if(vkQueueSubmit( + queue.queue, 1, &submit_info, cg_core.vk_swapchain->in_flight_fences[ + cg_core.vk_swapchain->current_frame]) != VK_SUCCESS) + throw std::runtime_error{"Failed to submit draw command buffer."}; + + VkSwapchainKHR swap_chains[]{cg_core.vk_swapchain->swapchain}; + + VkPresentInfoKHR present_info{}; + present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + present_info.pNext = nullptr; + present_info.waitSemaphoreCount = 1; + present_info.pWaitSemaphores = signal_semaphores; + present_info.swapchainCount = 1; + present_info.pSwapchains = swap_chains; + present_info.pImageIndices = &image_index; + present_info.pResults = nullptr; + + vkQueuePresentKHR(queue.queue, &present_info); + } + + // Prepare for the next frame. + { + this->models_to_draw[next_frame].clear(); + for(auto &view: this->views_2d) view->sprites_to_draw[next_frame].clear(); + for(auto &view: this->views_3d) view->sprites_to_draw[next_frame].clear(); + + cg_core.vk_swapchain->current_frame = next_frame; + } } - - // 2D drawing + else { - VkRenderPassBeginInfo render_pass_begin{}; - render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - render_pass_begin.pNext = nullptr; - render_pass_begin.renderPass = - cg_core.vk_graphics_pipeline_2d_layout->render_pass; - render_pass_begin.framebuffer = - cg_core.vk_graphics_pipeline_2d->swapchain_framebuffers[image_index]; - render_pass_begin.renderArea.offset = {0, 0}; - render_pass_begin.renderArea.extent = { - static_cast(cg_core.display_width), - static_cast(cg_core.display_height)}; - render_pass_begin.clearValueCount = 0; - render_pass_begin.pClearValues = nullptr; - - vkCmdBeginRenderPass( - draw_command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); - + // Clear images for the current frame because we are skipping this frame. + this->models_to_draw[cg_core.vk_swapchain->current_frame].clear(); for(auto &view: this->views_2d) - cg_core.vk_graphics_pipeline_2d->draw( - view, draw_command_buffer, cg_core.vk_swapchain->current_frame, - next_frame, image_index); - + view->sprites_to_draw[cg_core.vk_swapchain->current_frame].clear(); for(auto &view: this->views_3d) - cg_core.vk_graphics_pipeline_2d->draw( - view, draw_command_buffer, cg_core.vk_swapchain->current_frame, - next_frame, image_index); - - vkCmdEndRenderPass(draw_command_buffer); - } - - // End command buffer. - if(vkEndCommandBuffer(draw_command_buffer) != VK_SUCCESS) - throw std::runtime_error{"Failed to end draw command buffer."}; - - // Submit drawing command. - { - auto queue{this->queue_family->get_queue()}; - - VkSemaphore wait_semaphores[]{ - cg_core.vk_swapchain->image_available_semaphores[ - cg_core.vk_swapchain->current_frame]}; - VkPipelineStageFlags wait_stages[] = - {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; - VkSemaphore signal_semaphores[]{ - cg_core.vk_swapchain->render_finished_semaphores[ - cg_core.vk_swapchain->current_frame]}; - - VkSubmitInfo submit_info{}; - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit_info.pNext = nullptr; - submit_info.waitSemaphoreCount = 1; - submit_info.pWaitSemaphores = wait_semaphores; - submit_info.pWaitDstStageMask = wait_stages; - submit_info.commandBufferCount = 1; - submit_info.pCommandBuffers = &draw_command_buffer; - submit_info.signalSemaphoreCount = 1; - submit_info.pSignalSemaphores = signal_semaphores; - - if(vkQueueSubmit( - queue.queue, 1, &submit_info, cg_core.vk_swapchain->in_flight_fences[ - cg_core.vk_swapchain->current_frame]) != VK_SUCCESS) - throw std::runtime_error{"Failed to submit draw command buffer."}; - - VkSwapchainKHR swap_chains[]{cg_core.vk_swapchain->swapchain}; - - VkPresentInfoKHR present_info{}; - present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; - present_info.pNext = nullptr; - present_info.waitSemaphoreCount = 1; - present_info.pWaitSemaphores = signal_semaphores; - present_info.swapchainCount = 1; - present_info.pSwapchains = swap_chains; - present_info.pImageIndices = &image_index; - present_info.pResults = nullptr; - - vkQueuePresentKHR(queue.queue, &present_info); + view->sprites_to_draw[cg_core.vk_swapchain->current_frame].clear(); } - - // Prepare for the next frame. - this->models_to_draw[next_frame].clear(); - cg_core.vk_swapchain->current_frame = next_frame; } } -- cgit v1.2.3