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