/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2014-2016 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */ /*!
 * \file
 * \brief
 */ /*-------------------------------------------------------------------*/

/**
 */ /*!
 * \file  gl4cPipelineStatisticsQueryTests.cpp
 * \brief Implements conformance tests for GL_ARB_pipeline_statistics_query functionality
 */ /*-------------------------------------------------------------------*/

#include "gl4cPipelineStatisticsQueryTests.hpp"
#include "gluContextInfo.hpp"
#include "gluDefs.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuTestLog.hpp"

#include <string>
#include <vector>

#ifndef GL_VERTICES_SUBMITTED_ARB
#define GL_VERTICES_SUBMITTED_ARB (0x82EE)
#endif
#ifndef GL_PRIMITIVES_SUBMITTED_ARB
#define GL_PRIMITIVES_SUBMITTED_ARB (0x82EF)
#endif
#ifndef GL_VERTEX_SHADER_INVOCATIONS_ARB
#define GL_VERTEX_SHADER_INVOCATIONS_ARB (0x82F0)
#endif
#ifndef GL_TESS_CONTROL_SHADER_PATCHES_ARB
#define GL_TESS_CONTROL_SHADER_PATCHES_ARB (0x82F1)
#endif
#ifndef GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB
#define GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB (0x82F2)
#endif
#ifndef GL_GEOMETRY_SHADER_INVOCATIONS
#define GL_GEOMETRY_SHADER_INVOCATIONS (0x887F)
#endif
#ifndef GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB
#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB (0x82F3)
#endif
#ifndef GL_FRAGMENT_SHADER_INVOCATIONS_ARB
#define GL_FRAGMENT_SHADER_INVOCATIONS_ARB (0x82F4)
#endif
#ifndef GL_COMPUTE_SHADER_INVOCATIONS_ARB
#define GL_COMPUTE_SHADER_INVOCATIONS_ARB (0x82F5)
#endif
#ifndef GL_CLIPPING_INPUT_PRIMITIVES_ARB
#define GL_CLIPPING_INPUT_PRIMITIVES_ARB (0x82F6)
#endif
#ifndef GL_CLIPPING_OUTPUT_PRIMITIVES_ARB
#define GL_CLIPPING_OUTPUT_PRIMITIVES_ARB (0x82F7)
#endif

