HostDisplay: Make GL/D3D timestamp queries slightly less rubbish

This commit is contained in:
Connor McLaughlin 2022-09-03 14:55:12 +10:00 committed by refractionpcsx2
parent 800aca6f0f
commit 6e0ac7fa75
4 changed files with 18 additions and 13 deletions

View File

@ -677,6 +677,13 @@ bool D3D11HostDisplay::BeginPresent(bool frame_skip)
return false; 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 = {}; static constexpr std::array<float, 4> clear_color = {};
m_context->ClearRenderTargetView(m_swap_chain_rtv.get(), clear_color.data()); m_context->ClearRenderTargetView(m_swap_chain_rtv.get(), clear_color.data());
m_context->OMSetRenderTargets(1, m_swap_chain_rtv.addressof(), nullptr); m_context->OMSetRenderTargets(1, m_swap_chain_rtv.addressof(), nullptr);
@ -693,14 +700,15 @@ void D3D11HostDisplay::EndPresent()
ImGui::Render(); ImGui::Render();
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); 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(); PopTimestampQuery();
const UINT vsync_rate = static_cast<UINT>(m_vsync_mode != VsyncMode::Off); if (!vsync_on && m_using_allow_tearing)
if (vsync_rate == 0 && m_using_allow_tearing)
m_swap_chain->Present(0, DXGI_PRESENT_ALLOW_TEARING); m_swap_chain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
else else
m_swap_chain->Present(vsync_rate, 0); m_swap_chain->Present(static_cast<UINT>(vsync_on), 0);
if (m_gpu_timing_enabled) if (m_gpu_timing_enabled)
KickTimestampQuery(); KickTimestampQuery();
@ -772,8 +780,7 @@ void D3D11HostDisplay::PopTimestampQuery()
} }
} }
// delay ending the current query until we've read back some if (m_timestamp_query_started)
if (m_timestamp_query_started && m_waiting_timestamp_queries < (NUM_TIMESTAMP_QUERIES - 1))
{ {
m_context->End(m_timestamp_queries[m_write_timestamp_query][2].get()); m_context->End(m_timestamp_queries[m_write_timestamp_query][2].get());
m_context->End(m_timestamp_queries[m_write_timestamp_query][0].get()); m_context->End(m_timestamp_queries[m_write_timestamp_query][0].get());
@ -785,7 +792,7 @@ void D3D11HostDisplay::PopTimestampQuery()
void D3D11HostDisplay::KickTimestampQuery() 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; return;
m_context->Begin(m_timestamp_queries[m_write_timestamp_query][0].get()); m_context->Begin(m_timestamp_queries[m_write_timestamp_query][0].get());

View File

@ -75,7 +75,7 @@ public:
protected: protected:
static constexpr u32 DISPLAY_CONSTANT_BUFFER_SIZE = 16; 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); static AdapterAndModeList GetAdapterAndModeList(IDXGIFactory* dxgi_factory);

View File

@ -440,7 +440,6 @@ void OpenGLHostDisplay::PopTimestampQuery()
GLint available = 0; GLint available = 0;
GetQueryObjectiv(m_timestamp_queries[m_read_timestamp_query], GL_QUERY_RESULT_AVAILABLE, &available); GetQueryObjectiv(m_timestamp_queries[m_read_timestamp_query], GL_QUERY_RESULT_AVAILABLE, &available);
pxAssert(m_read_timestamp_query != m_write_timestamp_query);
if (!available) if (!available)
break; break;
@ -452,8 +451,7 @@ void OpenGLHostDisplay::PopTimestampQuery()
m_waiting_timestamp_queries--; m_waiting_timestamp_queries--;
} }
// delay ending the current query until we've read back some if (m_timestamp_query_started)
if (m_timestamp_query_started && m_waiting_timestamp_queries < (NUM_TIMESTAMP_QUERIES - 1))
{ {
const auto EndQuery = gles ? glEndQueryEXT : glEndQuery; const auto EndQuery = gles ? glEndQueryEXT : glEndQuery;
EndQuery(GL_TIME_ELAPSED); EndQuery(GL_TIME_ELAPSED);
@ -466,7 +464,7 @@ void OpenGLHostDisplay::PopTimestampQuery()
void OpenGLHostDisplay::KickTimestampQuery() void OpenGLHostDisplay::KickTimestampQuery()
{ {
if (m_timestamp_query_started) if (m_timestamp_query_started || m_waiting_timestamp_queries == NUM_TIMESTAMP_QUERIES)
return; return;
const bool gles = m_gl_context->IsGLES(); const bool gles = m_gl_context->IsGLES();

View File

@ -65,7 +65,7 @@ public:
float GetAndResetAccumulatedGPUTime() override; float GetAndResetAccumulatedGPUTime() override;
protected: protected:
static constexpr u8 NUM_TIMESTAMP_QUERIES = 3; static constexpr u8 NUM_TIMESTAMP_QUERIES = 5;
const char* GetGLSLVersionString() const; const char* GetGLSLVersionString() const;
std::string GetGLSLVersionHeader() const; std::string GetGLSLVersionHeader() const;