From 6e0ac7fa75fbd75471701a5e76ee76a6c2eee252 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin <stenzek@gmail.com> Date: Sat, 3 Sep 2022 14:55:12 +1000 Subject: [PATCH] HostDisplay: Make GL/D3D timestamp queries slightly less rubbish --- pcsx2/Frontend/D3D11HostDisplay.cpp | 21 ++++++++++++++------- pcsx2/Frontend/D3D11HostDisplay.h | 2 +- pcsx2/Frontend/OpenGLHostDisplay.cpp | 6 ++---- pcsx2/Frontend/OpenGLHostDisplay.h | 2 +- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/pcsx2/Frontend/D3D11HostDisplay.cpp b/pcsx2/Frontend/D3D11HostDisplay.cpp index dfbdaebc40..3521889f23 100644 --- a/pcsx2/Frontend/D3D11HostDisplay.cpp +++ b/pcsx2/Frontend/D3D11HostDisplay.cpp @@ -677,6 +677,13 @@ bool D3D11HostDisplay::BeginPresent(bool frame_skip) return false; } + // When using vsync, the time here seems to include the time for the buffer to become available. + // This blows our our GPU usage number considerably, so read the timestamp before the final blit + // in this configuration. It does reduce accuracy a little, but better than seeing 100% all of + // the time, when it's more like a couple of percent. + if (m_vsync_mode != VsyncMode::Off && m_gpu_timing_enabled) + PopTimestampQuery(); + static constexpr std::array<float, 4> clear_color = {}; m_context->ClearRenderTargetView(m_swap_chain_rtv.get(), clear_color.data()); m_context->OMSetRenderTargets(1, m_swap_chain_rtv.addressof(), nullptr); @@ -693,14 +700,15 @@ void D3D11HostDisplay::EndPresent() ImGui::Render(); ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); - if (m_gpu_timing_enabled) + // See note in BeginPresent() for why it's conditional on vsync-off. + const bool vsync_on = m_vsync_mode != VsyncMode::Off; + if (!vsync_on && m_gpu_timing_enabled) PopTimestampQuery(); - const UINT vsync_rate = static_cast<UINT>(m_vsync_mode != VsyncMode::Off); - if (vsync_rate == 0 && m_using_allow_tearing) + if (!vsync_on && m_using_allow_tearing) m_swap_chain->Present(0, DXGI_PRESENT_ALLOW_TEARING); else - m_swap_chain->Present(vsync_rate, 0); + m_swap_chain->Present(static_cast<UINT>(vsync_on), 0); if (m_gpu_timing_enabled) KickTimestampQuery(); @@ -772,8 +780,7 @@ void D3D11HostDisplay::PopTimestampQuery() } } - // delay ending the current query until we've read back some - if (m_timestamp_query_started && m_waiting_timestamp_queries < (NUM_TIMESTAMP_QUERIES - 1)) + if (m_timestamp_query_started) { m_context->End(m_timestamp_queries[m_write_timestamp_query][2].get()); m_context->End(m_timestamp_queries[m_write_timestamp_query][0].get()); @@ -785,7 +792,7 @@ void D3D11HostDisplay::PopTimestampQuery() void D3D11HostDisplay::KickTimestampQuery() { - if (m_timestamp_query_started || !m_timestamp_queries[0][0]) + if (m_timestamp_query_started || !m_timestamp_queries[0][0] || m_waiting_timestamp_queries == NUM_TIMESTAMP_QUERIES) return; m_context->Begin(m_timestamp_queries[m_write_timestamp_query][0].get()); diff --git a/pcsx2/Frontend/D3D11HostDisplay.h b/pcsx2/Frontend/D3D11HostDisplay.h index 9fe660d901..ea3e982658 100644 --- a/pcsx2/Frontend/D3D11HostDisplay.h +++ b/pcsx2/Frontend/D3D11HostDisplay.h @@ -75,7 +75,7 @@ public: protected: static constexpr u32 DISPLAY_CONSTANT_BUFFER_SIZE = 16; - static constexpr u8 NUM_TIMESTAMP_QUERIES = 3; + static constexpr u8 NUM_TIMESTAMP_QUERIES = 5; static AdapterAndModeList GetAdapterAndModeList(IDXGIFactory* dxgi_factory); diff --git a/pcsx2/Frontend/OpenGLHostDisplay.cpp b/pcsx2/Frontend/OpenGLHostDisplay.cpp index 80bc5cf3de..b37d428cfd 100644 --- a/pcsx2/Frontend/OpenGLHostDisplay.cpp +++ b/pcsx2/Frontend/OpenGLHostDisplay.cpp @@ -440,7 +440,6 @@ void OpenGLHostDisplay::PopTimestampQuery() GLint available = 0; GetQueryObjectiv(m_timestamp_queries[m_read_timestamp_query], GL_QUERY_RESULT_AVAILABLE, &available); - pxAssert(m_read_timestamp_query != m_write_timestamp_query); if (!available) break; @@ -452,8 +451,7 @@ void OpenGLHostDisplay::PopTimestampQuery() m_waiting_timestamp_queries--; } - // delay ending the current query until we've read back some - if (m_timestamp_query_started && m_waiting_timestamp_queries < (NUM_TIMESTAMP_QUERIES - 1)) + if (m_timestamp_query_started) { const auto EndQuery = gles ? glEndQueryEXT : glEndQuery; EndQuery(GL_TIME_ELAPSED); @@ -466,7 +464,7 @@ void OpenGLHostDisplay::PopTimestampQuery() void OpenGLHostDisplay::KickTimestampQuery() { - if (m_timestamp_query_started) + if (m_timestamp_query_started || m_waiting_timestamp_queries == NUM_TIMESTAMP_QUERIES) return; const bool gles = m_gl_context->IsGLES(); diff --git a/pcsx2/Frontend/OpenGLHostDisplay.h b/pcsx2/Frontend/OpenGLHostDisplay.h index c87146b05b..2af6683648 100644 --- a/pcsx2/Frontend/OpenGLHostDisplay.h +++ b/pcsx2/Frontend/OpenGLHostDisplay.h @@ -65,7 +65,7 @@ public: float GetAndResetAccumulatedGPUTime() override; protected: - static constexpr u8 NUM_TIMESTAMP_QUERIES = 3; + static constexpr u8 NUM_TIMESTAMP_QUERIES = 5; const char* GetGLSLVersionString() const; std::string GetGLSLVersionHeader() const;