diff --git a/src/dxgi/dxgi_options.cpp b/src/dxgi/dxgi_options.cpp index 0881279a5..81cc887e5 100644 --- a/src/dxgi/dxgi_options.cpp +++ b/src/dxgi/dxgi_options.cpp @@ -91,6 +91,7 @@ namespace dxvk { this->maxSharedMemory = VkDeviceSize(config.getOption("dxgi.maxSharedMemory", 0)) << 20; this->maxFrameRate = config.getOption("dxgi.maxFrameRate", 0); + this->maxFrameLatency = config.getOption("dxgi.maxFrameLatency", 0); this->syncInterval = config.getOption("dxgi.syncInterval", -1); // Expose Nvidia GPUs properly if NvAPI is enabled in environment diff --git a/src/dxgi/dxgi_options.h b/src/dxgi/dxgi_options.h index 1cd170210..3f412e093 100644 --- a/src/dxgi/dxgi_options.h +++ b/src/dxgi/dxgi_options.h @@ -49,6 +49,9 @@ namespace dxvk { /// Limit frame rate int32_t maxFrameRate; + /// Control frame latency + int32_t maxFrameLatency; + /// Sync interval. Overrides the value /// passed to IDXGISwapChain::Present. int32_t syncInterval; diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 67e2a54cd..924be5a40 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -1003,7 +1003,11 @@ namespace dxvk { m_frameRateSyncInterval = SyncInterval; m_frameRateRefresh = 0.0f; - if (SyncInterval > 1 && wsi::isWindow(m_window)) { + // Frame latency control can only work on windowed or borderless swap + // chains if the presenter is aware of the display refresh rate + UINT minSyncInterval = (m_factory->GetOptions()->maxFrameLatency < 0 && !m_is_d3d12) ? 0 : 1; + + if (SyncInterval > minSyncInterval && wsi::isWindow(m_window)) { wsi::WsiMode mode = { }; if (wsi::getCurrentDisplayMode(wsi::getWindowMonitor(m_window), &mode)) {