| 
									
										
										
										
											2013-03-01 23:12:41 +01:00
										 |  |  | #include "RenderBase.h"
 | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | #include "GLUtil.h"
 | 
					
						
							|  |  |  | #include "PerfQuery.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | namespace OGL | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | PerfQuery::PerfQuery() | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	: m_query_read_pos() | 
					
						
							|  |  |  | 	, m_query_count() | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-09-11 19:19:36 -05:00
										 |  |  | 	for (u32 i = 0; i != ArraySize(m_query_buffer); ++i) | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 		glGenQueries(1, &m_query_buffer[i].query_id); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	ResetQuery(); | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PerfQuery::~PerfQuery() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-09-11 19:19:36 -05:00
										 |  |  | 	for (u32 i = 0; i != ArraySize(m_query_buffer); ++i) | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 		glDeleteQueries(1, &m_query_buffer[i].query_id); | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PerfQuery::EnableQuery(PerfQueryGroup type) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-08-11 17:13:29 +02:00
										 |  |  | 	if (!ShouldEmulate()) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	// Is this sane?
 | 
					
						
							| 
									
										
										
										
											2013-09-11 19:19:36 -05:00
										 |  |  | 	if (m_query_count > ArraySize(m_query_buffer) / 2) | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 		WeakFlush(); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-09-11 19:19:36 -05:00
										 |  |  | 	if (ArraySize(m_query_buffer) == m_query_count) | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		FlushOne(); | 
					
						
							| 
									
										
										
										
											2013-03-31 19:10:21 -04:00
										 |  |  | 		//ERROR_LOG(VIDEO, "Flushed query buffer early!");
 | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | 	// start query
 | 
					
						
							|  |  |  | 	if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-09-11 19:19:36 -05:00
										 |  |  | 		auto& entry = m_query_buffer[(m_query_read_pos + m_query_count) % ArraySize(m_query_buffer)]; | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		glBeginQuery(GL_SAMPLES_PASSED, entry.query_id); | 
					
						
							|  |  |  | 		entry.query_type = type; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		++m_query_count; | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PerfQuery::DisableQuery(PerfQueryGroup type) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-08-11 17:13:29 +02:00
										 |  |  | 	if (!ShouldEmulate()) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | 	// stop query
 | 
					
						
							|  |  |  | 	if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		glEndQuery(GL_SAMPLES_PASSED); | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | bool PerfQuery::IsFlushed() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-08-11 17:13:29 +02:00
										 |  |  | 	if (!ShouldEmulate()) | 
					
						
							|  |  |  | 		return true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	return 0 == m_query_count; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PerfQuery::FlushOne() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-08-11 17:13:29 +02:00
										 |  |  | 	if (!ShouldEmulate()) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	auto& entry = m_query_buffer[m_query_read_pos]; | 
					
						
							| 
									
										
										
										
											2013-03-01 23:12:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	GLuint result = 0; | 
					
						
							|  |  |  | 	glGetQueryObjectuiv(entry.query_id, GL_QUERY_RESULT, &result); | 
					
						
							| 
									
										
										
										
											2013-03-01 23:12:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// NOTE: Reported pixel metrics should be referenced to native resolution
 | 
					
						
							| 
									
										
										
										
											2013-03-01 23:57:56 +01:00
										 |  |  | 	m_results[entry.query_type] += (u64)result * EFB_WIDTH / g_renderer->GetTargetWidth() * EFB_HEIGHT / g_renderer->GetTargetHeight(); | 
					
						
							| 
									
										
										
										
											2013-03-01 23:12:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 19:19:36 -05:00
										 |  |  | 	m_query_read_pos = (m_query_read_pos + 1) % ArraySize(m_query_buffer); | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	--m_query_count; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | // TODO: could selectively flush things, but I don't think that will do much
 | 
					
						
							|  |  |  | void PerfQuery::FlushResults() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-08-11 17:13:29 +02:00
										 |  |  | 	if (!ShouldEmulate()) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	while (!IsFlushed()) | 
					
						
							|  |  |  | 		FlushOne(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | void PerfQuery::WeakFlush() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-08-11 17:13:29 +02:00
										 |  |  | 	if (!ShouldEmulate()) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	while (!IsFlushed()) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		auto& entry = m_query_buffer[m_query_read_pos]; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		GLuint result = GL_FALSE; | 
					
						
							|  |  |  | 		glGetQueryObjectuiv(entry.query_id, GL_QUERY_RESULT_AVAILABLE, &result); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (GL_TRUE == result) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			FlushOne(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PerfQuery::ResetQuery() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	m_query_count = 0; | 
					
						
							| 
									
										
										
										
											2013-09-11 19:19:36 -05:00
										 |  |  | 	std::fill_n(m_results, ArraySize(m_results), 0); | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | u32 PerfQuery::GetQueryResult(PerfQueryType type) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-08-11 17:13:29 +02:00
										 |  |  | 	if (!ShouldEmulate()) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	u32 result = 0; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (type == PQ_ZCOMP_INPUT_ZCOMPLOC || type == PQ_ZCOMP_OUTPUT_ZCOMPLOC) | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 		result = m_results[PQG_ZCOMP_ZCOMPLOC]; | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	else if (type == PQ_ZCOMP_INPUT || type == PQ_ZCOMP_OUTPUT) | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 		result = m_results[PQG_ZCOMP]; | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	else if (type == PQ_BLEND_INPUT) | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 		result = m_results[PQG_ZCOMP] + m_results[PQG_ZCOMP_ZCOMPLOC]; | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	else if (type == PQ_EFB_COPY_CLOCKS) | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 		result = m_results[PQG_EFB_COPY_CLOCKS]; | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-02-16 17:50:40 -06:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	return result / 4; | 
					
						
							| 
									
										
										
										
											2012-06-17 13:58:29 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace
 |