/*-------------------------------------------------------------------------
 * 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  gl4cDirectStateAccessXFBTests.cpp
 * \brief Conformance tests for the Direct State Access feature functionality (Transform Feedbeck 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"

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

/** @brief Creation Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
CreationTest::CreationTest(deqp::Context& context)
	: deqp::TestCase(context, "xfb_creation", "Transform Feedback 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;

	/* Transform feedback objects */
	static const glw::GLuint xfb_count = 2;

	glw::GLuint xfb_dsa[xfb_count]	= {};
	glw::GLuint xfb_legacy[xfb_count] = {};

	try
	{
		/* Sanity default setup. */
		gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback have failed");

		/* Check legacy way. */
		gl.genTransformFeedbacks(xfb_count, xfb_legacy);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks have failed");

		for (glw::GLuint i = 0; i < xfb_count; ++i)
		{
			if (gl.isTransformFeedback(xfb_legacy[i]))
			{
				is_ok = false;

				/* Log. */
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "GenTransformFeedbacks has created defualt objects, but only shall reserve names for them."
					<< tcu::TestLog::EndMessage;
			}
		}

		/* Check direct state access way. */
		gl.createTransformFeedbacks(xfb_count, xfb_dsa);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");

		for (glw::GLuint i = 0; i < xfb_count; ++i)
		{
			if (!gl.isTransformFeedback(xfb_dsa[i]))
			{
				is_ok = false;

				/* Log. */
				m_context.getTestContext().getLog() << tcu::TestLog::Message
													<< "CreateTransformFeedbacks has not created defualt objects."
													<< tcu::TestLog::EndMessage;
			}
		}

		/* Check binding point. */
		glw::GLint xfb_binding_point = -1;

		gl.getIntegerv(GL_TRANSFORM_FEEDBACK_BINDING, &xfb_binding_point);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv have failed");

		if (0 != xfb_binding_point)
		{
			if (-1 == xfb_binding_point)
			{
				m_context.getTestContext().getLog() << tcu::TestLog::Message
													<< "glGetIntegerv used with GL_TRANSFORM_FEEDBACK_BINDING have not "
													   "returned anything and did not generate error."
													<< tcu::TestLog::EndMessage;

				throw 0;
			}
			else
			{
				m_context.getTestContext().getLog() << tcu::TestLog::Message
													<< "The usage of glCreateTransformFeedbacks have changed "
													   "GL_TRANSFORM_FEEDBACK_BINDING binding point."
													<< tcu::TestLog::EndMessage;

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

	/* Cleanup. */
	for (glw::GLuint i = 0; i < xfb_count; ++i)
	{
		if (xfb_legacy[i])
		{
			gl.deleteTransformFeedbacks(1, &xfb_legacy[i]);

			xfb_legacy[i] = 0;
		}

		if (xfb_dsa[i])
		{
			gl.deleteTransformFeedbacks(1, &xfb_dsa[i]);

			xfb_dsa[i] = 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, "xfb_defaults", "Transform Feedback Defaults Test")
	, m_gl_getTransformFeedbackiv(DE_NULL)
	, m_gl_getTransformFeedbacki_v(DE_NULL)
	, m_gl_getTransformFeedbacki64_v(DE_NULL)
	, m_xfb_dsa(0)
	, m_xfb_indexed_binding_points_count(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;

	try
	{
		prepare();

		is_ok &= testBuffersBindingPoints();
		is_ok &= testBuffersDimensions();
		is_ok &= testActive();
		is_ok &= testPaused();
	}
	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 Create XFB and Buffer Objects. Prepare function pointers.
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @return True if test succeeded, false otherwise.
 */
void DefaultsTest::prepare()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Fetching function pointers. */
	m_gl_getTransformFeedbackiv	= (GetTransformFeedbackiv_ProcAddress)gl.getTransformFeedbackiv;
	m_gl_getTransformFeedbacki_v   = (GetTransformFeedbacki_v_ProcAddress)gl.getTransformFeedbacki_v;
	m_gl_getTransformFeedbacki64_v = (GetTransformFeedbacki64_v_ProcAddress)gl.getTransformFeedbacki64_v;

	if ((DE_NULL == m_gl_getTransformFeedbackiv) || (DE_NULL == m_gl_getTransformFeedbacki_v) ||
		(DE_NULL == m_gl_getTransformFeedbacki64_v))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function pointers are set to NULL values."
											<< tcu::TestLog::EndMessage;

		throw 0;
	}

	/* XFB object creation */
	gl.createTransformFeedbacks(1, &m_xfb_dsa);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");

	/* Query limits. */
	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &m_xfb_indexed_binding_points_count);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glIntegerv have failed");
}

/** @brief Test default value of GL_TRANSFORM_FEEDBACK_BUFFER_BINDING.
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @return True if test succeeded, false otherwise.
 */
bool DefaultsTest::testBuffersBindingPoints()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check default binding points value. */
	for (glw::GLint i = 0; i < m_xfb_indexed_binding_points_count; ++i)
	{
		glw::GLint buffer_binding = -1;

		m_gl_getTransformFeedbacki_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, &buffer_binding);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");

		if (-1 == buffer_binding)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING has not returned "
				   "anything and error has not been generated."
				<< tcu::TestLog::EndMessage;

			return false;
		}
		else
		{
			if (0 != buffer_binding)
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING has returned "
					<< buffer_binding << ", however 0 is expected." << tcu::TestLog::EndMessage;

				return false;
			}
		}
	}

	return true;
}

