Merge pull request #6953 from ameerj/anv-semaphore
renderer_vulkan: Wait on present semaphore at queue submit
This commit is contained in:
commit
472aad69db
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue