summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ameerj2021-09-02 01:26:18 -0400
committerGravatar ameerj2021-09-02 13:13:20 -0400
commit7d854fbdb074f38f465403ce3d5de78288ddc570 (patch)
treef5f137e360b481e1804796cded4b1d2695f6911c
parentMerge pull request #6900 from ameerj/attr-reorder (diff)
downloadyuzu-7d854fbdb074f38f465403ce3d5de78288ddc570.tar.gz
yuzu-7d854fbdb074f38f465403ce3d5de78288ddc570.tar.xz
yuzu-7d854fbdb074f38f465403ce3d5de78288ddc570.zip
renderer_vulkan: Wait on present semaphore at queue submit
The present semaphore is being signalled by the call to acquire the swapchain image. This semaphore is meant to be waited on when rendering to the swapchain image. Currently it is waited on when presenting, but moving its usage to be waited on in the command buffer submission allows for proper usage of this semaphore. Fixes the device lost when launching titles on the Intel Linux Mesa driver.
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp3
-rw-r--r--src/video_core/renderer_vulkan/vk_scheduler.cpp40
-rw-r--r--src/video_core/renderer_vulkan/vk_scheduler.h6
-rw-r--r--src/video_core/renderer_vulkan/vk_swapchain.cpp6
-rw-r--r--src/video_core/renderer_vulkan/vk_swapchain.h4
5 files changed, 33 insertions, 26 deletions
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index 7c9b0d6db..9ff0a28cd 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -164,7 +164,8 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
164 blit_screen.Recreate(); 164 blit_screen.Recreate();
165 } 165 }
166 const VkSemaphore render_semaphore = blit_screen.DrawToSwapchain(*framebuffer, use_accelerated); 166 const VkSemaphore render_semaphore = blit_screen.DrawToSwapchain(*framebuffer, use_accelerated);
167 scheduler.Flush(render_semaphore); 167 const VkSemaphore present_semaphore = swapchain.CurrentPresentSemaphore();
168 scheduler.Flush(render_semaphore, present_semaphore);
168 scheduler.WaitWorker(); 169 scheduler.WaitWorker();
169 swapchain.Present(render_semaphore); 170 swapchain.Present(render_semaphore);
170 171
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp
index 4840962de..1d438787a 100644
--- a/src/video_core/renderer_vulkan/vk_scheduler.cpp
+++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp
@@ -55,14 +55,14 @@ VKScheduler::~VKScheduler() {
55 worker_thread.join(); 55 worker_thread.join();
56} 56}
57 57
58void VKScheduler::Flush(VkSemaphore semaphore) { 58void VKScheduler::Flush(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore) {
59 SubmitExecution(semaphore); 59 SubmitExecution(signal_semaphore, wait_semaphore);
60 AllocateNewContext(); 60 AllocateNewContext();
61} 61}
62 62
63void VKScheduler::Finish(VkSemaphore semaphore) { 63void VKScheduler::Finish(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore) {
64 const u64 presubmit_tick = CurrentTick(); 64 const u64 presubmit_tick = CurrentTick();
65 SubmitExecution(semaphore); 65 SubmitExecution(signal_semaphore, wait_semaphore);
66 WaitWorker(); 66 WaitWorker();
67 Wait(presubmit_tick); 67 Wait(presubmit_tick);
68 AllocateNewContext(); 68 AllocateNewContext();
@@ -171,37 +171,41 @@ void VKScheduler::AllocateWorkerCommandBuffer() {
171 }); 171 });
172} 172}
173 173
174void VKScheduler::SubmitExecution(VkSemaphore semaphore) { 174void VKScheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore) {
175 EndPendingOperations(); 175 EndPendingOperations();
176 InvalidateState(); 176 InvalidateState();
177 177
178 const u64 signal_value = master_semaphore->NextTick(); 178 const u64 signal_value = master_semaphore->NextTick();
179 Record([semaphore, signal_value, this](vk::CommandBuffer cmdbuf) { 179 Record([signal_semaphore, wait_semaphore, signal_value, this](vk::CommandBuffer cmdbuf) {
180 cmdbuf.End(); 180 cmdbuf.End();
181
182 const u32 num_signal_semaphores = semaphore ? 2U : 1U;
183
184 const u64 wait_value = signal_value - 1;
185 const VkPipelineStageFlags wait_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
186
187 const VkSemaphore timeline_semaphore = master_semaphore->Handle(); 181 const VkSemaphore timeline_semaphore = master_semaphore->Handle();
182
183 const u32 num_signal_semaphores = signal_semaphore ? 2U : 1U;
188 const std::array signal_values{signal_value, u64(0)}; 184 const std::array signal_values{signal_value, u64(0)};
189 const std::array signal_semaphores{timeline_semaphore, semaphore}; 185 const std::array signal_semaphores{timeline_semaphore, signal_semaphore};
186
187 const u32 num_wait_semaphores = wait_semaphore ? 2U : 1U;
188 const std::array wait_values{signal_value - 1, u64(1)};
189 const std::array wait_semaphores{timeline_semaphore, wait_semaphore};
190 static constexpr std::array<VkPipelineStageFlags, 2> wait_stage_masks{
191 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
192 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
193 };
190 194
191 const VkTimelineSemaphoreSubmitInfoKHR timeline_si{ 195 const VkTimelineSemaphoreSubmitInfoKHR timeline_si{
192 .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR, 196 .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,
193 .pNext = nullptr, 197 .pNext = nullptr,
194 .waitSemaphoreValueCount = 1, 198 .waitSemaphoreValueCount = num_wait_semaphores,
195 .pWaitSemaphoreValues = &wait_value, 199 .pWaitSemaphoreValues = wait_values.data(),
196 .signalSemaphoreValueCount = num_signal_semaphores, 200 .signalSemaphoreValueCount = num_signal_semaphores,
197 .pSignalSemaphoreValues = signal_values.data(), 201 .pSignalSemaphoreValues = signal_values.data(),
198 }; 202 };
199 const VkSubmitInfo submit_info{ 203 const VkSubmitInfo submit_info{
200 .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, 204 .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
201 .pNext = &timeline_si, 205 .pNext = &timeline_si,
202 .waitSemaphoreCount = 1, 206 .waitSemaphoreCount = num_wait_semaphores,
203 .pWaitSemaphores = &timeline_semaphore, 207 .pWaitSemaphores = wait_semaphores.data(),
204 .pWaitDstStageMask = &wait_stage_mask, 208 .pWaitDstStageMask = wait_stage_masks.data(),
205 .commandBufferCount = 1, 209 .commandBufferCount = 1,
206 .pCommandBuffers = cmdbuf.address(), 210 .pCommandBuffers = cmdbuf.address(),
207 .signalSemaphoreCount = num_signal_semaphores, 211 .signalSemaphoreCount = num_signal_semaphores,
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.h b/src/video_core/renderer_vulkan/vk_scheduler.h
index cf39a2363..759ed5a48 100644
--- a/src/video_core/renderer_vulkan/vk_scheduler.h
+++ b/src/video_core/renderer_vulkan/vk_scheduler.h
@@ -34,10 +34,10 @@ public:
34 ~VKScheduler(); 34 ~VKScheduler();
35 35
36 /// Sends the current execution context to the GPU. 36 /// Sends the current execution context to the GPU.
37 void Flush(VkSemaphore semaphore = nullptr); 37 void Flush(VkSemaphore signal_semaphore = nullptr, VkSemaphore wait_semaphore = nullptr);
38 38
39 /// Sends the current execution context to the GPU and waits for it to complete. 39 /// Sends the current execution context to the GPU and waits for it to complete.
40 void Finish(VkSemaphore semaphore = nullptr); 40 void Finish(VkSemaphore signal_semaphore = nullptr, VkSemaphore wait_semaphore = nullptr);
41 41
42 /// Waits for the worker thread to finish executing everything. After this function returns it's 42 /// Waits for the worker thread to finish executing everything. After this function returns it's
43 /// safe to touch worker resources. 43 /// safe to touch worker resources.
@@ -191,7 +191,7 @@ private:
191 191
192 void AllocateWorkerCommandBuffer(); 192 void AllocateWorkerCommandBuffer();
193 193
194 void SubmitExecution(VkSemaphore semaphore); 194 void SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore);
195 195
196 void AllocateNewContext(); 196 void AllocateNewContext();
197 197
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp
index d990eefba..71b12efe8 100644
--- a/src/video_core/renderer_vulkan/vk_swapchain.cpp
+++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp
@@ -107,14 +107,12 @@ void VKSwapchain::AcquireNextImage() {
107} 107}
108 108
109void VKSwapchain::Present(VkSemaphore render_semaphore) { 109void VKSwapchain::Present(VkSemaphore render_semaphore) {
110 const VkSemaphore present_semaphore{*present_semaphores[frame_index]};
111 const std::array<VkSemaphore, 2> semaphores{present_semaphore, render_semaphore};
112 const auto present_queue{device.GetPresentQueue()}; 110 const auto present_queue{device.GetPresentQueue()};
113 const VkPresentInfoKHR present_info{ 111 const VkPresentInfoKHR present_info{
114 .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, 112 .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
115 .pNext = nullptr, 113 .pNext = nullptr,
116 .waitSemaphoreCount = render_semaphore ? 2U : 1U, 114 .waitSemaphoreCount = render_semaphore ? 1U : 0U,
117 .pWaitSemaphores = semaphores.data(), 115 .pWaitSemaphores = &render_semaphore,
118 .swapchainCount = 1, 116 .swapchainCount = 1,
119 .pSwapchains = swapchain.address(), 117 .pSwapchains = swapchain.address(),
120 .pImageIndices = &image_index, 118 .pImageIndices = &image_index,
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.h b/src/video_core/renderer_vulkan/vk_swapchain.h
index 35c2cdc14..bbc8f07a8 100644
--- a/src/video_core/renderer_vulkan/vk_swapchain.h
+++ b/src/video_core/renderer_vulkan/vk_swapchain.h
@@ -72,6 +72,10 @@ public:
72 return image_format; 72 return image_format;
73 } 73 }
74 74
75 VkSemaphore CurrentPresentSemaphore() const {
76 return *present_semaphores[frame_index];
77 }
78
75private: 79private:
76 void CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height, 80 void CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height,
77 bool srgb); 81 bool srgb);