namespace glcts
{
const char* PipelineStatisticsQueryUtilities::dummy_cs_code =
	"#version 430\n"
	"\n"
	"layout(local_size_x=1, local_size_y = 1, local_size_z = 1) in;\n"
	"\n"
	"layout(binding = 0) uniform atomic_uint test_counter;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    atomicCounterIncrement(test_counter);\n"
	"}\n";
const char* PipelineStatisticsQueryUtilities::dummy_cs_code_arb =
	"#version 330\n"
	"#extension GL_ARB_compute_shader : require\n"
	"#extension GL_ARB_shader_atomic_counters : require\n"
	"\n"
	"layout(local_size_x=1, local_size_y = 1, local_size_z = 1) in;\n"
	"\n"
	"layout(binding = 0) uniform atomic_uint test_counter;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    atomicCounterIncrement(test_counter);\n"
	"}\n";
const char* PipelineStatisticsQueryUtilities::dummy_fs_code = "#version 130\n"
															  "\n"
															  "out vec4 result;\n"
															  "\n"
															  "void main()\n"
															  "{\n"
															  "    result = gl_FragCoord;\n"
															  "}\n";
const char* PipelineStatisticsQueryUtilities::dummy_tc_code =
	"#version 400\n"
	"\n"
	"layout(vertices = 3) out;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
	"    gl_TessLevelInner[0]                = 1.0;\n"
	"    gl_TessLevelInner[1]                = 2.0;\n"
	"    gl_TessLevelOuter[0]                = 3.0;\n"
	"    gl_TessLevelOuter[1]                = 4.0;\n"
	"    gl_TessLevelOuter[2]                = 5.0;\n"
	"    gl_TessLevelOuter[3]                = 6.0;\n"
	"}\n";
const char* PipelineStatisticsQueryUtilities::dummy_te_code =
	"#version 400\n"
	"\n"
	"layout(triangles) in;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    gl_Position = gl_TessCoord.xyxy * gl_in[gl_PrimitiveID].gl_Position;\n"
	"}\n";
const char* PipelineStatisticsQueryUtilities::dummy_vs_code = "#version 130\n"
															  "\n"
															  "in vec4 position;\n"
															  "\n"
															  "void main()\n"
															  "{\n"
															  "    gl_Position = position;\n"
															  "}\n";

/** An array holding all query targets that are introduced by GL_ARB_pipeline_statistics_query */
const glw::GLenum PipelineStatisticsQueryUtilities::query_targets[] = {
	GL_VERTICES_SUBMITTED_ARB,
	GL_PRIMITIVES_SUBMITTED_ARB,
	GL_VERTEX_SHADER_INVOCATIONS_ARB,
	GL_TESS_CONTROL_SHADER_PATCHES_ARB,
	GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB,
	GL_GEOMETRY_SHADER_INVOCATIONS,
	GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB,
	GL_FRAGMENT_SHADER_INVOCATIONS_ARB,
	GL_COMPUTE_SHADER_INVOCATIONS_ARB,
	GL_CLIPPING_INPUT_PRIMITIVES_ARB,
	GL_CLIPPING_OUTPUT_PRIMITIVES_ARB,
};
const unsigned int PipelineStatisticsQueryUtilities::n_query_targets = sizeof(query_targets) / sizeof(query_targets[0]);

/* Offsets that point to locations in a buffer object storage that will hold
 * query object result values for a specific value type. */
const unsigned int PipelineStatisticsQueryUtilities::qo_bo_int_offset   = (0);
const unsigned int PipelineStatisticsQueryUtilities::qo_bo_int64_offset = (0 + 4 /* int */ + 4 /* alignment */);
const unsigned int PipelineStatisticsQueryUtilities::qo_bo_uint_offset  = (0 + 8 /* int + alignment */ + 8 /* int64 */);
const unsigned int PipelineStatisticsQueryUtilities::qo_bo_uint64_offset =
	(0 + 8 /* int + alignment */ + 8 /* int64 */ + 8 /* uint + alignment */);
const unsigned int PipelineStatisticsQueryUtilities::qo_bo_size = 32;

/** Buffer object size required to run the second functional test. */
const unsigned int PipelineStatisticsQueryTestFunctional2::bo_size = 32;

/** Builds body of a geometry shader, given user-specified properties.
 *
 *  This function works in two different ways:
 *
 *  1) If the caller only needs the geometry shader to use a single stream, the body
 *     will be constructed in a way that ignores stream existence completely.
 *  2) Otherwise, the shader will only be compilable by platforms that support vertex
 *     streams.
 *
 *  The shader will emit @param n_primitives_to_emit_in_stream0 primitives on the zeroth
 *  stream, (@param n_primitives_to_emit_in_stream0 + 1) primitives on the first stream,
 *  and so on.
 *
 *  @param gs_input                         Input primitive type that should be used by the geometry shader body.
 *  @param gs_output                        Output primitive type that should be used by the geometry shader body.
 *  @param n_primitives_to_emit_in_stream0  Number of primitives to be emitted on the zeroth vertex stream.
 *  @param n_streams                        Number of streams the geometry shader should emit primitives on.
 *
 *  @return Geometry shader body.
 **/
std::string PipelineStatisticsQueryUtilities::buildGeometryShaderBody(_geometry_shader_input  gs_input,
																	  _geometry_shader_output gs_output,
																	  unsigned int n_primitives_to_emit_in_stream0,
																	  unsigned int n_streams)
{
	DE_ASSERT(n_primitives_to_emit_in_stream0 >= 1);
	DE_ASSERT(n_streams >= 1);

	/* Each stream will output (n+1) primitives, where n corresponds to the number of primitives emitted
	 * by the previous stream. Stream 0 emits user-defined number of primitievs.
	 */
	std::stringstream gs_body_sstream;
	const std::string gs_input_string  = getGLSLStringForGSInput(gs_input);
	const std::string gs_output_string = getGLSLStringForGSOutput(gs_output);
	unsigned int	  n_max_vertices   = 0;
	unsigned int	  n_vertices_required_for_gs_output =
		PipelineStatisticsQueryUtilities::getNumberOfVerticesForGSOutput(gs_output);

	for (unsigned int n_stream = 0; n_stream < n_streams; ++n_stream)
	{
		n_max_vertices += n_vertices_required_for_gs_output * (n_primitives_to_emit_in_stream0 + n_stream);
	} /* for (all streams) */

	/* Form the preamble. Note that we need to use the right ES SL version,
	 * since vertex streams are not a core GL3.2 feature.
	 **/
	gs_body_sstream << ((n_streams > 1) ? "#version 400" : "#version 150\n") << "\n"
																				"layout("
					<< gs_input_string << ")                 in;\n"
										  "layout("
					<< gs_output_string << ", max_vertices=" << n_max_vertices << ") out;\n";

	/* If we need to define multiple streams, do it now */
	if (n_streams > 1)
	{
		gs_body_sstream << "\n";

		for (unsigned int n_stream = 0; n_stream < n_streams; ++n_stream)
		{
			gs_body_sstream << "layout(stream = " << n_stream << ") out vec4 out_stream" << n_stream << ";\n";
		} /* for (all streams) */
	}	 /* if (n_streams > 1) */

	/* Contine forming actual body */
	gs_body_sstream << "\n"
					   "void main()\n"
					   "{\n";

	/* Emit primitives */
	const unsigned int n_output_primitive_vertices =
		PipelineStatisticsQueryUtilities::getNumberOfVerticesForGSOutput(gs_output);

	for (unsigned int n_stream = 0; n_stream < n_streams; ++n_stream)
	{
		const unsigned int n_primitives_to_emit = n_primitives_to_emit_in_stream0 + n_stream;

		for (unsigned int n_primitive = 0; n_primitive < n_primitives_to_emit; ++n_primitive)
		{
			for (unsigned int n_vertex = 0; n_vertex < n_output_primitive_vertices; ++n_vertex)
			{
				gs_body_sstream << "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n";

				if (n_streams == 1)
				{
					gs_body_sstream << "    EmitVertex();\n";
				}
				else
				{
					gs_body_sstream << "    EmitStreamVertex(" << n_stream << ");\n";
				}
			}

			if (n_streams == 1)
			{
				gs_body_sstream << "    EndPrimitive();\n";
			}
			else
			{
				gs_body_sstream << "    EndStreamPrimitive(" << n_stream << ");\n";
			}
		} /* for (all primitives the caller wants the shader to emit) */
	}	 /* for (all streams) */

	gs_body_sstream << "}\n";

	return gs_body_sstream.str();
}

/** Executes the query and collects the result data from both query object buffer object
 *  (if these are supported by the running OpenGL implementation) and the query counters.
 *  The result data is then exposed via @param out_result.
 *
 *  @param query_type     Type of the query to be executed for the iteration.
 *  @param qo_id          ID of the query object to be used for the execution.
 *                        The query object must not have been assigned a type
 *                        prior to the call, or the type must be a match with
 *                        @param query_type .
 *  @param qo_bo_id       ID of the query buffer object to use for the call.
 *                        Pass 0, if the running OpenGL implementation does not
 *                        support QBOs.
 *  @param pfn_draw       Function pointer to caller-specific routine that is
 *                        going to execute the draw call. Must not be NULL.
 *  @param draw_user_arg  Caller-specific user argument to be passed with the
 *                        @param pfn_draw callback.
 *  @param render_context glu::RenderContext& to be used by the method.
 *  @param test_context   tcu::TestContext& to be used by the method.
 *  @param context_info   glu::ContextInfo& to be used by the method.
 *  @param out_result     Deref will be used to store the test execution result.
 *                        Must not be NULL. Will only be modified if the method
 *                        returns true.
 *
 *  @return true if the test executed successfully, and @param out_result 's fields
 *          were modified.
 *
 */
bool PipelineStatisticsQueryUtilities::executeQuery(glw::GLenum query_type, glw::GLuint qo_id, glw::GLuint qo_bo_id,
													PFNQUERYDRAWHANDLERPROC pfn_draw, void* draw_user_arg,
													const glu::RenderContext& render_context,
													tcu::TestContext&		  test_context,
													const glu::ContextInfo&   context_info,
													_test_execution_result*   out_result)
{
	glw::GLenum			  error_code = GL_NO_ERROR;
	const glw::Functions& gl		 = render_context.getFunctions();
	bool				  result	 = true;

	/* Check if the implementation provides non-zero number of bits for the query.
	 * Queries, for which GL implementations provide zero bits of space return
	 * indeterminate values, so we should skip them */
	glw::GLint n_query_bits = 0;

	gl.getQueryiv(query_type, GL_QUERY_COUNTER_BITS, &n_query_bits);

	error_code = gl.getError();
	if (error_code != GL_NO_ERROR)
	{
		test_context.getLog() << tcu::TestLog::Message
							  << "glGetQueryiv() call failed for GL_QUERY_COUNTER_BITS pname and "
							  << PipelineStatisticsQueryUtilities::getStringForEnum(query_type) << "query target."
							  << tcu::TestLog::EndMessage;

		return false;
	}

	if (n_query_bits == 0)
	{
		test_context.getLog() << tcu::TestLog::Message << "Skipping "
														  "["
							  << PipelineStatisticsQueryUtilities::getStringForEnum(query_type)
							  << "]"
								 ": zero bits available for counter storage"
							  << tcu::TestLog::EndMessage;

		return result;
	}

	/* Start the query */
	gl.beginQuery(query_type, qo_id);

	error_code = gl.getError();
	if (error_code != GL_NO_ERROR)
	{
		test_context.getLog() << tcu::TestLog::Message
							  << "A valid glBeginQuery() call generated the following error code:"
								 "["
							  << error_code << "]" << tcu::TestLog::EndMessage;

		return false;
	}

	/* If GL_ARB_query_buffer_object is supported and the caller supplied a BO id, use
	 * it before we fire any draw calls */
	if (context_info.isExtensionSupported("GL_ARB_query_buffer_object") && qo_bo_id != 0)
	{
		gl.bindBuffer(GL_QUERY_BUFFER, qo_bo_id);

		error_code = gl.getError();
		if (error_code != GL_NO_ERROR)
		{
			test_context.getLog() << tcu::TestLog::Message
								  << "Could not bind a buffer object to GL_QUERY_BUFFER buffer object "
									 "binding point. Error reported:"
									 "["
								  << error_code << "]" << tcu::TestLog::EndMessage;

			/* Stop the query before we leave */
			gl.endQuery(query_type);

			return false;
		} /* if (buffer binding operation failed) */
	}	 /* if (GL_ARB_query_buffer_object extension is supported and the supplied QO BO id
	 *     is not 0) */
	else
	{
		/* Reset the QO BO id, so that we can skip the checks later */
		qo_bo_id = 0;
	}

	/* Perform the draw calls, if any supplied call-back function pointer was supplied
	 * by the caller. */
	if (pfn_draw != DE_NULL)
	{
		pfn_draw(draw_user_arg);
	}

	/* End the query */
	gl.endQuery(query_type);

	error_code = gl.getError();
	if (error_code != GL_NO_ERROR)
	{
		test_context.getLog() << tcu::TestLog::Message << "glEndQuery() call failed with error code"
														  "["
							  << error_code << "]" << tcu::TestLog::EndMessage;

		return false;
	} /* if (glEndQuery() call failed) */

	/* We now need to retrieve the result data using all query getter functions
	 * GL has to offer. This will be handled in two iterations:
	 *
	 * 1. The data will be retrieved using the getters without a QO BO being bound.
	 * 2. If QO was provided, we will need to issue all getter calls executed against
	 *    the QO BO. We will then need to retrieve that data directly from the BO
	 *    storage.
	 */
	const unsigned int iteration_index_wo_qo_bo   = 0;
	const unsigned int iteration_index_with_qo_bo = 1;

	for (unsigned int n_iteration = 0; n_iteration < 2; /* as per description */
		 ++n_iteration)
	{
		glw::GLint*	offset_int			 = DE_NULL;
		glw::GLint64*  offset_int64			 = DE_NULL;
		glw::GLuint*   offset_uint			 = DE_NULL;
		glw::GLuint64* offset_uint64		 = DE_NULL;
		glw::GLint	 result_int			 = INT_MAX;
		glw::GLint64   result_int64			 = LLONG_MAX;
		bool		   result_int64_written  = false;
		glw::GLuint	result_uint			 = UINT_MAX;
		glw::GLuint64  result_uint64		 = ULLONG_MAX;
		bool		   result_uint64_written = false;

		/* Skip the QO BO iteration if QO BO id has not been provided */
		if (n_iteration == iteration_index_with_qo_bo && qo_bo_id == 0)
		{
			continue;
		}

		/* Determine the offsets we should use for the getter calls */
		if (n_iteration == iteration_index_wo_qo_bo)
		{
			offset_int	= &result_int;
			offset_int64  = &result_int64;
			offset_uint   = &result_uint;
			offset_uint64 = &result_uint64;
		}
		else
		{
			offset_int	= (glw::GLint*)(deUintptr)PipelineStatisticsQueryUtilities::qo_bo_int_offset;
			offset_int64  = (glw::GLint64*)(deUintptr)PipelineStatisticsQueryUtilities::qo_bo_int64_offset;
			offset_uint   = (glw::GLuint*)(deUintptr)PipelineStatisticsQueryUtilities::qo_bo_uint_offset;
			offset_uint64 = (glw::GLuint64*)(deUintptr)PipelineStatisticsQueryUtilities::qo_bo_uint64_offset;
		}

		/* Bind the QO BO if we need to use it for the getter calls */
		if (n_iteration == iteration_index_with_qo_bo)
		{
			gl.bindBuffer(GL_QUERY_BUFFER, qo_bo_id);
		}
		else if (qo_bo_id != 0)
		{
			gl.bindBuffer(GL_QUERY_BUFFER, 0 /* buffer */);
		}

		error_code = gl.getError();
		if (error_code != GL_NO_ERROR)
		{
			test_context.getLog() << tcu::TestLog::Message
								  << "glBindBuffer() call failed for GL_QUERY_BUFFER target with error "
									 "["
								  << error_code << "]" << tcu::TestLog::EndMessage;

			return false;
		}

		/* Issue the getter calls.
		 *
		 * NOTE: 64-bit getter calls are supported only if >= GL 3.3*/
		if (glu::contextSupports(render_context.getType(), glu::ApiType::core(3, 3)))
		{
			gl.getQueryObjecti64v(qo_id, GL_QUERY_RESULT, offset_int64);

			error_code = gl.getError();
			if (error_code != GL_NO_ERROR)
			{
				test_context.getLog() << tcu::TestLog::Message << "glGetQueryObjecti64v() call failed with error "
																  "["
									  << error_code << "]" << tcu::TestLog::EndMessage;

				return false;
			}

			result_int64_written = true;
		}
		else
		{
			result_int64_written = false;
		}

		gl.getQueryObjectiv(qo_id, GL_QUERY_RESULT, offset_int);

		error_code = gl.getError();
		if (error_code != GL_NO_ERROR)
		{
			test_context.getLog() << tcu::TestLog::Message << "glGetQueryObjectiv() call failed with error "
															  "["
								  << error_code << "]" << tcu::TestLog::EndMessage;

			return false;
		}

		if (glu::contextSupports(render_context.getType(), glu::ApiType::core(3, 3)))
		{
			gl.getQueryObjectui64v(qo_id, GL_QUERY_RESULT, offset_uint64);

			error_code = gl.getError();
			if (error_code != GL_NO_ERROR)
			{
				test_context.getLog() << tcu::TestLog::Message << "glGetQueryObjectui64v() call failed with error "
																  "["
									  << error_code << "]" << tcu::TestLog::EndMessage;

				return false;
			}

			result_uint64_written = true;
		}
		else
		{
			result_uint64_written = false;
		}

		gl.getQueryObjectuiv(qo_id, GL_QUERY_RESULT, offset_uint);

		error_code = gl.getError();
		if (error_code != GL_NO_ERROR)
		{
			test_context.getLog() << tcu::TestLog::Message << "glGetQueryObjectuiv() call failed with error "
															  "["
								  << error_code << "]" << tcu::TestLog::EndMessage;

			return false;
		}

		/* If the getters wrote the result values to the BO, we need to retrieve the data
		 * from the BO storage */
		if (n_iteration == iteration_index_with_qo_bo)
		{
			/* Map the BO to process space */
			const unsigned char* bo_data_ptr = (const unsigned char*)gl.mapBuffer(GL_QUERY_BUFFER, GL_READ_ONLY);

			error_code = gl.getError();

			if (error_code != GL_NO_ERROR || bo_data_ptr == NULL)
			{
				test_context.getLog() << tcu::TestLog::Message << "QO BO mapping failed with error "
																  "["
									  << error_code << "] and data ptr returned:"
													   "["
									  << bo_data_ptr << "]" << tcu::TestLog::EndMessage;

				return false;
			}

			/* Retrieve the query result data */
			result_int	= *(glw::GLint*)(bo_data_ptr + (int)(deIntptr)offset_int);
			result_int64  = *(glw::GLint64*)(bo_data_ptr + (int)(deIntptr)offset_int64);
			result_uint   = *(glw::GLuint*)(bo_data_ptr + (int)(deIntptr)offset_uint);
			result_uint64 = *(glw::GLuint64*)(bo_data_ptr + (int)(deIntptr)offset_uint64);

			/* Unmap the BO */
			gl.unmapBuffer(GL_QUERY_BUFFER);

			error_code = gl.getError();
			if (error_code != GL_NO_ERROR)
			{
				test_context.getLog() << tcu::TestLog::Message << "QO BO unmapping failed with error "
																  "["
									  << error_code << "]" << tcu::TestLog::EndMessage;

				return false;
			}
		} /* if (QO BO iteration) */

		/* Store the retrieved data in user-provided location */
		if (n_iteration == iteration_index_with_qo_bo)
		{
			out_result->result_qo_int	= result_int;
			out_result->result_qo_int64  = result_int64;
			out_result->result_qo_uint   = result_uint;
			out_result->result_qo_uint64 = result_uint64;
		}
		else
		{
			out_result->result_int	= result_int;
			out_result->result_int64  = result_int64;
			out_result->result_uint   = result_uint;
			out_result->result_uint64 = result_uint64;
		}

		out_result->int64_written  = result_int64_written;
		out_result->uint64_written = result_uint64_written;
	} /* for (both iterations) */
	return result;
}

/** Retrieves a GLenum value corresponding to internal _primitive_type
 *  enum value.
 *
 *  @param primitive_type Internal primitive type to use for the getter call.
 *
 *  @return Corresponding GL value that can be used for the draw calls, or
 *          GL_NONE if the conversion failed.
 *
 **/
glw::GLenum PipelineStatisticsQueryUtilities::getEnumForPrimitiveType(_primitive_type primitive_type)
{
	glw::GLenum result = GL_NONE;

	switch (primitive_type)
	{
	case PRIMITIVE_TYPE_POINTS:
		result = GL_POINTS;
		break;
	case PRIMITIVE_TYPE_LINE_LOOP:
		result = GL_LINE_LOOP;
		break;
	case PRIMITIVE_TYPE_LINE_STRIP:
		result = GL_LINE_STRIP;
		break;
	case PRIMITIVE_TYPE_LINES:
		result = GL_LINES;
		break;
	case PRIMITIVE_TYPE_LINES_ADJACENCY:
		result = GL_LINES_ADJACENCY;
		break;
	case PRIMITIVE_TYPE_PATCHES:
		result = GL_PATCHES;
		break;
	case PRIMITIVE_TYPE_TRIANGLE_FAN:
		result = GL_TRIANGLE_FAN;
		break;
	case PRIMITIVE_TYPE_TRIANGLE_STRIP:
		result = GL_TRIANGLE_STRIP;
		break;
	case PRIMITIVE_TYPE_TRIANGLES:
		result = GL_TRIANGLES;
		break;
	case PRIMITIVE_TYPE_TRIANGLES_ADJACENCY:
		result = GL_TRIANGLES_ADJACENCY;
		break;

	default:
	{
		TCU_FAIL("Unrecognized primitive type");
	}
	} /* switch (primitive_type) */

	return result;
}

/** Retrieves a human-readable name for a _geometry_shader_input value.
 *
 *  @param gs_input Internal _geometry_shader_input value to use for
 *                  the conversion.
 *
 *  @return Human-readable string or empty string, if the conversion failed.
 *
 **/
std::string PipelineStatisticsQueryUtilities::getGLSLStringForGSInput(_geometry_shader_input gs_input)
{
	std::string result;

	switch (gs_input)
	{
	case GEOMETRY_SHADER_INPUT_POINTS:
		result = "points";
		break;
	case GEOMETRY_SHADER_INPUT_LINES:
		result = "lines";
		break;
	case GEOMETRY_SHADER_INPUT_LINES_ADJACENCY:
		result = "lines_adjacency";
		break;
	case GEOMETRY_SHADER_INPUT_TRIANGLES:
		result = "triangles";
		break;
	case GEOMETRY_SHADER_INPUT_TRIANGLES_ADJACENCY:
		result = "triangles_adjacency";
		break;

	default:
	{
		TCU_FAIL("Unrecognized geometry shader input enum");
	}
	} /* switch (gs_input) */

	return result;
}

/** Retrieves a human-readable string for a _geometry_shader_output value.
 *
 *  @param  gs_output _geometry_shader_output value to use for the conversion.
 *
 *  @return Requested value or empty string, if the value was not recognized.
 *
 **/
std::string PipelineStatisticsQueryUtilities::getGLSLStringForGSOutput(_geometry_shader_output gs_output)
{
	std::string result;

	switch (gs_output)
	{
	case GEOMETRY_SHADER_OUTPUT_POINTS:
		result = "points";
		break;
	case GEOMETRY_SHADER_OUTPUT_LINE_STRIP:
		result = "line_strip";
		break;
	case GEOMETRY_SHADER_OUTPUT_TRIANGLE_STRIP:
		result = "triangle_strip";
		break;

	default:
	{
		TCU_FAIL("Unrecognized geometry shader output enum");
	}
	} /* switch (gs_output) */

	return result;
}

/** Number of vertices the geometry shader can access on the input, if the shader
 *  uses @param gs_input input primitive type.
 *
 *  @param gs_input Geometry shader input to use for the query.
 *
 *  @return Requested value or 0 if @param gs_input was not recognized.
 **/
unsigned int PipelineStatisticsQueryUtilities::getNumberOfVerticesForGSInput(_geometry_shader_input gs_input)
{
	unsigned int result = 0;

	switch (gs_input)
	{
	case GEOMETRY_SHADER_INPUT_POINTS:
		result = 1;
		break;
	case GEOMETRY_SHADER_INPUT_LINES:
		result = 2;
		break;
	case GEOMETRY_SHADER_INPUT_LINES_ADJACENCY:
		result = 4;
		break;
	case GEOMETRY_SHADER_INPUT_TRIANGLES:
		result = 3;
		break;
	case GEOMETRY_SHADER_INPUT_TRIANGLES_ADJACENCY:
		result = 6;
		break;

	default:
	{
		TCU_FAIL("Unrecognized geometry shader input type");
	}
	} /* switch (gs_input) */

	return result;
}

/** Retrieves a number of vertices that need to be emitted before the shader
 *  can end the primitive, with the primitive being complete, assuming the
 *  geometry shader outputs a primitive of type described by @param gs_output.
 *
 *  @param gs_output Primitive type to be outputted by the geometry shader.
 *
 *  @return As per description, or 0 if @param gs_output was not recognized.
 **/
unsigned int PipelineStatisticsQueryUtilities::getNumberOfVerticesForGSOutput(_geometry_shader_output gs_output)
{
	unsigned int n_result_vertices = 0;

	switch (gs_output)
	{
	case GEOMETRY_SHADER_OUTPUT_LINE_STRIP:
		n_result_vertices = 2;
		break;
	case GEOMETRY_SHADER_OUTPUT_POINTS:
		n_result_vertices = 1;
		break;
	case GEOMETRY_SHADER_OUTPUT_TRIANGLE_STRIP:
		n_result_vertices = 3;
		break;

	default:
		TCU_FAIL("Unrecognized geometry shader output type");
	}

	/* All done */
	return n_result_vertices;
}

/** Returns the number of vertices a single primitive of type described by @param primitive_type
 *  consists of.
 *
 *  @param primitive_type Primitive type to use for the query.
 *
 *  @return Result value, or 0 if @param primive_type was not recognized.
 **/
unsigned int PipelineStatisticsQueryUtilities::getNumberOfVerticesForPrimitiveType(_primitive_type primitive_type)
{
	unsigned int result = 0;

	switch (primitive_type)
	{
	case PRIMITIVE_TYPE_POINTS:
		result = 1;
		break;
	case PRIMITIVE_TYPE_LINE_LOOP:  /* fall-through */
	case PRIMITIVE_TYPE_LINE_STRIP: /* fall-through */
	case PRIMITIVE_TYPE_LINES:
		result = 2;
		break;
	case PRIMITIVE_TYPE_TRIANGLE_FAN:   /* fall-through */
	case PRIMITIVE_TYPE_TRIANGLE_STRIP: /* fall-through */
	case PRIMITIVE_TYPE_TRIANGLES:
		result = 3;
		break;
	case PRIMITIVE_TYPE_LINES_ADJACENCY:
		result = 4;
		break;
	case PRIMITIVE_TYPE_TRIANGLES_ADJACENCY:
		result = 6;
		break;

	default:
		TCU_FAIL("Unrecognized primitive type");
	} /* switch (primitive_type) */

	return result;
}

/** Converts user-specified _geometry_shader_input value to a _primitive_type value.
 *
 *  @param gs_input Input value for the conversion.
 *
 *  @return Requested value, or PRIMITIVE_TYPE_COUNT if the user-specified value
 *          was unrecognized.
 **/
PipelineStatisticsQueryUtilities::_primitive_type PipelineStatisticsQueryUtilities::getPrimitiveTypeFromGSInput(
	_geometry_shader_input gs_input)
{
	_primitive_type result = PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_COUNT;

	switch (gs_input)
	{
	case GEOMETRY_SHADER_INPUT_POINTS:
		result = PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_POINTS;
		break;
	case GEOMETRY_SHADER_INPUT_LINES:
		result = PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_LINES;
		break;
	case GEOMETRY_SHADER_INPUT_LINES_ADJACENCY:
		result = PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_LINES_ADJACENCY;
		break;
	case GEOMETRY_SHADER_INPUT_TRIANGLES:
		result = PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_TRIANGLES;
		break;
	case GEOMETRY_SHADER_INPUT_TRIANGLES_ADJACENCY:
		result = PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_TRIANGLES_ADJACENCY;
		break;

	default:
	{
		TCU_FAIL("Unrecognized geometry shader input enum");
	}
	} /* switch (gs_input) */

	return result;
}

/** Converts user-specified _draw_call_type value to a human-readable string.
 *
 *  @param draw_call_type Input value to use for the conversion.
 *
 *  @return Human-readable string, or "[?]" (without the quotation marks) if
 *          the input value was not recognized.
 **/
std::string PipelineStatisticsQueryUtilities::getStringForDrawCallType(_draw_call_type draw_call_type)
{
	std::string result = "[?]";

	switch (draw_call_type)
	{
	case DRAW_CALL_TYPE_GLDRAWARRAYS:
		result = "glDrawArrays()";
		break;
	case DRAW_CALL_TYPE_GLDRAWARRAYSINDIRECT:
		result = "glDrawArraysIndirect()";
		break;
	case DRAW_CALL_TYPE_GLDRAWARRAYSINSTANCED:
		result = "glDrawArraysInstanced()";
		break;
	case DRAW_CALL_TYPE_GLDRAWARRAYSINSTANCEDBASEINSTANCE:
		result = "glDrawArraysInstancedBaseInstance()";
		break;
	case DRAW_CALL_TYPE_GLDRAWELEMENTS:
		result = "glDrawElements()";
		break;
	case DRAW_CALL_TYPE_GLDRAWELEMENTSBASEVERTEX:
		result = "glDrawElementsBaseVertex()";
		break;
	case DRAW_CALL_TYPE_GLDRAWELEMENTSINDIRECT:
		result = "glDrawElementsIndirect()";
		break;
	case DRAW_CALL_TYPE_GLDRAWELEMENTSINSTANCED:
		result = "glDrawElementsInstanced()";
		break;
	case DRAW_CALL_TYPE_GLDRAWELEMENTSINSTANCEDBASEINSTANCE:
		result = "glDrawElementsInstancedBaseInstance()";
		break;
	case DRAW_CALL_TYPE_GLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
		result = "glDrawElementsInstancedBaseVertexBaseInstance()";
		break;
	case DRAW_CALL_TYPE_GLDRAWRANGEELEMENTS:
		result = "glDrawRangeElements()";
		break;
	case DRAW_CALL_TYPE_GLDRAWRANGEELEMENTSBASEVERTEX:
		result = "glDrawRangeElementsBaseVertex()";
		break;
	default:
		DE_ASSERT(0);
		break;
	}

	return result;
}

/** Converts a GL enum value expressing a pipeline statistics query type
 *  into a human-readable string.
 *
 *  @param value Input value to use for the conversion.
 *
 *  @return Human-readable string or "[?]" (without the quotation marks)
 *          if the input value was not recognized.
 **/
std::string PipelineStatisticsQueryUtilities::getStringForEnum(glw::GLenum value)
{
	std::string result = "[?]";

	switch (value)
	{
	case GL_CLIPPING_INPUT_PRIMITIVES_ARB:
		result = "GL_CLIPPING_INPUT_PRIMITIVES_ARB";
		break;
	case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB:
		result = "GL_CLIPPING_OUTPUT_PRIMITIVES_ARB";
		break;
	case GL_COMPUTE_SHADER_INVOCATIONS_ARB:
		result = "GL_COMPUTE_SHADER_INVOCATIONS_ARB";
		break;
	case GL_FRAGMENT_SHADER_INVOCATIONS_ARB:
		result = "GL_FRAGMENT_SHADER_INVOCATIONS_ARB";
		break;
	case GL_GEOMETRY_SHADER_INVOCATIONS:
		result = "GL_GEOMETRY_SHADER_INVOCATIONS";
		break;
	case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB:
		result = "GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB";
		break;
	case GL_PRIMITIVES_SUBMITTED_ARB:
		result = "GL_PRIMITIVES_SUBMITTED_ARB";
		break;
	case GL_TESS_CONTROL_SHADER_PATCHES_ARB:
		result = "GL_TESS_CONTROL_SHADER_PATCHES_ARB";
		break;
	case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB:
		result = "GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB";
		break;
	case GL_VERTEX_SHADER_INVOCATIONS_ARB:
		result = "GL_VERTEX_SHADER_INVOCATIONS_ARB";
		break;
	case GL_VERTICES_SUBMITTED_ARB:
		result = "GL_VERTICES_SUBMITTED_ARB";
		break;
	} /* switch (value) */

	return result;
}

/** Converts a _primitive_type value into a human-readable string.
 *
 *  @param primitive_type Input value to use for the conversion.
 *
 *  @return Requested string or "[?]" (without the quotation marks)
 *          if the input value was not recognized.
 **/
std::string PipelineStatisticsQueryUtilities::getStringForPrimitiveType(_primitive_type primitive_type)
{
	std::string result = "[?]";

	switch (primitive_type)
	{
	case PRIMITIVE_TYPE_POINTS:
		result = "GL_POINTS";
		break;
	case PRIMITIVE_TYPE_LINE_LOOP:
		result = "GL_LINE_LOOP";
		break;
	case PRIMITIVE_TYPE_LINE_STRIP:
		result = "GL_LINE_STRIP";
		break;
	case PRIMITIVE_TYPE_LINES:
		result = "GL_LINES";
		break;
	case PRIMITIVE_TYPE_LINES_ADJACENCY:
		result = "GL_LINES_ADJACENCY";
		break;
	case PRIMITIVE_TYPE_PATCHES:
		result = "GL_PATCHES";
		break;
	case PRIMITIVE_TYPE_TRIANGLE_FAN:
		result = "GL_TRIANGLE_FAN";
		break;
	case PRIMITIVE_TYPE_TRIANGLE_STRIP:
		result = "GL_TRIANGLE_STRIP";
		break;
	case PRIMITIVE_TYPE_TRIANGLES:
		result = "GL_TRIANGLES";
		break;
	case PRIMITIVE_TYPE_TRIANGLES_ADJACENCY:
		result = "GL_TRIANGLES_ADJACENCY";
		break;
	default:
		DE_ASSERT(0);
		break;
	}

	return result;
}

/** Tells if it is safe to use a specific draw call type.
 *
 *  @param draw_call Draw call type to use for the query.
 *
 *  @return True if corresponding GL entry-point is available.
 */
bool PipelineStatisticsQueryUtilities::isDrawCallSupported(_draw_call_type draw_call, const glw::Functions& gl)
{

	bool result = false;

	switch (draw_call)
	{
	case DRAW_CALL_TYPE_GLDRAWARRAYS:
		result = (gl.drawArrays != DE_NULL);
		break;
	case DRAW_CALL_TYPE_GLDRAWARRAYSINDIRECT:
		result = (gl.drawArraysIndirect != DE_NULL);
		break;
	case DRAW_CALL_TYPE_GLDRAWARRAYSINSTANCED:
		result = (gl.drawArraysInstanced != DE_NULL);
		break;
	case DRAW_CALL_TYPE_GLDRAWARRAYSINSTANCEDBASEINSTANCE:
		result = (gl.drawArraysInstancedBaseInstance != DE_NULL);
		break;
	case DRAW_CALL_TYPE_GLDRAWELEMENTS:
		result = (gl.drawElements != DE_NULL);
		break;
	case DRAW_CALL_TYPE_GLDRAWELEMENTSBASEVERTEX:
		result = (gl.drawElementsBaseVertex != DE_NULL);
		break;
	case DRAW_CALL_TYPE_GLDRAWELEMENTSINDIRECT:
		result = (gl.drawElementsIndirect != DE_NULL);
		break;
	case DRAW_CALL_TYPE_GLDRAWELEMENTSINSTANCED:
		result = (gl.drawElementsInstanced != DE_NULL);
		break;
	case DRAW_CALL_TYPE_GLDRAWELEMENTSINSTANCEDBASEINSTANCE:
		result = (gl.drawElementsInstancedBaseInstance != DE_NULL);
		break;
	case DRAW_CALL_TYPE_GLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
		result = (gl.drawElementsInstancedBaseVertexBaseInstance != DE_NULL);
		break;
	case DRAW_CALL_TYPE_GLDRAWRANGEELEMENTS:
		result = (gl.drawRangeElements != DE_NULL);
		break;
	case DRAW_CALL_TYPE_GLDRAWRANGEELEMENTSBASEVERTEX:
		result = (gl.drawRangeElementsBaseVertex != DE_NULL);
		break;

	default:
	{
		TCU_FAIL("Unrecognized draw call type");
	}
	} /* switch (draw_call) */

	return result;
}

/** Tells if user-specified draw call type is an instanced draw call.
 *
 *  @param draw_call Input value to use for the conversion.
 *
 *  @return true if @param draw_call corresponds to an instanced draw call,
 *          false otherwise.
 **/
bool PipelineStatisticsQueryUtilities::isInstancedDrawCall(_draw_call_type draw_call)
{
	bool result =
		(draw_call == PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWARRAYSINDIRECT ||
		 draw_call == PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWARRAYSINSTANCED ||
		 draw_call == PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWARRAYSINSTANCEDBASEINSTANCE ||
		 draw_call == PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWELEMENTSINDIRECT ||
		 draw_call == PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWELEMENTSINSTANCED ||
		 draw_call == PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWELEMENTSINSTANCEDBASEINSTANCE ||
		 draw_call == PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE);

	return result;
}

/** Tells if the running GL implementation supports user-specified pipeline
 *  statistics query.
 *
 *  @param value          GL enum definining the pipeline statistics query type
 *                        that should be used for the query.
 *  @param context_info   glu::ContextInfo instance that can be used by the method.
 *  @param render_context glu::RenderContext instance that can be used by the method.
 *
 *  @return true if the query is supported, false otherwise. This method will return
 *          true for unrecognized enums.
 **/
bool PipelineStatisticsQueryUtilities::isQuerySupported(glw::GLenum value, const glu::ContextInfo& context_info,
														const glu::RenderContext& render_context)
{
	bool result = true;

	switch (value)
	{
	case GL_GEOMETRY_SHADER_INVOCATIONS:
	case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB:
	{
		if (!glu::contextSupports(render_context.getType(), glu::ApiType::core(3, 2)) &&
			!context_info.isExtensionSupported("GL_ARB_geometry_shader4"))
		{
			result = false;
		}

		break;
	}

	case GL_TESS_CONTROL_SHADER_PATCHES_ARB:
	case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB:
	{
		if (!glu::contextSupports(render_context.getType(), glu::ApiType::compatibility(4, 0)) &&
			!context_info.isExtensionSupported("GL_ARB_tessellation_shader"))
		{
			result = false;
		}

		break;
	}

	case GL_COMPUTE_SHADER_INVOCATIONS_ARB:
	{
		if (!glu::contextSupports(render_context.getType(), glu::ApiType::core(4, 3)) &&
			!context_info.isExtensionSupported("GL_ARB_compute_shader"))
		{
			result = false;
		}

		break;
	}
	} /* switch (value) */

	return result;
}

/** Takes a filled _test_execution_result structure and performs the validation
 *  of the embedded data.
 *
 *  @param run_result                   A filled _test_execution_result structure that
 *                                      should be used as input by the method.
 *  @param n_expected_values            Number of possible expected values.
 *  @param expected_values              Array of possible expected values.
 *  @param should_check_qo_bo_values    true if the method should also verify the values
 *                                      retrieved from a query buffer object, false
 *                                      if it is OK to ignore them.
 *  @param query_type                   Pipeline statistics query type that was used to
 *                                      capture the results stored in @param run_result .
 *  @param draw_call_type_ptr           Type of the draw call that was used to capture the
 *                                      results stored in @param run_result .
 *  @param primitive_type_ptr           Primitive type that was used for the draw call that
 *                                      was used to capture the results stored in @param
 *                                      run_result .
 *  @param is_primitive_restart_enabled true if "Primitive Restart" rendering mode had been enabled
 *                                      when the draw call used to capture the results was made.
 *  @param test_context                 tcu::TestContext instance that the method can use.
 *  @param verification_type            Tells how the captured values should be compared against the
 *                                      reference value.
 *
 *  @return true if the result values were found valid, false otherwise.
 **/
bool PipelineStatisticsQueryUtilities::verifyResultValues(
	const _test_execution_result& run_result, unsigned int n_expected_values, const glw::GLuint64* expected_values,
	bool should_check_qo_bo_values, const glw::GLenum query_type, const _draw_call_type* draw_call_type_ptr,
	const _primitive_type* primitive_type_ptr, bool is_primitive_restart_enabled, tcu::TestContext& test_context,
	_verification_type verification_type)
{
	bool result = true;

	/* Make sure all values are set to one of the expected values */
	std::string draw_call_name;
	std::string primitive_name;

	bool is_result_int_valid	   = false;
	bool is_result_int64_valid	 = false;
	bool is_result_uint_valid	  = false;
	bool is_result_uint64_valid	= false;
	bool is_result_qo_int_valid	= false;
	bool is_result_qo_int64_valid  = false;
	bool is_result_qo_uint_valid   = false;
	bool is_result_qo_uint64_valid = false;

	if (draw_call_type_ptr != DE_NULL)
	{
		draw_call_name = getStringForDrawCallType(*draw_call_type_ptr);
	}
	else
	{
		draw_call_name = "(does not apply)";
	}

	if (primitive_type_ptr != DE_NULL)
	{
		primitive_name = getStringForPrimitiveType(*primitive_type_ptr);
	}
	else
	{
		primitive_name = "(does not apply)";
	}

	for (unsigned int n_expected_value = 0; n_expected_value < n_expected_values; ++n_expected_value)
	{
		glw::GLuint64 expected_value = 0;

		expected_value = expected_values[n_expected_value];

		if ((verification_type == VERIFICATION_TYPE_EXACT_MATCH &&
			 (glw::GLuint64)run_result.result_int == expected_value) ||
			(verification_type == VERIFICATION_TYPE_EQUAL_OR_GREATER &&
			 (glw::GLuint64)run_result.result_int >= expected_value))
		{
			is_result_int_valid = true;
		}

		if (run_result.int64_written && ((verification_type == VERIFICATION_TYPE_EXACT_MATCH &&
										  run_result.result_int64 == (glw::GLint64)expected_value) ||
										 (verification_type == VERIFICATION_TYPE_EQUAL_OR_GREATER &&
										  run_result.result_int64 >= (glw::GLint64)expected_value)))
		{
			is_result_int64_valid = true;
		}

		if ((verification_type == VERIFICATION_TYPE_EXACT_MATCH &&
			 (glw::GLuint64)run_result.result_uint == expected_value) ||
			(verification_type == VERIFICATION_TYPE_EQUAL_OR_GREATER &&
			 (glw::GLuint64)run_result.result_uint >= expected_value))
		{
			is_result_uint_valid = true;
		}

		if (run_result.uint64_written &&
			((verification_type == VERIFICATION_TYPE_EXACT_MATCH && run_result.result_uint64 == expected_value) ||
			 (verification_type == VERIFICATION_TYPE_EQUAL_OR_GREATER && run_result.result_uint64 >= expected_value)))
		{
			is_result_uint64_valid = true;
		}

		if (should_check_qo_bo_values)
		{
			if ((verification_type == VERIFICATION_TYPE_EXACT_MATCH &&
				 (glw::GLuint64)run_result.result_qo_int == expected_value) ||
				(verification_type == VERIFICATION_TYPE_EQUAL_OR_GREATER &&
				 (glw::GLuint64)run_result.result_qo_int >= expected_value))
			{
				is_result_qo_int_valid = true;
			}

			if (run_result.int64_written && ((verification_type == VERIFICATION_TYPE_EXACT_MATCH &&
											  run_result.result_qo_int64 == (glw::GLint64)expected_value) ||
											 (verification_type == VERIFICATION_TYPE_EQUAL_OR_GREATER &&
											  run_result.result_qo_int64 >= (glw::GLint64)expected_value)))
			{
				is_result_qo_int64_valid = true;
			}

			if ((verification_type == VERIFICATION_TYPE_EXACT_MATCH &&
				 (glw::GLuint64)run_result.result_qo_uint == expected_value) ||
				(verification_type == VERIFICATION_TYPE_EQUAL_OR_GREATER &&
				 (glw::GLuint64)run_result.result_qo_uint >= expected_value))
			{
				is_result_qo_uint_valid = true;
			}

			if (run_result.uint64_written && ((verification_type == VERIFICATION_TYPE_EXACT_MATCH &&
											   run_result.result_qo_uint64 == expected_value) ||
											  (verification_type == VERIFICATION_TYPE_EQUAL_OR_GREATER &&
											   run_result.result_qo_uint64 >= expected_value)))
			{
				is_result_qo_uint64_valid = true;
			}
		} /* if (should_check_qo_bo_values) */
	}	 /* for (both expected values) */

	if (!is_result_int_valid)
	{
		std::string log = PipelineStatisticsQueryUtilities::getVerifyResultValuesErrorString<glw::GLint>(
			run_result.result_int, "non-QO BO int32", n_expected_values, expected_values, query_type, draw_call_name,
			primitive_name, is_primitive_restart_enabled);

		test_context.getLog() << tcu::TestLog::Message << log.c_str() << tcu::TestLog::EndMessage;

		result = false;
	}

	if (run_result.int64_written && !is_result_int64_valid)
	{
		std::string log = PipelineStatisticsQueryUtilities::getVerifyResultValuesErrorString<glw::GLint64>(
			run_result.result_int64, "non-QO BO int64", n_expected_values, expected_values, query_type, draw_call_name,
			primitive_name, is_primitive_restart_enabled);

		test_context.getLog() << tcu::TestLog::Message << log.c_str() << tcu::TestLog::EndMessage;

		result = false;
	}

	if (!is_result_uint_valid)
	{
		std::string log = PipelineStatisticsQueryUtilities::getVerifyResultValuesErrorString<glw::GLuint>(
			run_result.result_uint, "non-QO BO uint32", n_expected_values, expected_values, query_type, draw_call_name,
			primitive_name, is_primitive_restart_enabled);

		test_context.getLog() << tcu::TestLog::Message << log.c_str() << tcu::TestLog::EndMessage;

		result = false;
	}

	if (run_result.uint64_written && !is_result_uint64_valid)
	{
		std::string log = PipelineStatisticsQueryUtilities::getVerifyResultValuesErrorString<glw::GLuint64>(
			run_result.result_uint, "non-QO BO uint64", n_expected_values, expected_values, query_type, draw_call_name,
			primitive_name, is_primitive_restart_enabled);

		test_context.getLog() << tcu::TestLog::Message << log.c_str() << tcu::TestLog::EndMessage;

		result = false;
	}

	if (should_check_qo_bo_values)
	{
		if (!is_result_qo_int_valid)
		{
			std::string log = PipelineStatisticsQueryUtilities::getVerifyResultValuesErrorString<glw::GLint>(
				run_result.result_qo_int, "QO BO int32", n_expected_values, expected_values, query_type, draw_call_name,
				primitive_name, is_primitive_restart_enabled);

			test_context.getLog() << tcu::TestLog::Message << log.c_str() << tcu::TestLog::EndMessage;

			result = false;
		}

		if (run_result.int64_written && !is_result_qo_int64_valid)
		{
			std::string log = PipelineStatisticsQueryUtilities::getVerifyResultValuesErrorString<glw::GLint64>(
				run_result.result_qo_int64, "QO BO int64", n_expected_values, expected_values, query_type,
				draw_call_name, primitive_name, is_primitive_restart_enabled);

			test_context.getLog() << tcu::TestLog::Message << log.c_str() << tcu::TestLog::EndMessage;

			result = false;
		}

		if (!is_result_qo_uint_valid)
		{
			std::string log = PipelineStatisticsQueryUtilities::getVerifyResultValuesErrorString<glw::GLuint>(
				run_result.result_qo_uint, "QO BO uint32", n_expected_values, expected_values, query_type,
				draw_call_name, primitive_name, is_primitive_restart_enabled);

			test_context.getLog() << tcu::TestLog::Message << log.c_str() << tcu::TestLog::EndMessage;

			result = false;
		}

		if (run_result.uint64_written && !is_result_qo_uint64_valid)
		{
			std::string log = PipelineStatisticsQueryUtilities::getVerifyResultValuesErrorString<glw::GLuint64>(
				run_result.result_qo_uint64, "QO BO uint64", n_expected_values, expected_values, query_type,
				draw_call_name, primitive_name, is_primitive_restart_enabled);

			test_context.getLog() << tcu::TestLog::Message << log.c_str() << tcu::TestLog::EndMessage;

			result = false;
		}
	}

	return result;
}

/** Constructor.
 *
 *  @param context     Rendering context
 *  @param name        Test name
 *  @param description Test description
 */
PipelineStatisticsQueryTestAPICoverage1::PipelineStatisticsQueryTestAPICoverage1(deqp::Context& context)
	: TestCase(context, "api_coverage_invalid_glbeginquery_calls",
			   "Verifies that an attempt to assign a different query object type "
			   "to an object thas has already been assigned a type, results in "
			   "an error.")
	, m_qo_id(0)
{
	/* Left blank intentionally */
}

/** Deinitializes all GL objects that were created during test execution. */
void PipelineStatisticsQueryTestAPICoverage1::deinit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_qo_id != 0)
	{
		gl.deleteQueries(1, &m_qo_id);

		m_qo_id = 0;
	}
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult PipelineStatisticsQueryTestAPICoverage1::iterate()
{
	const glu::ContextInfo& context_info   = m_context.getContextInfo();
	bool					has_passed	 = true;
	glu::RenderContext&		render_context = m_context.getRenderContext();
	glu::ContextType		contextType	= m_context.getRenderContext().getType();

	/* Only continue if GL_ARB_pipeline_statistics_query extension is supported */
	if (!glu::contextSupports(contextType, glu::ApiType::core(4, 6)) &&
		!context_info.isExtensionSupported("GL_ARB_pipeline_statistics_query"))
	{
		throw tcu::NotSupportedError("GL_ARB_pipeline_statistics_query extension is not supported");
	}

	/* Verify that a query object which has been assigned a pipeline statistics query target A,
	 * cannot be assigned another type B (assuming A != B) */
	const glw::Functions& gl = render_context.getFunctions();

	for (unsigned int n_current_item = 0; n_current_item < PipelineStatisticsQueryUtilities::n_query_targets;
		 ++n_current_item)
	{
		glw::GLenum current_pq = PipelineStatisticsQueryUtilities::query_targets[n_current_item];

		/* Make sure the query is supported */
		if (!PipelineStatisticsQueryUtilities::isQuerySupported(current_pq, context_info, render_context))
		{
			continue;
		}

		/* Generate a new query object */
		gl.genQueries(1, &m_qo_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries() call failed.");

		/* Assign a type to the query object */
		gl.beginQuery(current_pq, m_qo_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery() call failed.");

		gl.endQuery(current_pq);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQuery() call failed.");

		for (unsigned int n_different_item = 0; n_different_item < PipelineStatisticsQueryUtilities::n_query_targets;
			 ++n_different_item)
		{
			glw::GLenum different_pq = PipelineStatisticsQueryUtilities::query_targets[n_different_item];

			if (current_pq == different_pq)
			{
				/* Skip valid iterations */
				continue;
			}

			/* Make sure the other query type is supported */
			if (!PipelineStatisticsQueryUtilities::isQuerySupported(different_pq, context_info, render_context))
			{
				continue;
			}

			/* Try using a different type for the same object */
			glw::GLenum error_code = GL_NO_ERROR;

			gl.beginQuery(different_pq, m_qo_id);

			/* Has GL_INVALID_OPERATION error been generated? */
			error_code = gl.getError();

			if (error_code != GL_INVALID_OPERATION)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Unexpected error code "
															   "["
								   << error_code << "]"
													" generated when using glBeginQuery() for a query object of type "
													"["
								   << PipelineStatisticsQueryUtilities::getStringForEnum(current_pq)
								   << "]"
									  ", when used for a query type "
									  "["
								   << PipelineStatisticsQueryUtilities::getStringForEnum(different_pq) << "]"
								   << tcu::TestLog::EndMessage;

				has_passed = false;
			}

			if (error_code == GL_NO_ERROR)
			{
				/* Clean up before we continue */
				gl.endQuery(different_pq);
				GLU_EXPECT_NO_ERROR(gl.getError(),
									"glEndQuery() should not have failed for a successful glBeginQuery() call");
			}
		} /* for (all query object types) */

		/* We need to switch to a new pipeline statistics query, so
		 * delete the query object */
		gl.deleteQueries(1, &m_qo_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteQueries() call failed.");
	} /* for (all pipeline statistics query object types) */

	if (has_passed)
	{
		/* Test case passed */
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	return STOP;
}

/** Constructor.
 *
 *  @param context     Rendering context
 *  @param name        Test name
 *  @param description Test description
 */
PipelineStatisticsQueryTestAPICoverage2::PipelineStatisticsQueryTestAPICoverage2(deqp::Context& context)
	: TestCase(context, "api_coverage_unsupported_calls",
			   "Verifies that an attempt of using unsupported pipeline statistics queries"
			   " results in a GL_INVALID_ENUM error.")
	, m_qo_id(0)
{
	/* Left blank intentionally */
}

/** Deinitializes all GL objects that were created during test execution. */
void PipelineStatisticsQueryTestAPICoverage2::deinit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_qo_id != 0)
	{
		gl.deleteQueries(1, &m_qo_id);

		m_qo_id = 0;
	}
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult PipelineStatisticsQueryTestAPICoverage2::iterate()
{
	const glu::ContextInfo& context_info   = m_context.getContextInfo();
	glw::GLenum				error_code	 = GL_NO_ERROR;
	bool					has_passed	 = true;
	glu::RenderContext&		render_context = m_context.getRenderContext();
	const glw::Functions&   gl			   = render_context.getFunctions();
	glu::ContextType		contextType	= m_context.getRenderContext().getType();

	/* Only continue if GL_ARB_pipeline_statistics_query extension is supported */
	if (!glu::contextSupports(contextType, glu::ApiType::core(4, 6)) &&
		!m_context.getContextInfo().isExtensionSupported("GL_ARB_pipeline_statistics_query"))
	{
		throw tcu::NotSupportedError("GL_ARB_pipeline_statistics_query extension is not supported");
	}

	/* Generate a query object we will use for the tests */
	gl.genQueries(1, &m_qo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries() call failed.");

	const glw::GLenum query_types[] = { GL_GEOMETRY_SHADER_INVOCATIONS, GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB,
										GL_TESS_CONTROL_SHADER_PATCHES_ARB, GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB,
										GL_COMPUTE_SHADER_INVOCATIONS_ARB };
	const unsigned int n_query_types = sizeof(query_types) / sizeof(query_types[0]);

	for (unsigned int n_query_type = 0; n_query_type < n_query_types; ++n_query_type)
	{
		glw::GLenum query_type = query_types[n_query_type];

		if (!PipelineStatisticsQueryUtilities::isQuerySupported(query_type, context_info, render_context))
		{
			gl.beginQuery(query_type, m_qo_id);

			error_code = gl.getError();
			if (error_code != GL_INVALID_ENUM)
			{
				m_testCtx.getLog() << tcu::TestLog::Message
								   << "glBeginQuery() call did not generate a GL_INVALID_ENUM error "
									  "for an unsupported query type "
									  "["
								   << PipelineStatisticsQueryUtilities::getStringForEnum(query_type) << "]"
								   << tcu::TestLog::EndMessage;

				has_passed = false;
			}

			/* If the query succeeded, stop it before we continue */
			if (error_code == GL_NO_ERROR)
			{
				gl.endQuery(query_type);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQuery() call failed.");
			}
		} /* if (query is not supported) */
	}	 /* for (all query types) */

	if (has_passed)
	{
		/* Test case passed */
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	return STOP;
}

/** Constructor.
 *
 *  @param context     Rendering context
 *  @param name        Test name
 *  @param description Test description
 */
PipelineStatisticsQueryTestFunctionalBase::PipelineStatisticsQueryTestFunctionalBase(deqp::Context& context,
																					 const char*	name,
																					 const char*	description)
	: TestCase(context, name, description)
	, m_bo_qo_id(0)
	, m_fbo_id(0)
	, m_po_id(0)
	, m_qo_id(0)
	, m_to_id(0)
	, m_vao_id(0)
	, m_vbo_id(0)
	, m_to_height(64)
	, m_to_width(64)
	, m_current_draw_call_type(PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_COUNT)
	, m_current_primitive_type(PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_COUNT)
	, m_indirect_draw_call_baseinstance_argument(0)
	, m_indirect_draw_call_basevertex_argument(0)
	, m_indirect_draw_call_count_argument(0)
	, m_indirect_draw_call_first_argument(0)
	, m_indirect_draw_call_firstindex_argument(0)
	, m_indirect_draw_call_primcount_argument(0)
{
	/* Left blank intentionally */
}

/** Creates a program object that can be used for dispatch/draw calls, using
 *  user-specified shader bodies. The method can either create a compute program,
 *  or a regular rendering program.
 *
 *  ID of the initialized program object is stored in m_po_id.
 *
 *  @param cs_body Compute shader body. If not NULL, all other arguments must
 *                 be NULL.
 *  @param fs_body Fragment shader body. If not NULL, @param cs_body must be NULL.
 *  @param gs_body Geometry shader body. If not NULL, @param cs_body must be NULL.
 *  @param tc_body Tess control shader body. If not NULL, @param cs_body must be NULL.
 *  @param te_body Tess evaluation shader body. If not NULL, @param cs_body must be NULL.
 *  @param vs_body Vertex shader body. If not NULL, @param cs_body must be NULL.
 *
 * */
void PipelineStatisticsQueryTestFunctionalBase::buildProgram(const char* cs_body, const char* fs_body,
															 const char* gs_body, const char* tc_body,
															 const char* te_body, const char* vs_body)
{
	const glw::Functions& gl	= m_context.getRenderContext().getFunctions();
	glw::GLuint			  cs_id = 0;
	glw::GLuint			  fs_id = 0;
	glw::GLuint			  gs_id = 0;
	glw::GLuint			  tc_id = 0;
	glw::GLuint			  te_id = 0;
	glw::GLuint			  vs_id = 0;

	/* Sanity checks */
	DE_ASSERT((cs_body != DE_NULL && (fs_body == DE_NULL && gs_body == DE_NULL && tc_body == DE_NULL &&
									  te_body == DE_NULL && vs_body == DE_NULL)) ||
			  (cs_body == DE_NULL && (fs_body != DE_NULL || gs_body != DE_NULL || tc_body != DE_NULL ||
									  te_body != DE_NULL || vs_body != DE_NULL)));

	/* Any existing program object already initialzied? Purge it before we continue */
	if (m_po_id != 0)
	{
		gl.deleteProgram(m_po_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram() call failed.");

		m_po_id = 0;
	}

	/* Generate all shader objects we'll need to use for the program */
	if (cs_body != DE_NULL)
	{
		cs_id = gl.createShader(GL_COMPUTE_SHADER);
	}

	if (fs_body != DE_NULL)
	{
		fs_id = gl.createShader(GL_FRAGMENT_SHADER);
	}

	if (gs_body != DE_NULL)
	{
		gs_id = gl.createShader(GL_GEOMETRY_SHADER);
	}

	if (tc_body != DE_NULL)
	{
		tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
	}

	if (te_body != DE_NULL)
	{
		te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
	}

	if (vs_body != DE_NULL)
	{
		vs_id = gl.createShader(GL_VERTEX_SHADER);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");

	/* Create a program object */
	m_po_id = gl.createProgram();

	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");

	/* Set source code of the shaders we've created */
	if (cs_id != 0)
	{
		gl.shaderSource(cs_id, 1,			/* count */
						&cs_body, DE_NULL); /* length */
	}

	if (fs_id != 0)
	{
		gl.shaderSource(fs_id, 1,			/* count */
						&fs_body, DE_NULL); /* length */
	}

	if (gs_id != 0)
	{
		gl.shaderSource(gs_id, 1,			/* count */
						&gs_body, DE_NULL); /* length */
	}

	if (tc_id != 0)
	{
		gl.shaderSource(tc_id, 1,			/* count */
						&tc_body, DE_NULL); /* length */
	}

	if (te_id != 0)
	{
		gl.shaderSource(te_id, 1,			/* count */
						&te_body, DE_NULL); /* length */
	}

	if (vs_id != 0)
	{
		gl.shaderSource(vs_id, 1,			/* count */
						&vs_body, DE_NULL); /* length */
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call(s) failed.");

	/* Compile the shaders */
	const glw::GLuint  so_ids[] = { cs_id, fs_id, gs_id, tc_id, te_id, vs_id };
	const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]);

	for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id)
	{
		glw::GLint  compile_status = GL_FALSE;
		glw::GLuint so_id		   = so_ids[n_so_id];

		if (so_id != 0)
		{
			gl.compileShader(so_id);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");

			gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");

			if (compile_status == GL_FALSE)
			{
				TCU_FAIL("Shader compilation failed.");
			}

			gl.attachShader(m_po_id, so_id);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
		} /* if (so_id != 0) */
	}	 /* for (all shader objects) */

	/* Link the program object */
	glw::GLint link_status = GL_FALSE;

	gl.linkProgram(m_po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");

	gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");

	if (link_status == GL_FALSE)
	{
		TCU_FAIL("Program linking failed.");
	}

	/* Release the shader objects - we no longer need them */
	if (cs_id != 0)
	{
		gl.deleteShader(cs_id);
	}

	if (fs_id != 0)
	{
		gl.deleteShader(fs_id);
	}

	if (gs_id != 0)
	{
		gl.deleteShader(gs_id);
	}

	if (tc_id != 0)
	{
		gl.deleteShader(tc_id);
	}

	if (te_id != 0)
	{
		gl.deleteShader(te_id);
	}

	if (vs_id != 0)
	{
		gl.deleteShader(vs_id);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteShader() call(s) failed.");
}

/** Deinitializes all GL objects that were created during test execution.
 *  Also calls the inheriting object's deinitObjects() method.
 **/
void PipelineStatisticsQueryTestFunctionalBase::deinit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_bo_qo_id != 0)
	{
		gl.deleteBuffers(1, &m_bo_qo_id);

		m_bo_qo_id = 0;
	}

	if (m_fbo_id != 0)
	{
		gl.deleteFramebuffers(1, &m_fbo_id);

		m_fbo_id = 0;
	}

	if (m_po_id != 0)
	{
		gl.deleteProgram(m_po_id);

		m_po_id = 0;
	}

	if (m_qo_id != 0)
	{
		gl.deleteQueries(1, &m_qo_id);

		m_qo_id = 0;
	}

	if (m_to_id != 0)
	{
		gl.deleteTextures(1, &m_to_id);

		m_to_id = 0;
	}

	if (m_vao_id != 0)
	{
		gl.deleteVertexArrays(1, &m_vao_id);

		m_vao_id = 0;
	}

	if (m_vbo_id != 0)
	{
		gl.deleteBuffers(1, &m_vbo_id);

		m_vbo_id = 0;
	}

	deinitObjects();
}

/** Dummy method that should be overloaded by inheriting methods.
 *
 *  The method can be thought as of a placeholder for code that deinitializes
 *  test-specific GL objects.
 **/
void PipelineStatisticsQueryTestFunctionalBase::deinitObjects()
{
	/* Left blank intentionally - this method should be overloaded by deriving
	 * classes.
	 */
}

/** Initializes a framebuffer object that can be used by inheriting tests
 *  for holding rendered data.
 **/
void PipelineStatisticsQueryTestFunctionalBase::initFBO()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Set up a framebuffer object */
	gl.genFramebuffers(1, &m_fbo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");

	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");

	/* Set up a texture object we will later use as a color attachment for the FBO */
	gl.genTextures(1, &m_to_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");

	gl.bindTexture(GL_TEXTURE_2D, m_to_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");

	gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
					GL_RGBA8, m_to_width, m_to_height);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");

	/* Set up the TO as a color attachment */
	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_id, 0); /* level */
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");

	gl.viewport(0, 0, m_to_width, m_to_height);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed.");
}

/** A dummy method, which can be thought of as a placeholder to initialize
 *  test-specific GL objects.
 **/
void PipelineStatisticsQueryTestFunctionalBase::initObjects()
{
	/* Left blank intentionally - this method should be overloaded by deriving
	 * classes.
	 */
}

/** Initializes a vertex array object which is going to be used for the draw calls.
 *  The initialized VAO's ID is going to be stored under m_vao_id. Zeroth vertex
 *  array attribute will be configured to use @param n_components_per_vertex components
 *  and will use vertex buffer object defined by ID stored in m_vbo_id, whose data
 *  are expected to start at an offset defined by m_vbo_vertex_data_offset.
 *
 *  @param n_components_per_vertex As per description.
 */
void PipelineStatisticsQueryTestFunctionalBase::initVAO(unsigned int n_components_per_vertex)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release an VAO that's already been created */
	if (m_vao_id != 0)
	{
		gl.deleteVertexArrays(1, &m_vao_id);

		m_vao_id = 0;
	}

	/* Generate a new one */
	gl.genVertexArrays(1, &m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");

	gl.bindVertexArray(m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");

	/* Set it up */
	gl.vertexAttribPointer(0,											/* index */
						   n_components_per_vertex, GL_FLOAT, GL_FALSE, /* normalized */
						   0,											/* stride */
						   (glw::GLvoid*)(deUintptr)m_vbo_vertex_data_offset);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() call failed.");

	gl.enableVertexAttribArray(0); /* index */
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() call failed.");

	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vbo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
}

/** Initializes a vertex buffer object and stores its ID under m_vbo_id.
 *  It is assumed index data is expressed in GL_UNSIGNED_INT.
 *
 *  The following fields will be modified by the method:
 *
 *  m_vbo_n_indices:                          Will hold the number of indices stored in index
 *                                            data buffer.
 *  m_vbo_vertex_data_offset:                 Will hold the offset, from which the vertex
 *                                            data will be stored in VBO.
 *  m_vbo_index_data_offset:                  Will hold the offset, from which the index
 *                                            data will be stored in VBO.
 *  m_vbo_indirect_arrays_argument_offset:    Will hold the offset, from which
 *                                            glDrawArraysIndirect() arguments will be
 *                                            stored in VBO.
 *  m_vbo_indirect_elements_argument_offset:  Will hold the offset, from which
 *                                            glDrawElementsIndirect() arguments will be
 *                                            stored in VBO.
 *  m_indirect_draw_call_firstindex_argument: Will be updated to point to the location, from
 *                                            which index data starts.
 *
 *  @param raw_vertex_data                        Pointer to a buffer that holds vertex data
 *                                                which should be used when constructing the VBO.
 *                                                Must not be NULL.
 *  @param raw_vertex_data_size                   Number of bytes available for reading under
 *                                                @param raw_vertex_data.
 *  @param raw_index_data                         Pointer to a buffer that holds index data
 *                                                which should be used when constructing the VBO.
 *                                                Must not be NULL.
 *  @param raw_index_data_size                    Number of bytes available for reading under
 *                                                @param raw_index_data .
 *  @param indirect_draw_bo_count_argument        Argument to be used for indirect draw calls'
 *                                                "count" argument.
 *  @param indirect_draw_bo_primcount_argument    Argument to be used for indirect draw calls'
 *                                                "primcount" argument.
 *  @param indirect_draw_bo_baseinstance_argument Argument to be used for indirect draw calls'
 *                                                "baseinstance" argument.
 *  @param indirect_draw_bo_first_argument        Argument to be used for indirect draw calls'
 *                                                "first" argument.
 *  @param indirect_draw_bo_basevertex_argument   Argument to be used for indirect draw calls'
 *                                                "basevertex" argument.
 *
 **/
void PipelineStatisticsQueryTestFunctionalBase::initVBO(
	const float* raw_vertex_data, unsigned int raw_vertex_data_size, const unsigned int* raw_index_data,
	unsigned int raw_index_data_size, unsigned int indirect_draw_bo_count_argument,
	unsigned int indirect_draw_bo_primcount_argument, unsigned int indirect_draw_bo_baseinstance_argument,
	unsigned int indirect_draw_bo_first_argument, unsigned int indirect_draw_bo_basevertex_argument)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	glu::ContextType contextType = m_context.getRenderContext().getType();

	/* If we already have initialized a VBO, delete it before we continue */
	if (m_vbo_id != 0)
	{
		gl.deleteBuffers(1, &m_vbo_id);

		m_vbo_id = 0;
	}

	/* Our BO storage is formed as below:
	 *
	 * [raw vertex data]
	 * [raw index data]
	 * [indirect glDrawArrays() call arguments]
	 * [indirect glDrawElements() call arguments]
	 *
	 * We store the relevant offsets in member fields, so that they can be used by actual test
	 * implementation.
	 */
	const unsigned int indirect_arrays_draw_call_arguments_size   = sizeof(unsigned int) * 4; /* as per spec */
	const unsigned int indirect_elements_draw_call_arguments_size = sizeof(unsigned int) * 5; /* as per spec */

	m_vbo_n_indices						  = raw_index_data_size / sizeof(unsigned int);
	m_vbo_vertex_data_offset			  = 0;
	m_vbo_index_data_offset				  = raw_vertex_data_size;
	m_vbo_indirect_arrays_argument_offset = m_vbo_index_data_offset + raw_index_data_size;
	m_vbo_indirect_elements_argument_offset =
		m_vbo_indirect_arrays_argument_offset + indirect_arrays_draw_call_arguments_size;

	/* Set up 'firstindex' argument so that it points at correct index data location */
	DE_ASSERT((m_vbo_index_data_offset % sizeof(unsigned int)) == 0);

	m_indirect_draw_call_firstindex_argument =
		static_cast<unsigned int>(m_vbo_index_data_offset / sizeof(unsigned int));

	/* Form indirect draw call argument buffers */
	unsigned int arrays_draw_call_arguments[] = { indirect_draw_bo_count_argument, indirect_draw_bo_primcount_argument,
												  indirect_draw_bo_first_argument,
												  indirect_draw_bo_baseinstance_argument };
	unsigned int elements_draw_call_arguments[] = {
		indirect_draw_bo_count_argument, indirect_draw_bo_primcount_argument, m_indirect_draw_call_firstindex_argument,
		indirect_draw_bo_basevertex_argument, indirect_draw_bo_baseinstance_argument
	};

	/* Set up BO storage */
	const unsigned int bo_data_size =
		m_vbo_indirect_elements_argument_offset + indirect_elements_draw_call_arguments_size;

	gl.genBuffers(1, &m_vbo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");

	gl.bindBuffer(GL_ARRAY_BUFFER, m_vbo_id);
	if (glu::contextSupports(contextType, glu::ApiType::core(4, 0)) ||
	    m_context.getContextInfo().isExtensionSupported("GL_ARB_draw_indirect"))
	{
		gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_vbo_id);
	}
	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vbo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call(s) failed.");

	gl.bufferData(GL_ARRAY_BUFFER, bo_data_size, DE_NULL, /* data */
				  GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");

	gl.bufferSubData(GL_ARRAY_BUFFER, m_vbo_vertex_data_offset, raw_vertex_data_size, raw_vertex_data);
	gl.bufferSubData(GL_ARRAY_BUFFER, m_vbo_index_data_offset, raw_index_data_size, raw_index_data);
	gl.bufferSubData(GL_ARRAY_BUFFER, m_vbo_indirect_arrays_argument_offset, sizeof(arrays_draw_call_arguments),
					 arrays_draw_call_arguments);
	gl.bufferSubData(GL_ARRAY_BUFFER, m_vbo_indirect_elements_argument_offset, sizeof(elements_draw_call_arguments),
					 elements_draw_call_arguments);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
}

/** Performs the actual test.
 *
 *  @return Always STOP.
 **/
tcu::TestNode::IterateResult PipelineStatisticsQueryTestFunctionalBase::iterate()
{
	bool has_passed = true;
	glu::ContextType contextType = m_context.getRenderContext().getType();

	/* Carry on only if GL_ARB_pipeline_statistics_query extension is supported */
	if (!glu::contextSupports(contextType, glu::ApiType::core(4, 6)) &&
		!m_context.getContextInfo().isExtensionSupported("GL_ARB_pipeline_statistics_query"))
	{
		throw tcu::NotSupportedError("GL_ARB_pipeline_statistics_query extension is not supported");
	}

	/* Initialize QO BO storage if GL_ARB_query_buffer_object is supported */
	if (m_context.getContextInfo().isExtensionSupported("GL_ARB_query_buffer_object"))
	{
		initQOBO();

		DE_ASSERT(m_bo_qo_id != 0);
	}

	/* Initialize other test-specific objects */
	initObjects();

	/* Iterate through all pipeline statistics query object types */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	for (unsigned int n_query_target = 0; n_query_target < PipelineStatisticsQueryUtilities::n_query_targets;
		 ++n_query_target)
	{
		glw::GLenum current_query_target = PipelineStatisticsQueryUtilities::query_targets[n_query_target];

		/* Make sure the query is supported */
		if (!PipelineStatisticsQueryUtilities::isQuerySupported(current_query_target, m_context.getContextInfo(), m_context.getRenderContext()))
		{
			continue;
		}

		if (shouldExecuteForQueryTarget(current_query_target))
		{
			/* Initialize the query object */
			gl.genQueries(1, &m_qo_id);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries() call failed.");

			/* Execute the test for the particular query target. */
			has_passed &= executeTest(current_query_target);

			/* Delete the query object */
			gl.deleteQueries(1, &m_qo_id);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteQueries() call failed.");

			m_qo_id = 0;
		}
	} /* for (all query targets) */

	if (has_passed)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	return STOP;
}

/** Initializes a query buffer object. */
void PipelineStatisticsQueryTestFunctionalBase::initQOBO()
{
	const glw::Functions gl = m_context.getRenderContext().getFunctions();

	/* Set up the buffer object we will use for storage of query object results */
	unsigned char bo_data[PipelineStatisticsQueryUtilities::qo_bo_size];

	memset(bo_data, 0xFF, sizeof(bo_data));

	gl.genBuffers(1, &m_bo_qo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");

	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_qo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");

	gl.bufferData(GL_ARRAY_BUFFER, PipelineStatisticsQueryUtilities::qo_bo_size, bo_data, GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
}

/** Executes a draw call, whose type is specified under pThis->m_current_draw_call_type.
 *
 *  @param pThis Pointer to a PipelineStatisticsQueryTestFunctionalBase instance, which
 *               should be used to extract the draw call type.
 *
 *  @return Always true.
 **/
bool PipelineStatisticsQueryTestFunctionalBase::queryCallbackDrawCallHandler(void* pThis)
{
	PipelineStatisticsQueryTestFunctionalBase* pInstance = (PipelineStatisticsQueryTestFunctionalBase*)pThis;
	const glw::Functions&					   gl		 = pInstance->m_context.getRenderContext().getFunctions();

	/* Issue the draw call */
	glw::GLenum primitive_type =
		PipelineStatisticsQueryUtilities::getEnumForPrimitiveType(pInstance->m_current_primitive_type);

	switch (pInstance->m_current_draw_call_type)
	{
	case PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWARRAYS:
	{
		gl.drawArrays(primitive_type, pInstance->m_indirect_draw_call_first_argument,
					  pInstance->m_indirect_draw_call_count_argument);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");

		break;
	}

	case PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWARRAYSINDIRECT:
	{
		gl.drawArraysIndirect(primitive_type,
							  (const glw::GLvoid*)(deUintptr)pInstance->m_vbo_indirect_arrays_argument_offset);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArraysIndirect() call failed.");

		break;
	}

	case PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWARRAYSINSTANCED:
	{
		gl.drawArraysInstanced(primitive_type, pInstance->m_indirect_draw_call_first_argument,
							   pInstance->m_indirect_draw_call_count_argument,
							   pInstance->m_indirect_draw_call_primcount_argument);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArraysInstanced() call failed.");

		break;
	}

	case PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWARRAYSINSTANCEDBASEINSTANCE:
	{
		gl.drawArraysInstancedBaseInstance(primitive_type, pInstance->m_indirect_draw_call_first_argument,
										   pInstance->m_indirect_draw_call_count_argument,
										   pInstance->m_indirect_draw_call_primcount_argument,
										   pInstance->m_indirect_draw_call_baseinstance_argument);

		break;
	}

	case PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWELEMENTS:
	{
		gl.drawElements(primitive_type, pInstance->m_indirect_draw_call_count_argument, GL_UNSIGNED_INT,
						(glw::GLvoid*)(deUintptr)pInstance->m_vbo_index_data_offset);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawElements() call failed.");

		break;
	}

	case PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWELEMENTSBASEVERTEX:
	{
		gl.drawElementsBaseVertex(primitive_type, pInstance->m_indirect_draw_call_count_argument, GL_UNSIGNED_INT,
								  (glw::GLvoid*)(deUintptr)pInstance->m_vbo_index_data_offset,
								  pInstance->m_indirect_draw_call_basevertex_argument);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawElementsBaseVertex() call failed.");

		break;
	}

	case PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWELEMENTSINDIRECT:
	{
		gl.drawElementsIndirect(primitive_type, GL_UNSIGNED_INT,
								(glw::GLvoid*)(deUintptr)pInstance->m_vbo_indirect_elements_argument_offset);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawElementsIndirect() call failed.");

		break;
	}

	case PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWELEMENTSINSTANCED:
	{
		gl.drawElementsInstanced(primitive_type, pInstance->m_indirect_draw_call_count_argument, GL_UNSIGNED_INT,
								 (glw::GLvoid*)(deUintptr)pInstance->m_vbo_index_data_offset,
								 pInstance->m_indirect_draw_call_primcount_argument);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawElementsInstanced() call failed.");

		break;
	}

	case PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWELEMENTSINSTANCEDBASEINSTANCE:
	{
		gl.drawElementsInstancedBaseInstance(
			primitive_type, pInstance->m_indirect_draw_call_count_argument, GL_UNSIGNED_INT,
			(glw::GLvoid*)(deUintptr)pInstance->m_vbo_index_data_offset,
			pInstance->m_indirect_draw_call_primcount_argument, pInstance->m_indirect_draw_call_baseinstance_argument);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawElementsInstancedBaseInstance() call failed.");

		break;
	}

	case PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
	{
		gl.drawElementsInstancedBaseVertexBaseInstance(
			primitive_type, pInstance->m_indirect_draw_call_count_argument, GL_UNSIGNED_INT,
			(glw::GLvoid*)(deUintptr)pInstance->m_vbo_index_data_offset,
			pInstance->m_indirect_draw_call_primcount_argument, pInstance->m_indirect_draw_call_basevertex_argument,
			pInstance->m_indirect_draw_call_baseinstance_argument);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawElementsInstancedBaseVertexBaseInstance() call failed.");

		break;
	}

	case PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWRANGEELEMENTS:
	{
		gl.drawRangeElements(primitive_type, 0, /* start */
							 pInstance->m_vbo_n_indices, pInstance->m_indirect_draw_call_count_argument,
							 GL_UNSIGNED_INT, (glw::GLvoid*)(deUintptr)pInstance->m_vbo_index_data_offset);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawRangeElements() call failed.");

		break;
	}

	case PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWRANGEELEMENTSBASEVERTEX:
	{
		gl.drawRangeElementsBaseVertex(primitive_type, 0,								   /* start */
									   pInstance->m_indirect_draw_call_count_argument - 1, /* end */
									   pInstance->m_indirect_draw_call_count_argument, GL_UNSIGNED_INT,
									   (glw::GLvoid*)(deUintptr)pInstance->m_vbo_index_data_offset,
									   pInstance->m_indirect_draw_call_basevertex_argument);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawRangeElementsBaseVertex() call failed.");

		break;
	}

	default:
	{
		TCU_FAIL("Unrecognized draw call type");
	}
	} /* switch (m_current_draw_call_type) */

	return true;
}

/** Tells whether the test instance should be executed for user-specified query target.
 *  Base class implementation returns true for all values of @param query_target.
 *
 *  @param query_target Query target to be used for the call.
 *
 *  @return Always true.
 **/
bool PipelineStatisticsQueryTestFunctionalBase::shouldExecuteForQueryTarget(glw::GLenum query_target)
{
	(void)query_target;
	return true;
}

/** Constructor.
 *
 *  @param context Rendering context.
 **/
PipelineStatisticsQueryTestFunctional1::PipelineStatisticsQueryTestFunctional1(deqp::Context& context)
	: PipelineStatisticsQueryTestFunctionalBase(context, "functional_default_qo_values",
												"Verifies that all pipeline statistics query objects "
												"use a default value of 0.")
{
	/* Left blank intentionally */
}

/** Executes a test iteration for user-specified query target.
 *
 *  @param current_query_target Pipeline statistics query target to execute the iteration
 *                              for.
 *
 *  @return true if the test passed for the iteration, false otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional1::executeTest(glw::GLenum current_query_target)
{
	bool													 result = true;
	PipelineStatisticsQueryUtilities::_test_execution_result run_result;

	if (!PipelineStatisticsQueryUtilities::executeQuery(
			current_query_target, m_qo_id, m_bo_qo_id, DE_NULL, /* pfn_draw */
			DE_NULL,											/* draw_user_arg */
			m_context.getRenderContext(), m_testCtx, m_context.getContextInfo(), &run_result))
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Could not retrieve test run results for query target "
													   "["
						   << PipelineStatisticsQueryUtilities::getStringForEnum(current_query_target) << "]"
						   << tcu::TestLog::EndMessage;

		result = false;
	}
	else
	{
		const glw::GLuint64 expected_value = 0;

		result &= PipelineStatisticsQueryUtilities::verifyResultValues(
			run_result, 1, &expected_value, m_bo_qo_id != 0, /* should_check_qo_bo_values */
			current_query_target, DE_NULL, DE_NULL,
			false, /* is_primitive_restart_enabled */
			m_testCtx, PipelineStatisticsQueryUtilities::VERIFICATION_TYPE_EXACT_MATCH);
	} /* if (run results were obtained successfully) */

	return result;
}

/** Constructor.
 *
 *  @param context Rendering context
 */
PipelineStatisticsQueryTestFunctional2::PipelineStatisticsQueryTestFunctional2(deqp::Context& context)
	: PipelineStatisticsQueryTestFunctionalBase(context, "functional_non_rendering_commands_do_not_affect_queries",
												"Verifies that non-rendering commands do not affect query"
												" values.")
	, m_bo_id(0)
	, m_fbo_draw_id(0)
	, m_fbo_read_id(0)
	, m_to_draw_fbo_id(0)
	, m_to_read_fbo_id(0)
	, m_to_height(16)
	, m_to_width(16)
{
	/* Left blank intentionally */
}

/** Deinitializes all GL objects that were created during test execution. */
void PipelineStatisticsQueryTestFunctional2::deinitObjects()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_bo_id != 0)
	{
		gl.deleteBuffers(1, &m_bo_id);

		m_bo_id = 0;
	}

	if (m_fbo_draw_id != 0)
	{
		gl.deleteFramebuffers(1, &m_fbo_draw_id);

		m_fbo_draw_id = 0;
	}

	if (m_fbo_read_id != 0)
	{
		gl.deleteFramebuffers(1, &m_fbo_read_id);

		m_fbo_read_id = 0;
	}

	if (m_to_draw_fbo_id != 0)
	{
		gl.deleteTextures(1, &m_to_draw_fbo_id);

		m_to_draw_fbo_id = 0;
	}

	if (m_to_read_fbo_id != 0)
	{
		gl.deleteTextures(1, &m_to_read_fbo_id);

		m_to_read_fbo_id = 0;
	}
}

/** Callback handler which calls glBlitFramebuffer() API function and makes sure it
 *  was executed successfully.
 *
 *  @param pThis Pointer to a PipelineStatisticsQueryTestFunctional2 instance. Must not
 *               be NULL.
 *
 *  @return Always true.
 **/
bool PipelineStatisticsQueryTestFunctional2::executeBlitFramebufferTest(void* pThis)
{
	PipelineStatisticsQueryTestFunctional2* data_ptr = (PipelineStatisticsQueryTestFunctional2*)pThis;
	const glw::Functions&					gl		 = data_ptr->m_context.getRenderContext().getFunctions();

	/* Framebuffer objects are bound to their FB targets at this point */
	gl.blitFramebuffer(0,						   /* srcX0 */
					   0,						   /* srcY0 */
					   data_ptr->m_to_width,	   /* srcX1 */
					   data_ptr->m_to_height,	  /* srcY1 */
					   0,						   /* dstX0 */
					   0,						   /* dstY0 */
					   data_ptr->m_to_width << 1,  /* dstX1 */
					   data_ptr->m_to_height << 1, /* dstY1 */
					   GL_COLOR_BUFFER_BIT,		   /* mask */
					   GL_LINEAR);				   /* filter */

	GLU_EXPECT_NO_ERROR(gl.getError(), "glBlitFramebuffer() call failed.");

	return true;
}

/** Callback handler which calls glBufferSubData() API function and makes sure it
 *  was executed successfully.
 *
 *  @param pThis Pointer to a PipelineStatisticsQueryTestFunctional2 instance. Must not
 *               be NULL.
 *
 *  @return Always true.
 **/
bool PipelineStatisticsQueryTestFunctional2::executeBufferSubDataTest(void* pThis)
{
	PipelineStatisticsQueryTestFunctional2* data_ptr	   = (PipelineStatisticsQueryTestFunctional2*)pThis;
	const glw::Functions&					gl			   = data_ptr->m_context.getRenderContext().getFunctions();
	const unsigned int						test_data_size = (PipelineStatisticsQueryTestFunctional2::bo_size / 2);
	unsigned char							test_bo_data[test_data_size];

	memset(test_bo_data, 0xFF, test_data_size);

	gl.bindBuffer(GL_ARRAY_BUFFER, data_ptr->m_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");

	gl.bufferSubData(GL_ARRAY_BUFFER, 0, /* offset */
					 test_data_size, test_bo_data);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");

	return true;
}

/** Callback handler which calls glClearBufferfv() API function and makes sure it
 *  was executed successfully.
 *
 *  @param pThis Pointer to a PipelineStatisticsQueryTestFunctional2 instance. Must not
 *               be NULL.
 *
 *  @return Always true.
 **/
bool PipelineStatisticsQueryTestFunctional2::executeClearBufferfvColorBufferTest(void* pThis)
{
	const glw::GLfloat						clear_color[4] = { 0, 0.1f, 0.2f, 0.3f };
	PipelineStatisticsQueryTestFunctional2* data_ptr	   = (PipelineStatisticsQueryTestFunctional2*)pThis;
	const glw::Functions&					gl			   = data_ptr->m_context.getRenderContext().getFunctions();

	gl.clearBufferfv(GL_COLOR, 0, /* drawbuffer */
					 clear_color);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearBufferfv() call failed.");

	return true;
}

/** Callback handler which calls glClearBufferfv() API function and makes sure it
 *  was executed successfully.
 *
 *  @param pThis Pointer to a PipelineStatisticsQueryTestFunctional2 instance. Must not
 *               be NULL.
 *
 *  @return Always true.
 **/
bool PipelineStatisticsQueryTestFunctional2::executeClearBufferfvDepthBufferTest(void* pThis)
{
	const glw::GLfloat						clear_depth = 0.1f;
	PipelineStatisticsQueryTestFunctional2* data_ptr	= (PipelineStatisticsQueryTestFunctional2*)pThis;
	const glw::Functions&					gl			= data_ptr->m_context.getRenderContext().getFunctions();

	gl.clearBufferfv(GL_DEPTH, 0, /* drawbuffer */
					 &clear_depth);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearBufferfv() call failed.");

	return true;
}

/** Callback handler which calls glClearBufferiv() API function and makes sure it
 *  was executed successfully.
 *
 *  @param pThis Pointer to a PipelineStatisticsQueryTestFunctional2 instance. Must not
 *               be NULL.
 *
 *  @return Always true.
 **/
bool PipelineStatisticsQueryTestFunctional2::executeClearBufferivStencilBufferTest(void* pThis)
{
	const glw::GLint						clear_stencil = 123;
	PipelineStatisticsQueryTestFunctional2* data_ptr	  = (PipelineStatisticsQueryTestFunctional2*)pThis;
	const glw::Functions&					gl			  = data_ptr->m_context.getRenderContext().getFunctions();

	gl.clearBufferiv(GL_STENCIL, 0, /* drawbuffer */
					 &clear_stencil);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearBufferfv() call failed.");

	return true;
}

/** Callback handler which calls glClearBufferSubData() API function and makes sure it
 *  was executed successfully.
 *
 *  @param pThis Pointer to a PipelineStatisticsQueryTestFunctional2 instance. Must not
 *               be NULL.
 *
 *  @return true if glClearBufferSubData() is available, false otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional2::executeClearBufferSubDataTest(void* pThis)
{
	PipelineStatisticsQueryTestFunctional2* data_ptr = (PipelineStatisticsQueryTestFunctional2*)pThis;
	const glw::Functions&					gl		 = data_ptr->m_context.getRenderContext().getFunctions();
	bool									result   = true;

	if (!glu::contextSupports(data_ptr->m_context.getRenderContext().getType(), glu::ApiType::core(4, 3)) &&
		gl.clearBufferSubData == NULL)
	{
		/* API is unavailable */
		return false;
	}

	/* Execute the API call */
	const unsigned char value = 0xFF;

	gl.clearBufferSubData(GL_ARRAY_BUFFER, GL_R8, 0, /* offset */
						  data_ptr->bo_size, GL_RED, GL_UNSIGNED_BYTE, &value);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearBufferSubData() call failed.");

	/* All done */
	return result;
}

