diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index bc80f188..ac12849d 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -98,7 +98,8 @@ namespace dxvk { InitReturnPtr(ppvObject); if (riid == __uuidof(IUnknown) - || riid == __uuidof(IDXGIVkSwapChain)) { + || riid == __uuidof(IDXGIVkSwapChain) + || riid == __uuidof(IDXGIVkSwapChain1)) { *ppvObject = ref(this); return S_OK; } @@ -340,6 +341,19 @@ namespace dxvk { } + void STDMETHODCALLTYPE D3D11SwapChain::GetLastPresentCount( + UINT64* pLastPresentCount) { + *pLastPresentCount = UINT64(m_frameId - DXGI_MAX_SWAP_CHAIN_BUFFERS); + } + + + void STDMETHODCALLTYPE D3D11SwapChain::GetFrameStatistics( + DXGI_VK_FRAME_STATISTICS* pFrameStatistics) { + std::lock_guard lock(m_frameStatisticsLock); + *pFrameStatistics = m_frameStatistics; + } + + HRESULT D3D11SwapChain::PresentImage(UINT SyncInterval) { // Flush pending rendering commands before auto immediateContext = m_parent->GetContext(); @@ -645,11 +659,17 @@ namespace dxvk { // Wait for the sync event so that we respect the maximum frame latency m_frameLatencySignal->wait(m_frameId - GetActualFrameLatency()); - if (m_frameLatencyEvent) { - m_frameLatencySignal->setCallback(m_frameId, [cFrameLatencyEvent = m_frameLatencyEvent] () { + m_frameLatencySignal->setCallback(m_frameId, [this, + cFrameId = m_frameId, + cFrameLatencyEvent = m_frameLatencyEvent + ] () { + if (cFrameLatencyEvent) ReleaseSemaphore(cFrameLatencyEvent, 1, nullptr); - }); - } + + std::lock_guard lock(m_frameStatisticsLock); + m_frameStatistics.PresentCount = cFrameId - DXGI_MAX_SWAP_CHAIN_BUFFERS; + m_frameStatistics.PresentQPCTime = dxvk::high_resolution_clock::get_counter(); + }); } diff --git a/src/d3d11/d3d11_swapchain.h b/src/d3d11/d3d11_swapchain.h index 4ff3cde2..7467b85b 100644 --- a/src/d3d11/d3d11_swapchain.h +++ b/src/d3d11/d3d11_swapchain.h @@ -13,7 +13,7 @@ namespace dxvk { class D3D11Device; class D3D11DXGIDevice; - class D3D11SwapChain : public ComObject { + class D3D11SwapChain : public ComObject { constexpr static uint32_t DefaultFrameLatency = 1; public: @@ -80,6 +80,12 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE SetHDRMetaData( const DXGI_VK_HDR_METADATA* pMetaData); + void STDMETHODCALLTYPE GetLastPresentCount( + UINT64* pLastPresentCount); + + void STDMETHODCALLTYPE GetFrameStatistics( + DXGI_VK_FRAME_STATISTICS* pFrameStatistics); + private: enum BindingIds : uint32_t { @@ -125,6 +131,9 @@ namespace dxvk { std::optional m_hdrMetadata; bool m_dirtyHdrMetadata = true; + dxvk::mutex m_frameStatisticsLock; + DXGI_VK_FRAME_STATISTICS m_frameStatistics = { }; + HRESULT PresentImage(UINT SyncInterval); void SubmitPresent(