summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFrederico Linhares <fred@linhares.blue>2022-10-21 11:52:48 -0300
committerFrederico Linhares <fred@linhares.blue>2022-10-21 13:54:28 -0300
commite14be07f0fab02d8c7742fc0232d96b56bc32361 (patch)
tree12d97337b1a444f8d6b4aa3e9b5f332592c67b16 /src
parent0a905a0c33a1ae93174212b94dfdec946ebfaceb (diff)
feat Skip frame if image is not available.
Diffstat (limited to 'src')
-rw-r--r--src/vk/renderer.cpp288
1 files 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<uint64_t>::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<uint64_t>::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<VkClearValue, 2> 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<uint32_t>(cg_core.display_width),
- static_cast<uint32_t>(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<VkClearValue, 2> 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<uint32_t>(cg_core.display_width),
+ static_cast<uint32_t>(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<uint32_t>(cg_core.display_width),
+ static_cast<uint32_t>(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<uint32_t>(cg_core.display_width),
- static_cast<uint32_t>(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;
}
}