From 3316003e3a8746b4abe65a99b516395eb82cae47 Mon Sep 17 00:00:00 2001 From: Ravbug Date: Sun, 15 Oct 2023 22:28:49 -0400 Subject: [PATCH] D3D12, Vk: API to toggle vsync via the swapchain --- include/RGL/Swapchain.hpp | 2 ++ src/D3D12Swapchain.cpp | 4 ++++ src/D3D12Swapchain.hpp | 4 +++- src/VkSwapchain.cpp | 28 ++++++++++++++++++++++------ src/VkSwapchain.hpp | 3 +++ 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/include/RGL/Swapchain.hpp b/include/RGL/Swapchain.hpp index 4c854db..cecf877 100644 --- a/include/RGL/Swapchain.hpp +++ b/include/RGL/Swapchain.hpp @@ -14,5 +14,7 @@ namespace RGL{ virtual void GetNextImage(uint32_t* index) = 0; virtual ITexture* ImageAtIndex(uint32_t index) = 0; virtual void Present(const SwapchainPresentConfig&) = 0; + + virtual void SetVsyncMode(bool mode) = 0; }; } diff --git a/src/D3D12Swapchain.cpp b/src/D3D12Swapchain.cpp index a2d05d7..1a1344c 100644 --- a/src/D3D12Swapchain.cpp +++ b/src/D3D12Swapchain.cpp @@ -193,6 +193,10 @@ namespace RGL { UINT presentFlags = (tearingSupported && !vsync) ? DXGI_PRESENT_ALLOW_TEARING : 0; swapchain->Present(syncInterval, presentFlags); } + void SwapchainD3D12::SetVsyncMode(bool mode) + { + vsync = mode; + } SwapchainD3D12::~SwapchainD3D12() { } diff --git a/src/D3D12Swapchain.hpp b/src/D3D12Swapchain.hpp index b9730dc..d3d5057 100644 --- a/src/D3D12Swapchain.hpp +++ b/src/D3D12Swapchain.hpp @@ -23,7 +23,6 @@ namespace RGL { D3D12DynamicDescriptorHeap::index_t rtvIndices[g_NumFrames]; bool tearingSupported = false; - bool vsync = true; bool initialized = false; SwapchainD3D12(decltype(owningDevice), std::shared_ptr, int width, int height, std::shared_ptr presentQueue); @@ -37,6 +36,9 @@ namespace RGL { void GetNextImage(uint32_t* index) final; ITexture* ImageAtIndex(uint32_t index) final; void Present(const SwapchainPresentConfig&) final; + void SetVsyncMode(bool mode) final; virtual ~SwapchainD3D12(); + private: + bool vsync = true; }; } \ No newline at end of file diff --git a/src/VkSwapchain.cpp b/src/VkSwapchain.cpp index 2c6d453..004df2c 100644 --- a/src/VkSwapchain.cpp +++ b/src/VkSwapchain.cpp @@ -40,14 +40,22 @@ void RGL::SwapchainVK::Resize(uint32_t width, uint32_t height) //otherwise hope the first one is good enough return availableFormats[0]; }; - constexpr auto chooseSwapPresentMode = [](const std::vector& availablePresentModes) -> VkPresentModeKHR { - for (const auto& availablePresentMode : availablePresentModes) { - if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) { - return availablePresentMode; // use Mailbox on high-perf devices + auto chooseSwapPresentMode = [this](const std::vector& availablePresentModes) -> VkPresentModeKHR { + if (vsync) { + // disabling this because apparently VK_PRESENT_MODE_MAILBOX_KHR is uncapped on some OS/driver combos +#if 0 + for (const auto& availablePresentMode : availablePresentModes) { + if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) { + return availablePresentMode; // use Mailbox on high-perf devices + } } - } +#endif - return VK_PRESENT_MODE_FIFO_KHR; // otherwise use FIFO when on low-power devices, like a mobile phone + return VK_PRESENT_MODE_FIFO_KHR; // otherwise use FIFO when on low-power devices, like a mobile phone + } + else { + return VK_PRESENT_MODE_IMMEDIATE_KHR; + } }; auto chooseSwapExtent = [width,height](const VkSurfaceCapabilitiesKHR& capabilities) ->VkExtent2D { if (capabilities.currentExtent.width != std::numeric_limits::max()) { @@ -181,6 +189,14 @@ void RGL::SwapchainVK::Present(const SwapchainPresentConfig& config) } } +void RGL::SwapchainVK::SetVsyncMode(bool mode) +{ + vsync = mode; + auto size = RGLTextureResources[0].GetSize(); + // re-create with the new queue present mode + Resize(size.width, size.height); +} + void RGL::SwapchainVK::DestroySwapchainIfNeeded() { diff --git a/src/VkSwapchain.hpp b/src/VkSwapchain.hpp index 153c282..f9f3d8c 100644 --- a/src/VkSwapchain.hpp +++ b/src/VkSwapchain.hpp @@ -28,7 +28,10 @@ namespace RGL { void Present(const SwapchainPresentConfig&) final; + void SetVsyncMode(bool mode) final; + private: + bool vsync = true; void DestroySwapchainIfNeeded(); }; } \ No newline at end of file