/** Callback handler which calls glClear() API function configured to clear color
 *  buffer and makes sure it was executed successfully.
 *
 *  @param pThis Pointer to a PipelineStatisticsQueryTestFunctional2 instance. Must not
 *               be NULL.
 *
 *  @return Always true.
 **/
bool PipelineStatisticsQueryTestFunctional2::executeClearColorBufferTest(void* pThis)
{
	PipelineStatisticsQueryTestFunctional2* data_ptr = (PipelineStatisticsQueryTestFunctional2*)pThis;
	const glw::Functions&					gl		 = data_ptr->m_context.getRenderContext().getFunctions();

	gl.clear(GL_COLOR_BUFFER_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");

	return true;
}

/** Callback handler which calls glClear() API function configured to clear depth
 *  buffer and makes sure it was executed successfully.
 *
 *  @param pThis Pointer to a PipelineStatisticsQueryTestFunctional2 instance. Must not
 *               be NULL.
 *
 *  @return Always true.
 **/
bool PipelineStatisticsQueryTestFunctional2::executeClearDepthBufferTest(void* pThis)
{
	PipelineStatisticsQueryTestFunctional2* data_ptr = (PipelineStatisticsQueryTestFunctional2*)pThis;
	const glw::Functions&					gl		 = data_ptr->m_context.getRenderContext().getFunctions();

	gl.clear(GL_DEPTH_BUFFER_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");

	return true;
}

/** Callback handler which calls glClear() API function configured to clear stencil
 *  buffer and makes sure it was executed successfully.
 *
 *  @param pThis Pointer to a PipelineStatisticsQueryTestFunctional2 instance. Must not
 *               be NULL.
 *
 *  @return Always true.
 **/
bool PipelineStatisticsQueryTestFunctional2::executeClearStencilBufferTest(void* pThis)
{
	PipelineStatisticsQueryTestFunctional2* data_ptr = (PipelineStatisticsQueryTestFunctional2*)pThis;
	const glw::Functions&					gl		 = data_ptr->m_context.getRenderContext().getFunctions();

	gl.clear(GL_STENCIL_BUFFER_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");

	return true;
}

/** Callback handler which calls glClearTexSubImage() API function (if available).
 *
 *  @param pThis Pointer to a PipelineStatisticsQueryTestFunctional2 instance. Must not
 *               be NULL.
 *
 *  @return true if the function is supported by the running GL implementation, false
 *               otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional2::executeClearTexSubImageTest(void* pThis)
{
	PipelineStatisticsQueryTestFunctional2* data_ptr = (PipelineStatisticsQueryTestFunctional2*)pThis;
	const glw::Functions&					gl		 = data_ptr->m_context.getRenderContext().getFunctions();
	bool									result   = true;

	if (!glu::contextSupports(data_ptr->m_context.getRenderContext().getType(), glu::ApiType::core(4, 4)) &&
		gl.clearTexSubImage == NULL)
	{
		/* API is unavailable */
		return false;
	}

	/* Execute the API call */
	const unsigned char test_value = 0xFF;

	gl.clearTexSubImage(data_ptr->m_to_draw_fbo_id, 0,							/* level */
						0,														/* xoffset */
						0,														/* yoffset */
						0,														/* zoffset */
						data_ptr->m_to_width / 2, data_ptr->m_to_height / 2, 1, /* depth */
						GL_RED, GL_UNSIGNED_BYTE, &test_value);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearTexSubImage() call failed.");

	/* All done */
	return result;
}

/** Callback handler which calls glCopyImageSubData() API function (if available).
 *
 *  @param pThis Pointer to a PipelineStatisticsQueryTestFunctional2 instance. Must not
 *               be NULL.
 *
 *  @return true if the function is supported by the running GL implementation, false
 *               otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional2::executeCopyImageSubDataTest(void* pThis)
{
	PipelineStatisticsQueryTestFunctional2* data_ptr = (PipelineStatisticsQueryTestFunctional2*)pThis;
	const glw::Functions&					gl		 = data_ptr->m_context.getRenderContext().getFunctions();
	bool									result   = true;

	if (!glu::contextSupports(data_ptr->m_context.getRenderContext().getType(), glu::ApiType::core(4, 3)) &&
		gl.copyImageSubData == NULL)
	{
		/* API is unavailable */
		return false;
	}

	/* Execute the API call */
	gl.copyImageSubData(data_ptr->m_to_draw_fbo_id, GL_TEXTURE_2D, 0,			 /* srcLevel */
						0,														 /* srcX */
						0,														 /* srcY */
						0,														 /* srcZ */
						data_ptr->m_to_read_fbo_id, GL_TEXTURE_2D, 0,			 /* dstLevel */
						0,														 /* dstX */
						0,														 /* dstY */
						0,														 /* dstZ */
						data_ptr->m_to_width / 2, data_ptr->m_to_height / 2, 1); /* src_depth */
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyImageSubData() call failed.");

	/* All done */
	return result;
}