/** @brief Test default values of GL_TRANSFORM_FEEDBACK_START and GL_TRANSFORM_FEEDBACK_SIZE.
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @return True if test succeeded, false otherwise.
 */
bool DefaultsTest::testBuffersDimensions()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check default buffers' start value. */
	for (glw::GLint i = 0; i < m_xfb_indexed_binding_points_count; ++i)
	{
		glw::GLint64 buffer_start = -1;

		m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_START, i, &buffer_start);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");

		if (-1 == buffer_start)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START has not returned "
				   "anything and error has not been generated."
				<< tcu::TestLog::EndMessage;

			return false;
		}
		else
		{
			if (0 != buffer_start)
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START has returned "
					<< buffer_start << ", however 0 is expected." << tcu::TestLog::EndMessage;

				return false;
			}
		}
	}

	/** @brief Check default buffers' size value.
	 *
	 *  @note The function may throw if unexpected error has occured.
	 */
	for (glw::GLint i = 0; i < m_xfb_indexed_binding_points_count; ++i)
	{
		glw::GLint64 buffer_size = -1;

		m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, i, &buffer_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");

		if (-1 == buffer_size)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE has not returned "
				   "anything and error has not been generated."
				<< tcu::TestLog::EndMessage;

			return false;
		}
		else
		{
			if (0 != buffer_size)
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE has returned "
					<< buffer_size << ", however 0 is expected." << tcu::TestLog::EndMessage;

				return false;
			}
		}
	}

	return true;
}

/** @brief Test default value of GL_TRANSFORM_FEEDBACK_ACTIVE.
 *
 *  @return True if test succeeded, false otherwise.
 */
bool DefaultsTest::testActive()
{
	/* Check that it is not active. */
	glw::GLint is_active = -1;
	m_gl_getTransformFeedbackiv(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_ACTIVE, &is_active);

	if (-1 == is_active)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetTransformFeedbackiv with parameter GL_TRANSFORM_FEEDBACK_ACTIVE "
											   "has not returned anything and error has not been generated."
											<< tcu::TestLog::EndMessage;

		return false;
	}
	else
	{
		if (0 != is_active)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetTransformFeedbackiv with parameter GL_TRANSFORM_FEEDBACK_ACTIVE has returned " << is_active
				<< ", however FALSE is expected." << tcu::TestLog::EndMessage;

			return false;
		}
	}

	return true;
}

/** @brief Test default value of GL_TRANSFORM_FEEDBACK_PAUSED.
 *
 *  @return True if test succeeded, false otherwise.
 */
bool DefaultsTest::testPaused()
{
	/* Check that it is not paused. */
	glw::GLint is_paused = -1;
	m_gl_getTransformFeedbackiv(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_PAUSED, &is_paused);

	if (-1 == is_paused)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_PAUSED "
											   "has not returned anything and error has not been generated."
											<< tcu::TestLog::EndMessage;

		return false;
	}
	else
	{
		if (0 != is_paused)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetTransformFeedbackiv with parameter GL_TRANSFORM_FEEDBACK_PAUSED has returned " << is_paused
				<< ", however FALSE is 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_xfb_dsa)
	{
		gl.deleteTransformFeedbacks(1, &m_xfb_dsa);

		m_xfb_dsa = 0;
	}
}

/******************************** Buffers Test Implementation   ********************************/

