2
1
Fork 0
mirror of https://github.com/yuzu-emu/yuzu.git synced 2024-07-04 23:31:19 +01:00

Merge pull request #6953 from ameerj/anv-semaphore

renderer_vulkan: Wait on present semaphore at queue submit
This commit is contained in:
Fernando S 2021-09-11 22:35:52 +02:00 committed by GitHub
commit 472aad69db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 26 deletions

View file

@ -164,7 +164,8 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
blit_screen.Recreate(); blit_screen.Recreate();
} }
const VkSemaphore render_semaphore = blit_screen.DrawToSwapchain(*framebuffer, use_accelerated); 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(); scheduler.WaitWorker();
swapchain.Present(render_semaphore); swapchain.Present(render_semaphore);

View file

@ -55,14 +55,14 @@ VKScheduler::~VKScheduler() {
worker_thread.join(); worker_thread.join();
} }
void VKScheduler::Flush(VkSemaphore semaphore) { void VKScheduler::Flush(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore) {
SubmitExecution(semaphore); SubmitExecution(signal_semaphore, wait_semaphore);
AllocateNewContext(); AllocateNewContext();
} }
void VKScheduler::Finish(VkSemaphore semaphore) { void VKScheduler::Finish(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore) {
const u64 presubmit_tick = CurrentTick(); const u64 presubmit_tick = CurrentTick();
SubmitExecution(semaphore); SubmitExecution(signal_semaphore, wait_semaphore);
WaitWorker(); WaitWorker();
Wait(presubmit_tick); Wait(presubmit_tick);
AllocateNewContext(); AllocateNewContext();
@ -171,37 +171,41 @@ void VKScheduler::AllocateWorkerCommandBuffer() {
}); });
} }
void VKScheduler::SubmitExecution(VkSemaphore semaphore) { void VKScheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore) {
EndPendingOperations(); EndPendingOperations();
InvalidateState(); InvalidateState();
const u64 signal_value = master_semaphore->NextTick(); 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(); 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 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_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{ const VkTimelineSemaphoreSubmitInfoKHR timeline_si{
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR, .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,
.pNext = nullptr, .pNext = nullptr,
.waitSemaphoreValueCount = 1, .waitSemaphoreValueCount = num_wait_semaphores,
.pWaitSemaphoreValues = &wait_value, .pWaitSemaphoreValues = wait_values.data(),
.signalSemaphoreValueCount = num_signal_semaphores, .signalSemaphoreValueCount = num_signal_semaphores,
.pSignalSemaphoreValues = signal_values.data(), .pSignalSemaphoreValues = signal_values.data(),
}; };
const VkSubmitInfo submit_info{ const VkSubmitInfo submit_info{
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pNext = &timeline_si, .pNext = &timeline_si,
.waitSemaphoreCount = 1, .waitSemaphoreCount = num_wait_semaphores,
.pWaitSemaphores = &timeline_semaphore, .pWaitSemaphores = wait_semaphores.data(),
.pWaitDstStageMask = &wait_stage_mask, .pWaitDstStageMask = wait_stage_masks.data(),
.commandBufferCount = 1, .commandBufferCount = 1,
.pCommandBuffers = cmdbuf.address(), .pCommandBuffers = cmdbuf.address(),
.signalSemaphoreCount = num_signal_semaphores, .signalSemaphoreCount = num_signal_semaphores,

View file

@ -34,10 +34,10 @@ public:
~VKScheduler(); ~VKScheduler();
/// Sends the current execution context to the GPU. /// 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. /// 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 /// Waits for the worker thread to finish executing everything. After this function returns it's
/// safe to touch worker resources. /// safe to touch worker resources.
@ -191,7 +191,7 @@ private:
void AllocateWorkerCommandBuffer(); void AllocateWorkerCommandBuffer();
void SubmitExecution(VkSemaphore semaphore); void SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore);
void AllocateNewContext(); void AllocateNewContext();

View file

@ -107,14 +107,12 @@ void VKSwapchain::AcquireNextImage() {
} }
void VKSwapchain::Present(VkSemaphore render_semaphore) { 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 auto present_queue{device.GetPresentQueue()};
const VkPresentInfoKHR present_info{ const VkPresentInfoKHR present_info{
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.pNext = nullptr, .pNext = nullptr,
.waitSemaphoreCount = render_semaphore ? 2U : 1U, .waitSemaphoreCount = render_semaphore ? 1U : 0U,
.pWaitSemaphores = semaphores.data(), .pWaitSemaphores = &render_semaphore,
.swapchainCount = 1, .swapchainCount = 1,
.pSwapchains = swapchain.address(), .pSwapchains = swapchain.address(),
.pImageIndices = &image_index, .pImageIndices = &image_index,

View file

@ -72,6 +72,10 @@ public:
return image_format; return image_format;
} }
VkSemaphore CurrentPresentSemaphore() const {
return *present_semaphores[frame_index];
}
private: private:
void CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height, void CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height,
bool srgb); bool srgb);