/** Callback handler which calls glTexSubImage2D().
 *
 *  @param pThis Pointer to a PipelineStatisticsQueryTestFunctional2 instance. Must not
 *               be NULL.
 *
 *  @return true Always true.
 **/
bool PipelineStatisticsQueryTestFunctional2::executeTexSubImageTest(void* pThis)
{
	PipelineStatisticsQueryTestFunctional2* data_ptr	   = (PipelineStatisticsQueryTestFunctional2*)pThis;
	const glw::Functions&					gl			   = data_ptr->m_context.getRenderContext().getFunctions();
	const unsigned int						test_data_size = PipelineStatisticsQueryTestFunctional2::bo_size / 2;
	unsigned char							test_data[test_data_size];

	memset(test_data, 0xFF, test_data_size);

	gl.texSubImage2D(GL_TEXTURE_2D, 0, /* level */
					 0,				   /* xoffset */
					 0,				   /* yoffset */
					 data_ptr->m_to_width / 2, data_ptr->m_to_height / 2, GL_RED, GL_UNSIGNED_BYTE, test_data);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed.");

	return true;
}

/** Executes a test iteration for user-specified query target.
 *
 *  @param current_query_target Pipeline statistics query target to execute the iteration
 *                              for.
 *
 *  @return true if the test passed for the iteration, false otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional2::executeTest(glw::GLenum current_query_target)
{
	bool															result = true;
	PipelineStatisticsQueryUtilities::_test_execution_result		run_result;
	const PipelineStatisticsQueryUtilities::PFNQUERYDRAWHANDLERPROC query_draw_handlers[] = {
		executeBlitFramebufferTest,
		executeBufferSubDataTest,
		executeClearBufferfvColorBufferTest,
		executeClearBufferfvDepthBufferTest,
		executeClearBufferivStencilBufferTest,
		executeClearBufferSubDataTest,
		executeClearColorBufferTest,
		executeClearDepthBufferTest,
		executeClearStencilBufferTest,
		executeClearTexSubImageTest,
		executeCopyImageSubDataTest,
		executeTexSubImageTest,
	};
	const unsigned int n_query_draw_handlers = sizeof(query_draw_handlers) / sizeof(query_draw_handlers[0]);

	for (unsigned int n = 0; n < n_query_draw_handlers; ++n)
	{
		const PipelineStatisticsQueryUtilities::PFNQUERYDRAWHANDLERPROC& draw_handler_pfn = query_draw_handlers[n];

		/* Query executors can return false if a given test cannot be executed, given
		 * work environment constraint (eg. insufficient GL version). In case of an error,
		 * they will throw an exception.
		 */
		if (draw_handler_pfn(this))
		{
			if (!PipelineStatisticsQueryUtilities::executeQuery(
					current_query_target, m_qo_id, m_bo_qo_id, DE_NULL, /* pfn_draw */
					DE_NULL,											/* draw_user_arg */
					m_context.getRenderContext(), m_testCtx, m_context.getContextInfo(), &run_result))
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Query execution failed for query target "
															   "["
								   << PipelineStatisticsQueryUtilities::getStringForEnum(current_query_target) << "]"
								   << tcu::TestLog::EndMessage;

				result = false;
			}
			else
			{
				const glw::GLuint64 expected_value = 0;
				bool				has_passed	 = true;

				has_passed = PipelineStatisticsQueryUtilities::verifyResultValues(
					run_result, 1, &expected_value, m_bo_qo_id != 0,  /* should_check_qo_bo_values */
					current_query_target, DE_NULL, DE_NULL, false, /* is_primitive_restart_enabled */
					m_testCtx, PipelineStatisticsQueryUtilities::VERIFICATION_TYPE_EXACT_MATCH);

				if (!has_passed)
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "Test failed for iteration index [" << n << "]."
									   << tcu::TestLog::EndMessage;

					result = false;
				}
			} /* if (run results were obtained successfully) */
		}	 /* if (draw handler executed successfully) */
	}

	return result;
}

