Improve PerfQuery accuracy

In TimeSplitters: Future Perfect, PerfQuery is used to detect
the visibility of lights and draw coronas. 25 points are drawn
for each light. However, the returned count was incorrectly
being divided by four leading to dim coronas.

Using 4x antialiasing was a workaround because of a bug where
antialiasing multiplied the PerfQuery results. This commit
fixes that bug too (but only for OpenGL).
This commit is contained in:
hthh 2016-06-13 15:41:29 +10:00
parent f8bf839e36
commit 8be5717a60
3 changed files with 24 additions and 7 deletions

View File

@ -86,7 +86,7 @@ u32 PerfQuery::GetQueryResult(PerfQueryType type)
else if (type == PQ_EFB_COPY_CLOCKS) else if (type == PQ_EFB_COPY_CLOCKS)
result = m_results[PQG_EFB_COPY_CLOCKS]; result = m_results[PQG_EFB_COPY_CLOCKS];
return result / 4; return result;
} }
void PerfQuery::FlushOne() void PerfQuery::FlushOne()
@ -102,6 +102,8 @@ void PerfQuery::FlushOne()
} }
// NOTE: Reported pixel metrics should be referenced to native resolution // NOTE: Reported pixel metrics should be referenced to native resolution
// TODO: Dropping the lower 2 bits from this count should be closer to actual
// hardware behavior when drawing triangles.
m_results[entry.query_type] += (u32)(result * EFB_WIDTH / g_renderer->GetTargetWidth() * m_results[entry.query_type] += (u32)(result * EFB_WIDTH / g_renderer->GetTargetWidth() *
EFB_HEIGHT / g_renderer->GetTargetHeight()); EFB_HEIGHT / g_renderer->GetTargetHeight());

View File

@ -98,7 +98,7 @@ u32 PerfQuery::GetQueryResult(PerfQueryType type)
else if (type == PQ_EFB_COPY_CLOCKS) else if (type == PQ_EFB_COPY_CLOCKS)
result = m_results[PQG_EFB_COPY_CLOCKS]; result = m_results[PQG_EFB_COPY_CLOCKS];
return result / 4; return result;
} }
void PerfQuery::FlushOne() void PerfQuery::FlushOne()
@ -126,6 +126,8 @@ void PerfQuery::FlushOne()
m_query_readback_buffer->Unmap(0, &write_range); m_query_readback_buffer->Unmap(0, &write_range);
// NOTE: Reported pixel metrics should be referenced to native resolution // NOTE: Reported pixel metrics should be referenced to native resolution
// TODO: Dropping the lower 2 bits from this count should be closer to actual
// hardware behavior when drawing triangles.
m_results[entry.query_type] += (u32)(result * EFB_WIDTH / g_renderer->GetTargetWidth() * m_results[entry.query_type] += (u32)(result * EFB_WIDTH / g_renderer->GetTargetWidth() *
EFB_HEIGHT / g_renderer->GetTargetHeight()); EFB_HEIGHT / g_renderer->GetTargetHeight());
@ -179,6 +181,8 @@ void PerfQuery::FlushResults()
sizeof(UINT64)); sizeof(UINT64));
// NOTE: Reported pixel metrics should be referenced to native resolution // NOTE: Reported pixel metrics should be referenced to native resolution
// TODO: Dropping the lower 2 bits from this count should be closer to actual
// hardware behavior when drawing triangles.
m_results[entry.query_type] += (u32)(result * EFB_WIDTH / g_renderer->GetTargetWidth() * m_results[entry.query_type] += (u32)(result * EFB_WIDTH / g_renderer->GetTargetWidth() *
EFB_HEIGHT / g_renderer->GetTargetHeight()); EFB_HEIGHT / g_renderer->GetTargetHeight());

View File

@ -11,6 +11,7 @@
#include "VideoBackends/OGL/PerfQuery.h" #include "VideoBackends/OGL/PerfQuery.h"
#include "VideoCommon/RenderBase.h" #include "VideoCommon/RenderBase.h"
#include "VideoCommon/VideoConfig.h"
namespace OGL namespace OGL
{ {
@ -79,7 +80,7 @@ u32 PerfQuery::GetQueryResult(PerfQueryType type)
result = m_results[PQG_EFB_COPY_CLOCKS]; result = m_results[PQG_EFB_COPY_CLOCKS];
} }
return result / 4; return result;
} }
// Implementations // Implementations
@ -155,8 +156,16 @@ void PerfQueryGL::FlushOne()
glGetQueryObjectuiv(entry.query_id, GL_QUERY_RESULT, &result); glGetQueryObjectuiv(entry.query_id, GL_QUERY_RESULT, &result);
// NOTE: Reported pixel metrics should be referenced to native resolution // NOTE: Reported pixel metrics should be referenced to native resolution
m_results[entry.query_type] += (u64)result * EFB_WIDTH / g_renderer->GetTargetWidth() * // TODO: Dropping the lower 2 bits from this count should be closer to actual
EFB_HEIGHT / g_renderer->GetTargetHeight(); // hardware behavior when drawing triangles.
result = static_cast<u64>(result) * EFB_WIDTH * EFB_HEIGHT /
(g_renderer->GetTargetWidth() * g_renderer->GetTargetHeight());
// Adjust for multisampling
if (g_ActiveConfig.iMultisamples > 1)
result /= g_ActiveConfig.iMultisamples;
m_results[entry.query_type] += result;
m_query_read_pos = (m_query_read_pos + 1) % m_query_buffer.size(); m_query_read_pos = (m_query_read_pos + 1) % m_query_buffer.size();
--m_query_count; --m_query_count;
@ -241,8 +250,10 @@ void PerfQueryGLESNV::FlushOne()
glGetOcclusionQueryuivNV(entry.query_id, GL_OCCLUSION_TEST_RESULT_HP, &result); glGetOcclusionQueryuivNV(entry.query_id, GL_OCCLUSION_TEST_RESULT_HP, &result);
// NOTE: Reported pixel metrics should be referenced to native resolution // NOTE: Reported pixel metrics should be referenced to native resolution
m_results[entry.query_type] += (u64)result * EFB_WIDTH / g_renderer->GetTargetWidth() * // TODO: Dropping the lower 2 bits from this count should be closer to actual
EFB_HEIGHT / g_renderer->GetTargetHeight(); // hardware behavior when drawing triangles.
m_results[entry.query_type] += static_cast<u64>(result) * EFB_WIDTH * EFB_HEIGHT /
(g_renderer->GetTargetWidth() * g_renderer->GetTargetHeight());
m_query_read_pos = (m_query_read_pos + 1) % m_query_buffer.size(); m_query_read_pos = (m_query_read_pos + 1) % m_query_buffer.size();
--m_query_count; --m_query_count;