/** @brief Buffers Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
BuffersTest::BuffersTest(deqp::Context& context)
	: deqp::TestCase(context, "xfb_buffers", "Transform Feedback Buffers Test")
	, m_gl_getTransformFeedbacki_v(DE_NULL)
	, m_gl_getTransformFeedbacki64_v(DE_NULL)
	, m_gl_TransformFeedbackBufferBase(DE_NULL)
	, m_gl_TransformFeedbackBufferRange(DE_NULL)
	, m_xfb_dsa(0)
	, m_bo_a(0)
	, m_bo_b(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Buffers Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult BuffersTest::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;

	try
	{
		/* Prepare function pointers, transform feedback and buffer objects. */
		prepareObjects();

		/* Setup transform feedback object binding points with buffer objects. */
		is_ok = prepareTestSetup();

		/* Continue only if test setup succeeded */
		if (is_ok)
		{
			is_ok &= testBindingPoint(0, m_bo_a, "glTransformFeedbackBufferBase");
			is_ok &= testBindingPoint(1, m_bo_b, "glTransformFeedbackBufferRange");
			is_ok &= testBindingPoint(2, m_bo_b, "glTransformFeedbackBufferRange");

			is_ok &= testStart(0, 0, "glTransformFeedbackBufferBase");
			is_ok &= testStart(1, 0, "glTransformFeedbackBufferRange");
			is_ok &= testStart(2, s_bo_size / 2, "glTransformFeedbackBufferRange");

			is_ok &= testSize(0, 0, "glTransformFeedbackBufferBase");
			is_ok &= testSize(1, s_bo_size / 2, "glTransformFeedbackBufferRange");
			is_ok &= testSize(2, s_bo_size / 2, "glTransformFeedbackBufferRange");
		}
	}
	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 Create XFB amd BO objects. Setup function pointers.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void BuffersTest::prepareObjects()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Fetching function pointers. */
	m_gl_getTransformFeedbacki_v	  = (GetTransformFeedbacki_v_ProcAddress)gl.getTransformFeedbacki_v;
	m_gl_getTransformFeedbacki64_v	= (GetTransformFeedbacki64_v_ProcAddress)gl.getTransformFeedbacki64_v;
	m_gl_TransformFeedbackBufferBase  = (TransformFeedbackBufferBase_ProcAddress)gl.transformFeedbackBufferBase;
	m_gl_TransformFeedbackBufferRange = (TransformFeedbackBufferRange_ProcAddress)gl.transformFeedbackBufferRange;

	if ((DE_NULL == m_gl_getTransformFeedbacki_v) || (DE_NULL == m_gl_getTransformFeedbacki64_v) ||
		(DE_NULL == m_gl_TransformFeedbackBufferBase) || (DE_NULL == m_gl_TransformFeedbackBufferRange))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function pointers are set to NULL values."
											<< tcu::TestLog::EndMessage;

		throw 0;
	}

	/** @brief XFB object creation */
	gl.createTransformFeedbacks(1, &m_xfb_dsa);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");

	/* Buffer Objects creation. */
	gl.genBuffers(1, &m_bo_a);
	gl.genBuffers(1, &m_bo_b);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");

	if ((0 == m_bo_a) || (0 == m_bo_b))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Buffer object has not been generated and no error has been triggered."
											<< tcu::TestLog::EndMessage;

		throw 0;
	}

	/* First buffer memory allocation. */
	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_a);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");

	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, NULL, GL_DYNAMIC_COPY);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed");

	/* Sainty check of buffer size */
	glw::GLint allocated_size = -1;

	gl.getBufferParameteriv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_BUFFER_SIZE, &allocated_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferParameteriv have failed");

	if (allocated_size != (glw::GLint)s_bo_size)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Buffer allocation failed."
											<< tcu::TestLog::EndMessage;

		throw 0;
	}

	/* Second buffer memory allocation. */
	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_b);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");

	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, NULL, GL_DYNAMIC_COPY);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed");

	/* Sainty check of buffer size */
	allocated_size = -1;

	gl.getBufferParameteriv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_BUFFER_SIZE, &allocated_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferParameteriv have failed");

	if (allocated_size != (glw::GLint)s_bo_size)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Buffer allocation failed."
											<< tcu::TestLog::EndMessage;

		throw 0;
	}

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

/** @brief Setup indexed buffer binding points in the xfb object using
 *         glTransformFeedbackBufferBase and glTransformFeedbackBufferRange
 *         functions.
 *
 *  @return True if setup succeeded, false otherwise (functions triggered errors).
 */
bool BuffersTest::prepareTestSetup()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Bind Buffer Object to first indexed binding point. */
	m_gl_TransformFeedbackBufferBase(m_xfb_dsa, 0, m_bo_a);

	/* Check errors. */
	glw::GLenum error_value = gl.getError();

	if (GL_NONE != error_value)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "glTransformFeedbackBufferBase has generated unexpected error ("
			<< glu::getErrorStr(error_value) << "). Test Failed." << tcu::TestLog::EndMessage;

		return false;
	}

	/* Bind Buffer Object to second and third indexed binding point. */
	m_gl_TransformFeedbackBufferRange(m_xfb_dsa, 1, m_bo_b, 0, s_bo_size / 2);
	m_gl_TransformFeedbackBufferRange(m_xfb_dsa, 2, m_bo_b, s_bo_size / 2, s_bo_size / 2);

	/* Check errors. */
	error_value = gl.getError();

	if (GL_NONE != error_value)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "glTransformFeedbackBufferRange has generated unexpected error ("
			<< glu::getErrorStr(error_value) << "). Test Failed." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Test that xfb object's binding point #<index> has <expected_value>.
 *
 *  @param [in] index                   Tested index point.
 *  @param [in] expected_value          Value to be expected (buffer name).
 *  @param [in] tested_function_name    Name of function which this function is going to test
 *                                      (glTransformFeedbackBufferBase or glTransformFeedbackBufferRange)
 *                                      for logging purposes.
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @return True if test succeeded, false otherwise.
 */