/* Initializes all GL objects used by the test */
void PipelineStatisticsQueryTestFunctional2::initObjects()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Set up a buffer object we will use for one of the tests */
	gl.genBuffers(1, &m_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");

	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call(s) failed.");

	gl.bufferData(GL_ARRAY_BUFFER, bo_size, DE_NULL, /* data */
				  GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");

	/* Set up texture objects we will  use as color attachments for test FBOs */
	gl.genTextures(1, &m_to_draw_fbo_id);
	gl.genTextures(1, &m_to_read_fbo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed");

	gl.bindTexture(GL_TEXTURE_2D, m_to_draw_fbo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");

	gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
					GL_RGBA8, m_to_width, m_to_height);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");

	gl.bindTexture(GL_TEXTURE_2D, m_to_read_fbo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");

	gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
					GL_RGBA8, m_to_width, m_to_height);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");

	/* Set up framebuffer objects */
	gl.genFramebuffers(1, &m_fbo_draw_id);
	gl.genFramebuffers(1, &m_fbo_read_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call(s) failed.");

	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_draw_id);
	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call(s) failed.");

	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_draw_fbo_id, 0); /* level */
	gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_read_fbo_id, 0); /* level */
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call(s) failed.");
}

/** Constructor.
 *
 *  @param context Rendering context
 */
