/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2015-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  gl4cDirectStateAccessQueriesTests.cpp
 * \brief Conformance tests for the Direct State Access feature functionality (Queries access part).
 */ /*-----------------------------------------------------------------------------------------------------------*/

/* Includes. */
#include "gl4cDirectStateAccessTests.hpp"

#include "deSharedPtr.hpp"

#include "gluContextInfo.hpp"
#include "gluDefs.hpp"
#include "gluPixelTransfer.hpp"
#include "gluStrUtil.hpp"

#include "tcuFuzzyImageCompare.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"

#include "glw.h"
#include "glwFunctions.hpp"

/* Define OpenGL enumerations not available in framework. */
#ifndef GL_QUERY_TARGET
#define GL_QUERY_TARGET 0x82EA
#endif

namespace gl4cts
{
namespace DirectStateAccess
{
namespace Queries
{
/******************************** Creation Test Implementation   ********************************/

/** @brief Creation Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
CreationTest::CreationTest(deqp::Context& context)
	: deqp::TestCase(context, "queries_creation", "Query Objects Creation Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Creation Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult CreationTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Query targets */
	static const glw::GLenum targets[] = {
		GL_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED,   GL_ANY_SAMPLES_PASSED_CONSERVATIVE,		 GL_TIME_ELAPSED,
		GL_TIMESTAMP,	  GL_PRIMITIVES_GENERATED, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
	};
	static const glw::GLuint targets_count = sizeof(targets) / sizeof(targets[0]);

	/* Queries objects */
	static const glw::GLuint queries_count = 2;

	glw::GLuint queries_legacy[queries_count]			  = {};
	glw::GLuint queries_dsa[targets_count][queries_count] = {};

	try
	{
		/* Check legacy state creation. */
		gl.genQueries(queries_count, queries_legacy);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries have failed");

		for (glw::GLuint i = 0; i < queries_count; ++i)
		{
			if (gl.isQuery(queries_legacy[i]))
			{
				is_ok = false;

				/* Log. */
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "GenQueries has created default objects, but it should create only a names."
					<< tcu::TestLog::EndMessage;
			}
		}

		/* Check direct state creation. */
		for (glw::GLuint i = 0; i < targets_count; ++i)
		{
			gl.createQueries(targets[i], queries_count, queries_dsa[i]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed");

			for (glw::GLuint j = 0; j < queries_count; ++j)
			{
				if (!gl.isQuery(queries_dsa[i][j]))
				{
					is_ok = false;

					/* Log. */
					m_context.getTestContext().getLog() << tcu::TestLog::Message
														<< "CreateQueries has not created default objects."
														<< tcu::TestLog::EndMessage;
				}
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	for (glw::GLuint j = 0; j < queries_count; ++j)
	{
		if (queries_legacy[j])
		{
			gl.deleteQueries(1, &queries_legacy[j]);

			queries_legacy[j] = 0;
		}

		for (glw::GLuint i = 0; i < targets_count; ++i)
		{
			if (queries_dsa[i][j])
			{
				gl.deleteQueries(1, &queries_dsa[i][j]);

				queries_dsa[i][j] = 0;
			}
		}
	}

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/******************************** Defaults Test Implementation   ********************************/

/** @brief Defaults Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
DefaultsTest::DefaultsTest(deqp::Context& context)
	: deqp::TestCase(context, "queries_defaults", "Queries Defaults Test"), m_query_dsa(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Defaults Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult DefaultsTest::iterate()
{
	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Query targets. */
	static const glw::GLenum targets[] = {
		GL_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED,   GL_ANY_SAMPLES_PASSED_CONSERVATIVE,		 GL_TIME_ELAPSED,
		GL_TIMESTAMP,	  GL_PRIMITIVES_GENERATED, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
	};

	static const glw::GLchar* target_names[] = {
		"GL_SAMPLES_PASSED", "GL_ANY_SAMPLES_PASSED",   "GL_ANY_SAMPLES_PASSED_CONSERVATIVE",	  "GL_TIME_ELAPSED",
		"GL_TIMESTAMP",		 "GL_PRIMITIVES_GENERATED", "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN"
	};

	static const glw::GLuint targets_count = sizeof(targets) / sizeof(targets[0]);

	try
	{
		/* Check direct state creation. */
		for (glw::GLuint i = 0; i < targets_count; ++i)
		{
			prepare(targets[i]);

			is_ok &= testQueryParameter(GL_QUERY_RESULT, GL_FALSE, target_names[i]);
			is_ok &= testQueryParameter(GL_QUERY_RESULT_AVAILABLE, GL_TRUE, target_names[i]);

			clean();
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;

		clean();
	}

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Create Query Objects.
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @return True if test succeeded, false otherwise.
 */
void DefaultsTest::prepare(const glw::GLenum target)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Query object creation */
	gl.createQueries(target, 1, &m_query_dsa);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
}

/** @brief Test Query Integer Parameter.
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @param [in] pname           Parameter name to be tested.
 *  @param [in] expected_value  Expected value for comparison.
 *  @param [in] target_name     Target name of the tested query object - for logging purposes.
 *
 *  @return True if test succeeded, false otherwise.
 */
bool DefaultsTest::testQueryParameter(const glw::GLenum pname, const glw::GLuint expected_value,
									  const glw::GLchar* target_name)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get data. */
	glw::GLuint value = 0;

	gl.getQueryObjectuiv(m_query_dsa, pname, &value);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv have failed");

	if (expected_value != value)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "glGetQueryObjectuiv of query object with target " << target_name
			<< " with parameter " << pname << " has returned " << value << ", however " << expected_value
			<< " was expected." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Release GL objects.
 */
void DefaultsTest::clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_query_dsa)
	{
		gl.deleteQueries(1, &m_query_dsa);

		m_query_dsa = 0;
	}
}

/******************************** Errors Test Implementation   ********************************/

/** @brief Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
ErrorsTest::ErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "queries_errors", "Queries Errors Test")
	, m_pGetQueryBufferObjectiv(DE_NULL)
	, m_pGetQueryBufferObjectuiv(DE_NULL)
	, m_pGetQueryBufferObjecti64v(DE_NULL)
	, m_pGetQueryBufferObjectui64v(DE_NULL)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult ErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Getting function pointers. */
	m_pGetQueryBufferObjectiv	= (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectiv;
	m_pGetQueryBufferObjectuiv   = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectuiv;
	m_pGetQueryBufferObjecti64v  = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjecti64v;
	m_pGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectui64v;

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		if ((DE_NULL == m_pGetQueryBufferObjectiv) || (DE_NULL == m_pGetQueryBufferObjectuiv) ||
			(DE_NULL == m_pGetQueryBufferObjecti64v) || (DE_NULL == m_pGetQueryBufferObjectui64v))
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "Test could not get the pointers for glGetQueryBufferObject* functions."
				<< tcu::TestLog::EndMessage;

			throw 0;
		}

		is_ok &= testNegativeNumberOfObjects();
		is_ok &= testInvalidTarget();
		is_ok &= testInvalidQueryName();
		is_ok &= testInvalidBufferName();
		is_ok &= testInvalidParameterName();
		is_ok &= testBufferOverflow();
		is_ok &= testBufferNegativeOffset();
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Check that CreateQueries generates INVALID_VALUE
 *         error if number of query objects to create is
 *         negative.
 *
 *  @return True if test succeded, false otherwise.
 */
bool ErrorsTest::testNegativeNumberOfObjects()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Test for each target. */
	for (glw::GLuint i = 0; i < s_targets_count; ++i)
	{
		glw::GLuint query = 0;

		gl.createQueries(s_targets[i], -1, &query); /* Create negative number of queries. */

		glw::GLenum error = gl.getError();

		if (GL_INVALID_VALUE != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "glCreateQueries called with target " << s_target_names[i]
				<< " with negative number of objects to be created (-1) has generated error " << glu::getErrorStr(error)
				<< ", however GL_INVALID_VALUE was expected." << tcu::TestLog::EndMessage;

			if (query)
			{
				gl.deleteQueries(1, &query);

				while (error == gl.getError())
					;

				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "glCreateQueries called with target " << s_target_names[i]
					<< " with negative number of objects to be created (-1) has created at least one object."
					<< tcu::TestLog::EndMessage;
			}

			return false;
		}
	}

	return true;
}

/** @brief Check that CreateQueries generates INVALID_ENUM error if target is not
 *         one of accepted values:
 *          -  SAMPLES_PASSED,
 *          -  ANY_SAMPLES_PASSED,
 *          -  ANY_SAMPLES_PASSED_CONSERVATIVE,
 *          -  TIME_ELAPSED,
 *          -  TIMESTAMP,
 *          -  PRIMITIVES_GENERATED or
 *          -  TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN.
 *
 *  @return True if test succeded, false otherwise.
 */
bool ErrorsTest::testInvalidTarget()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Creating invalid target. */
	glw::GLenum invalid_target = 0;

	while (isTarget(++invalid_target))
		;

	/* Test. */
	glw::GLuint query = 0;

	gl.createQueries(invalid_target, 1, &query); /* Create negative number of queries. */

	glw::GLenum error = gl.getError();

	if (GL_INVALID_ENUM != error)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "glCreateQueries called with invalid target ("
											<< invalid_target << ") has generated error " << glu::getErrorStr(error)
											<< ", however GL_INVALID_ENUM was expected." << tcu::TestLog::EndMessage;

		if (query)
		{
			gl.deleteQueries(1, &query);

			while (error == gl.getError())
				;

			m_context.getTestContext().getLog() << tcu::TestLog::Message
												<< "glCreateQueries called with invalid target (" << invalid_target
												<< ") has created an object." << tcu::TestLog::EndMessage;
		}

		return false;
	}

	return true;
}

/** @brief Check that GetQueryBufferObjectiv, GetQueryBufferObjectuiv,
 *         GetQueryBufferObjecti64v and GetQueryBufferObjectui64v generate
 *         INVALID_OPERATION error if <id> is not the name of a query object, or
 *         if the query object named by <id> is currently active.
 *
 *  @return True if test succeded, false otherwise.
 */
bool ErrorsTest::testInvalidQueryName()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Creating invalid query name. */
	glw::GLuint invalid_query = 0;

	/* Default result. */
	bool is_ok	= true;
	bool is_error = false;

	while (gl.isQuery(++invalid_query))
		;

	/* Test's objects. */
	glw::GLuint buffer = 0;
	glw::GLuint query  = 0;

	try
	{
		/* Creating buffer for the test. */
		gl.genBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");

		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");

		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(glw::GLint64), DE_NULL, GL_DYNAMIC_COPY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");

		/* Test invalid query object name (integer version). */
		m_pGetQueryBufferObjectiv(invalid_query, buffer, GL_QUERY_RESULT, 0);

		glw::GLenum error = gl.getError();

		if (GL_INVALID_OPERATION != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjectiv called with invalid query name has generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
				<< tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test invalid query object name (unsigned integer version). */
		m_pGetQueryBufferObjectuiv(invalid_query, buffer, GL_QUERY_RESULT, 0);

		error = gl.getError();

		if (GL_INVALID_OPERATION != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjectuiv called with invalid query name has generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
				<< tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test invalid query object name (64-bit integer version). */
		m_pGetQueryBufferObjecti64v(invalid_query, buffer, GL_QUERY_RESULT, 0);

		error = gl.getError();

		if (GL_INVALID_OPERATION != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjecti64v called with invalid query name has generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
				<< tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test invalid query object name (64-bit unsigned integer version). */
		m_pGetQueryBufferObjectui64v(invalid_query, buffer, GL_QUERY_RESULT, 0);

		error = gl.getError();

		if (GL_INVALID_OPERATION != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjectui64v called with invalid query name has generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
				<< tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Create query object for the test. */
		gl.createQueries(s_targets[0], 1, &query);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed");

		gl.beginQuery(s_targets[0], query);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed");

		/* Test query of active query object name (integer version). */
		m_pGetQueryBufferObjectiv(query, buffer, GL_QUERY_RESULT, 0);

		error = gl.getError();

		if (GL_INVALID_OPERATION != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjectiv called with active query object has generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
				<< tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test query of active query object name (unsigned integer version). */
		m_pGetQueryBufferObjectuiv(query, buffer, GL_QUERY_RESULT, 0);

		error = gl.getError();

		if (GL_INVALID_OPERATION != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjectuiv called with active query object has generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
				<< tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test query of active query object name (64-bit integer version). */
		m_pGetQueryBufferObjecti64v(query, buffer, GL_QUERY_RESULT, 0);

		error = gl.getError();

		if (GL_INVALID_OPERATION != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjecti64v called with active query object has generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
				<< tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test query of active query object name (64-bit unsigned integer version). */
		m_pGetQueryBufferObjectui64v(query, buffer, GL_QUERY_RESULT, 0);

		error = gl.getError();

		if (GL_INVALID_OPERATION != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjectui64v called with active query object has generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
				<< tcu::TestLog::EndMessage;

			is_ok = false;
		}
	}
	catch (...)
	{
		is_error = true;
	}

	/* Releasing objects. */
	if (query)
	{
		gl.endQuery(s_targets[0]);

		gl.deleteQueries(1, &query);
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);
	}

	/* Error cleanup. */
	while (gl.getError())
		;

	if (is_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Check that GetQueryBufferObjectiv, GetQueryBufferObjectuiv,
 *         GetQueryBufferObjecti64v and GetQueryBufferObjectui64v generate
 *         INVALID_OPERATION error if <buffer> is not the name of an existing
 *         buffer object.
 *
 *  @return True if test succeded, false otherwise.
 */
bool ErrorsTest::testInvalidBufferName()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Default result. */
	bool is_ok	= true;
	bool is_error = false;

	/* Creating invalid buffer name. */
	glw::GLuint invalid_buffer = 0;

	while (gl.isBuffer(++invalid_buffer))
		;

	/* Test's objects. */
	glw::GLuint query = 0;

	try
	{
		/* Create query object for the test. */
		gl.createQueries(s_targets[0], 1, &query);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed");

		/* Test query of invalid buffer name (integer version). */
		m_pGetQueryBufferObjectiv(query, invalid_buffer, GL_QUERY_RESULT_AVAILABLE, 0);

		glw::GLenum error = gl.getError();

		if (GL_INVALID_OPERATION != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjectiv which could generate buffers overflow generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
				<< tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test query of invalid buffer name (unsigned integer version). */
		m_pGetQueryBufferObjectuiv(query, invalid_buffer, GL_QUERY_RESULT_AVAILABLE, 0);

		error = gl.getError();

		if (GL_INVALID_OPERATION != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjectuiv which could generate buffers overflow generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
				<< tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test query of invalid buffer name (64-bit integer version). */
		m_pGetQueryBufferObjecti64v(query, invalid_buffer, GL_QUERY_RESULT_AVAILABLE, 0);

		error = gl.getError();

		if (GL_INVALID_OPERATION != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjecti64v which could generate buffers overflow generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
				<< tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test query of invalid buffer name (64-bit unsigned integer version). */
		m_pGetQueryBufferObjectui64v(query, invalid_buffer, GL_QUERY_RESULT_AVAILABLE, 0);

		error = gl.getError();

		if (GL_INVALID_OPERATION != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjectui64v which could generate buffers overflow generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
				<< tcu::TestLog::EndMessage;

			is_ok = false;
		}
	}
	catch (...)
	{
		is_error = true;
	}

	/* Releasing objects. */
	if (query)
	{
		gl.deleteQueries(1, &query);
	}

	/* Error cleanup. */
	while (gl.getError())
		;

	if (is_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Check that GetQueryBufferObjectiv, GetQueryBufferObjectuiv,
 *         GetQueryBufferObjecti64v and GetQueryBufferObjectui64v generate
 *         INVALID_ENUM error if <pname> is not QUERY_RESULT,
 *         QUERY_RESULT_AVAILABLE, QUERY_RESULT_NO_WAIT or QUERY_TARGET.
 *
 *  @return True if test succeded, false otherwise.
 */
bool ErrorsTest::testInvalidParameterName()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Creating invalid parameter name. */
	glw::GLuint invalid_pname = 0;

	while (isParameterName(++invalid_pname))
		;

	/* Default result. */
	bool is_ok	= true;
	bool is_error = false;

	/* Test's objects. */
	glw::GLuint buffer = 0;
	glw::GLuint query  = 0;

	try
	{
		/* Creating buffer for the test. */
		gl.genBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");

		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");

		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(glw::GLint64), DE_NULL, GL_DYNAMIC_COPY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");

		/* Create query object for the test. */
		gl.createQueries(s_targets[0], 1, &query);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed");

		/* Test query of invalid parameter name (integer version). */
		m_pGetQueryBufferObjectiv(query, buffer, invalid_pname, 0);

		glw::GLenum error = gl.getError();

		if (GL_INVALID_ENUM != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjectiv called with invalid parameter name has generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_ENUM was expected." << tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test query of invalid parameter name (unsigned integer version). */
		m_pGetQueryBufferObjectuiv(query, buffer, invalid_pname, 0);

		error = gl.getError();

		if (GL_INVALID_ENUM != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjectuiv called with invalid parameter name has generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_ENUM was expected." << tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test query of invalid parameter name (64-bit integer version). */
		m_pGetQueryBufferObjecti64v(query, buffer, invalid_pname, 0);

		error = gl.getError();

		if (GL_INVALID_ENUM != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjecti64v called with invalid parameter name has generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_ENUM was expected." << tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test query of invalid parameter name (64-bit unsigned integer version). */
		m_pGetQueryBufferObjectui64v(query, buffer, invalid_pname, 0);

		error = gl.getError();

		if (GL_INVALID_ENUM != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjectui64v called with invalid parameter name has generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_ENUM was expected." << tcu::TestLog::EndMessage;

			is_ok = false;
		}
	}
	catch (...)
	{
		is_error = true;
	}

	/* Releasing objects. */
	if (query)
	{
		gl.deleteQueries(1, &query);
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);
	}

	/* Error cleanup. */
	while (gl.getError())
		;

	if (is_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Check that GetQueryBufferObjectiv, GetQueryBufferObjectuiv,
 *         GetQueryBufferObjecti64v and GetQueryBufferObjectui64v generate
 *         INVALID_OPERATION error if the query writes to a buffer object, and the
 *         specified buffer offset would cause data to be written beyond the bounds
 *         of that buffer object.
 *
 *  @return True if test succeded, false otherwise.
 */
bool ErrorsTest::testBufferOverflow()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Default result. */
	bool is_ok	= true;
	bool is_error = false;

	/* Test's objects. */
	glw::GLuint buffer = 0;
	glw::GLuint query  = 0;

	try
	{
		/* Creating buffer for the test. */
		gl.genBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");

		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");

		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(glw::GLint64), DE_NULL, GL_DYNAMIC_COPY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");

		/* Create query object for the test. */
		gl.createQueries(s_targets[0], 1, &query);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed");

		/* Test query of buffer overflow (integer version). */
		m_pGetQueryBufferObjectiv(query, buffer, GL_QUERY_RESULT_AVAILABLE, sizeof(glw::GLint64));

		glw::GLenum error = gl.getError();

		if (GL_INVALID_OPERATION != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjectiv which could generate buffers overflow generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
				<< tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test query of buffer overflow (unsigned integer version). */
		m_pGetQueryBufferObjectuiv(query, buffer, GL_QUERY_RESULT_AVAILABLE, sizeof(glw::GLint64));

		error = gl.getError();

		if (GL_INVALID_OPERATION != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjectuiv which could generate buffers overflow generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
				<< tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test query of  buffer overflow (64-bit integer version). */
		m_pGetQueryBufferObjecti64v(query, buffer, GL_QUERY_RESULT_AVAILABLE, sizeof(glw::GLint64));

		error = gl.getError();

		if (GL_INVALID_OPERATION != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjecti64v which could generate buffers overflow generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
				<< tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test query of  buffer overflow (64-bit unsigned integer version). */
		m_pGetQueryBufferObjectui64v(query, buffer, GL_QUERY_RESULT_AVAILABLE, sizeof(glw::GLint64));

		error = gl.getError();

		if (GL_INVALID_OPERATION != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetQueryBufferObjectui64v which could generate buffers overflow generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
				<< tcu::TestLog::EndMessage;

			is_ok = false;
		}
	}
	catch (...)
	{
		is_error = true;
	}

	/* Releasing objects. */
	if (query)
	{
		gl.deleteQueries(1, &query);
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);
	}

	/* Error cleanup. */
	while (gl.getError())
		;

	if (is_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Check that GetQueryBufferObjectiv, GetQueryBufferObjectuiv,
 *         GetQueryBufferObjecti64v and GetQueryBufferObjectui64v generate
 *         INVALID_VALUE error if <offset> is negative.
 *
 *  @return True if test succeded, false otherwise.
 */
bool ErrorsTest::testBufferNegativeOffset()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Default result. */
	bool is_ok	= true;
	bool is_error = false;

	/* Test's objects. */
	glw::GLuint buffer = 0;
	glw::GLuint query  = 0;

	try
	{
		/* Creating buffer for the test. */
		gl.genBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");

		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");

		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(glw::GLint64), DE_NULL, GL_DYNAMIC_COPY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");

		/* Create query object for the test. */
		gl.createQueries(s_targets[0], 1, &query);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed");

		/* Test query with negative offset (integer version). */
		m_pGetQueryBufferObjectiv(query, buffer, GL_QUERY_RESULT_AVAILABLE, -1);

		glw::GLenum error = gl.getError();

		if (GL_INVALID_VALUE != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "glGetQueryBufferObjectiv called with negative offset generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_VALUE was expected." << tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test query with negative offset (unsigned integer version). */
		m_pGetQueryBufferObjectuiv(query, buffer, GL_QUERY_RESULT_AVAILABLE, -1);

		error = gl.getError();

		if (GL_INVALID_VALUE != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "glGetQueryBufferObjectuiv called with negative offset generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_VALUE was expected." << tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test query with negative offset (64-bit integer version). */
		m_pGetQueryBufferObjecti64v(query, buffer, GL_QUERY_RESULT_AVAILABLE, -1);

		error = gl.getError();

		if (GL_INVALID_VALUE != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "glGetQueryBufferObjecti64v called with negative offset generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_VALUE was expected." << tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Test query with negative offset (64-bit unsigned integer version). */
		m_pGetQueryBufferObjectui64v(query, buffer, GL_QUERY_RESULT_AVAILABLE, -1);

		error = gl.getError();

		if (GL_INVALID_VALUE != error)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "glGetQueryBufferObjectui64v called with negative offset generated error "
				<< glu::getErrorStr(error) << ", however GL_INVALID_VALUE was expected." << tcu::TestLog::EndMessage;

			is_ok = false;
		}
	}
	catch (...)
	{
		is_error = true;
	}

	/* Releasing objects. */
	if (query)
	{
		gl.deleteQueries(1, &query);
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);
	}

	/* Error cleanup. */
	while (gl.getError())
		;

	if (is_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Check if argument is one of the target names:
 *          -  SAMPLES_PASSED,
 *          -  TIME_ELAPSED,
 *          -  PRIMITIVES_GENERATED,
 *          -  TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN.
 *
 *  @param [in] maybe_target   Target to be checked.
 *
 *  @return True if argument is one of the listed targets, false otherwise.
 */
bool ErrorsTest::isTarget(glw::GLenum maybe_target)
{
	for (glw::GLuint i = 0; i < s_targets_count; ++i)
	{
		if (maybe_target == s_targets[i])
		{
			return true;
		}
	}

	return false;
}

/** @brief Check if argument is one of the parameter names:
 *          -  QUERY_RESULT,
 *          -  QUERY_RESULT_AVAILABLE,
 *          -  QUERY_RESULT_NO_WAIT,
 *          -  QUERY_TARGET.
 *
 *  @param [in] maybe_pname   Parameter name to be checked.
 *
 *  @return True if argument is one of the listed parameters, false otherwise.
 */
bool ErrorsTest::isParameterName(glw::GLenum maybe_pname)
{
	glw::GLenum pnames[]	 = { GL_QUERY_RESULT, GL_QUERY_RESULT_AVAILABLE, GL_QUERY_RESULT_NO_WAIT, GL_QUERY_TARGET };
	glw::GLuint pnames_count = sizeof(pnames) / sizeof(pnames[0]);

	for (glw::GLuint i = 0; i < pnames_count; ++i)
	{
		if (maybe_pname == pnames[i])
		{
			return true;
		}
	}

	return false;
}

/** Targets to be tested. */
const glw::GLenum ErrorsTest::s_targets[] = {
	GL_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED,   GL_ANY_SAMPLES_PASSED_CONSERVATIVE,		 GL_TIME_ELAPSED,
	GL_TIMESTAMP,	  GL_PRIMITIVES_GENERATED, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
};

/** Names of targets to be tested. */
const glw::GLchar* ErrorsTest::s_target_names[] = {
	"GL_SAMPLES_PASSED", "GL_ANY_SAMPLES_PASSED",   "GL_ANY_SAMPLES_PASSED_CONSERVATIVE",	  "GL_TIME_ELAPSED",
	"GL_TIMESTAMP",		 "GL_PRIMITIVES_GENERATED", "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN"
};

/** Number of targets. */
const glw::GLuint ErrorsTest::s_targets_count = sizeof(s_targets) / sizeof(s_targets[0]);

/******************************** Functional Test Implementation   ********************************/

/** @brief Functional Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
FunctionalTest::FunctionalTest(deqp::Context& context)
	: deqp::TestCase(context, "queries_functional", "Queries Functional Test")
	, m_pGetQueryBufferObjectiv(DE_NULL)
	, m_pGetQueryBufferObjectuiv(DE_NULL)
	, m_pGetQueryBufferObjecti64v(DE_NULL)
	, m_pGetQueryBufferObjectui64v(DE_NULL)
	, m_fbo(0)
	, m_rbo(0)
	, m_vao(0)
	, m_bo_query(0)
	, m_bo_xfb(0)
	, m_qo(DE_NULL)
	, m_po(0)
{
	/* Intentionally left blank. */
}

/** @brief Do comparison (a == b).
 *
 *  @tparam         Type of the values to be compared.
 *
 *  @param [in] a   First  value to be compared.
 *  @param [in] b   Second value to be compared.
 *
 *  @return Result of the comparison.
 */
template <typename T>
bool FunctionalTest::equal(T a, T b)
{
	return (a == b);
}

/** @brief Do comparison (a < b).
 *
 *  @tparam         Type of the values to be compared.
 *
 *  @param [in] a   First  value to be compared.
 *  @param [in] b   Second value to be compared.
 *
 *  @return Result of the comparison.
 */
template <typename T>
bool FunctionalTest::less(T a, T b)
{
	return (a < b);
}

/** @brief Template specialization of glGetQueryBufferObject* function for GLint.
 *         This is pass through function to glGetQueryBufferObjectiv
 *
 *  @param [in] id          Query object identifier.
 *  @param [in] buffer      Buffer object identifier.
 *  @param [in] pname       Parameter name to be queried.
 *  @param [in] offset      Offset of the buffer to be saved at.
 */
template <>
void FunctionalTest::GetQueryBufferObject<glw::GLint>(glw::GLuint id, glw::GLuint buffer, glw::GLenum pname,
													  glw::GLintptr offset)
{
	m_pGetQueryBufferObjectiv(id, buffer, pname, offset);
}

/** @brief Template specialization of glGetQueryBufferObject* function for GLuint.
 *         This is pass through function to glGetQueryBufferObjectuiv
 *
 *  @param [in] id          Query object identifier.
 *  @param [in] buffer      Buffer object identifier.
 *  @param [in] pname       Parameter name to be queried.
 *  @param [in] offset      Offset of the buffer to be saved at.
 */
template <>
void FunctionalTest::GetQueryBufferObject<glw::GLuint>(glw::GLuint id, glw::GLuint buffer, glw::GLenum pname,
													   glw::GLintptr offset)
{
	m_pGetQueryBufferObjectuiv(id, buffer, pname, offset);
}

/** @brief Template specialization of glGetQueryBufferObject* function for GLint64.
 *         This is pass through function to glGetQueryBufferObjecti64v
 *
 *  @param [in] id          Query object identifier.
 *  @param [in] buffer      Buffer object identifier.
 *  @param [in] pname       Parameter name to be queried.
 *  @param [in] offset      Offset of the buffer to be saved at.
 */
template <>
void FunctionalTest::GetQueryBufferObject<glw::GLint64>(glw::GLuint id, glw::GLuint buffer, glw::GLenum pname,
														glw::GLintptr offset)
{
	m_pGetQueryBufferObjecti64v(id, buffer, pname, offset);
}

/** @brief Template specialization of glGetQueryBufferObject* function for GLuint64.
 *         This is pass through function to glGetQueryBufferObjectui64v
 *
 *  @param [in] id          Query object identifier.
 *  @param [in] buffer      Buffer object identifier.
 *  @param [in] pname       Parameter name to be queried.
 *  @param [in] offset      Offset of the buffer to be saved at.
 */
template <>
void FunctionalTest::GetQueryBufferObject<glw::GLuint64>(glw::GLuint id, glw::GLuint buffer, glw::GLenum pname,
														 glw::GLintptr offset)
{
	m_pGetQueryBufferObjectui64v(id, buffer, pname, offset);
}

/** @brief Function template fetches query result to buffer object using
 *         glGetQueryBufferObject* function (selected on the basis of template parameter).
 *         Then buffer is mapped and the result is compared with expected_value using comparison function.
 *
 *  @tparam                     Templated type of fetched data.
 *                              It shall be one of glw::GL[u]int[64].
 *
 *  @param [in] query           Query object to be queried.
 *  @param [in] pname           Parameter name to be queried.
 *  @param [in] expected_value  Reference value to be compared.
 *  @param [in] comparison      Comparison function pointer.
 *                              Comparsion function shall NOT throw.
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @return True if comparison succeeded, false otherwise.
 */
template <typename T>
bool FunctionalTest::checkQueryBufferObject(glw::GLuint query, glw::GLenum pname, T expected_value,
											bool (*comparison)(T, T))
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Default result. */
	bool is_ok = true;

	/* Saving results to buffer. */
	GetQueryBufferObject<T>(query, m_bo_query, pname, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryBufferObject* have failed");

	/* Mapping buffer to user space. */
	T* value = (T*)gl.mapBuffer(GL_QUERY_BUFFER, GL_READ_ONLY);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer have failed");

	/* Doing test. */
	if (!comparison(expected_value, *value))
	{
		is_ok = false;
	}

	/* Cleanup. */
	gl.unmapBuffer(GL_QUERY_BUFFER);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer have failed");

	/* Return test result. */
	return is_ok;
}

/** @brief Iterate Functional Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult FunctionalTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Fetching access point to GL functions. */
	m_pGetQueryBufferObjectiv	= (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectiv;
	m_pGetQueryBufferObjectuiv   = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectuiv;
	m_pGetQueryBufferObjecti64v  = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjecti64v;
	m_pGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectui64v;

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		if ((DE_NULL == m_pGetQueryBufferObjectiv) || (DE_NULL == m_pGetQueryBufferObjectuiv) ||
			(DE_NULL == m_pGetQueryBufferObjecti64v) || (DE_NULL == m_pGetQueryBufferObjectui64v))
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "Test could not get the pointers for glGetQueryBufferObject* functions."
				<< tcu::TestLog::EndMessage;

			throw 0;
		}

		prepareView();
		prepareVertexArray();
		prepareBuffers();
		prepareQueries();
		prepareProgram();

		draw();

		/* Make sure that framebuffer and transform feedback buffer are filled with expectd data. */
		is_ok &= checkView();
		is_ok &= checkXFB();

		/* Make comparisons for each query object. */
		for (glw::GLuint i = 0; i < s_targets_count; ++i)
		{
			/* Checking targets. */
			is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_TARGET, s_targets[i],
														&FunctionalTest::equal<glw::GLint>);
			is_ok &= checkQueryBufferObject<glw::GLuint>(m_qo[i], GL_QUERY_TARGET, s_targets[i],
														 &FunctionalTest::equal<glw::GLuint>);
			is_ok &= checkQueryBufferObject<glw::GLint64>(m_qo[i], GL_QUERY_TARGET, s_targets[i],
														  &FunctionalTest::equal<glw::GLint64>);
			is_ok &= checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_TARGET, s_targets[i],
														   &FunctionalTest::equal<glw::GLuint64>);

			/* Checking result availability. */
			is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_RESULT_AVAILABLE, GL_TRUE,
														&FunctionalTest::equal<glw::GLint>);
			is_ok &= checkQueryBufferObject<glw::GLuint>(m_qo[i], GL_QUERY_RESULT_AVAILABLE, GL_TRUE,
														 &FunctionalTest::equal<glw::GLuint>);
			is_ok &= checkQueryBufferObject<glw::GLint64>(m_qo[i], GL_QUERY_RESULT_AVAILABLE, GL_TRUE,
														  &FunctionalTest::equal<glw::GLint64>);
			is_ok &= checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_RESULT_AVAILABLE, GL_TRUE,
														   &FunctionalTest::equal<glw::GLuint64>);

			if (GL_TIME_ELAPSED == s_targets[i])
			{
				/* Checking result. */
				is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_RESULT, (glw::GLint)s_results[i],
															&FunctionalTest::less<glw::GLint>);
				is_ok &= checkQueryBufferObject<glw::GLuint>(m_qo[i], GL_QUERY_RESULT, (glw::GLuint)s_results[i],
															 &FunctionalTest::less<glw::GLuint>);
				is_ok &= checkQueryBufferObject<glw::GLint64>(m_qo[i], GL_QUERY_RESULT, (glw::GLint64)s_results[i],
															  &FunctionalTest::less<glw::GLint64>);
				is_ok &= checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_RESULT, (glw::GLuint64)s_results[i],
															   &FunctionalTest::less<glw::GLuint64>);

				/* Checking result (no-wait). */
				is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLint)s_results[i],
															&FunctionalTest::less<glw::GLint>);
				is_ok &= checkQueryBufferObject<glw::GLuint>(
					m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLuint)s_results[i], &FunctionalTest::less<glw::GLuint>);
				is_ok &= checkQueryBufferObject<glw::GLint64>(
					m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLint64)s_results[i], &FunctionalTest::less<glw::GLint64>);
				is_ok &=
					checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLuint64)s_results[i],
														  &FunctionalTest::less<glw::GLuint64>);
			}
			else
			{
				/* Checking result. */
				is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_RESULT, (glw::GLint)s_results[i],
															&FunctionalTest::equal<glw::GLint>);
				is_ok &= checkQueryBufferObject<glw::GLuint>(m_qo[i], GL_QUERY_RESULT, (glw::GLuint)s_results[i],
															 &FunctionalTest::equal<glw::GLuint>);
				is_ok &= checkQueryBufferObject<glw::GLint64>(m_qo[i], GL_QUERY_RESULT, (glw::GLint64)s_results[i],
															  &FunctionalTest::equal<glw::GLint64>);
				is_ok &= checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_RESULT, (glw::GLuint64)s_results[i],
															   &FunctionalTest::equal<glw::GLuint64>);

				/* Checking result (no-wait). */
				is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLint)s_results[i],
															&FunctionalTest::equal<glw::GLint>);
				is_ok &= checkQueryBufferObject<glw::GLuint>(
					m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLuint)s_results[i], &FunctionalTest::equal<glw::GLuint>);
				is_ok &= checkQueryBufferObject<glw::GLint64>(
					m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLint64)s_results[i], &FunctionalTest::equal<glw::GLint64>);
				is_ok &=
					checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLuint64)s_results[i],
														  &FunctionalTest::equal<glw::GLuint64>);
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Clean up. */
	clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Function prepares framebuffer with RGBA8 color attachment.
 *         Viewport is set up. Content of the framebuffer is cleared.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void FunctionalTest::prepareView()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare framebuffer. */
	gl.genFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");