bool BuffersTest::testBindingPoint(glw::GLuint const index, glw::GLint const expected_value,
								   glw::GLchar const* const tested_function_name)
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check default binding points value. */
	glw::GLint buffer_binding = -1;

	m_gl_getTransformFeedbacki_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, index, &buffer_binding);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");

	if (-1 == buffer_binding)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING "
										"has not returned anything and error has not been generated."
			<< tcu::TestLog::EndMessage;

		return false;
	}
	else
	{
		if (expected_value != buffer_binding)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING has returned "
				<< buffer_binding << ", however " << expected_value << " is expected. As a consequence function "
				<< tested_function_name << " have failed to setup proper value." << tcu::TestLog::EndMessage;

			return false;
		}
	}

	return true;
}

/** @brief Test that buffer object at xfb object's binding point #<index> has starting offset set to the <expected_value>.
 *
 *  @param [in] index                   Tested index point.
 *  @param [in] expected_value          Value to be expected (starting offset).
 *  @param [in] tested_function_name    Name of function which this function is going to test
 *                                      (glTransformFeedbackBufferBase or glTransformFeedbackBufferRange)
 *                                      for logging purposes.
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @return True if test succeeded, false otherwise.
 */
bool BuffersTest::testStart(glw::GLuint const index, glw::GLint const expected_value,
							glw::GLchar const* const tested_function_name)
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check default buffers' start value. */
	glw::GLint64 buffer_start = -1;

	m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_START, index, &buffer_start);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");

	/* Checking results and errors. */
	if (-1 == buffer_start)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START "
										"has not returned anything and error has not been generated."
			<< tcu::TestLog::EndMessage;

		return false;
	}
	else
	{
		if (expected_value != buffer_start)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START has returned "
				<< buffer_start << ", however " << expected_value << " is expected. As a consequence function "
				<< tested_function_name << " have failed to setup proper value." << tcu::TestLog::EndMessage;

			return false;
		}
	}

	return true;
}

/** @brief Test that buffer object at xfb object's binding point #<index> has size set to the <expected_value>.
 *
 *  @param [in] index                   Tested index point.
 *  @param [in] expected_value          Value to be expected (buffer's size).
 *  @param [in] tested_function_name    Name of function which this function is going to test
 *                                      (glTransformFeedbackBufferBase or glTransformFeedbackBufferRange)
 *                                      for logging purposes.
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @return True if test succeeded, false otherwise.
 */
bool BuffersTest::testSize(glw::GLuint const index, glw::GLint const expected_value,
						   glw::GLchar const* const tested_function_name)
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check default buffer's size value. */
	glw::GLint64 buffer_size = -1;

	m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, index, &buffer_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");

	/* Checking results and errors. */
	if (-1 == buffer_size)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE "
										"has not returned anything and error has not been generated."
			<< tcu::TestLog::EndMessage;

		return false;
	}
	else
	{
		if (expected_value != buffer_size)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE has returned "
				<< buffer_size << ", however " << expected_value << " is expected. As a consequence function "
				<< tested_function_name << " have failed to setup proper value." << tcu::TestLog::EndMessage;

			return false;
		}
	}

	return true;
}

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

	/* Release transform feedback object. */
	if (m_xfb_dsa)
	{
		gl.deleteTransformFeedbacks(1, &m_xfb_dsa);

		m_xfb_dsa = 0;
	}

	/* Release buffer objects. */
	if (m_bo_a)
	{
		gl.deleteBuffers(1, &m_bo_a);

		m_bo_a = 0;
	}

	if (m_bo_b)
	{
		gl.deleteBuffers(1, &m_bo_b);

		m_bo_b = 0;
	}
}

/** @brief Buffer Object Size */
const glw::GLuint BuffersTest::s_bo_size = 512;

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

/** @brief Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
ErrorsTest::ErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "xfb_errors", "Transform Feedback Errors Test")
	, m_gl_getTransformFeedbackiv(DE_NULL)
	, m_gl_getTransformFeedbacki_v(DE_NULL)
	, m_gl_getTransformFeedbacki64_v(DE_NULL)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult ErrorsTest::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;

	try
	{
		prepareFunctionPointers();

		is_ok &= testCreateTransformFeedbacksForInvalidNumberOfObjects();
		cleanErrors();

		is_ok &= testQueriesForInvalidNameOfObject();
		cleanErrors();

		is_ok &= testGetTransformFeedbackivQueryForInvalidParameterName();
		cleanErrors();

		is_ok &= testGetTransformFeedbacki_vQueryForInvalidParameterName();
		cleanErrors();

		is_ok &= testGetTransformFeedbacki64_vQueryForInvalidParameterName();
		cleanErrors();

		is_ok &= testIndexedQueriesForInvalidBindingPoint();
		cleanErrors();
	}
	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 Fetch GL function pointers.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void ErrorsTest::prepareFunctionPointers()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Fetching function pointers. */
	m_gl_getTransformFeedbackiv	= (GetTransformFeedbackiv_ProcAddress)gl.getTransformFeedbackiv;
	m_gl_getTransformFeedbacki_v   = (GetTransformFeedbacki_v_ProcAddress)gl.getTransformFeedbacki_v;
	m_gl_getTransformFeedbacki64_v = (GetTransformFeedbacki64_v_ProcAddress)gl.getTransformFeedbacki64_v;

	if ((DE_NULL == m_gl_getTransformFeedbackiv) || (DE_NULL == m_gl_getTransformFeedbacki_v) ||
		(DE_NULL == m_gl_getTransformFeedbacki64_v))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function pointers are set to NULL values."
											<< tcu::TestLog::EndMessage;

		throw 0;
	}
}