PipelineStatisticsQueryTestFunctional3::PipelineStatisticsQueryTestFunctional3(deqp::Context& context)
	: PipelineStatisticsQueryTestFunctionalBase(
		  context, "functional_primitives_vertices_submitted_and_clipping_input_output_primitives",
		  "Verifies that GL_PRIMITIVES_SUBMITTED_ARB, GL_VERTICES_SUBMITTED_ARB, "
		  "GL_CLIPPING_INPUT_PRIMITIVES_ARB, and GL_CLIPPING_OUTPUT_PRIMITIVES_ARB "
		  "queries work correctly.")
	, m_is_primitive_restart_enabled(false)
{
	/* Left blank intentionally */
}

/** Deinitializes all GL objects that were created during test execution. */
void PipelineStatisticsQueryTestFunctional3::deinitObjects()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_po_id != 0)
	{
		gl.deleteProgram(m_po_id);

		m_po_id = 0;
	}

	/* Disable "primitive restart" functionality */
	gl.disable(GL_PRIMITIVE_RESTART);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call failed.");
}

/** Executes a test iteration for user-specified query target.
 *
 *  @param current_query_target Pipeline statistics query target to execute the iteration
 *                              for.
 *
 *  @return true if the test passed for the iteration, false otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional3::executeTest(glw::GLenum current_query_target)
{
	const glw::Functions&									 gl		= m_context.getRenderContext().getFunctions();
	bool													 result = true;
	PipelineStatisticsQueryUtilities::_test_execution_result run_result;

	/* Sanity check: This method should only be called for GL_VERTICES_SUBMITTED_ARB,
	 * GL_PRIMITIVES_SUBMITTED_ARB, GL_CLIPPING_INPUT_PRIMITIVES_ARB and
	 * GL_CLIPPING_OUTPUT_PRIMITIVES_ARB queries */
	DE_ASSERT(current_query_target == GL_VERTICES_SUBMITTED_ARB ||
			  current_query_target == GL_PRIMITIVES_SUBMITTED_ARB ||
			  current_query_target == GL_CLIPPING_INPUT_PRIMITIVES_ARB ||
			  current_query_target == GL_CLIPPING_OUTPUT_PRIMITIVES_ARB);

	/* Set up VBO. We don't really care much about the visual outcome,
	 * so any data will do.
	 */
	const unsigned int n_vertex_components = 2;
	const float		   vertex_data[]	   = { -0.1f, 0.2f, 0.3f,  0.1f,  0.2f,  -0.7f, 0.5f,  -0.5f,
								  0.0f,  0.0f, -0.6f, -0.9f, -0.3f, 0.3f,  -0.5f, -0.5f };
	const unsigned int index_data[] = {
		0, 6, 2, 1, 3, 5, 4,
	};
	const unsigned int n_indices = sizeof(index_data) / sizeof(index_data[0]);

	m_indirect_draw_call_baseinstance_argument = 1;
	m_indirect_draw_call_basevertex_argument   = 0;
	m_indirect_draw_call_count_argument		   = n_indices;
	m_indirect_draw_call_first_argument		   = 0;
	m_indirect_draw_call_primcount_argument	= 3;

	initVBO(vertex_data, sizeof(vertex_data), index_data, sizeof(index_data), m_indirect_draw_call_count_argument,
			m_indirect_draw_call_primcount_argument, m_indirect_draw_call_baseinstance_argument,
			m_indirect_draw_call_first_argument, m_indirect_draw_call_basevertex_argument);

	initVAO(n_vertex_components);

	/* Verify that the query works correctly both when primitive restart functionality
	 * is disabled and enabled */
	const bool		   pr_statuses[] = { false, true };
	const unsigned int n_pr_statuses = sizeof(pr_statuses) / sizeof(pr_statuses[0]);

	for (unsigned int n_pr_status = 0; n_pr_status < n_pr_statuses; ++n_pr_status)
	{
		m_is_primitive_restart_enabled = pr_statuses[n_pr_status];

		/* Primitive restart should never be enabled for GL_CLIPPING_INPUT_PRIMITIVES_ARB query. */
		if ((current_query_target == GL_CLIPPING_INPUT_PRIMITIVES_ARB ||
			 current_query_target == GL_CLIPPING_OUTPUT_PRIMITIVES_ARB) &&
			m_is_primitive_restart_enabled)
		{
			continue;
		}

		/* Configure 'primitive restart' functionality */
		if (!m_is_primitive_restart_enabled)
		{
			gl.disable(GL_PRIMITIVE_RESTART);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call failed.");
		}
		else
		{
			gl.primitiveRestartIndex(0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glPrimitiveRestartIndex() call failed.");

			gl.enable(GL_PRIMITIVE_RESTART);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call failed.");
		}

		/* Iterate through all primitive types */
		for (unsigned int n_primitive_type = 0;
			 n_primitive_type < PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_COUNT; ++n_primitive_type)
		{
			m_current_primitive_type = (PipelineStatisticsQueryUtilities::_primitive_type)n_primitive_type;

			/* Exclude patches from the test */
			if (m_current_primitive_type == PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_PATCHES)
			{
				continue;
			}

			/* Iterate through all draw call types while the query is enabled (skip DrawArrays calls if primitive restart is enabled) */
			for (unsigned int n_draw_call_type =
					 (m_is_primitive_restart_enabled ? PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_GLDRAWELEMENTS :
													   0);
				 n_draw_call_type < PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_COUNT; ++n_draw_call_type)
			{
				m_current_draw_call_type = (PipelineStatisticsQueryUtilities::_draw_call_type)n_draw_call_type;

				/* Only continue if the draw call is supported by the context */
				if (!PipelineStatisticsQueryUtilities::isDrawCallSupported(m_current_draw_call_type, gl))
				{
					continue;
				}

				if (!PipelineStatisticsQueryUtilities::executeQuery(
						current_query_target, m_qo_id, m_bo_qo_id, queryCallbackDrawCallHandler,
						(PipelineStatisticsQueryTestFunctionalBase*)this, m_context.getRenderContext(), m_testCtx,
						m_context.getContextInfo(), &run_result))
				{
					m_testCtx.getLog() << tcu::TestLog::Message
									   << "Could not retrieve test run results for query target "
										  "["
									   << PipelineStatisticsQueryUtilities::getStringForEnum(current_query_target)
									   << "]" << tcu::TestLog::EndMessage;

					result = false;
				}
				else
				{
					glw::GLuint64										 expected_values[4] = { 0 };
					unsigned int										 n_expected_values  = 0;
					PipelineStatisticsQueryUtilities::_verification_type verification_type =
						PipelineStatisticsQueryUtilities::VERIFICATION_TYPE_EXACT_MATCH;

					if (current_query_target == GL_CLIPPING_OUTPUT_PRIMITIVES_ARB)
					{
						verification_type = PipelineStatisticsQueryUtilities::VERIFICATION_TYPE_EQUAL_OR_GREATER;
					}

					if (current_query_target == GL_VERTICES_SUBMITTED_ARB)
					{
						getExpectedVerticesSubmittedQueryResult(m_current_primitive_type, &n_expected_values,
																expected_values);
					}
					else
					{
						getExpectedPrimitivesSubmittedQueryResult(m_current_primitive_type, &n_expected_values,
																  expected_values);
					}

					result &= PipelineStatisticsQueryUtilities::verifyResultValues(
						run_result, n_expected_values, expected_values, m_bo_qo_id != 0, /* should_check_qo_bo_values */
						current_query_target, &m_current_draw_call_type, &m_current_primitive_type,
						m_is_primitive_restart_enabled, m_testCtx, verification_type);

				} /* if (run results were obtained successfully) */
			}	 /* for (all draw call types) */
		}		  /* for (all primitive types) */
	}			  /* for (both when primitive restart is disabled and enabled) */

	return result;
}

/** Returns the expected result value(s) for a GL_PRIMITIVES_SUBMITTED_ARB query. There
 *  can be either one or two result values, depending on how the implementation handles
 *  incomplete primitives.
 *
 *  @param current_primitive_type Primitive type used for the draw call, for which
 *                                the query would be executed
 *  @param out_result1_written    Deref will be set to true, if the first result value
 *                                was written to @param out_result1. Otherwise, it will
 *                                be set to false.
 *  @param out_result1            Deref will be set to the first of the acceptable
 *                                result values, if @param out_result1_written was set
 *                                to true.
 *  @param out_result2_written    Deref will be set to true, if the second result value
 *                                was written to @param out_result2. Otherwise, it will
 *                                be set to false.
 *  @param out_result2            Deref will be set to the second of the acceptable
 *                                result values, if @param out_result2_written was set
 *                                to true.
 *
 **/
void PipelineStatisticsQueryTestFunctional3::getExpectedPrimitivesSubmittedQueryResult(
	PipelineStatisticsQueryUtilities::_primitive_type current_primitive_type, unsigned int* out_results_written,
	glw::GLuint64 out_results[4])
{
	unsigned int n_input_vertices = m_indirect_draw_call_count_argument;

	*out_results_written = 0;

	/* Sanity checks */
	DE_ASSERT(current_primitive_type != PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_PATCHES);

	/* Carry on */
	if (m_is_primitive_restart_enabled)
	{
		/* Primitive restart functionality in our test removes a single index.
		 *
		 * Note: This also applies to arrayed draw calls, since we're testing
		 *       GL_PRIMITIVE_RESTART rendering mode, and we're using a primitive
		 *       restart index of 0.
		 **/
		n_input_vertices--;
	}

	switch (current_primitive_type)
	{
	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_POINTS:
	{
		out_results[(*out_results_written)++] = n_input_vertices;

		break;
	}

	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_LINE_LOOP:
	{
		if (n_input_vertices > 2)
		{
			out_results[(*out_results_written)++] = n_input_vertices;
		}
		else if (n_input_vertices > 1)
		{
			out_results[(*out_results_written)++] = 1;
		}
		else
		{
			out_results[(*out_results_written)++] = 0;
		}

		break;
	} /* PRIMITIVE_TYPE_LINE_LOOP */

	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_TRIANGLE_FAN:
	{
		if (n_input_vertices > 2)
		{
			out_results[(*out_results_written)++] = n_input_vertices - 2;
		}
		else
		{
			out_results[(*out_results_written)++] = 0;

			if (n_input_vertices >= 1)
			{
				/* If the submitted triangle fan is incomplete, also include the case
				 * where the incomplete triangle fan's vertices are counted as a primitive.
				 */
				out_results[(*out_results_written)++] = 1;
			}
		}

		break;
	}

	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_LINE_STRIP:
	{
		if (n_input_vertices > 1)
		{
			out_results[(*out_results_written)++] = n_input_vertices - 1;
		}
		else
		{
			out_results[(*out_results_written)++] = 0;

			if (n_input_vertices > 0)
			{
				/* If the submitted line strip is incomplete, also include the case
				 * where the incomplete line's vertices are counted as a primitive.
				 */
				out_results[(*out_results_written)++] = 1;
			}
		}

		break;
	}

	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_TRIANGLE_STRIP:
	{
		if (n_input_vertices > 2)
		{
			out_results[(*out_results_written)++] = n_input_vertices - 2;
		}
		else
		{
			out_results[(*out_results_written)++] = 0;

			if (n_input_vertices >= 1)
			{
				/* If the submitted triangle strip is incomplete, also include the case
				 * where the incomplete triangle's vertices are counted as a primitive.
				 */
				out_results[(*out_results_written)++] = 1;
			}
		}

		break;
	}

	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_LINES:
	{
		out_results[(*out_results_written)++] = n_input_vertices / 2;

		/* If the submitted line is incomplete, also include the case where
		 * the incomplete line's vertices are counted as a primitive.
		 */
		if (n_input_vertices > 0 && (n_input_vertices % 2) != 0)
		{
			out_results[(*out_results_written)++] = n_input_vertices / 2 + 1;
		}

		break;
	}

	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_LINES_ADJACENCY:
	{
		out_results[(*out_results_written)++] = n_input_vertices / 4;

		/* If the submitted line is incomplete, also include the case where
		 * the incomplete line's vertices are counted as a primitive.
		 */
		if (n_input_vertices > 0 && (n_input_vertices % 4) != 0)
		{
			out_results[(*out_results_written)++] = n_input_vertices / 4 + 1;
		}

		break;
	}

	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_TRIANGLES:
	{
		out_results[(*out_results_written)++] = n_input_vertices / 3;

		/* If the submitted triangle is incomplete, also include the case
		 * when the incomplete triangle's vertices are counted as a primitive.
		 */
		if (n_input_vertices > 0 && (n_input_vertices % 3) != 0)
		{
			out_results[(*out_results_written)++] = n_input_vertices / 3 + 1;
		}

		break;
	}

	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_TRIANGLES_ADJACENCY:
	{
		out_results[(*out_results_written)++] = n_input_vertices / 6;

		/* If the submitted triangle is incomplete, also include the case
		 * when the incomplete triangle's vertices are counted as a primitive.
		 */
		if (n_input_vertices > 0 && (n_input_vertices % 6) != 0)
		{
			out_results[(*out_results_written)++] = n_input_vertices / 6 + 1;
		}

		break;
	}

	default:
	{
		TCU_FAIL("Unrecognized primitive type");
	}
	} /* switch (current_primitive_type) */

	if (PipelineStatisticsQueryUtilities::isInstancedDrawCall(m_current_draw_call_type))
	{
		for (unsigned int i = 0; i < *out_results_written; ++i)
		{
			out_results[i] *= m_indirect_draw_call_primcount_argument;
		}
	} /* if (instanced draw call type) */
}

/** Returns the expected result value(s) for a GL_VERTICES_SUBMITTED_ARB query. There
 *  can be either one or two result values, depending on how the implementation handles
 *  incomplete primitives.
 *
 *  @param current_primitive_type Primitive type used for the draw call, for which
 *                                the query would be executed
 *  @param out_result1_written    Deref will be set to true, if the first result value
 *                                was written to @param out_result1. Otherwise, it will
 *                                be set to false.
 *  @param out_result1            Deref will be set to the first of the acceptable
 *                                result values, if @param out_result1_written was set
 *                                to true.
 *  @param out_result2_written    Deref will be set to true, if the second result value
 *                                was written to @param out_result2. Otherwise, it will
 *                                be set to false.
 *  @param out_result2            Deref will be set to the second of the acceptable
 *                                result values, if @param out_result2_written was set
 *                                to true.
 *
 **/
void PipelineStatisticsQueryTestFunctional3::getExpectedVerticesSubmittedQueryResult(
	PipelineStatisticsQueryUtilities::_primitive_type current_primitive_type, unsigned int* out_results_written,
	glw::GLuint64 out_results[4])
{
	unsigned int n_input_vertices = m_indirect_draw_call_count_argument;

	*out_results_written = 0;

	/* Sanity checks */
	DE_ASSERT(current_primitive_type != PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_PATCHES);

	/* Carry on */
	if (m_is_primitive_restart_enabled)
	{
		/* Primitive restart functionality in our test removes a single index.
		 *
		 * Note: This also applies to arrayed draw calls, since we're testing
		 *       GL_PRIMITIVE_RESTART rendering mode, and we're using a primitive
		 *       restart index of 0.
		 **/
		n_input_vertices--;
	}

	switch (current_primitive_type)
	{
	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_POINTS:
	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_LINE_STRIP:
	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_TRIANGLE_FAN:
	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_TRIANGLE_STRIP:
	{
		out_results[(*out_results_written)++] = n_input_vertices;

		break;
	}

	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_LINE_LOOP:
	{
		out_results[(*out_results_written)++] = n_input_vertices;

		/* Allow line loops to count the first vertex twice as that vertex
		 * is part of both the first and the last primitives.
		 */
		out_results[(*out_results_written)++] = n_input_vertices + 1;
		break;
	}

	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_LINES:
	{
		out_results[(*out_results_written)++] = n_input_vertices;

		/* If the submitted line is incomplete, also include the case where
		 * the incomplete line's vertices are not counted.
		 */
		if (n_input_vertices > 0 && (n_input_vertices % 2) != 0)
		{
			out_results[(*out_results_written)++] = n_input_vertices - 1;
		}

		break;
	}

	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_LINES_ADJACENCY:
	{
		/* Allow implementations to both include or exclude the adjacency
		 * vertices.
		 */
		out_results[(*out_results_written)++] = n_input_vertices;
		out_results[(*out_results_written)++] = n_input_vertices / 2;

		/* If the submitted line is incomplete, also include the case where
		 * the incomplete line's vertices are not counted.
		 */
		if (n_input_vertices > 0 && (n_input_vertices % 4) != 0)
		{
			out_results[(*out_results_written)++] = n_input_vertices - (n_input_vertices % 4);
			out_results[(*out_results_written)++] = (n_input_vertices - (n_input_vertices % 4)) / 2;
		}

		break;
	}

	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_TRIANGLES:
	{
		out_results[(*out_results_written)++] = n_input_vertices;

		/* If the submitted triangle is incomplete, also include the case
		 * when the incomplete triangle's vertices are not counted.
		 */
		if (n_input_vertices > 0 && (n_input_vertices % 3) != 0)
		{
			out_results[(*out_results_written)++] = n_input_vertices - (n_input_vertices % 3);
		}

		break;
	}

	case PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_TRIANGLES_ADJACENCY:
	{
		/* Allow implementations to both include or exclude the adjacency
		 * vertices.
		 */
		out_results[(*out_results_written)++] = n_input_vertices;
		out_results[(*out_results_written)++] = n_input_vertices / 2;

		/* If the submitted triangle is incomplete, also include the case
		 * when the incomplete triangle's vertices are not counted.
		 */
		if (n_input_vertices > 0 && (n_input_vertices % 6) != 0)
		{
			out_results[(*out_results_written)++] = n_input_vertices - (n_input_vertices % 6);
			out_results[(*out_results_written)++] = (n_input_vertices - (n_input_vertices % 6)) / 2;
		}

		break;
	}

	default:
	{
		TCU_FAIL("Unrecognized primitive type");
	}
	} /* switch (current_primitive_type) */

	if (PipelineStatisticsQueryUtilities::isInstancedDrawCall(m_current_draw_call_type))
	{
		for (unsigned int i = 0; i < *out_results_written; ++i)
		{
			out_results[i] *= m_indirect_draw_call_primcount_argument;
		}
	} /* if (instanced draw call type) */
}

