summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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);