/** @brief Sanity clean-up of GL errors.
 *
 *  @note This function is to only make sure that failing test will not affect other tests.
 */
void ErrorsTest::cleanErrors()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Cleaning errors. */
	while (GL_NO_ERROR != gl.getError())
		;
}

/** @brief Test Creation of Transform Feedbacks using Invalid Number Of Objects
 *
 *  @note Test checks that CreateTransformFeedbacks generates INVALID_VALUE error if
 *        number of transform feedback objects to create is negative.
 *
 *  @return true if test succeded, false otherwise.
 */
bool ErrorsTest::testCreateTransformFeedbacksForInvalidNumberOfObjects()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLuint xfbs = 314159;

	gl.createTransformFeedbacks(-1 /* invalid count */, &xfbs);

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

	if (GL_INVALID_VALUE != error)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glCreateTransformFeedbacks called with negative number of objects had "
											   "been expected to generate GL_INVALID_VALUE. However, "
											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;

		return false;
	}

	if (314159 != xfbs)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glCreateTransformFeedbacks called with negative number of objects had "
											   "been expected not to change the given buffer."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Test Direct State Access queries with invalid object name
 *
 *  @note Test checks that GetTransformFeedbackiv, GetTransformFeedbacki_v and
 *        GetTransformFeedbacki64_v generate INVALID_OPERATION error if xfb is not
 *        zero or the name of an existing transform feedback object.
 *
 *  @return true if test succeded, false otherwise.
 */
bool ErrorsTest::testQueriesForInvalidNameOfObject()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Generating not a-TransformFeedback name. */
	glw::GLuint invalid_name = 0;

	while (GL_TRUE == gl.isTransformFeedback(++invalid_name))
		;

	/* unused storage. */
	glw::GLint   buffer   = 314159;
	glw::GLint64 buffer64 = 314159;

	/* Error variable. */
	glw::GLenum error = 0;

	/* Test of GetTransformFeedbackiv. */
	m_gl_getTransformFeedbackiv(invalid_name, GL_TRANSFORM_FEEDBACK_PAUSED, &buffer);

	if (GL_INVALID_OPERATION != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetTransformFeedbackiv called with invalid object name had been "
											   "expected to generate GL_INVALID_OPERATION. However, "
											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;

		return false;
	}

	if (314159 != buffer)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetTransformFeedbackiv called with invalid object name had been "
											   "expected not to change the given buffer."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	while (GL_NO_ERROR != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Warning! glGetTransformFeedbackiv called with invalid object name has "
											   "generated more than one error, The next error was  "
											<< glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
	}

	/* Test of GetTransformFeedbacki_v. */
	m_gl_getTransformFeedbacki_v(invalid_name, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, &buffer);

	if (GL_INVALID_OPERATION != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetTransformFeedbacki_v called with invalid object name had been "
											   "expected to generate GL_INVALID_OPERATION. However, "
											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;

		return false;
	}

	if (314159 != buffer)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetTransformFeedbacki_v called with invalid object name had been "
											   "expected not to change the given buffer."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	while (GL_NO_ERROR != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Warning! glGetTransformFeedbacki_v called with invalid object name has "
											   "unexpectedly generated more than one error, The next error was  "
											<< glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
	}

	/* Test of GetTransformFeedbacki64_v. */
	m_gl_getTransformFeedbacki64_v(invalid_name, GL_TRANSFORM_FEEDBACK_BUFFER_START, 0, &buffer64);

	if (GL_INVALID_OPERATION != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetTransformFeedbacki64_v called with invalid object name had been "
											   "expected to generate GL_INVALID_OPERATION. However, "
											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;

		return false;
	}

	if (314159 != buffer64)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetTransformFeedbacki64_v called with invalid object name had been "
											   "expected not to change the given buffer."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	while (GL_NO_ERROR != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Warning! glGetTransformFeedbacki64_v called with invalid object name "
											   "has unexpectedly generated more than one error, The next error was  "
											<< glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
	}

	return true;
}

/** @brief Test Direct State Access queries with invalid parameter name
 *
 *  @note Test checks that GetTransformFeedbackiv generates INVALID_ENUM error if pname
 *        is not TRANSFORM_FEEDBACK_PAUSED or TRANSFORM_FEEDBACK_ACTIVE.
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @return true if test succeded, false otherwise.
 */
