@@ -1487,27 +1487,6 @@ void Renderer::drawFrame(float time)
1487
1487
// vkWaitForFences(device, 1, &in_flight_fences[current_frame], VK_TRUE, UINT64_MAX);
1488
1488
// vkResetFences(device, 1, &in_flight_fences[current_frame]);
1489
1489
1490
- uint32_t img_index;
1491
- VkResult result = vkAcquireNextImageKHR (device, swap_chain, UINT64_MAX, img_available_semaphore[current_frame], VK_NULL_HANDLE, &img_index);
1492
-
1493
- if (result == VK_ERROR_OUT_OF_DATE_KHR)
1494
- {
1495
- m.recreateSwapChain ();
1496
- return ;
1497
- } else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
1498
- throw std::runtime_error (" VKERR: Failed to acquire swap chain image!" );
1499
- }
1500
-
1501
- // Check if a previous frame is using this image (i.e. there is its fence to wait on)
1502
- if (imgs_in_flight[img_index] != VK_NULL_HANDLE)
1503
- vkWaitForFences (device, 1 , &imgs_in_flight[img_index], VK_TRUE, UINT64_MAX);
1504
-
1505
- // Mark the image as now being in use by this frame
1506
- imgs_in_flight[img_index] = imgs_in_flight[current_frame];
1507
-
1508
- // Update the Uniform Buffer
1509
- updateUniformBuffer (img_index, time);
1510
-
1511
1490
size_t key_indices[256 ] = {};
1512
1491
size_t cur_offset = 0 ;
1513
1492
// yep, this iterates over the keys twice...
@@ -1590,10 +1569,35 @@ void Renderer::drawFrame(float time)
1590
1569
else {
1591
1570
last_notes_shown_count = notes_shown_size;
1592
1571
}
1572
+
1573
+ uint32_t img_index;
1574
+ VkResult result = vkAcquireNextImageKHR (device, swap_chain, UINT64_MAX, img_available_semaphore[current_frame], VK_NULL_HANDLE, &img_index);
1575
+
1576
+ if (result == VK_ERROR_OUT_OF_DATE_KHR)
1577
+ {
1578
+ m.recreateSwapChain ();
1579
+ return ;
1580
+ }
1581
+ else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
1582
+ throw std::runtime_error (" VKERR: Failed to acquire swap chain image!" );
1583
+ }
1584
+
1585
+ // Check if a previous frame is using this image (i.e. there is its fence to wait on)
1586
+ if (imgs_in_flight[img_index] != VK_NULL_HANDLE)
1587
+ vkWaitForFences (device, 1 , &imgs_in_flight[img_index], VK_TRUE, UINT64_MAX);
1588
+
1589
+ // Mark the image as now being in use by this frame
1590
+ imgs_in_flight[img_index] = imgs_in_flight[current_frame];
1591
+
1592
+ // Update the Uniform Buffer
1593
+ updateUniformBuffer (img_index, time);
1594
+
1595
+ vkWaitForFences (device, 1 , &in_flight_fences[current_frame], VK_TRUE, UINT64_MAX);
1593
1596
1597
+ VkCommandBuffer last_note_cmdbuf = nullptr ; // used to submit a single note draw command buffer at the same time as the imgui one
1594
1598
size_t instances_left = notes_shown_size;
1595
1599
if (notes_shown_size == 0 )
1596
- submitSingleCommandBuffer ( cmd_buffers[img_index * MAX_NOTES_MULT]) ;
1600
+ last_note_cmdbuf = cmd_buffers[img_index * MAX_NOTES_MULT];
1597
1601
for (size_t i = 0 ; i < notes_shown_size; i += MAX_NOTES) {
1598
1602
size_t instances_processed = min (instances_left, MAX_NOTES);
1599
1603
vkMapMemory (device, note_instance_buffer_mem, 0 , sizeof (InstanceData) * instances_processed, 0 , &data);
@@ -1611,12 +1615,17 @@ void Renderer::drawFrame(float time)
1611
1615
}
1612
1616
}
1613
1617
1614
- submitSingleCommandBuffer (cmd_buffers[(i == 0 ? 0 : swap_chain_framebuffers.size () * MAX_NOTES_MULT) + note_cmd_buf + img_index * MAX_NOTES_MULT]);
1615
1618
instances_left -= instances_processed;
1616
1619
last_instances_processed = instances_processed;
1620
+ auto cmd_buf = cmd_buffers[(i == 0 ? 0 : swap_chain_framebuffers.size () * MAX_NOTES_MULT) + note_cmd_buf + img_index * MAX_NOTES_MULT];
1621
+ if (instances_left == 0 )
1622
+ last_note_cmdbuf = cmd_buf;
1623
+ else
1624
+ submitSingleCommandBuffer (cmd_buf);
1617
1625
}
1618
1626
1619
1627
// render imgui command buffers
1628
+ // TODO: this can be done at the same time as the above block, but how can that be done efficiently?
1620
1629
ImGui_ImplVulkan_NewFrame ();
1621
1630
ImGui_ImplGlfw_NewFrame ();
1622
1631
ImGui::NewFrame ();
@@ -1650,13 +1659,38 @@ void Renderer::drawFrame(float time)
1650
1659
}
1651
1660
}
1652
1661
1653
- submitSingleCommandBuffer (imgui_cmd_buffers[img_index]);
1662
+ // Submit to the command buffer
1663
+ VkSubmitInfo submit_info = {};
1664
+ submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1665
+
1666
+ std::array<VkCommandBuffer, 2 > command_buffers = { last_note_cmdbuf, imgui_cmd_buffers[img_index] };
1667
+
1668
+ VkSemaphore wait_semaphores[] = { img_available_semaphore[current_frame] }; // The semaphores we are waiting for
1669
+ VkPipelineStageFlags wait_stages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; // Wait with writing colors until the image is available
1670
+ submit_info.waitSemaphoreCount = 1 ;
1671
+ submit_info.pWaitSemaphores = wait_semaphores;
1672
+ submit_info.pWaitDstStageMask = wait_stages;
1673
+ submit_info.commandBufferCount = static_cast <uint32_t >(command_buffers.size ());
1674
+ submit_info.pCommandBuffers = command_buffers.data ();
1675
+
1676
+ submit_info.signalSemaphoreCount = 1 ;
1677
+ submit_info.pSignalSemaphores = &render_fin_semaphore[current_frame];
1678
+
1679
+ // vkWaitForFences(device, 1, &in_flight_fences[current_frame], VK_TRUE, UINT64_MAX);
1680
+ vkResetFences (device, 1 , &in_flight_fences[current_frame]);
1681
+
1682
+ auto submit_res = vkQueueSubmit (graphics_queue, 1 , &submit_info, in_flight_fences[current_frame]);
1683
+ if (submit_res != VK_SUCCESS)
1684
+ {
1685
+ printf (" %d\n " , submit_res);
1686
+ throw std::runtime_error (" VKERR: Failed to submit draw to command buffer!" );
1687
+ }
1654
1688
1655
1689
// Presentation
1656
1690
VkPresentInfoKHR present_info = {};
1657
1691
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
1658
1692
present_info.waitSemaphoreCount = 1 ;
1659
- present_info.pWaitSemaphores = &img_available_semaphore [current_frame];
1693
+ present_info.pWaitSemaphores = &render_fin_semaphore [current_frame];
1660
1694
1661
1695
VkSwapchainKHR swap_chains[] = { swap_chain }; // An array of all our swap chains
1662
1696
present_info.swapchainCount = 1 ;
0 commit comments