	gl.genRenderbuffers(1, &m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1 /* x size */, 1 /* y size */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");

	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");

	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
	{
		throw 0;
	}

	gl.viewport(0, 0, 1, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");

	/* Clear framebuffer's content. */
	gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");

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

/** @brief Function creates and binds empty vertex array.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void FunctionalTest::prepareVertexArray()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Creating and binding VAO. */
	gl.genVertexArrays(1, &m_vao);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays have failed");

	gl.bindVertexArray(m_vao);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray have failed");
}

/** @brief Function creates buffers for query and transform feedback data storage.
 *         The storage is allocated and buffers are bound to QUERY_BUFFER and
 *         TRANSFORM_FEEDBACK_BUFFER binding points respectively.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void FunctionalTest::prepareBuffers()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Buffer for storing query's result. */
	gl.genBuffers(1, &m_bo_query);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");

	gl.bindBuffer(GL_QUERY_BUFFER, m_bo_query);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer have failed");

	gl.bufferData(GL_QUERY_BUFFER, sizeof(glw::GLint64), DE_NULL, GL_DYNAMIC_COPY);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed");

	/* Buffer for storing transform feedback results. */
	gl.genBuffers(1, &m_bo_xfb);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");

	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer have failed");

	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER,
				  3 /* number of vertices per triangle */ * 2 /* number of triangles */ * sizeof(glw::GLint), DE_NULL,
				  GL_DYNAMIC_COPY);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed");

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase have failed");
}

/** @brief Function creates array of query objects using DSA-style method.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void FunctionalTest::prepareQueries()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Allocating memory for queries array. */
	m_qo = new glw::GLuint[s_targets_count];