bool ErrorsTest::testGetTransformFeedbackivQueryForInvalidParameterName()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Creating XFB object. */
	glw::GLuint xfb = 0;

	gl.createTransformFeedbacks(1, &xfb);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");

	/* Generating invalid parameter name. */
	glw::GLuint invalid_parameter_name = 0;

	/* Unused storage. */
	glw::GLint buffer = 314159;

	/* Error variable. */
	glw::GLenum error = 0;

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

	/* Test of GetTransformFeedbackiv. */
	m_gl_getTransformFeedbackiv(xfb, invalid_parameter_name, &buffer);

	if (GL_INVALID_ENUM != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetTransformFeedbackiv called with invalid parameter name had been "
											   "expected to generate GL_INVALID_ENUM. However, "
											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;

		is_ok = false;
	}

	if (314159 != buffer)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetTransformFeedbackiv called with invalid parameter name had been "
											   "expected not to change the given buffer."
											<< tcu::TestLog::EndMessage;

		is_ok = false;
	}

	while (GL_NO_ERROR != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Warning! glGetTransformFeedbackiv called with invalid parameter name "
											   "has generated more than one error, The next error was  "
											<< glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
	}

	/* Clean-up. */
	gl.deleteTransformFeedbacks(1, &xfb);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed");

	return is_ok;
}

/** @brief Test Direct State Access indexed integer query with invalid parameter name
 *
 *  @note Test checks that GetTransformFeedbacki_v generates INVALID_ENUM error if pname
 *        is not TRANSFORM_FEEDBACK_BUFFER_BINDING.
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @return true if test succeded, false otherwise.
 */
bool ErrorsTest::testGetTransformFeedbacki_vQueryForInvalidParameterName()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Creating XFB object. */
	glw::GLuint xfb = 0;

	gl.createTransformFeedbacks(1, &xfb);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");

	/* Generating invalid parameter name. */
	glw::GLuint invalid_parameter_name = 0;

	/* Unused storage. */
	glw::GLint buffer = 314159;

	/* Error variable. */
	glw::GLenum error = 0;

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

	/* Test of GetTransformFeedbackiv. */
	m_gl_getTransformFeedbacki_v(xfb, invalid_parameter_name, 0, &buffer);

	if (GL_INVALID_ENUM != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetTransformFeedbacki_v called with invalid parameter name had been "
											   "expected to generate GL_INVALID_ENUM. However, "
											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;

		is_ok = false;
	}

	if (314159 != buffer)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetTransformFeedbacki_v called with invalid parameter name had been "
											   "expected not to change the given buffer."
											<< tcu::TestLog::EndMessage;

		is_ok = false;
	}

	while (GL_NO_ERROR != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Warning! glGetTransformFeedbacki_v called with invalid parameter name "
											   "has generated more than one error, The next error was  "
											<< glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
	}

	/* Clean-up. */
	gl.deleteTransformFeedbacks(1, &xfb);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed");

	return is_ok;
}

/** @brief Test Direct State Access indexed 64 bit integer query with invalid parameter name
 *
 *  @note Test checks that GetTransformFeedbacki64_v generates INVALID_ENUM error if
 *        pname is not TRANSFORM_FEEDBACK_BUFFER_START or
 *        TRANSFORM_FEEDBACK_BUFFER_SIZE.
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @return true if test succeded, false otherwise.
 */
bool ErrorsTest::testGetTransformFeedbacki64_vQueryForInvalidParameterName()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Creating XFB object. */
	glw::GLuint xfb = 0;

	gl.createTransformFeedbacks(1, &xfb);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");

	/* Generating invalid parameter name. */
	glw::GLuint invalid_parameter_name = 0;

	/* Unused storage. */
	glw::GLint64 buffer = 314159;

	/* Error variable. */
	glw::GLenum error = 0;

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

	/* Test of GetTransformFeedbackiv. */
	m_gl_getTransformFeedbacki64_v(xfb, invalid_parameter_name, 0, &buffer);

	if (GL_INVALID_ENUM != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetTransformFeedbacki64_v called with invalid parameter name had "
											   "been expected to generate GL_INVALID_ENUM. However, "
											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;

		is_ok = false;
	}

	if (314159 != buffer)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetTransformFeedbacki64_v called with invalid parameter name had "
											   "been expected not to change the given buffer."
											<< tcu::TestLog::EndMessage;

		is_ok = false;
	}

	while (GL_NO_ERROR != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Warning! glGetTransformFeedbacki64_v called with invalid parameter "
											   "name has generated more than one error, The next error was  "
											<< glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
	}

	/* Clean-up. */
	gl.deleteTransformFeedbacks(1, &xfb);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed");

	return is_ok;
}

/** @brief Test Direct State Access indexed queries with invalid index
 *
 *  @note Test checks that GetTransformFeedbacki_v and GetTransformFeedbacki64_v
 *        generate INVALID_VALUE error by GetTransformFeedbacki_v and
 *        GetTransformFeedbacki64_v if index is greater than or equal to the
 *        number of binding points for transform feedback (the value of
 *        MAX_TRANSFORM_FEEDBACK_BUFFERS).
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @return true if test succeded, false otherwise.
 */
bool ErrorsTest::testIndexedQueriesForInvalidBindingPoint()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Generating invalid index. */
	glw::GLint max_transform_feedback_buffers =
		4; /* Default limit is 4 - OpenGL 4.5 Core Specification, Table 23.72: Implementation Dependent Transform Feedback Limits. */

	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv have failed");

	/* Creating XFB object. */
	glw::GLuint xfb = 0;

	gl.createTransformFeedbacks(1, &xfb);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");

	/* Unused storage. */
	glw::GLint   buffer   = 314159;
	glw::GLint64 buffer64 = 314159;

	/* Error variable. */
	glw::GLenum error = 0;

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

	/* Test of GetTransformFeedbacki_v. */
	m_gl_getTransformFeedbacki_v(xfb, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, max_transform_feedback_buffers, &buffer);

	if (GL_INVALID_VALUE != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetTransformFeedbacki_v called with invalid index had been expected "
											   "to generate GL_INVALID_VALUE. However, "
											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;

		is_ok = false;
	}

	if (314159 != buffer)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "glGetTransformFeedbacki_v called with invalid index had been expected not to change the given buffer."
			<< tcu::TestLog::EndMessage;

		is_ok = false;
	}

	while (GL_NO_ERROR != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Warning! glGetTransformFeedbacki_v called with invalid index has "
											   "unexpectedly generated more than one error, The next error was  "
											<< glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
	}

	/* Test of GetTransformFeedbacki64_v. */
	m_gl_getTransformFeedbacki64_v(xfb, GL_TRANSFORM_FEEDBACK_BUFFER_START, max_transform_feedback_buffers, &buffer64);

	if (GL_INVALID_VALUE != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetTransformFeedbacki64_v called with invalid index had been "
											   "expected to generate GL_INVALID_VALUE. However, "
											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;

		is_ok = false;
	}

	if (314159 != buffer64)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "glGetTransformFeedbacki64_v called with invalid index had been expected not to change the given buffer."
			<< tcu::TestLog::EndMessage;

		is_ok = false;
	}

	while (GL_NO_ERROR != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Warning! glGetTransformFeedbacki64_v called with invalid index has "
											   "unexpectedly generated more than one error, The next error was  "
											<< glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
	}

	/* Clean-up. */
	gl.deleteTransformFeedbacks(1, &xfb);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed");

	return is_ok;
}

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

/** @brief Functional Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
FunctionalTest::FunctionalTest(deqp::Context& context)
	: deqp::TestCase(context, "xfb_functional", "Transform Feedback Functional Test")
	, m_gl_getTransformFeedbackiv(DE_NULL)
	, m_gl_TransformFeedbackBufferBase(DE_NULL)
	, m_xfb_dsa(0)
	, m_bo(0)
	, m_po(0)
	, m_vao(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Functional Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult FunctionalTest::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;

	try
	{
		prepareFunctionPointers();
		prepareTransformFeedback();
		prepareBuffer();
		prepareProgram();
		prepareVertexArrayObject();

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

	/* Releasing GL objects. */
	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 Get access pointers to GL functions.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void FunctionalTest::prepareFunctionPointers()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Fetching function pointers. */
	m_gl_getTransformFeedbackiv		 = (GetTransformFeedbackiv_ProcAddress)gl.getTransformFeedbackiv;
	m_gl_TransformFeedbackBufferBase = (TransformFeedbackBufferBase_ProcAddress)gl.transformFeedbackBufferBase;

	if ((DE_NULL == m_gl_getTransformFeedbackiv) || (DE_NULL == m_gl_TransformFeedbackBufferBase))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function pointers are set to NULL values."
											<< tcu::TestLog::EndMessage;

		throw 0;
	}
}

/** @brief Create transform feedback object using direct access function.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void FunctionalTest::prepareTransformFeedback()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* XFB object creation. */
	gl.createTransformFeedbacks(1, &m_xfb_dsa);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
}

/** @brief Create buffer object and bind it to transform feedback object using direct access function.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void FunctionalTest::prepareBuffer()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Buffer creation and memory allocation. */
	gl.genBuffers(1, &m_bo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");

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

	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, DE_NULL, GL_DYNAMIC_COPY);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed");

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

	/* Bind buffer to xfb object (using direct state access function). */
	m_gl_TransformFeedbackBufferBase(m_xfb_dsa, 0, m_bo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackBufferBase have failed");
}

/** @brief Build test's GLSL program.
 *
 *  @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, 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 Create and bind empty vertex array object.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void FunctionalTest::prepareVertexArrayObject()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Creating and binding empty vertex array object. */
	gl.genVertexArrays(1, &m_vao);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

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

/** @brief Draw with XFB.
 *
 *  @note Function follows steps:
 *           Begin transform feedback environment.
 *
 *           Using the program with discarded rasterizer, draw array of 4 indices
 *           using POINTS.
 *
 *           Pause transform feedback environment.
 *
 *           Query parameter TRANSFORM_FEEDBACK_PAUSED using GetTransformFeedbackiv.
 *           Expect value equal to TRUE.
 *
 *           Query parameter TRANSFORM_FEEDBACK_ACTIVE using GetTransformFeedbackiv.
 *           Expect value equal to TRUE.
 *
 *           Resume transform feedback environment.
 *
 *           Query parameter TRANSFORM_FEEDBACK_PAUSED using GetTransformFeedbackiv.
 *           Expect value equal to FALSE.
 *
 *           Query parameter TRANSFORM_FEEDBACK_ACTIVE using GetTransformFeedbackiv.
 *           Expect value equal to TRUE.
 *
 *           End Transform feedback environment.
 *
 *           Query parameter TRANSFORM_FEEDBACK_ACTIVE using GetTransformFeedbackiv.
 *           Expect value equal to FALSE.
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @return True if included tests succeded, false otherwise.
 */
