Merge pull request #6953 from ameerj/anv-semaphore
renderer_vulkan: Wait on present semaphore at queue submit
This commit is contained in:
		| @@ -164,7 +164,8 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | ||||
|         blit_screen.Recreate(); | ||||
|     } | ||||
|     const VkSemaphore render_semaphore = blit_screen.DrawToSwapchain(*framebuffer, use_accelerated); | ||||
|     scheduler.Flush(render_semaphore); | ||||
|     const VkSemaphore present_semaphore = swapchain.CurrentPresentSemaphore(); | ||||
|     scheduler.Flush(render_semaphore, present_semaphore); | ||||
|     scheduler.WaitWorker(); | ||||
|     swapchain.Present(render_semaphore); | ||||
|  | ||||
|   | ||||
| @@ -55,14 +55,14 @@ VKScheduler::~VKScheduler() { | ||||
|     worker_thread.join(); | ||||
| } | ||||
|  | ||||
| void VKScheduler::Flush(VkSemaphore semaphore) { | ||||
|     SubmitExecution(semaphore); | ||||
| void VKScheduler::Flush(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore) { | ||||
|     SubmitExecution(signal_semaphore, wait_semaphore); | ||||
|     AllocateNewContext(); | ||||
| } | ||||
|  | ||||
| void VKScheduler::Finish(VkSemaphore semaphore) { | ||||
| void VKScheduler::Finish(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore) { | ||||
|     const u64 presubmit_tick = CurrentTick(); | ||||
|     SubmitExecution(semaphore); | ||||
|     SubmitExecution(signal_semaphore, wait_semaphore); | ||||
|     WaitWorker(); | ||||
|     Wait(presubmit_tick); | ||||
|     AllocateNewContext(); | ||||
| @@ -171,37 +171,41 @@ void VKScheduler::AllocateWorkerCommandBuffer() { | ||||
|     }); | ||||
| } | ||||
|  | ||||
| void VKScheduler::SubmitExecution(VkSemaphore semaphore) { | ||||
| void VKScheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore) { | ||||
|     EndPendingOperations(); | ||||
|     InvalidateState(); | ||||
|  | ||||
|     const u64 signal_value = master_semaphore->NextTick(); | ||||
|     Record([semaphore, signal_value, this](vk::CommandBuffer cmdbuf) { | ||||
|     Record([signal_semaphore, wait_semaphore, signal_value, this](vk::CommandBuffer cmdbuf) { | ||||
|         cmdbuf.End(); | ||||
|  | ||||
|         const u32 num_signal_semaphores = semaphore ? 2U : 1U; | ||||
|  | ||||
|         const u64 wait_value = signal_value - 1; | ||||
|         const VkPipelineStageFlags wait_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; | ||||
|  | ||||
|         const VkSemaphore timeline_semaphore = master_semaphore->Handle(); | ||||
|  | ||||
|         const u32 num_signal_semaphores = signal_semaphore ? 2U : 1U; | ||||
|         const std::array signal_values{signal_value, u64(0)}; | ||||
|         const std::array signal_semaphores{timeline_semaphore, semaphore}; | ||||
|         const std::array signal_semaphores{timeline_semaphore, signal_semaphore}; | ||||
|  | ||||
|         const u32 num_wait_semaphores = wait_semaphore ? 2U : 1U; | ||||
|         const std::array wait_values{signal_value - 1, u64(1)}; | ||||
|         const std::array wait_semaphores{timeline_semaphore, wait_semaphore}; | ||||
|         static constexpr std::array<VkPipelineStageFlags, 2> wait_stage_masks{ | ||||
|             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, | ||||
|             VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, | ||||
|         }; | ||||
|  | ||||
|         const VkTimelineSemaphoreSubmitInfoKHR timeline_si{ | ||||
|             .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR, | ||||
|             .pNext = nullptr, | ||||
|             .waitSemaphoreValueCount = 1, | ||||
|             .pWaitSemaphoreValues = &wait_value, | ||||
|             .waitSemaphoreValueCount = num_wait_semaphores, | ||||
|             .pWaitSemaphoreValues = wait_values.data(), | ||||
|             .signalSemaphoreValueCount = num_signal_semaphores, | ||||
|             .pSignalSemaphoreValues = signal_values.data(), | ||||
|         }; | ||||
|         const VkSubmitInfo submit_info{ | ||||
|             .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, | ||||
|             .pNext = &timeline_si, | ||||
|             .waitSemaphoreCount = 1, | ||||
|             .pWaitSemaphores = &timeline_semaphore, | ||||
|             .pWaitDstStageMask = &wait_stage_mask, | ||||
|             .waitSemaphoreCount = num_wait_semaphores, | ||||
|             .pWaitSemaphores = wait_semaphores.data(), | ||||
|             .pWaitDstStageMask = wait_stage_masks.data(), | ||||
|             .commandBufferCount = 1, | ||||
|             .pCommandBuffers = cmdbuf.address(), | ||||
|             .signalSemaphoreCount = num_signal_semaphores, | ||||
|   | ||||
| @@ -34,10 +34,10 @@ public: | ||||
|     ~VKScheduler(); | ||||
|  | ||||
|     /// Sends the current execution context to the GPU. | ||||
|     void Flush(VkSemaphore semaphore = nullptr); | ||||
|     void Flush(VkSemaphore signal_semaphore = nullptr, VkSemaphore wait_semaphore = nullptr); | ||||
|  | ||||
|     /// Sends the current execution context to the GPU and waits for it to complete. | ||||
|     void Finish(VkSemaphore semaphore = nullptr); | ||||
|     void Finish(VkSemaphore signal_semaphore = nullptr, VkSemaphore wait_semaphore = nullptr); | ||||
|  | ||||
|     /// Waits for the worker thread to finish executing everything. After this function returns it's | ||||
|     /// safe to touch worker resources. | ||||
| @@ -191,7 +191,7 @@ private: | ||||
|  | ||||
|     void AllocateWorkerCommandBuffer(); | ||||
|  | ||||
|     void SubmitExecution(VkSemaphore semaphore); | ||||
|     void SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore); | ||||
|  | ||||
|     void AllocateNewContext(); | ||||
|  | ||||
|   | ||||
| @@ -107,14 +107,12 @@ void VKSwapchain::AcquireNextImage() { | ||||
| } | ||||
|  | ||||
| void VKSwapchain::Present(VkSemaphore render_semaphore) { | ||||
|     const VkSemaphore present_semaphore{*present_semaphores[frame_index]}; | ||||
|     const std::array<VkSemaphore, 2> semaphores{present_semaphore, render_semaphore}; | ||||
|     const auto present_queue{device.GetPresentQueue()}; | ||||
|     const VkPresentInfoKHR present_info{ | ||||
|         .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, | ||||
|         .pNext = nullptr, | ||||
|         .waitSemaphoreCount = render_semaphore ? 2U : 1U, | ||||
|         .pWaitSemaphores = semaphores.data(), | ||||
|         .waitSemaphoreCount = render_semaphore ? 1U : 0U, | ||||
|         .pWaitSemaphores = &render_semaphore, | ||||
|         .swapchainCount = 1, | ||||
|         .pSwapchains = swapchain.address(), | ||||
|         .pImageIndices = &image_index, | ||||
|   | ||||
| @@ -72,6 +72,10 @@ public: | ||||
|         return image_format; | ||||
|     } | ||||
|  | ||||
|     VkSemaphore CurrentPresentSemaphore() const { | ||||
|         return *present_semaphores[frame_index]; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     void CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height, | ||||
|                          bool srgb); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Fernando S
					Fernando S