	if (DE_NULL == m_qo)
	{
		throw 0;
	}

	/* Creating query object for each target. */
	for (glw::GLuint i = 0; i < s_targets_count; ++i)
	{
		gl.createQueries(s_targets[i], 1, &m_qo[i]);

		/* Error checking. */
		if (GL_NO_ERROR != gl.getError())
		{
			/* Remove previous. */
			if (i > 0)
			{
				gl.deleteQueries(i, m_qo);
			}

			/* Deallocate storage. */
			delete[] m_qo;

			m_qo = DE_NULL;

			/* Signalise test failure. */
			throw 0;
		}
	}
}

/** @brief Function builds test's GLSL program.
 *         If succeded, the program will be set to be used.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void FunctionalTest::prepareProgram()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	struct Shader
	{
		glw::GLchar const* const source;
		glw::GLenum const		 type;
		glw::GLuint				 id;
	} shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };

	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);

	try
	{
		/* Create program. */
		m_po = gl.createProgram();
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");

		/* Shader compilation. */

		for (glw::GLuint i = 0; i < shader_count; ++i)
		{
			if (DE_NULL != shader[i].source)
			{
				shader[i].id = gl.createShader(shader[i].type);

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

				gl.attachShader(m_po, shader[i].id);

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

				gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);

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

				gl.compileShader(shader[i].id);

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

				glw::GLint status = GL_FALSE;

				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

				if (GL_FALSE == status)
				{
					glw::GLint log_size = 0;
					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

					glw::GLchar* log_text = new glw::GLchar[log_size];

					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);

					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
														<< "Shader type: " << glu::getShaderTypeStr(shader[i].type)
														<< "\n"
														<< "Shader compilation error log:\n"
														<< log_text << "\n"
														<< "Shader source code:\n"
														<< shader[i].source << "\n"
														<< tcu::TestLog::EndMessage;

					delete[] log_text;

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

					throw 0;
				}
			}
		}

		/* Transform Feedback setup. */
		gl.transformFeedbackVaryings(m_po, 1, &s_xfb_varying_name, GL_INTERLEAVED_ATTRIBS);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

		/* Link. */
		gl.linkProgram(m_po);

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

		glw::GLint status = GL_FALSE;

		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);

		if (GL_TRUE == status)
		{
			for (glw::GLuint i = 0; i < shader_count; ++i)
			{
				if (shader[i].id)
				{
					gl.detachShader(m_po, shader[i].id);

					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
				}
			}
		}
		else
		{
			glw::GLint log_size = 0;

			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);

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

			glw::GLchar* log_text = new glw::GLchar[log_size];

			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);

			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
												<< log_text << "\n"
												<< tcu::TestLog::EndMessage;

			delete[] log_text;

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

			throw 0;
		}
	}
	catch (...)
	{
		if (m_po)
		{
			gl.deleteProgram(m_po);

			m_po = 0;
		}
	}

	for (glw::GLuint i = 0; i < shader_count; ++i)
	{
		if (0 != shader[i].id)
		{
			gl.deleteShader(shader[i].id);

			shader[i].id = 0;
		}
	}

	if (m_po)
	{
		gl.useProgram(m_po);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
	}

	if (0 == m_po)
	{
		throw 0;
	}
}

