From 27427f795094b855423aa5a6f90e6e5e25365bbb Mon Sep 17 00:00:00 2001 From: Skyth <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Wed, 25 Dec 2024 13:06:08 +0300 Subject: [PATCH] Make max frame latency configurable. --- UnleashedRecomp/gpu/rhi/plume_d3d12.cpp | 9 +++++---- UnleashedRecomp/gpu/rhi/plume_d3d12.h | 5 +++-- UnleashedRecomp/gpu/rhi/plume_render_interface.h | 2 +- UnleashedRecomp/gpu/rhi/plume_vulkan.cpp | 12 ++++++------ UnleashedRecomp/gpu/rhi/plume_vulkan.h | 5 +++-- UnleashedRecomp/gpu/video.cpp | 2 +- UnleashedRecomp/user/config.h | 3 ++- 7 files changed, 21 insertions(+), 17 deletions(-) diff --git a/UnleashedRecomp/gpu/rhi/plume_d3d12.cpp b/UnleashedRecomp/gpu/rhi/plume_d3d12.cpp index 808ac658..336ef6b2 100644 --- a/UnleashedRecomp/gpu/rhi/plume_d3d12.cpp +++ b/UnleashedRecomp/gpu/rhi/plume_d3d12.cpp @@ -1191,7 +1191,7 @@ namespace plume { // D3D12SwapChain - D3D12SwapChain::D3D12SwapChain(D3D12CommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format) { + D3D12SwapChain::D3D12SwapChain(D3D12CommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency) { assert(commandQueue != nullptr); assert(renderWindow != 0); @@ -1199,6 +1199,7 @@ namespace plume { this->renderWindow = renderWindow; this->textureCount = textureCount; this->format = format; + this->maxFrameLatency = maxFrameLatency; // Store the native format representation. nativeFormat = toDXGI(format); @@ -1230,7 +1231,7 @@ namespace plume { } d3d = static_cast(swapChain1); - d3d->SetMaximumFrameLatency(2); + d3d->SetMaximumFrameLatency(maxFrameLatency); waitableObject = d3d->GetFrameLatencyWaitableObject(); textures.resize(textureCount); @@ -2199,8 +2200,8 @@ namespace plume { } } - std::unique_ptr D3D12CommandQueue::createSwapChain(RenderWindow renderWindow, uint32_t bufferCount, RenderFormat format) { - return std::make_unique(this, renderWindow, bufferCount, format); + std::unique_ptr D3D12CommandQueue::createSwapChain(RenderWindow renderWindow, uint32_t bufferCount, RenderFormat format, uint32_t maxFrameLatency) { + return std::make_unique(this, renderWindow, bufferCount, format, maxFrameLatency); } void D3D12CommandQueue::executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount, RenderCommandSemaphore **signalSemaphores, uint32_t signalSemaphoreCount, RenderCommandFence *signalFence) { diff --git a/UnleashedRecomp/gpu/rhi/plume_d3d12.h b/UnleashedRecomp/gpu/rhi/plume_d3d12.h index c1a160c5..bc1b4ea9 100644 --- a/UnleashedRecomp/gpu/rhi/plume_d3d12.h +++ b/UnleashedRecomp/gpu/rhi/plume_d3d12.h @@ -107,8 +107,9 @@ namespace plume { uint32_t height = 0; uint32_t refreshRate = 0; bool vsyncEnabled = true; + uint32_t maxFrameLatency = 0; - D3D12SwapChain(D3D12CommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format); + D3D12SwapChain(D3D12CommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency); ~D3D12SwapChain() override; bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) override; void wait() override; @@ -231,7 +232,7 @@ namespace plume { D3D12CommandQueue(D3D12Device *device, RenderCommandListType type); ~D3D12CommandQueue() override; - std::unique_ptr createSwapChain(RenderWindow renderWindow, uint32_t textureCount, RenderFormat format) override; + std::unique_ptr createSwapChain(RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t newFrameLatency) override; void executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount, RenderCommandSemaphore **signalSemaphores, uint32_t signalSemaphoreCount, RenderCommandFence *signalFence) override; void waitForCommandFence(RenderCommandFence *fence) override; }; diff --git a/UnleashedRecomp/gpu/rhi/plume_render_interface.h b/UnleashedRecomp/gpu/rhi/plume_render_interface.h index bc09e6fb..45b382ae 100644 --- a/UnleashedRecomp/gpu/rhi/plume_render_interface.h +++ b/UnleashedRecomp/gpu/rhi/plume_render_interface.h @@ -191,7 +191,7 @@ namespace plume { struct RenderCommandQueue { virtual ~RenderCommandQueue() { } - virtual std::unique_ptr createSwapChain(RenderWindow renderWindow, uint32_t textureCount, RenderFormat format) = 0; + virtual std::unique_ptr createSwapChain(RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency) = 0; virtual void executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores = nullptr, uint32_t waitSemaphoreCount = 0, RenderCommandSemaphore **signalSemaphores = nullptr, uint32_t signalSemaphoreCount = 0, RenderCommandFence *signalFence = nullptr) = 0; virtual void waitForCommandFence(RenderCommandFence *fence) = 0; diff --git a/UnleashedRecomp/gpu/rhi/plume_vulkan.cpp b/UnleashedRecomp/gpu/rhi/plume_vulkan.cpp index 7e10ae9a..b6b18f2b 100644 --- a/UnleashedRecomp/gpu/rhi/plume_vulkan.cpp +++ b/UnleashedRecomp/gpu/rhi/plume_vulkan.cpp @@ -1966,13 +1966,14 @@ namespace plume { // VulkanSwapChain - VulkanSwapChain::VulkanSwapChain(VulkanCommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format) { + VulkanSwapChain::VulkanSwapChain(VulkanCommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency) { assert(commandQueue != nullptr); assert(textureCount > 0); this->commandQueue = commandQueue; this->renderWindow = renderWindow; this->format = format; + this->maxFrameLatency = maxFrameLatency; VkResult res; @@ -2170,10 +2171,9 @@ namespace plume { } void VulkanSwapChain::wait() { - constexpr uint64_t MaxFrameDelay = 1; - if (commandQueue->device->capabilities.presentWait && (currentPresentId > MaxFrameDelay)) { + if (commandQueue->device->capabilities.presentWait && (currentPresentId >= maxFrameLatency)) { constexpr uint64_t waitTimeout = 100000000; - vkWaitForPresentKHR(commandQueue->device->vk, vk, currentPresentId - MaxFrameDelay, waitTimeout); + vkWaitForPresentKHR(commandQueue->device->vk, vk, currentPresentId - (maxFrameLatency - 1), waitTimeout); } } @@ -3276,8 +3276,8 @@ namespace plume { device->queueFamilies[familyIndex].remove(this); } - std::unique_ptr VulkanCommandQueue::createSwapChain(RenderWindow renderWindow, uint32_t bufferCount, RenderFormat format) { - return std::make_unique(this, renderWindow, bufferCount, format); + std::unique_ptr VulkanCommandQueue::createSwapChain(RenderWindow renderWindow, uint32_t bufferCount, RenderFormat format, uint32_t maxFrameLatency) { + return std::make_unique(this, renderWindow, bufferCount, format, maxFrameLatency); } void VulkanCommandQueue::executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount, RenderCommandSemaphore **signalSemaphores, uint32_t signalSemaphoreCount, RenderCommandFence *signalFence) { diff --git a/UnleashedRecomp/gpu/rhi/plume_vulkan.h b/UnleashedRecomp/gpu/rhi/plume_vulkan.h index 1e1d18d3..c4184a4d 100644 --- a/UnleashedRecomp/gpu/rhi/plume_vulkan.h +++ b/UnleashedRecomp/gpu/rhi/plume_vulkan.h @@ -231,8 +231,9 @@ namespace plume { std::vector textures; uint64_t currentPresentId = 0; bool immediatePresentModeSupported = false; + uint32_t maxFrameLatency = 0; - VulkanSwapChain(VulkanCommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format); + VulkanSwapChain(VulkanCommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency); ~VulkanSwapChain() override; bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) override; void wait() override; @@ -347,7 +348,7 @@ namespace plume { VulkanCommandQueue(VulkanDevice *device, RenderCommandListType commandListType); ~VulkanCommandQueue() override; - std::unique_ptr createSwapChain(RenderWindow renderWindow, uint32_t bufferCount, RenderFormat format) override; + std::unique_ptr createSwapChain(RenderWindow renderWindow, uint32_t bufferCount, RenderFormat format, uint32_t maxFrameLatency) override; void executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount, RenderCommandSemaphore **signalSemaphores, uint32_t signalSemaphoreCount, RenderCommandFence *signalFence) override; void waitForCommandFence(RenderCommandFence *fence) override; }; diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 32b5bc5a..801dec6a 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -1464,7 +1464,7 @@ void Video::CreateHostDevice(const char *sdlVideoDriver) break; } - g_swapChain = g_queue->createSwapChain(GameWindow::s_renderWindow, bufferCount, BACKBUFFER_FORMAT); + g_swapChain = g_queue->createSwapChain(GameWindow::s_renderWindow, bufferCount, BACKBUFFER_FORMAT, Config::MaxFrameLatency); g_swapChain->setVsyncEnabled(Config::VSync); g_swapChainValid = !g_swapChain->needsResize(); diff --git a/UnleashedRecomp/user/config.h b/UnleashedRecomp/user/config.h index f2c173ef..30a251db 100644 --- a/UnleashedRecomp/user/config.h +++ b/UnleashedRecomp/user/config.h @@ -647,10 +647,11 @@ public: CONFIG_DEFINE_LOCALISED("Video", bool, VSync, true); CONFIG_DEFINE_ENUM("Video", ETripleBuffering, TripleBuffering, ETripleBuffering::Auto); CONFIG_DEFINE_LOCALISED("Video", int32_t, FPS, 60); + CONFIG_DEFINE("Video", uint32_t, MaxFrameLatency, 2); CONFIG_DEFINE_LOCALISED("Video", float, Brightness, 0.5f); CONFIG_DEFINE_ENUM_LOCALISED("Video", EAntiAliasing, AntiAliasing, EAntiAliasing::MSAA4x); CONFIG_DEFINE_LOCALISED("Video", bool, TransparencyAntiAliasing, true); - CONFIG_DEFINE("Video", size_t, AnisotropicFiltering, 16); + CONFIG_DEFINE("Video", uint32_t, AnisotropicFiltering, 16); CONFIG_DEFINE_ENUM_LOCALISED("Video", EShadowResolution, ShadowResolution, EShadowResolution::x4096); CONFIG_DEFINE_ENUM_LOCALISED("Video", EGITextureFiltering, GITextureFiltering, EGITextureFiltering::Bicubic); CONFIG_DEFINE_ENUM("Video", EDepthOfFieldQuality, DepthOfFieldQuality, EDepthOfFieldQuality::Auto);