diff options
author | Joshua Ashton <joshua@froggi.es> | 2021-05-20 16:30:15 +0300 |
---|---|---|
committer | Joshua Ashton <joshua@froggi.es> | 2021-05-20 16:30:15 +0300 |
commit | eac94823c82b77530ea2991c83f05dc81711c3e5 (patch) | |
tree | a15a9db465e7e6e18602d37fb22c7a0ad0df9d7d | |
parent | a3d169982395d9e5ff6f71d304651203adcfc86e (diff) |
[dxgi] WIP frame timing implframe-stats-stuff
rough
-rw-r--r-- | src/dxgi/dxgi_interfaces.h | 1 | ||||
-rw-r--r-- | src/dxgi/dxgi_output.cpp | 25 | ||||
-rw-r--r-- | src/dxgi/dxgi_output.h | 3 | ||||
-rw-r--r-- | src/dxgi/dxgi_swapchain.cpp | 30 | ||||
-rw-r--r-- | src/dxgi/dxgi_swapchain.h | 4 |
5 files changed, 44 insertions, 19 deletions
diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index 427f3976..3c4ab8dc 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -22,7 +22,6 @@ struct IDXGIVkInteropDevice; */ struct DXGI_VK_MONITOR_DATA { dxvk::DxgiSwapChain* pSwapChain; - DXGI_FRAME_STATISTICS FrameStats; DXGI_GAMMA_CONTROL GammaCurve; }; diff --git a/src/dxgi/dxgi_output.cpp b/src/dxgi/dxgi_output.cpp index bee7c493..70a169cd 100644 --- a/src/dxgi/dxgi_output.cpp +++ b/src/dxgi/dxgi_output.cpp @@ -13,6 +13,7 @@ #include "dxgi_swapchain.h" #include "../dxvk/dxvk_format.h" +#include "../util/util_time.h" namespace dxvk { @@ -26,10 +27,13 @@ namespace dxvk { // Init monitor info if necessary DXGI_VK_MONITOR_DATA monitorData; monitorData.pSwapChain = nullptr; - monitorData.FrameStats = DXGI_FRAME_STATISTICS(); monitorData.GammaCurve.Scale = { 1.0f, 1.0f, 1.0f }; monitorData.GammaCurve.Offset = { 0.0f, 0.0f, 0.0f }; + m_startQPC = dxvk::high_resolution_clock::getCounter(); + // TODO: We should get the refresh rate of the output and update it when that changes. + m_frameQPF = dxvk::high_resolution_clock::getFrequency() * 60; + for (uint32_t i = 0; i < DXGI_VK_GAMMA_CP_COUNT; i++) { const float value = GammaControlPointLocation(i); monitorData.GammaCurve.GammaCurve[i] = { value, value, value }; @@ -368,14 +372,19 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DxgiOutput::GetFrameStatistics(DXGI_FRAME_STATISTICS* pStats) { - DXGI_VK_MONITOR_DATA* monitorInfo = nullptr; - HRESULT hr = m_monitorInfo->AcquireMonitorData(m_monitor, &monitorInfo); + if (pStats == nullptr) + return E_INVALIDARG; - if (FAILED(hr)) - return hr; - - *pStats = monitorInfo->FrameStats; - m_monitorInfo->ReleaseMonitorData(); + int64_t qpc = dxvk::high_resolution_clock::getCounter(); + + // Good enough to pretend this is when we're presenting. + UINT presentCount = UINT((qpc - m_startQPC) / m_frameQPF); + + pStats->PresentCount = presentCount; + pStats->PresentRefreshCount = presentCount; + pStats->SyncRefreshCount = presentCount; + pStats->SyncQPCTime.QuadPart = qpc; + pStats->SyncGPUTime.QuadPart = 0; return S_OK; } diff --git a/src/dxgi/dxgi_output.h b/src/dxgi/dxgi_output.h index 0dc30868..23531cad 100644 --- a/src/dxgi/dxgi_output.h +++ b/src/dxgi/dxgi_output.h @@ -133,6 +133,9 @@ namespace dxvk { Com<DxgiAdapter> m_adapter = nullptr; HMONITOR m_monitor = nullptr; + int64_t m_startQPC; + int64_t m_frameQPF; + static void FilterModesByDesc( std::vector<DXGI_MODE_DESC1>& Modes, const DXGI_MODE_DESC1& TargetMode); diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 4d90fa6f..567e6406 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -2,6 +2,8 @@ #include "dxgi_output.h" #include "dxgi_swapchain.h" +#include "../util/util_time.h" + namespace dxvk { DxgiSwapChain::DxgiSwapChain( @@ -16,12 +18,10 @@ namespace dxvk { m_descFs (*pFullscreenDesc), m_presenter (pPresenter), m_monitor (nullptr) { - // Initialize frame statistics - m_stats.PresentCount = 0; - m_stats.PresentRefreshCount = 0; - m_stats.SyncRefreshCount = 0; - m_stats.SyncQPCTime.QuadPart = 0; - m_stats.SyncGPUTime.QuadPart = 0; + // For frame statistics + m_startQPC = dxvk::high_resolution_clock::getCounter(); + // TODO: We should get the refresh rate of the fullscreen mode or the output and update it when that changes + m_frameQPF = dxvk::high_resolution_clock::getFrequency() * 60; if (FAILED(m_presenter->GetAdapter(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&m_adapter)))) throw DxvkError("DXGI: Failed to get adapter for present device"); @@ -174,7 +174,16 @@ namespace dxvk { if (pStats == nullptr) return E_INVALIDARG; - *pStats = m_stats; + int64_t qpc = dxvk::high_resolution_clock::getCounter(); + + // Good enough to pretend this is when we're presenting. + UINT presentCount = UINT((qpc - m_startQPC) / m_frameQPF); + + pStats->PresentCount = presentCount; + pStats->PresentRefreshCount = presentCount; + pStats->SyncRefreshCount = presentCount; + pStats->SyncQPCTime.QuadPart = qpc; + pStats->SyncGPUTime.QuadPart = 0; return S_OK; } @@ -227,8 +236,11 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DxgiSwapChain::GetLastPresentCount(UINT* pLastPresentCount) { if (pLastPresentCount == nullptr) return E_INVALIDARG; - - *pLastPresentCount = m_stats.PresentCount; + + int64_t qpc = dxvk::high_resolution_clock::getCounter(); + + // Good enough to pretend this is when we're presenting. + *pLastPresentCount = UINT((qpc - m_startQPC) / m_frameQPF); return S_OK; } diff --git a/src/dxgi/dxgi_swapchain.h b/src/dxgi/dxgi_swapchain.h index b39ff6f4..ee0665cd 100644 --- a/src/dxgi/dxgi_swapchain.h +++ b/src/dxgi/dxgi_swapchain.h @@ -184,7 +184,9 @@ namespace dxvk { HWND m_window; DXGI_SWAP_CHAIN_DESC1 m_desc; DXGI_SWAP_CHAIN_FULLSCREEN_DESC m_descFs; - DXGI_FRAME_STATISTICS m_stats; + + int64_t m_startQPC; + int64_t m_frameQPF; Com<IDXGIVkSwapChain> m_presenter; |