/** @brief Function draws full screen quad. Queries are measured during the process.
 *         Also, transform feedback data is captured.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void FunctionalTest::draw()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Start queries. */
	for (glw::GLuint i = 0; i < s_targets_count; ++i)
	{
		gl.beginQuery(s_targets[i], m_qo[i]);
	}

	/* Start XFB. */
	gl.beginTransformFeedback(GL_TRIANGLES);

	/* Draw full screen quad. */
	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);

	/* Finish XFB. */
	gl.endTransformFeedback();

	/* Finish queries. */
	for (glw::GLuint i = 0; i < s_targets_count; ++i)
	{
		gl.endQuery(s_targets[i]);
	}

	/* Make sure OpenGL finished drawing. */
	gl.finish();

	/* Error checking. */
	GLU_EXPECT_NO_ERROR(gl.getError(), "Drawing function have failed.");
}

/** @brief Check that framebuffer is filled with red color.
 */
bool FunctionalTest::checkView()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Fetch framebuffer data. */
	glw::GLubyte pixel[4] = { 0 };

	gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels have failed");

	/* Comparison with expected values. */
	if ((255 != pixel[0]) || (0 != pixel[1]) || (0 != pixel[2]) || (255 != pixel[3]))
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "Frameuffer content (" << (unsigned int)pixel[0] << ", "
			<< (unsigned int)pixel[1] << ", " << (unsigned int)pixel[2] << ", " << (unsigned int)pixel[3]
			<< ") is different than expected (255, 0, 0, 255)." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Check that transform feedback buffer
 *         contains values representing quad.
 */
bool FunctionalTest::checkXFB()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Default result. */
	bool is_ok = true;

	/* Mapping buffer object to the user-space. */
	glw::GLint* buffer = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");

	if ((0 != buffer[0]) || (1 != buffer[1]) || (2 != buffer[2]) ||

		(2 != buffer[3]) || (1 != buffer[4]) || (3 != buffer[5]))
	{
		is_ok = false;
	}

	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");

	return is_ok;
}

/** @brief Release all created objects.
 */
void FunctionalTest::clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Releasing queries. */
	if (DE_NULL != m_qo)
	{
		gl.deleteQueries(s_targets_count, m_qo);

		delete[] m_qo;

		m_qo = DE_NULL;
	}

	/* Release framebuffer. */
	if (m_fbo)
	{
		gl.deleteFramebuffers(1, &m_fbo);

		m_fbo = 0;
	}

	/* Release renderbuffer. */
	if (m_rbo)
	{
		gl.deleteRenderbuffers(1, &m_rbo);

		m_rbo = 0;
	}

	/* Release vertex array object. */
	if (m_vao)
	{
		gl.deleteVertexArrays(1, &m_vao);

		m_vao = 0;
	}

	/* Release buffer object for storing queries' results. */
	if (m_bo_query)
	{
		gl.deleteBuffers(1, &m_bo_query);

		m_bo_query = 0;
	}

	/* Release transform feedback buffer. */
	if (m_bo_xfb)
	{
		gl.deleteBuffers(1, &m_bo_xfb);

		m_bo_xfb = 0;
	}

	/* Release GLSL program. */
	if (m_po)
	{
		gl.useProgram(0);

		gl.deleteProgram(m_po);

		m_po = 0;
	}
}

/** Targets to be tested. */
const glw::GLenum FunctionalTest::s_targets[] = { GL_SAMPLES_PASSED, GL_TIME_ELAPSED, GL_PRIMITIVES_GENERATED,
												  GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN };

/** Expected result for each target. */
const glw::GLint FunctionalTest::s_results[] = { 1, 0, 2, 2 };

/** Number of targets. */
const glw::GLuint FunctionalTest::s_targets_count = sizeof(s_targets) / sizeof(s_targets[0]);

/** Vertex shader source code. */
const glw::GLchar FunctionalTest::s_vertex_shader[] = "#version 450\n"
													  "\n"
													  "out int xfb_result;\n"
													  "\n"
													  "void main()\n"
													  "{\n"
													  "    switch(gl_VertexID)\n"
													  "    {\n"
													  "        case 0:\n"
													  "            gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
													  "            break;\n"
													  "        case 1:\n"
													  "            gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
													  "            break;\n"
													  "        case 2:\n"
													  "            gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
													  "            break;\n"
													  "        case 3:\n"
													  "            gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
													  "            break;\n"
													  "    }\n"
													  "\n"
													  "    xfb_result = gl_VertexID;\n"
													  "}\n";

/** Fragment shader source program. */
const glw::GLchar FunctionalTest::s_fragment_shader[] = "#version 450\n"
														"\n"
														"out vec4 color;\n"
														"\n"
														"void main()\n"
														"{\n"
														"    color = vec4(1.0, 0.0, 0.0, 1.0);\n"
														"}\n";