/** Initializes GL objects used by the test */
void PipelineStatisticsQueryTestFunctional3::initObjects()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	buildProgram(DE_NULL,												   /* cs_body */
				 PipelineStatisticsQueryUtilities::dummy_fs_code, DE_NULL, /* gs_body */
				 DE_NULL,												   /* tc_body */
				 DE_NULL,												   /* te_body */
				 PipelineStatisticsQueryUtilities::dummy_vs_code);

	gl.useProgram(m_po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
}

/** Tells whether the test instance should be executed for user-specified query target.
 *
 *  @param query_target Query target to be used for the call.
 *
 *  @return true  if @param query_target is either GL_VERTICES_SUBMITTED_ARB,
 *                GL_PRIMITIVES_SUBMITTED_ARB, GL_CLIPPING_INPUT_PRIMITIVES_ARB, or
 *                GL_CLIPPING_OUTPUT_PRIMITIVES_ARB.
 *          false otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional3::shouldExecuteForQueryTarget(glw::GLenum query_target)
{
	return (query_target == GL_VERTICES_SUBMITTED_ARB || query_target == GL_PRIMITIVES_SUBMITTED_ARB ||
			query_target == GL_CLIPPING_INPUT_PRIMITIVES_ARB || query_target == GL_CLIPPING_OUTPUT_PRIMITIVES_ARB);
}

/** Constructor.
 *
 *  @param context Rendering context
 */
PipelineStatisticsQueryTestFunctional4::PipelineStatisticsQueryTestFunctional4(deqp::Context& context)
	: PipelineStatisticsQueryTestFunctionalBase(context, "functional_vertex_shader_invocations",
												"Verifies GL_VERTEX_SHADER_INVOCATIONS_ARB query works correctly")
{
	/* Left blank intentionally */
}

/** Deinitializes all GL objects that were created during test execution. */
void PipelineStatisticsQueryTestFunctional4::deinitObjects()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_po_id != 0)
	{
		gl.deleteProgram(m_po_id);

		m_po_id = 0;
	}
}

/** Executes a test iteration for user-specified query target.
 *
 *  @param current_query_target Pipeline statistics query target to execute the iteration
 *                              for.
 *
 *  @return true if the test passed for the iteration, false otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional4::executeTest(glw::GLenum current_query_target)
{
	const glw::Functions&									 gl		= m_context.getRenderContext().getFunctions();
	bool													 result = true;
	PipelineStatisticsQueryUtilities::_test_execution_result run_result;

	/* Sanity check: This method should only be called for GL_VERTEX_SHADER_INVOCATIONS_ARB
	 * query */
	DE_ASSERT(current_query_target == GL_VERTEX_SHADER_INVOCATIONS_ARB);

	/* Set up VBO. */
	const unsigned int n_vertex_components = 2;
	const float		   vertex_data[]  = { -0.1f, 0.2f, 0.3f, 0.1f, 0.2f, -0.7f, 0.5f, -0.5f, 0.0f, 0.0f, 0.1f, 0.2f };
	const unsigned int index_data[]   = { 4, 3, 2, 1, 0 };
	const unsigned int n_data_indices = sizeof(index_data) / sizeof(index_data[0]);

	/* Issue the test for 1 to 5 indices */
	for (unsigned int n_indices = 1; n_indices < n_data_indices; ++n_indices)
	{
		m_indirect_draw_call_baseinstance_argument = 1;
		m_indirect_draw_call_basevertex_argument   = 1;
		m_indirect_draw_call_count_argument		   = n_indices;
		m_indirect_draw_call_first_argument		   = 0;
		m_indirect_draw_call_primcount_argument	= 4;

		initVBO(vertex_data, sizeof(vertex_data), index_data, sizeof(index_data), m_indirect_draw_call_count_argument,
				m_indirect_draw_call_primcount_argument, m_indirect_draw_call_baseinstance_argument,
				m_indirect_draw_call_first_argument, m_indirect_draw_call_basevertex_argument);

		initVAO(n_vertex_components);

		/* Iterate through all primitive types */
		for (unsigned int n_primitive_type = 0;
			 n_primitive_type < PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_COUNT; ++n_primitive_type)
		{
			m_current_primitive_type = (PipelineStatisticsQueryUtilities::_primitive_type)n_primitive_type;

			/* Exclude patches from the test */
			if (m_current_primitive_type == PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_PATCHES)
			{
				continue;
			}

			/* Exclude the primitive types, for which the number of indices is insufficient to form
			 * a primitive.
			 */
			if ((m_current_primitive_type == PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_LINE_LOOP &&
				 n_indices < 2) ||
				(m_current_primitive_type == PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_LINE_STRIP &&
				 n_indices < 2) ||
				(m_current_primitive_type == PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_LINES && n_indices < 2) ||
				(m_current_primitive_type == PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_TRIANGLE_FAN &&
				 n_indices < 3) ||
				(m_current_primitive_type == PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_TRIANGLE_STRIP &&
				 n_indices < 3) ||
				(m_current_primitive_type == PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_TRIANGLES &&
				 n_indices < 3))
			{
				/* Skip the iteration */
				continue;
			}

			/* Exclude adjacency primitive types from the test, since we're not using geometry shader stage. */
			if (m_current_primitive_type == PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_LINES_ADJACENCY ||
				m_current_primitive_type == PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_TRIANGLES_ADJACENCY)
			{
				continue;
			}

			/* Iterate through all draw call types */
			for (unsigned int n_draw_call_type = 0;
				 n_draw_call_type < PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_COUNT; ++n_draw_call_type)
			{
				m_current_draw_call_type = (PipelineStatisticsQueryUtilities::_draw_call_type)n_draw_call_type;

				/* Only continue if the draw call is supported by the context */
				if (!PipelineStatisticsQueryUtilities::isDrawCallSupported(m_current_draw_call_type, gl))
				{
					continue;
				}

				/* Execute the query */
				if (!PipelineStatisticsQueryUtilities::executeQuery(
						current_query_target, m_qo_id, m_bo_qo_id, queryCallbackDrawCallHandler,
						(PipelineStatisticsQueryTestFunctionalBase*)this, m_context.getRenderContext(), m_testCtx,
						m_context.getContextInfo(), &run_result))
				{
					m_testCtx.getLog() << tcu::TestLog::Message
									   << "Could not retrieve test run results for query target "
										  "["
									   << PipelineStatisticsQueryUtilities::getStringForEnum(current_query_target)
									   << "]" << tcu::TestLog::EndMessage;

					result = false;
				}
				else
				{
					static const glw::GLuint64 expected_value = 1;

					/* Compare it against query result values */
					result &= PipelineStatisticsQueryUtilities::verifyResultValues(
						run_result, 1, &expected_value, m_bo_qo_id != 0, /* should_check_qo_bo_values */
						current_query_target, &m_current_draw_call_type, &m_current_primitive_type,
						false, /* is_primitive_restart_enabled */
						m_testCtx, PipelineStatisticsQueryUtilities::VERIFICATION_TYPE_EQUAL_OR_GREATER);

				} /* if (run results were obtained successfully) */
			}	 /* for (all draw call types) */
		}		  /* for (all primitive types) */
	}			  /* for (1 to 5 indices) */

	return result;
}

/** Initializes all GL objects used by the test */
void PipelineStatisticsQueryTestFunctional4::initObjects()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	buildProgram(DE_NULL, /* cs_body */
				 DE_NULL, /* fs_body */
				 DE_NULL, /* gs_body */
				 DE_NULL, /* tc_body */
				 DE_NULL, /* te_body */
				 PipelineStatisticsQueryUtilities::dummy_vs_code);

	gl.useProgram(m_po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
}

/** Tells whether the test instance should be executed for user-specified query target.
 *
 *  @param query_target Query target to be used for the call.
 *
 *  @return true  if @param query_target is GL_VERTEX_SHADER_INVOCATIONS_ARB.
 *          false otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional4::shouldExecuteForQueryTarget(glw::GLenum query_target)
{
	return (query_target == GL_VERTEX_SHADER_INVOCATIONS_ARB);
}

/** Constructor.
 *
 *  @param context Rendering context
 */
PipelineStatisticsQueryTestFunctional5::PipelineStatisticsQueryTestFunctional5(deqp::Context& context)
	: PipelineStatisticsQueryTestFunctionalBase(context, "functional_tess_queries",
												"Verifies that GL_TESS_CONTROL_SHADER_PATCHES_ARB and "
												"GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB queries "
												"work correctly.")
{
	/* Left blank intentionally */
}

/** Deinitializes all GL objects that were created during test execution. */
void PipelineStatisticsQueryTestFunctional5::deinitObjects()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_po_id != 0)
	{
		gl.deleteProgram(m_po_id);

		m_po_id = 0;
	}
}

/** Executes a test iteration for user-specified query target.
 *
 *  @param current_query_target Pipeline statistics query target to execute the iteration
 *                              for.
 *
 *  @return true if the test passed for the iteration, false otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional5::executeTest(glw::GLenum current_query_target)
{
	const glw::Functions&									 gl		= m_context.getRenderContext().getFunctions();
	bool													 result = true;
	PipelineStatisticsQueryUtilities::_test_execution_result run_result;

	/* Sanity check: This method should only be called for GL_TESS_CONTROL_SHADER_PATCHES_ARB and
	 * GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB queries. */
	DE_ASSERT(current_query_target == GL_TESS_CONTROL_SHADER_PATCHES_ARB ||
			  current_query_target == GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB);

	/* Set up VBO. */
	const unsigned int n_vertex_components = 2;
	const float		   vertex_data[]	   = {
		-0.1f, 0.2f, 0.2f, -0.7f, 0.5f, -0.5f,
	};
	const unsigned int index_data[] = { 2, 1, 0 };

	m_indirect_draw_call_baseinstance_argument = 1;
	m_indirect_draw_call_basevertex_argument   = 1;
	m_indirect_draw_call_count_argument		   = 3; /* default GL_PATCH_VERTICES value */
	m_indirect_draw_call_first_argument		   = 0;
	m_indirect_draw_call_primcount_argument	= 4;

	initVBO(vertex_data, sizeof(vertex_data), index_data, sizeof(index_data), m_indirect_draw_call_count_argument,
			m_indirect_draw_call_primcount_argument, m_indirect_draw_call_baseinstance_argument,
			m_indirect_draw_call_first_argument, m_indirect_draw_call_basevertex_argument);

	initVAO(n_vertex_components);

	/* Set up the primitive type */
	m_current_primitive_type = PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_PATCHES;

	/* Iterate through all draw call types */
	for (unsigned int n_draw_call_type = 0; n_draw_call_type < PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_COUNT;
		 ++n_draw_call_type)
	{
		m_current_draw_call_type = (PipelineStatisticsQueryUtilities::_draw_call_type)n_draw_call_type;

		/* Only continue if the draw call is supported by the context */
		if (!PipelineStatisticsQueryUtilities::isDrawCallSupported(m_current_draw_call_type, gl))
		{
			continue;
		}

		/* Execute the query */
		if (!PipelineStatisticsQueryUtilities::executeQuery(
				current_query_target, m_qo_id, m_bo_qo_id, queryCallbackDrawCallHandler,
				(PipelineStatisticsQueryTestFunctionalBase*)this, m_context.getRenderContext(), m_testCtx,
				m_context.getContextInfo(), &run_result))
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Could not retrieve test run results for query target "
														   "["
							   << PipelineStatisticsQueryUtilities::getStringForEnum(current_query_target) << "]"
							   << tcu::TestLog::EndMessage;

			result = false;
		}
		else
		{
			static const glw::GLuint64 expected_value = 1; /* as per test spec */

			/* Compare it against query result values */
			result &= PipelineStatisticsQueryUtilities::verifyResultValues(
				run_result, 1, &expected_value, m_bo_qo_id != 0, /* should_check_qo_bo_values */
				current_query_target, &m_current_draw_call_type, &m_current_primitive_type,
				false, /* is_primitive_restart_enabled */
				m_testCtx, PipelineStatisticsQueryUtilities::VERIFICATION_TYPE_EQUAL_OR_GREATER);

		} /* if (run results were obtained successfully) */
	}	 /* for (all draw call types) */

	return result;
}

/** Initializes all GL objects used by the test */
void PipelineStatisticsQueryTestFunctional5::initObjects()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* This test should not execute if we're not running at least a GL4.0 context */
	if (!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)))
	{
		throw tcu::NotSupportedError("OpenGL 4.0+ is required to run this test.");
	}

	buildProgram(DE_NULL,												   /* cs_body */
				 PipelineStatisticsQueryUtilities::dummy_fs_code, DE_NULL, /* gs_body */
				 PipelineStatisticsQueryUtilities::dummy_tc_code, PipelineStatisticsQueryUtilities::dummy_te_code,
				 PipelineStatisticsQueryUtilities::dummy_vs_code);

	gl.useProgram(m_po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
}

/** Tells whether the test instance should be executed for user-specified query target.
 *
 *  @param query_target Query target to be used for the call.
 *
 *  @return true  if @param query_target is either GL_TESS_CONTROL_SHADER_PATCHES_ARB,
 *                or GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB.
 *          false otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional5::shouldExecuteForQueryTarget(glw::GLenum query_target)
{
	return (query_target == GL_TESS_CONTROL_SHADER_PATCHES_ARB ||
			query_target == GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB);
}

/** Constructor.
 *
 *  @param context Rendering context
 */
PipelineStatisticsQueryTestFunctional6::PipelineStatisticsQueryTestFunctional6(deqp::Context& context)
	: PipelineStatisticsQueryTestFunctionalBase(context, "functional_geometry_shader_queries",
												"Verifies that GL_GEOMETRY_SHADER_INVOCATIONS and "
												"GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB queries "
												"work correctly.")
	, m_n_primitives_emitted_by_gs(3)
	, m_n_streams_emitted_by_gs(3)
{
	/* Left blank intentionally */
}

/** Deinitializes all GL objects that were created during test execution. */
void PipelineStatisticsQueryTestFunctional6::deinitObjects()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_po_id != 0)
	{
		gl.deleteProgram(m_po_id);

		m_po_id = 0;
	}
}

