From f919ff65684f426fce6773f6bc93c2791898a9d1 Mon Sep 17 00:00:00 2001 From: yzct12345 <87620833+yzct12345@users.noreply.github.com> Date: Tue, 20 Jul 2021 19:49:14 +0000 Subject: [PATCH] Manually wait semaphores on Intel Mesa --- .../renderer_vulkan/vk_swapchain.cpp | 38 ++++++++++++++++++- src/video_core/renderer_vulkan/vk_swapchain.h | 3 ++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index dfd5c65ba0..9dde90933c 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp @@ -9,6 +9,7 @@ #include "common/assert.h" #include "common/logging/log.h" +#include "common/settings.h" #include "core/core.h" #include "core/frontend/framebuffer_layout.h" #include "video_core/renderer_vulkan/vk_scheduler.h" @@ -59,6 +60,15 @@ VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, u32 wi VKSwapchain::VKSwapchain(VkSurfaceKHR surface_, const Device& device_, VKScheduler& scheduler_, u32 width, u32 height, bool srgb) : surface{surface_}, device{device_}, scheduler{scheduler_} { +#if defined(__linux__) + if (device_.GetDriverID() == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA && + Settings::values.gpu_accuracy.GetValue() == Settings::GPUAccuracy::Normal || true) { + manually_wait_semaphores = true; + LOG_WARNING( + Render_Vulkan, + "Will manually wait for semaphores separately from present to avoid Intel Mesa device loss"); + } +#endif Create(width, height, srgb); } @@ -97,11 +107,35 @@ bool VKSwapchain::Present(VkSemaphore render_semaphore) { const auto present_queue{device.GetPresentQueue()}; bool recreated = false; + auto waitSemaphores = semaphores.data(); + u32 semaphoreCount = render_semaphore ? 2U : 1U; +#if defined(__linux__) + if (manually_wait_semaphores) { + waitSemaphores = nullptr; + semaphoreCount = 0; + + const std::array semaphore_values{0, 0}; + const VkSemaphoreWaitInfoKHR wait_info{ + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR, + .pNext = nullptr, + .flags = 0, + .semaphoreCount = render_semaphore ? 2U : 1U, + .pSemaphores = semaphores.data(), + .pValues = semaphore_values.data(), + }; + const VkResult waitres = device.GetDispatchLoader().vkWaitSemaphoresKHR( + *device.GetLogical(), &wait_info, std::numeric_limits::max()); + if (waitres != VK_SUCCESS) { + LOG_WARNING(Render_Vulkan, "Manual semaphore wait failed {}", waitres); + } + } +#endif + const VkPresentInfoKHR present_info{ .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, .pNext = nullptr, - .waitSemaphoreCount = render_semaphore ? 2U : 1U, - .pWaitSemaphores = semaphores.data(), + .waitSemaphoreCount = semaphoreCount, + .pWaitSemaphores = waitSemaphores, .swapchainCount = 1, .pSwapchains = swapchain.address(), .pImageIndices = &image_index, diff --git a/src/video_core/renderer_vulkan/vk_swapchain.h b/src/video_core/renderer_vulkan/vk_swapchain.h index adc8d27cfc..47201ca75b 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.h +++ b/src/video_core/renderer_vulkan/vk_swapchain.h @@ -85,6 +85,9 @@ private: std::vector framebuffers; std::vector resource_ticks; std::vector present_semaphores; +#if defined(__linux__) + bool manually_wait_semaphores{}; +#endif u32 image_index{}; u32 frame_index{};