mirror of
https://github.com/yuzu-mirror/yuzu
synced 2024-12-01 06:19:09 +00:00
Merge pull request #6953 from ameerj/anv-semaphore
renderer_vulkan: Wait on present semaphore at queue submit
This commit is contained in:
commit
472aad69db
5 changed files with 33 additions and 26 deletions
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue