From 1acd9d627cf109605582a1bec90df6ff129a1082 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Tue, 8 Jul 2025 21:09:34 +0900 Subject: [PATCH] Support tearing in VK swapchain --- src/Veldrid/Vk/VkGraphicsDevice.cs | 6 ++++++ src/Veldrid/Vk/VkSwapchain.cs | 31 +++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/Veldrid/Vk/VkGraphicsDevice.cs b/src/Veldrid/Vk/VkGraphicsDevice.cs index 7271e02b0..825da5fda 100644 --- a/src/Veldrid/Vk/VkGraphicsDevice.cs +++ b/src/Veldrid/Vk/VkGraphicsDevice.cs @@ -27,6 +27,12 @@ internal unsafe class VkGraphicsDevice : GraphicsDevice public override bool IsClipSpaceYInverted => !standardClipYDirection; + public override bool AllowTearing + { + get => mainSwapchain.AllowTearing; + set => mainSwapchain.AllowTearing = value; + } + public override Swapchain MainSwapchain => mainSwapchain; public override GraphicsDeviceFeatures Features { get; } diff --git a/src/Veldrid/Vk/VkSwapchain.cs b/src/Veldrid/Vk/VkSwapchain.cs index b92b4acf0..e4db95fc5 100644 --- a/src/Veldrid/Vk/VkSwapchain.cs +++ b/src/Veldrid/Vk/VkSwapchain.cs @@ -40,6 +40,22 @@ public override bool SyncToVerticalBlank } } + private bool allowTearing; + + public bool AllowTearing + { + get => allowTearing; + set + { + if (allowTearing == value) + return; + + allowTearing = value; + + recreateAndReacquire(framebuffer.Width, framebuffer.Height); + } + } + private readonly VkGraphicsDevice gd; private readonly VkSwapchainFramebuffer framebuffer; private readonly uint presentQueueIndex; @@ -203,14 +219,15 @@ private bool createSwapchain(uint width, uint height) if (syncToVBlank) { - if (presentModes.Contains(VkPresentModeKHR.FifoRelaxedKHR)) presentMode = VkPresentModeKHR.FifoRelaxedKHR; - } - else - { - if (presentModes.Contains(VkPresentModeKHR.MailboxKHR)) - presentMode = VkPresentModeKHR.MailboxKHR; - else if (presentModes.Contains(VkPresentModeKHR.ImmediateKHR)) presentMode = VkPresentModeKHR.ImmediateKHR; + if (presentModes.Contains(VkPresentModeKHR.FifoRelaxedKHR)) + presentMode = VkPresentModeKHR.FifoRelaxedKHR; } + else if (allowTearing && presentModes.Contains(VkPresentModeKHR.ImmediateKHR)) + presentMode = VkPresentModeKHR.ImmediateKHR; + else if (presentModes.Contains(VkPresentModeKHR.MailboxKHR)) + presentMode = VkPresentModeKHR.MailboxKHR; + else if (presentModes.Contains(VkPresentModeKHR.ImmediateKHR)) + presentMode = VkPresentModeKHR.ImmediateKHR; uint maxImageCount = surfaceCapabilities.maxImageCount == 0 ? uint.MaxValue : surfaceCapabilities.maxImageCount; uint imageCount = Math.Min(maxImageCount, surfaceCapabilities.minImageCount + 1);