Manually wait semaphores on Intel Mesa
This commit is contained in:
@@ -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<u64, 2> 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<u64>::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,
|
||||
|
||||
@@ -85,6 +85,9 @@ private:
|
||||
std::vector<vk::Framebuffer> framebuffers;
|
||||
std::vector<u64> resource_ticks;
|
||||
std::vector<vk::Semaphore> present_semaphores;
|
||||
#if defined(__linux__)
|
||||
bool manually_wait_semaphores{};
|
||||
#endif
|
||||
|
||||
u32 image_index{};
|
||||
u32 frame_index{};
|
||||
|
||||
Reference in New Issue
Block a user