/** Name of transform feedback varying in vertex shader. */
const glw::GLchar* FunctionalTest::s_xfb_varying_name = "xfb_result";

/******************************** Reuse Test Implementation   ********************************/

/** @brief Reuse Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
ReuseTest::ReuseTest(deqp::Context& context) : deqp::TestCase(context, "queries_reuse", "Query Objects Reuse Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Reuse Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult ReuseTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok = true;

	GLuint query_id_a = 0;
	GLuint query_id_b = 0;
	/* Allocate query object */
	gl.genQueries(1, &query_id_a);
	/* Associate object with GL_TIMESTAMP */
	gl.queryCounter(query_id_a, GL_TIMESTAMP);
	/* Deallocate query object */
	gl.deleteQueries(1, &query_id_a);

	/* Allocate query object again - should result in the same id */
	gl.genQueries(1, &query_id_b);
	/* Use the id with something else */
	gl.beginQuery(GL_TIME_ELAPSED, query_id_b);
	if (gl.getError() != 0) /* Crash was reported here. */
		is_ok = false;
	gl.endQuery(GL_TIME_ELAPSED);
	/* Clean up */
	gl.deleteQueries(1, &query_id_b);

	if (query_id_a != query_id_b)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "Note: Queries got different id:s, so no actual reuse occurred."
			<< tcu::TestLog::EndMessage;
	}

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	return STOP;
}

} /* Queries namespace. */
} /* DirectStateAccess namespace. */
} /* gl4cts namespace. */