/** Executes a test iteration for user-specified query target.
 *
 *  @param current_query_target Pipeline statistics query target to execute the iteration
 *                              for.
 *
 *  @return true if the test passed for the iteration, false otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional6::executeTest(glw::GLenum current_query_target)
{
	const glw::Functions&									 gl		= m_context.getRenderContext().getFunctions();
	bool													 result = true;
	PipelineStatisticsQueryUtilities::_test_execution_result run_result;

	/* Sanity check: This method should only be called for GL_GEOMETRY_SHADER_INVOCATIONS and
	 * GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB queries. */
	DE_ASSERT(current_query_target == GL_GEOMETRY_SHADER_INVOCATIONS ||
			  current_query_target == GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB);

	/* Set up VBO. */
	const unsigned int n_vertex_components = 2;
	const float		   vertex_data[]	   = {
		-0.1f, 0.2f, 0.2f, -0.7f, 0.5f, -0.5f, 0.1f, -0.2f, -0.2f, 0.7f, -0.5f, 0.5f,
	};
	const unsigned int index_data[]			   = { 2, 1, 0 };
	m_indirect_draw_call_baseinstance_argument = 1;
	m_indirect_draw_call_basevertex_argument   = 1;
	m_indirect_draw_call_count_argument =
		3; /* note: we will update the argument per iteration, so just use anything for now */
	m_indirect_draw_call_first_argument		= 0;
	m_indirect_draw_call_primcount_argument = 4;

	initVBO(vertex_data, sizeof(vertex_data), index_data, sizeof(index_data), m_indirect_draw_call_count_argument,
			m_indirect_draw_call_primcount_argument, m_indirect_draw_call_baseinstance_argument,
			m_indirect_draw_call_first_argument, m_indirect_draw_call_basevertex_argument);

	initVAO(n_vertex_components);

	/* Iterate over all input primitives supported by geometry shaders */
	for (int gs_input_it = static_cast<int>(PipelineStatisticsQueryUtilities::GEOMETRY_SHADER_INPUT_FIRST);
		 gs_input_it != static_cast<int>(PipelineStatisticsQueryUtilities::GEOMETRY_SHADER_INPUT_COUNT); ++gs_input_it)
	{
		PipelineStatisticsQueryUtilities::_geometry_shader_input gs_input =
			static_cast<PipelineStatisticsQueryUtilities::_geometry_shader_input>(gs_input_it);
		/* Set up the 'count' argument and update the VBO contents */
		m_indirect_draw_call_count_argument = PipelineStatisticsQueryUtilities::getNumberOfVerticesForGSInput(gs_input);

		/* Update the VBO contents */
		gl.bufferSubData(
			GL_ARRAY_BUFFER,
			m_vbo_indirect_arrays_argument_offset, /* the very first argument is 'count' which we need to update */
			sizeof(m_indirect_draw_call_count_argument), &m_indirect_draw_call_count_argument);
		gl.bufferSubData(
			GL_ARRAY_BUFFER,
			m_vbo_indirect_elements_argument_offset, /* the very first argument is 'count' which we need to update */
			sizeof(m_indirect_draw_call_count_argument), &m_indirect_draw_call_count_argument);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call(s) failed.");

		for (int gs_output_it = static_cast<int>(PipelineStatisticsQueryUtilities::GEOMETRY_SHADER_OUTPUT_FIRST);
			 gs_output_it != static_cast<int>(PipelineStatisticsQueryUtilities::GEOMETRY_SHADER_OUTPUT_COUNT);
			 ++gs_output_it)
		{
			PipelineStatisticsQueryUtilities::_geometry_shader_output gs_output =
				static_cast<PipelineStatisticsQueryUtilities::_geometry_shader_output>(gs_output_it);
			/* For GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB query, we need to test both single-stream and
			 * multi-stream geometry shaders.
			 *
			 * For GL_GEOMETRY_SHADER_INVOCATIONS, we only need a single iteration.
			 **/
			const bool streams_supported = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0));
			const unsigned int n_internal_iterations =
				(current_query_target == GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB && streams_supported) ? 2 : 1;

			for (unsigned int n_internal_iteration = 0; n_internal_iteration < n_internal_iterations;
				 ++n_internal_iteration)
			{
				/* Build the test program. */
				std::string gs_body;

				if (n_internal_iteration == 1)
				{
					/* This path will only be entered for GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB query.
					 *
					 * OpenGL does not support multiple vertex streams for output primitive types other than
					 * points.
					 */
					if (gs_output != PipelineStatisticsQueryUtilities::GEOMETRY_SHADER_OUTPUT_POINTS)
					{
						continue;
					}

					/* Build a multi-streamed geometry shader */
					gs_body = PipelineStatisticsQueryUtilities::buildGeometryShaderBody(
						gs_input, gs_output, m_n_primitives_emitted_by_gs, m_n_streams_emitted_by_gs);
				}
				else
				{
					gs_body = PipelineStatisticsQueryUtilities::buildGeometryShaderBody(
						gs_input, gs_output, m_n_primitives_emitted_by_gs, 1); /* n_streams */
				}

				buildProgram(DE_NULL,																	/* cs_body */
							 PipelineStatisticsQueryUtilities::dummy_fs_code, gs_body.c_str(), DE_NULL, /* tc_body */
							 DE_NULL,																	/* te_body */
							 PipelineStatisticsQueryUtilities::dummy_vs_code);

				gl.useProgram(m_po_id);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");

				/* Set up the primitive type */
				m_current_primitive_type = PipelineStatisticsQueryUtilities::getPrimitiveTypeFromGSInput(gs_input);

				/* Iterate through all draw call types */
				for (unsigned int n_draw_call_type = 0;
					 n_draw_call_type < PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_COUNT; ++n_draw_call_type)
				{
					m_current_draw_call_type = (PipelineStatisticsQueryUtilities::_draw_call_type)n_draw_call_type;

					/* Only continue if the draw call is supported by the context */
					if (!PipelineStatisticsQueryUtilities::isDrawCallSupported(m_current_draw_call_type, gl))
					{
						continue;
					}

					/* Execute the query */
					if (!PipelineStatisticsQueryUtilities::executeQuery(
							current_query_target, m_qo_id, m_bo_qo_id, queryCallbackDrawCallHandler,
							(PipelineStatisticsQueryTestFunctionalBase*)this, m_context.getRenderContext(), m_testCtx,
							m_context.getContextInfo(), &run_result))
					{
						m_testCtx.getLog()
							<< tcu::TestLog::Message << "Could not retrieve test run results for query target "
														"["
							<< PipelineStatisticsQueryUtilities::getStringForEnum(current_query_target) << "]"
							<< tcu::TestLog::EndMessage;

						result = false;
					}
					else
					{
						unsigned int										 n_expected_values  = 0;
						glw::GLuint64										 expected_values[2] = { 0 };
						PipelineStatisticsQueryUtilities::_verification_type verification_type =
							PipelineStatisticsQueryUtilities::VERIFICATION_TYPE_UNDEFINED;

						if (current_query_target == GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB)
						{
							n_expected_values  = 2;
							expected_values[0] = m_n_primitives_emitted_by_gs;
							expected_values[1] = m_n_primitives_emitted_by_gs;
							verification_type  = PipelineStatisticsQueryUtilities::VERIFICATION_TYPE_EXACT_MATCH;

							if (n_internal_iteration == 1)
							{
								/* Multi-stream geometry shader case. Count in non-default vertex streams */
								for (unsigned int n_stream = 1; n_stream < m_n_streams_emitted_by_gs; ++n_stream)
								{
									expected_values[1] += (m_n_primitives_emitted_by_gs + n_stream);
								} /* for (non-default streams) */
							}

							if (PipelineStatisticsQueryUtilities::isInstancedDrawCall(m_current_draw_call_type))
							{
								expected_values[0] *= m_indirect_draw_call_primcount_argument;
								expected_values[1] *= m_indirect_draw_call_primcount_argument;
							}
						}
						else
						{
							n_expected_values  = 1;
							expected_values[0] = 1; /* as per test spec */
							verification_type  = PipelineStatisticsQueryUtilities::VERIFICATION_TYPE_EQUAL_OR_GREATER;
						}

						/* Compare it against query result values */
						result &= PipelineStatisticsQueryUtilities::verifyResultValues(
							run_result, n_expected_values, expected_values,
							m_bo_qo_id != 0, /* should_check_qo_bo_values */
							current_query_target, &m_current_draw_call_type, &m_current_primitive_type,
							false, /* is_primitive_restart_enabled */
							m_testCtx, verification_type);

					} /* if (run results were obtained successfully) */
				}	 /* for (all draw call types) */
			}		  /* for (all internal iterations) */
		}			  /* for (all geometry shader output primitive types) */
	}				  /* for (all geometry shader input primitive types) */
	return result;
}

/** Initializes all GL objects used by the test */
void PipelineStatisticsQueryTestFunctional6::initObjects()
{
	/* This test should not execute if we're not running at least a GL3.2 context */
	if (!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 2)))
	{
		throw tcu::NotSupportedError("OpenGL 3.2+ is required to run this test.");
	}
}

/** Tells whether the test instance should be executed for user-specified query target.
 *
 *  @param query_target Query target to be used for the call.
 *
 *  @return true  if @param query_target is either GL_GEOMETRY_SHADER_INVOCATIONS, or
 *                GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB.
 *          false otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional6::shouldExecuteForQueryTarget(glw::GLenum query_target)
{
	return (query_target == GL_GEOMETRY_SHADER_INVOCATIONS ||
			query_target == GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB);
}

/** Constructor.
 *
 *  @param context Rendering context
 */
PipelineStatisticsQueryTestFunctional7::PipelineStatisticsQueryTestFunctional7(deqp::Context& context)
	: PipelineStatisticsQueryTestFunctionalBase(context, "functional_fragment_shader_invocations",
												"Verifies GL_FRAGMENT_SHADER_INVOCATIONS_ARB queries "
												"work correctly.")
{
	/* Left blank intentionally */
}

/** Deinitializes all GL objects that were created during test execution. */
void PipelineStatisticsQueryTestFunctional7::deinitObjects()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_po_id != 0)
	{
		gl.deleteProgram(m_po_id);

		m_po_id = 0;
	}
}

/** Executes a test iteration for user-specified query target.
 *
 *  @param current_query_target Pipeline statistics query target to execute the iteration
 *                              for.
 *
 *  @return true if the test passed for the iteration, false otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional7::executeTest(glw::GLenum current_query_target)
{
	const glw::Functions&									 gl		= m_context.getRenderContext().getFunctions();
	bool													 result = true;
	PipelineStatisticsQueryUtilities::_test_execution_result run_result;

	/* Sanity check: This method should only be called for GL_FRAGMENT_SHADER_INVOCATIONS_ARB query */
	DE_ASSERT(current_query_target == GL_FRAGMENT_SHADER_INVOCATIONS_ARB);

	/* Set up VBO. */
	const unsigned int n_vertex_components = 2;
	const float		   vertex_data[]	   = { 0.0f,  0.75f, -0.75f, -0.75f, 0.75f, -0.75f, 0.3f, 0.7f,
								  -0.4f, 0.2f,  0.6f,   -0.3f,  -0.3f, -0.7f,  0.0f, 0.0f };
	const unsigned int index_data[] = { 0, 2, 1, 3, 4, 5, 6, 7 };

	m_indirect_draw_call_baseinstance_argument = 1;
	m_indirect_draw_call_basevertex_argument   = 1;
	m_indirect_draw_call_count_argument =
		3; /* this value will be updated in the actual loop, so use anything for now */
	m_indirect_draw_call_first_argument		= 0;
	m_indirect_draw_call_primcount_argument = 4;

	initFBO();
	initVBO(vertex_data, sizeof(vertex_data), index_data, sizeof(index_data), m_indirect_draw_call_count_argument,
			m_indirect_draw_call_primcount_argument, m_indirect_draw_call_baseinstance_argument,
			m_indirect_draw_call_first_argument, m_indirect_draw_call_basevertex_argument);

	initVAO(n_vertex_components);

	/* Iterate over all primitive types */
	for (int current_primitive_type_it = static_cast<int>(PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_FIRST);
		 current_primitive_type_it < static_cast<int>(PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_COUNT);
		 ++current_primitive_type_it)
	{
		PipelineStatisticsQueryUtilities::_primitive_type current_primitive_type =
			static_cast<PipelineStatisticsQueryUtilities::_primitive_type>(current_primitive_type_it);
		/* Exclude 'patches' primitive type */
		if (current_primitive_type == PipelineStatisticsQueryUtilities::PRIMITIVE_TYPE_PATCHES)
		{
			continue;
		}

		m_current_primitive_type = current_primitive_type;

		/* Update 'count' argument so that we only use as many vertices as needed for current
		 * primitive type.
		 */
		unsigned int count_argument_value =
			PipelineStatisticsQueryUtilities::getNumberOfVerticesForPrimitiveType(m_current_primitive_type);

		m_indirect_draw_call_count_argument = count_argument_value;

		gl.bufferSubData(GL_ARRAY_BUFFER, m_vbo_indirect_arrays_argument_offset, sizeof(unsigned int),
						 &m_indirect_draw_call_count_argument);
		gl.bufferSubData(GL_ARRAY_BUFFER, m_vbo_indirect_elements_argument_offset, sizeof(unsigned int),
						 &m_indirect_draw_call_count_argument);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call(s) failed.");

		/* Iterate through all draw call types */
		for (unsigned int n_draw_call_type = 0;
			 n_draw_call_type < PipelineStatisticsQueryUtilities::DRAW_CALL_TYPE_COUNT; ++n_draw_call_type)
		{
			m_current_draw_call_type = (PipelineStatisticsQueryUtilities::_draw_call_type)n_draw_call_type;

			/* Only continue if the draw call is supported by the context */
			if (!PipelineStatisticsQueryUtilities::isDrawCallSupported(m_current_draw_call_type, gl))
			{
				continue;
			}

			/* Clear the buffers before we proceed */
			gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");

			/* Execute the query */
			if (!PipelineStatisticsQueryUtilities::executeQuery(
					current_query_target, m_qo_id, m_bo_qo_id, queryCallbackDrawCallHandler,
					(PipelineStatisticsQueryTestFunctionalBase*)this, m_context.getRenderContext(), m_testCtx,
					m_context.getContextInfo(), &run_result))
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Could not retrieve test run results for query target "
															   "["
								   << PipelineStatisticsQueryUtilities::getStringForEnum(current_query_target) << "]"
								   << tcu::TestLog::EndMessage;

				result = false;
			}
			else
			{
				static const glw::GLuint64 expected_value = 1; /* as per test spec */

				/* Compare it against query result values */
				result &= PipelineStatisticsQueryUtilities::verifyResultValues(
					run_result, 1, &expected_value, m_bo_qo_id != 0, /* should_check_qo_bo_values */
					current_query_target, &m_current_draw_call_type, &m_current_primitive_type,
					false, /* is_primitive_restart_enabled */
					m_testCtx, PipelineStatisticsQueryUtilities::VERIFICATION_TYPE_EQUAL_OR_GREATER);

			} /* if (run results were obtained successfully) */
		}	 /* for (all draw call types) */
	}		  /* for (all primitive types) */

	return result;
}

/** Initializes all GL objects used by the test */
void PipelineStatisticsQueryTestFunctional7::initObjects()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	buildProgram(DE_NULL,												   /* cs_body */
				 PipelineStatisticsQueryUtilities::dummy_fs_code, DE_NULL, /* gs_body */
				 DE_NULL,												   /* tc_body */
				 DE_NULL,												   /* te_body */
				 PipelineStatisticsQueryUtilities::dummy_vs_code);

	gl.useProgram(m_po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
}

/** Tells whether the test instance should be executed for user-specified query target.
 *
 *  @param query_target Query target to be used for the call.
 *
 *  @return true  if @param query_target is GL_FRAGMENT_SHADER_INVOCATIONS_ARB.
 *          false otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional7::shouldExecuteForQueryTarget(glw::GLenum query_target)
{
	return (query_target == GL_FRAGMENT_SHADER_INVOCATIONS_ARB);
}

/** Constructor.
 *
 *  @param context Rendering context
 */
PipelineStatisticsQueryTestFunctional8::PipelineStatisticsQueryTestFunctional8(deqp::Context& context)
	: PipelineStatisticsQueryTestFunctionalBase(context, "functional_compute_shader_invocations",
												"Verifies that GL_COMPUTE_SHADER_INVOCATIONS_ARB queries "
												"work correctly.")
	, m_bo_dispatch_compute_indirect_args_offset(0)
	, m_bo_id(0)
	, m_current_iteration(0)
{
	/* Left blank intentionally */
}

/** Deinitializes all GL objects that were created during test execution. */
void PipelineStatisticsQueryTestFunctional8::deinitObjects()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_bo_id != 0)
	{
		gl.deleteBuffers(1, &m_bo_id);

		m_bo_id = 0;
	}
}

/** Executes a test iteration for user-specified query target.
 *
 *  @param current_query_target Pipeline statistics query target to execute the iteration
 *                              for.
 *
 *  @return true if the test passed for the iteration, false otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional8::executeTest(glw::GLenum current_query_target)
{
	bool													 result = true;
	PipelineStatisticsQueryUtilities::_test_execution_result run_result;

	/* Sanity check: This method should only be called for
	 * GL_COMPUTE_SHADER_INVOCATIONS_ARB queries. */
	DE_ASSERT(current_query_target == GL_COMPUTE_SHADER_INVOCATIONS_ARB);

	/* This test needs to be run in two iterations:
	 *
	 * 1. glDispatchCompute() should be called.
	 * 2. glDispatchComputeIndirect() should be called.
	 *
	 */
	for (m_current_iteration = 0; m_current_iteration < 2; /* as per description */
		 ++m_current_iteration)
	{
		/* Execute the query */
		if (!PipelineStatisticsQueryUtilities::executeQuery(
				current_query_target, m_qo_id, m_bo_qo_id, queryCallbackDispatchCallHandler, this,
				m_context.getRenderContext(), m_testCtx, m_context.getContextInfo(), &run_result))
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Could not retrieve test run results for query target "
														   "["
							   << PipelineStatisticsQueryUtilities::getStringForEnum(current_query_target) << "]"
							   << tcu::TestLog::EndMessage;

			result = false;
		}
		else
		{
			static const glw::GLuint64 expected_value = 1; /* as per test spec */

			/* Compare it against query result values */
			result &= PipelineStatisticsQueryUtilities::verifyResultValues(
				run_result, 1, &expected_value, m_bo_qo_id != 0,  /* should_check_qo_bo_values */
				current_query_target, DE_NULL, DE_NULL, false, /* is_primitive_restart_enabled */
				m_testCtx, PipelineStatisticsQueryUtilities::VERIFICATION_TYPE_EQUAL_OR_GREATER);
		} /* if (run results were obtained successfully) */
	}	 /* for (both iterations) */

	return result;
}

/** Initializes all GL objects used by the test */
void PipelineStatisticsQueryTestFunctional8::initObjects()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	const char*			  cs_code = NULL;

	/* This test should not execute if we don't have compute shaders */
	if (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 3)))
	{
		cs_code = PipelineStatisticsQueryUtilities::dummy_cs_code;
	}
	else if (m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader") &&
	m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_atomic_counters"))
	{
		cs_code = PipelineStatisticsQueryUtilities::dummy_cs_code_arb;
	}
	else
	{
		throw tcu::NotSupportedError("OpenGL 4.3+ / compute shaders and atomic counters required to run this test.");
	}

	buildProgram(cs_code,
				 DE_NULL,												   /* fs_body */
				 DE_NULL,												   /* gs_body */
				 DE_NULL,												   /* tc_body */
				 DE_NULL,												   /* te_body */
				 DE_NULL);												   /* vs_body */

	gl.useProgram(m_po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");

	/* Init BO to hold atomic counter data, as well as the indirect dispatch compute
	 * draw call arguments */
	unsigned int	   atomic_counter_value = 0;
	const unsigned int bo_size				= sizeof(unsigned int) * (1 /* counter value */ + 3 /* draw call args */);

	const unsigned int drawcall_args[] = {
		1, /* num_groups_x */
		1, /* num_groups_y */
		1  /* num_groups_z */
	};

	gl.genBuffers(1, &m_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");

	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id);
	gl.bindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call(s) failed.");

	gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, /* index */
					  m_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");

	gl.bufferData(GL_ARRAY_BUFFER, bo_size, DE_NULL, GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");

	gl.bufferSubData(GL_ARRAY_BUFFER, 0, /* offset */
					 sizeof(unsigned int), &atomic_counter_value);
	gl.bufferSubData(GL_ARRAY_BUFFER, sizeof(unsigned int), /* offset */
					 sizeof(drawcall_args), drawcall_args);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");

	/* Store rthe offset, at which the draw call args start */
	m_bo_dispatch_compute_indirect_args_offset = sizeof(unsigned int);
}

/** Either issues a regular or indirect compute shader dispatch call, and then verifies
 *  the call has executed without any error being generated. The regular dispatch call
 *  will be executed if pInstance->m_current_iteration is equal to 0, otherwise the
 *  method will use the indirect version.
 *
 *  @param pInstance Pointer to a PipelineStatisticsQueryTestFunctional8 instance.
 */
bool PipelineStatisticsQueryTestFunctional8::queryCallbackDispatchCallHandler(void* pInstance)
{
	glw::GLenum								error_code = GL_NO_ERROR;
	PipelineStatisticsQueryTestFunctional8* pThis	  = (PipelineStatisticsQueryTestFunctional8*)pInstance;
	bool									result	 = true;
	const glw::Functions&					gl		   = pThis->m_context.getRenderContext().getFunctions();

	if (pThis->m_current_iteration == 0)
	{
		gl.dispatchCompute(1,  /* num_groups_x */
						   1,  /* num_groups_y */
						   1); /* num_groups_z */
	}
	else
	{
		gl.dispatchComputeIndirect(pThis->m_bo_dispatch_compute_indirect_args_offset);
	}

	error_code = gl.getError();
	if (error_code != GL_NO_ERROR)
	{
		pThis->m_testCtx.getLog() << tcu::TestLog::Message
								  << ((pThis->m_current_iteration == 0) ? "glDispatchCompute()" :
																		  "glDispatchComputeIndirect()")
								  << " call failed with error code "
									 "["
								  << error_code << "]." << tcu::TestLog::EndMessage;

		result = false;
	}

	return result;
}

/** Tells whether the test instance should be executed for user-specified query target.
 *
 *  @param query_target Query target to be used for the call.
 *
 *  @return true  if @param query_target is GL_COMPUT_SHADER_INVOCATIONS_ARB.
 *          false otherwise.
 **/
bool PipelineStatisticsQueryTestFunctional8::shouldExecuteForQueryTarget(glw::GLenum query_target)
{
	return (query_target == GL_COMPUTE_SHADER_INVOCATIONS_ARB);
}

/** Constructor.
 *
 *  @param context Rendering context.
 */
PipelineStatisticsQueryTests::PipelineStatisticsQueryTests(deqp::Context& context)
	: TestCaseGroup(context, "pipeline_statistics_query_tests_ARB",
					"Contains conformance tests that verify GL implementation's support "
					"for GL_ARB_pipeline_statistics_query extension.")
{
	/* Left blank intentionally */
}

/** Initializes the test group contents. */
void PipelineStatisticsQueryTests::init()
{
	addChild(new PipelineStatisticsQueryTestAPICoverage1(m_context));
	addChild(new PipelineStatisticsQueryTestAPICoverage2(m_context));
	addChild(new PipelineStatisticsQueryTestFunctional1(m_context));
	addChild(new PipelineStatisticsQueryTestFunctional2(m_context));
	addChild(new PipelineStatisticsQueryTestFunctional3(m_context));
	addChild(new PipelineStatisticsQueryTestFunctional4(m_context));
	addChild(new PipelineStatisticsQueryTestFunctional5(m_context));
	addChild(new PipelineStatisticsQueryTestFunctional6(m_context));
	addChild(new PipelineStatisticsQueryTestFunctional7(m_context));
	addChild(new PipelineStatisticsQueryTestFunctional8(m_context));
}
} /* glcts namespace */