bool FunctionalTest::draw()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

	/* Start transform feedback environment. */
	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_dsa);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback call failed.");

	gl.beginTransformFeedback(GL_POINTS);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");

	/* Use only xfb. No rendering. */
	gl.enable(GL_RASTERIZER_DISCARD);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) call failed.");

	/* Draw. */
	gl.drawArrays(GL_POINTS, 0, 4);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");

	/* Pause Transform Feedback and tests direct state queries related to paused state. */
	gl.pauseTransformFeedback();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback call failed.");

	is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_PAUSED, GL_TRUE);
	is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_ACTIVE, GL_TRUE);

	/* Activate Transform Feedback and tests direct state queries related to paused state. */
	gl.resumeTransformFeedback();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback call failed.");

	is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_PAUSED, GL_FALSE);
	is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_ACTIVE, GL_TRUE);

	/* Finish transform feedback. */
	gl.endTransformFeedback();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");

	is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_ACTIVE, GL_FALSE);

	return is_ok;
}

/** @brief Check that selected Transform Feedback state has an expected value.
 *
 *  @param [in] parameter_name      Name of the parameter to be queried.
 *                                  It must be GL_TRANSFORM_FEEDBACK_PAUSED or
 *                                  GL_TRANSFORM_FEEDBACK_ACTIVE
 *  @param [in] expected_value      The expected value of the query.
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @return True if the queried value is equal to expected value, false otherwise.
 */
bool FunctionalTest::testTransformFeedbackStatus(glw::GLenum parameter_name, glw::GLint expected_value)
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Unused storage. */
	glw::GLint value = 314159;

	/* Test of GetTransformFeedbackiv. */
	m_gl_getTransformFeedbackiv(m_xfb_dsa, parameter_name, &value);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbackiv call failed.");

	if (expected_value != value)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "It was expected that glGetTransformFeedbackiv query of parameter "
			<< ((parameter_name == GL_TRANSFORM_FEEDBACK_PAUSED) ? "GL_TRANSFORM_FEEDBACK_PAUSED" :
																   "GL_TRANSFORM_FEEDBACK_ACTIVE")
			<< " shall return " << ((expected_value == GL_TRUE) ? "GL_TRUE" : "GL_FALSE") << "however, "
			<< ((value == GL_TRUE) ? "GL_TRUE" : "GL_FALSE") << " was returned." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Check that transform feedback buffer contains
 *         consecutive integer numbers from 0 to 3 (included).
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @return True if buffer conatins consecutive integer
 *          numbers from 0 to 3 (included), false otherwise.
 */
bool FunctionalTest::verifyBufferContent()
{
	/* 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. */
	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

	glw::GLint* buffer = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");

	for (glw::GLint i = 0; i < 4 /* Number of emitted vertices. */; ++i)
	{
		if (buffer[i] != i)
		{
			is_ok = false;

			break;
		}
	}

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

	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

	return is_ok;
}

/** Release GL objects, return to the default state
 */
void FunctionalTest::clean()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release transform feedback object. */
	if (m_xfb_dsa)
	{
		gl.deleteTransformFeedbacks(1, &m_xfb_dsa);

		m_xfb_dsa = 0;
	}

	/* Release buffer object. */
	if (m_bo)
	{
		gl.deleteBuffers(1, &m_bo);

		m_bo = 0;
	}

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

		gl.deleteProgram(m_po);

		m_po = 0;
	}

	/* Release vertex array object. */
	if (m_vao)
	{
		gl.bindVertexArray(0);

		gl.deleteVertexArrays(1, &m_vao);

		m_vao = 0;
	}

	/* Returning to default rasterizer state. */
	gl.disable(GL_RASTERIZER_DISCARD);
}

const glw::GLuint FunctionalTest::s_bo_size = 4 * sizeof(glw::GLint);

const glw::GLchar FunctionalTest::s_vertex_shader[] = "#version 130\n"
													  "\n"
													  "out int result;\n"
													  "\n"
													  "void main()\n"
													  "{\n"
													  "\n"
													  "    result      = gl_VertexID;\n"
													  "    gl_Position = vec4(1.0);\n"
													  "}\n";

const glw::GLchar FunctionalTest::s_fragment_shader[] = "#version 130\n"
														"\n"
														"out vec4 color;\n"
														"\n"
														"void main()\n"
														"{\n"
														"    color = vec4(0.0, 0.0, 0.0, 1.0);\n"
														"}\n";

const glw::GLchar* const FunctionalTest::s_xfb_varying = "result";

} /* TransformFeedback namespace */
} /* DirectStateAccess namespace */
} /* gl4cts namespace */
