/*-------------------------------------------------------------------------
 * 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  gl3cTransformFeedback.cpp
 * \brief Transform Feedback Test Suite Implementation
 */ /*-------------------------------------------------------------------*/

/* Includes. */
#include "gl3cTransformFeedbackTests.hpp"
#include "gluContextInfo.hpp"
#include "gluDefs.hpp"
#include "gluRenderContext.hpp"
#include "gluStrUtil.hpp"
#include "tcuTestLog.hpp"

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdlib>
#include <sstream>

/* Stringify macro. */
#define _STR(s) STR(s)
#define STR(s) #s

/* Unused attribute / variable MACRO.
 Some methods of clesses' heirs do not need all function parameters.
 This triggers warnings on GCC platform. This macro will silence them.
 */
#ifdef __GNUC__
#define UNUSED __attribute__((__unused__))
#else
#define UNUSED
#endif

gl3cts::TransformFeedback::Tests::Tests(deqp::Context& context)
	: TestCaseGroup(context, "transform_feedback", "Transform Feedback Test Suite")
{
	addChild(new TransformFeedback::APIErrors(m_context));
	addChild(new TransformFeedback::LinkingErrors(m_context));
	addChild(new TransformFeedback::Limits(m_context));
	addChild(new TransformFeedback::CaptureVertexInterleaved(m_context, "capture_vertex_interleaved_test",
															 "Transform Feedback Capture Vertex Interleaved Test"));
	addChild(new TransformFeedback::CaptureGeometryInterleaved(m_context, "capture_geometry_interleaved_test",
															   "Transform Feedback Capture Geometry Interleaved Test"));
	addChild(new TransformFeedback::CaptureVertexSeparate(m_context, "capture_vertex_separate_test",
														  "Transform Feedback Capture Vertex Separate Test"));
	addChild(new TransformFeedback::CaptureGeometrySeparate(m_context, "capture_geometry_separate_test",
															"Transform Feedback Capture Geometry Separate Test"));
	addChild(new TransformFeedback::CheckGetXFBVarying(m_context, "get_xfb_varying",
													   "Transform Feedback Varying Getters Test"));
	addChild(new TransformFeedback::QueryVertexInterleaved(m_context, "query_vertex_interleaved_test",
														   "Transform Feedback Query Vertex Interleaved Test"));
	addChild(new TransformFeedback::QueryGeometryInterleaved(m_context, "query_geometry_interleaved_test",
															 "Transform Feedback Query Geometry Interleaved Test"));
	addChild(new TransformFeedback::QueryVertexSeparate(m_context, "query_vertex_separate_test",
														"Transform Feedback Query Vertex Separate Test"));
	addChild(new TransformFeedback::QueryGeometrySeparate(m_context, "query_geometry_separate_test",
														  "Transform Feedback Query Geometry Separate Test"));
	addChild(new TransformFeedback::DiscardVertex(m_context, "discard_vertex_test",
												  "Transform Feedback Discard Vertex Test"));
	addChild(new TransformFeedback::DiscardGeometry(m_context, "discard_geometry_test",
													"Transform Feedback Discard Geometry Test"));
	addChild(new TransformFeedback::DrawXFB(m_context, "draw_xfb_test", "Transform Feedback Draw Test"));
	addChild(new TransformFeedback::DrawXFBFeedback(m_context, "draw_xfb_feedbackk_test",
													"Transform Feedback Draw Feedback Test"));
	addChild(
		new TransformFeedback::DrawXFBStream(m_context, "draw_xfb_stream_test", "Transform Feedback Draw Stream Test"));
	addChild(new TransformFeedback::CaptureSpecialInterleaved(m_context, "capture_special_interleaved_test",
															  "Transform Feedback Capture Special Test"));
	addChild(new TransformFeedback::DrawXFBInstanced(m_context, "draw_xfb_instanced_test",
													 "Transform Feedback Draw Instanced Test"));
	addChild(new TransformFeedback::DrawXFBStreamInstanced(m_context, "draw_xfb_stream_instanced_test",
														   "Transform Feedback Draw Stream Instanced Test"));
}

gl3cts::TransformFeedback::Tests::~Tests(void)
{
}

void gl3cts::TransformFeedback::Tests::init(void)
{
}

gl3cts::TransformFeedback::APIErrors::APIErrors(deqp::Context& context)
	: deqp::TestCase(context, "api_errors_test", "Transform Feedback API Errors Test")
	, m_context(context)
	, m_buffer_0(0)
	, m_buffer_1(0)
	, m_vertex_array_object(0)
	, m_transform_feedback_object_0(0)
	, m_transform_feedback_object_1(0)
	, m_query_object(0)
	, m_program_id_with_input_output(0)
	, m_program_id_with_output(0)
	, m_program_id_without_output(0)
	, m_program_id_with_geometry_shader(0)
	, m_program_id_with_tessellation_shaders(0)
	, m_glBindBufferOffsetEXT(DE_NULL)
	, m_glGetIntegerIndexedvEXT(DE_NULL)
	, m_glGetBooleanIndexedvEXT(DE_NULL)
{
}

gl3cts::TransformFeedback::APIErrors::~APIErrors(void)
{
}

tcu::TestNode::IterateResult gl3cts::TransformFeedback::APIErrors::iterate(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Initializations. */
	bool is_at_least_gl_30 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)));
	bool is_at_least_gl_40 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
	bool is_at_least_gl_42 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 2)));

	bool is_ext_tf_1		 = m_context.getContextInfo().isExtensionSupported("GL_EXT_transform_feedback");
	bool is_arb_tf_2		 = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback2");
	bool is_arb_tf_3		 = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback3");
	bool is_arb_tf_instanced = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback_instanced");

	if (is_ext_tf_1)
	{
		/* Extension query. */
		m_glBindBufferOffsetEXT =
			(BindBufferOffsetEXT_ProcAddress)m_context.getRenderContext().getProcAddress("glBindBufferOffsetEXT");
		m_glGetIntegerIndexedvEXT =
			(GetIntegerIndexedvEXT_ProcAddress)m_context.getRenderContext().getProcAddress("glGetIntegerIndexedvEXT");
		m_glGetBooleanIndexedvEXT =
			(GetBooleanIndexedvEXT_ProcAddress)m_context.getRenderContext().getProcAddress("glGetBooleanIndexedvEXT");
	}

	if (is_at_least_gl_40 || is_arb_tf_2)
	{
		/* Create transform feedback objects. */
		gl.genTransformFeedbacks(1, &m_transform_feedback_object_0);

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

	if (is_at_least_gl_40 || is_arb_tf_3)
	{
		/* Create query object. */
		gl.genQueries(1, &m_query_object);

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

	if (is_at_least_gl_42 || is_arb_tf_instanced)
	{
		/* Create transform feedback objects. */
		gl.genTransformFeedbacks(1, &m_transform_feedback_object_1);

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

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

	/* Entities setup. */
	try
	{
		/* VAO setup. */
		gl.genVertexArrays(1, &m_vertex_array_object);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

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

		/* Buffer setup. */
		gl.genBuffers(1, &m_buffer_0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

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

		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, NULL, GL_STATIC_DRAW);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

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

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

		gl.bufferData(GL_ARRAY_BUFFER, m_buffer_1_size, m_buffer_1_data, GL_STATIC_DRAW);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

		/* Programs setup. */

		m_program_id_with_input_output = gl3cts::TransformFeedback::Utilities::buildProgram(
			gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_with_input_output,
			s_fragment_shader, &m_varying_name, 1, GL_INTERLEAVED_ATTRIBS);

		m_program_id_with_output = gl3cts::TransformFeedback::Utilities::buildProgram(
			gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_with_output, s_fragment_shader,
			&m_varying_name, 1, GL_INTERLEAVED_ATTRIBS, true);

		m_program_id_without_output = gl3cts::TransformFeedback::Utilities::buildProgram(
			gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_without_output,
			s_fragment_shader, NULL, 0, GL_SEPARATE_ATTRIBS);

		m_program_id_with_geometry_shader = gl3cts::TransformFeedback::Utilities::buildProgram(
			gl, m_context.getTestContext().getLog(), m_geometry_shader, NULL, NULL, s_vertex_shader_without_output,
			s_fragment_shader, &m_varying_name, 1, GL_INTERLEAVED_ATTRIBS);

		m_program_id_with_tessellation_shaders = gl3cts::TransformFeedback::Utilities::buildProgram(
			gl, m_context.getTestContext().getLog(), NULL, m_tessellation_control_shader,
			m_tessellation_evaluation_shader, s_vertex_shader_without_output, s_fragment_shader, &m_varying_name, 1,
			GL_INTERLEAVED_ATTRIBS);

		is_ok = is_ok && m_program_id_with_input_output && m_program_id_with_output && m_program_id_without_output &&
				m_program_id_with_geometry_shader && m_program_id_with_tessellation_shaders;
	}
	catch (...)
	{
		is_ok	  = false;
		test_error = true;
	}

	/* Iterating tests. */
	try
	{
		if (is_at_least_gl_30 || is_ext_tf_1)
		{
			is_ok = is_ok && testExtension1();
		}

		if (is_at_least_gl_40 || is_arb_tf_2)
		{
			is_ok = is_ok && testExtension2();
		}

		if (is_at_least_gl_40 || is_arb_tf_3)
		{
			is_ok = is_ok && testExtension3();
		}

		if (is_at_least_gl_42 || is_arb_tf_instanced)
		{
			is_ok = is_ok && testInstanced();
		}
	}
	catch (...)
	{
		is_ok	  = false;
		test_error = true;
	}

	/* Deinitialization. */
	if (m_vertex_array_object)
	{
		gl.deleteVertexArrays(1, &m_vertex_array_object);

		m_vertex_array_object = 0;
	}

	if (m_buffer_0)
	{
		gl.deleteBuffers(1, &m_buffer_0); // silently unbinds

		m_buffer_0 = 0;
	}

	if (m_buffer_1)
	{
		gl.deleteBuffers(1, &m_buffer_1); // silently unbinds

		m_buffer_1 = 0;
	}

	if (m_transform_feedback_object_0)
	{
		gl.deleteTransformFeedbacks(1, &m_transform_feedback_object_0);

		m_transform_feedback_object_0 = 0;
	}

	if (m_transform_feedback_object_1)
	{
		gl.deleteTransformFeedbacks(1, &m_transform_feedback_object_1);

		m_transform_feedback_object_1 = 0;
	}

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

		m_query_object = 0;
	}

	if (m_program_id_with_input_output)
	{
		gl.deleteProgram(m_program_id_with_input_output);

		m_program_id_with_input_output = 0;
	}

	if (m_program_id_with_output)
	{
		gl.deleteProgram(m_program_id_with_output);

		m_program_id_with_output = 0;
	}

	if (m_program_id_without_output)
	{
		gl.deleteProgram(m_program_id_without_output);

		m_program_id_without_output = 0;
	}

	if (m_program_id_with_geometry_shader)
	{
		gl.deleteProgram(m_program_id_with_geometry_shader);

		m_program_id_with_geometry_shader = 0;
	}

	if (m_program_id_with_tessellation_shaders)
	{
		gl.deleteProgram(m_program_id_with_tessellation_shaders);

		m_program_id_with_tessellation_shaders = 0;
	}

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

	return STOP;
}

bool gl3cts::TransformFeedback::APIErrors::testExtension1(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/*  INVALID_VALUE is generated by BindBufferRange, BindBufferOffset and
	 BindBufferBase when <index> is greater or equal to
	 MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS; */

	glw::GLint index_count = 0;

	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &index_count);

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

	if (index_count == 0)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "glGetIntegerv did not returned any value."
											<< tcu::TestLog::EndMessage;
		throw 0;
	}

	gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, index_count, m_buffer_0, 0, 16);

	if (GL_INVALID_VALUE != gl.getError())
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_VALUE was not generated by BindBufferRange "
											   "when <index> was greater or equal to "
											   "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS."
											<< tcu::TestLog::EndMessage;
		return false;
	}

	if (DE_NULL != m_glBindBufferOffsetEXT)
	{
		m_glBindBufferOffsetEXT(GL_TRANSFORM_FEEDBACK_BUFFER, index_count, m_buffer_0, 0);

		if (GL_INVALID_VALUE != gl.getError())
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message
												<< "INVALID_VALUE was not generated by BindBufferOffset "
												   "when <index> was greater or equal to "
												   "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS."
												<< tcu::TestLog::EndMessage;
			return false;
		}
	}

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, index_count, m_buffer_0);

	if (GL_INVALID_VALUE != gl.getError())
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_VALUE was not generated by "
											   "BindBufferBase when <index> was greater or equal to "
											   "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS."
											<< tcu::TestLog::EndMessage;
		return false;
	}

	/*  INVALID_VALUE is generated by BindBufferRange when <size> is less or equal to zero; */

	gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, index_count, m_buffer_0, 0, 0);

	if (GL_INVALID_VALUE != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "INVALID_VALUE was not generated by BindBufferRange when <size> was less or equal to zero."
			<< tcu::TestLog::EndMessage;
		return false;
	}

	/*  INVALID_VALUE is generated by BindBufferRange and BindBufferOffset
	 when <offset> is not word-aligned; */

	gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, index_count, m_buffer_0, 3, 4);

	if (GL_INVALID_VALUE != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "INVALID_VALUE was not generated by BindBufferRange when <offset> was not word-aligned."
			<< tcu::TestLog::EndMessage;
		return false;
	}

	if (DE_NULL != m_glBindBufferOffsetEXT)
	{
		m_glBindBufferOffsetEXT(GL_TRANSFORM_FEEDBACK_BUFFER, index_count, m_buffer_0, 3);

		if (GL_INVALID_VALUE != gl.getError())
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "INVALID_VALUE was not generated by BindBufferOffset when <offset> was not word-aligned."
				<< tcu::TestLog::EndMessage;
			return false;
		}
	}

	/*  INVALID_VALUE is generated by BindBufferRange when <size> is not word-aligned; */

	gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, index_count, m_buffer_0, 0, 3);

	if (GL_INVALID_VALUE != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "INVALID_VALUE was not generated by BindBufferRange when <size> was not word-aligned."
			<< tcu::TestLog::EndMessage;
		return false;
	}

	/*  INVALID_OPERATION is generated by BindBufferRange, BindBufferOffset and
	 BindBufferBase when <target> is TRANSFORM_FEEDBACK_BUFFER and transform
	 feedback is active; */

	gl.useProgram(m_program_id_with_output);

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

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);

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

	gl.beginTransformFeedback(GL_POINTS);

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

	gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0, 0, 16);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_OPERATION was not generated by BindBufferRange "
											   "when <target> was TRANSFORM_FEEDBACK_BUFFER and transform "
											   "feedback was active."
											<< tcu::TestLog::EndMessage;

		gl.endTransformFeedback();

		return false;
	}

	if (DE_NULL != m_glBindBufferOffsetEXT)
	{
		m_glBindBufferOffsetEXT(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0, 0);

		if (GL_INVALID_OPERATION != gl.getError())
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message
												<< "INVALID_OPERATION was not generated by BindBufferOffset "
												   "when <target> was TRANSFORM_FEEDBACK_BUFFER and transform "
												   "feedback was active."
												<< tcu::TestLog::EndMessage;

			gl.endTransformFeedback();

			return false;
		}
	}

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by "
										"BindBufferBase when <target> was TRANSFORM_FEEDBACK_BUFFER and transform "
										"feedback was active."
			<< tcu::TestLog::EndMessage;

		gl.endTransformFeedback();

		return false;
	}

	gl.endTransformFeedback();

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

	/*  INVALID_OPERATION is generated by UseProgram when transform feedback is
	 active; */

	gl.beginTransformFeedback(GL_POINTS);

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

	gl.useProgram(0);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "INVALID_OPERATION was not generated by UseProgram when transform feedback was active."
			<< tcu::TestLog::EndMessage;

		gl.endTransformFeedback();

		return false;
	}

	gl.endTransformFeedback();

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

	/*  INVALID_OPERATION is generated by LinkProgram when <program> is currently
	 active and transform feedback is active; */

	gl.useProgram(m_program_id_with_output);

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

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);

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

	gl.beginTransformFeedback(GL_POINTS);

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

	gl.linkProgram(m_program_id_with_output);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_OPERATION was not generated by LinkProgram when <program> was "
											   "currently active and transform feedback was active."
											<< tcu::TestLog::EndMessage;

		gl.endTransformFeedback();

		return false;
	}

	gl.endTransformFeedback();

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

	/*  INVALID_OPERATION is generated by BeginTransformFeedback when transform
	 feedback is active; */

	gl.useProgram(m_program_id_with_output);

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

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);

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

	gl.beginTransformFeedback(GL_POINTS);

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

	gl.beginTransformFeedback(GL_POINTS);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "INVALID_OPERATION was not generated by BeginTransformFeedback when transform feedback was active."
			<< tcu::TestLog::EndMessage;

		gl.endTransformFeedback();

		return false;
	}

	gl.endTransformFeedback();

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

	/*  INVALID_OPERATION is generated by EndTransformFeedback when transform
	 feedback is inactive; */

	gl.endTransformFeedback();

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "INVALID_OPERATION was not generated by EndTransformFeedback when transform feedback was inactive."
			<< tcu::TestLog::EndMessage;

		return false;
	}

	/*  INVALID_OPERATION is generated by draw command when generated primitives
	 type does not match <primitiveMode>; */

	gl.useProgram(m_program_id_with_output);

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

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);

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

	gl.beginTransformFeedback(GL_POINTS);

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

	gl.drawArrays(GL_LINES, 0, 2);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_OPERATION was not generated by draw command when generated "
											   "primitives type does not match <primitiveMode>."
											<< tcu::TestLog::EndMessage;

		gl.endTransformFeedback();

		return false;
	}

	gl.endTransformFeedback();

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

	/*  INVALID_OPERATION is generated by BeginTransformFeedback when any binding
	 point used by XFB does not have buffer bound; */

	gl.useProgram(m_program_id_with_output);

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

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);

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

	gl.beginTransformFeedback(GL_POINTS);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_OPERATION was not generated by BeginTransformFeedback when any "
											   "binding point used by XFB does not have buffer bound."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	/*  INVALID_OPERATION is generated by BeginTransformFeedback when no program
	 is active; */

	gl.useProgram(0);

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

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);

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

	gl.beginTransformFeedback(GL_POINTS);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "INVALID_OPERATION was not generated by BeginTransformFeedback when no program was active."
			<< tcu::TestLog::EndMessage;

		gl.endTransformFeedback();

		return false;
	}

	/*  INVALID_OPERATION is generated by BeginTransformFeedback when no variable
	 are specified to be captured in the active program; */

	gl.useProgram(m_program_id_without_output);

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

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);

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

	gl.beginTransformFeedback(GL_POINTS);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "INVALID_OPERATION was not generated by BeginTransformFeedback when no variable "
			   "are specified to be captured in the active program."
			<< tcu::TestLog::EndMessage;

		gl.endTransformFeedback();

		return false;
	}

	/*  INVALID_VALUE is generated by TransformFeedbackVaryings when <program> is
	 not id of the program object; */

	unsigned short int invalid_name = 1;

	while (gl.isProgram(invalid_name) || gl.isShader(invalid_name))
	{
		++invalid_name;

		/* Make sure that this loop ends someday, bad day. */
		if (invalid_name == USHRT_MAX)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "Cannot find unused trnasform feedback object." << tcu::TestLog::EndMessage;
			throw 0;
		}
	}

	gl.transformFeedbackVaryings((glw::GLuint)invalid_name, 1, &m_varying_name, GL_INTERLEAVED_ATTRIBS);

	if (GL_INVALID_VALUE != gl.getError())
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_VALUE was not generated by TransformFeedbackVaryings when "
											   "<program> was not id of the program object."
											<< tcu::TestLog::EndMessage;
		return false;
	}

	/*  INVALID_VALUE is generated by TransformFeedbackVaryings when <bufferMode>
	 is SEPARATE_ATTRIBS and <count> is exceeds limits; */

	glw::GLint max_separate_attribs = 0;

	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &max_separate_attribs);

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

	if (max_separate_attribs == 0)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "INVALID_VALUE was not generated by TransformFeedbackVaryings when <bufferMode>"
										" was SEPARATE_ATTRIBS and <count> was exceeds limits."
			<< tcu::TestLog::EndMessage;
		throw 0;
	}

	glw::GLint more_than_max_separate_attribs = max_separate_attribs + 1;

	glw::GLchar** attrib = new glw::GLchar*[more_than_max_separate_attribs];

	for (glw::GLint i = 0; i < more_than_max_separate_attribs; ++i)
	{
		std::string new_attrib = "a" + gl3cts::TransformFeedback::Utilities::itoa(i);

		size_t new_attrib_size = new_attrib.size();

		attrib[i] = new glw::GLchar[new_attrib_size + 1];

		memset(attrib[i], 0, new_attrib_size + 1);

		memcpy(attrib[i], new_attrib.c_str(), new_attrib_size);
	}

	gl.transformFeedbackVaryings(m_program_id_with_output, more_than_max_separate_attribs, attrib, GL_SEPARATE_ATTRIBS);

	for (glw::GLint i = 0; i < more_than_max_separate_attribs; ++i)
	{
		delete[] attrib[i];
	}

	delete[] attrib;

	if (GL_INVALID_VALUE != gl.getError())
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_VALUE was not generated by TransformFeedbackVaryings when "
											   "<bufferMode> was SEPARATE_ATTRIBS and <count> exceeded limits."
											<< tcu::TestLog::EndMessage;
		return false;
	}

	/*  INVALID_VALUE is generated by GetTransformFeedbackVarying when <index> is
	 greater than or equal to TRANSFORM_FEEDBACK_VARYINGS; */

	glw::GLint transform_feedback_varyings = 0;

	gl.getProgramiv(m_program_id_with_output, GL_TRANSFORM_FEEDBACK_VARYINGS, &transform_feedback_varyings);

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

	if (transform_feedback_varyings == 0)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glGetProgramiv failed to return GL_TRANSFORM_FEEDBACK_VARYINGS."
											<< tcu::TestLog::EndMessage;
		throw 0;
	}

	glw::GLchar tmp_buffer[256];

	glw::GLsizei tmp_size = 0;

	glw::GLenum tmp_type = GL_NONE;

	gl.getTransformFeedbackVarying(m_program_id_with_output, transform_feedback_varyings, sizeof(tmp_buffer), NULL,
								   &tmp_size, &tmp_type, tmp_buffer);

	if (GL_INVALID_VALUE != gl.getError())
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_VALUE was not generated by GetTransformFeedbackVarying when "
											   "<index> was greater than or equal to TRANSFORM_FEEDBACK_VARYINGS."
											<< tcu::TestLog::EndMessage;
		return false;
	}

	/*  INVALID_VALUE is generated by GetIntegerIndexdv when <index> exceeds the
	 limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> is one of the
	 following:
	 * TRANSFORM_FEEDBACK_BUFFER_BINDING,
	 * TRANSFORM_FEEDBACK_BUFFER_START,
	 * TRANSFORM_FEEDBACK_BUFFER_SIZE; */

	if (DE_NULL != m_glGetIntegerIndexedvEXT)
	{
		glw::GLint tmp_int_value;

		m_glGetIntegerIndexedvEXT(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, more_than_max_separate_attribs, &tmp_int_value);

		if (GL_INVALID_VALUE != gl.getError())
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "INVALID_VALUE was not generated by GetIntegerIndexdv when <index> exceeds the "
				   "limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> was "
				   "TRANSFORM_FEEDBACK_BUFFER_BINDING."
				<< tcu::TestLog::EndMessage;
			return false;
		}

		m_glGetIntegerIndexedvEXT(GL_TRANSFORM_FEEDBACK_BUFFER_START, more_than_max_separate_attribs, &tmp_int_value);

		if (GL_INVALID_VALUE != gl.getError())
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "INVALID_VALUE was not generated by GetIntegerIndexdv when <index> exceeds the "
				   "limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> was "
				   "GL_TRANSFORM_FEEDBACK_BUFFER_START."
				<< tcu::TestLog::EndMessage;
			return false;
		}

		m_glGetIntegerIndexedvEXT(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, more_than_max_separate_attribs, &tmp_int_value);

		if (GL_INVALID_VALUE != gl.getError())
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "INVALID_VALUE was not generated by GetIntegerIndexdv when <index> exceeds the "
				   "limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> was "
				   "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE."
				<< tcu::TestLog::EndMessage;
			return false;
		}
	}

	/*  INVALID_VALUE is generated by GetBooleanIndexedv when <index> exceeds the
	 limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> is
	 TRANSFORM_FEEDBACK_BUFFER_BINDING. */

	if (DE_NULL != m_glGetBooleanIndexedvEXT)
	{
		glw::GLboolean tmp_bool_value;

		m_glGetBooleanIndexedvEXT(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, more_than_max_separate_attribs,
								  &tmp_bool_value);

		if (GL_INVALID_VALUE != gl.getError())
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "INVALID_VALUE was not generated by GetBooleanIndexedv when <index> exceeds the "
				   "limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> was "
				   "TRANSFORM_FEEDBACK_BUFFER_BINDING."
				<< tcu::TestLog::EndMessage;
			return false;
		}
	}

	return true;
}

bool gl3cts::TransformFeedback::APIErrors::testExtension2(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/*  Bind Transform Feedback Object */
	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_transform_feedback_object_0);

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

	/*  INVALID_OPERATION is generated by PauseTransformFeedback if current
	 transform feedback is not active or paused; */

	gl.pauseTransformFeedback();

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_OPERATION is not generated by PauseTransformFeedback if "
											   "current transform feedback is not active or paused."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	/*  INVALID_OPERATION is generated by ResumeTransformFeedback if current
	 transform feedback is not active; */

	gl.resumeTransformFeedback();

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_OPERATION is not generated by ResumeTransformFeedback if "
											   "current transform feedback is not active."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	/*  Prepare program and buffer. */
	gl.useProgram(m_program_id_with_output);

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

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);

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

	/*  INVALID_OPERATION is generated by DrawTransformFeedback when
	 EndTransformFeedback was never called for the object named <id>. */
	gl.drawTransformFeedback(GL_POINTS, m_transform_feedback_object_0);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_OPERATION is not generated by DrawTransformFeedback when "
											   "EndTransformFeedback was never called for the object named <id>."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	/*  Make Transform Feedback Active */
	gl.beginTransformFeedback(GL_POINTS);

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

	/*  INVALID_OPERATION is generated by BindTransformFeedback if current
	 transform feedback is active and not paused; */

	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_transform_feedback_object_0);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		gl.endTransformFeedback();

		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_OPERATION is not generated by BindTransformFeedback if current "
											   "transform feedback is active and not paused."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	/*  INVALID_OPERATION is generated by DeleteTransformFeedbacks if any of <ids>
	 is active; */

	gl.deleteTransformFeedbacks(1, &m_transform_feedback_object_0);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		gl.endTransformFeedback();

		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "INVALID_OPERATION is not generated by DeleteTransformFeedbacks if any of <ids> is active."
			<< tcu::TestLog::EndMessage;

		return false;
	}

	/*  INVALID_OPERATION is generated by ResumeTransformFeedback if current
	 transform feedback is not not paused; */

	gl.resumeTransformFeedback();

	if (GL_INVALID_OPERATION != gl.getError())
	{
		gl.endTransformFeedback();

		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_OPERATION is not generated by ResumeTransformFeedback if "
											   "current transform feedback is not not paused."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	/*  pause transform feedback */

	gl.pauseTransformFeedback();

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

	/*  No error is generated by draw command when transform feedback is paused
	 and primitive modes do not match; */

	gl.drawArrays(GL_LINES, 0, 2);

	if (GL_NO_ERROR != gl.getError())
	{
		gl.endTransformFeedback();

		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "No error is not generated by draw command when transform feedback is "
											   "paused and primitive modes do not match."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	/*  INVALID_OPERATION is generated by LinkProgram when <program> is used by
	 some transform feedback object that is currently not active; */

	gl.linkProgram(m_program_id_with_output);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_OPERATION was not generated by LinkProgram when <program> was "
											   "used by some transform feedback object that is currently not active."
											<< tcu::TestLog::EndMessage;

		gl.endTransformFeedback();

		return false;
	}

	/*  No error is generated by UseProgram when transform feedback is paused; */

	gl.useProgram(0);

	if (GL_NO_ERROR != gl.getError())
	{
		gl.endTransformFeedback();

		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glUseProgram unexpectedly failed when transform feedback is paused."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	gl.useProgram(m_program_id_with_output);

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

	/*  End Transform Feedback and make draw. */

	gl.endTransformFeedback();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");

	/*  INVALID_VALUE is generated by DrawTransformFeedback if <id> is not name of
	 transform feedback object; */

	unsigned short int invalid_name = 1;

	while (gl.isTransformFeedback(invalid_name))
	{
		++invalid_name;

		/* Make sure that this loop ends someday, bad day. */
		if (invalid_name == USHRT_MAX)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "Cannot find unused trnasform feedback object." << tcu::TestLog::EndMessage;
			throw 0;
		}
	}

	gl.drawTransformFeedback(GL_POINTS, (glw::GLuint)invalid_name);

	if (GL_INVALID_VALUE != gl.getError())
	{
		gl.endTransformFeedback();

		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glUseProgram unexpectedly failed when transform feedback is paused."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

bool gl3cts::TransformFeedback::APIErrors::testExtension3(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/*  INVALID_VALUE is generated by BeginQueryIndexed, EndQueryIndexed and
	 GetQueryIndexediv when <target> is TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN and
	 <index> exceeds limits of MAX_VERTEX_STREAMS

	 INVALID_VALUE is generated by BeginQueryIndexed, EndQueryIndexed and
	 GetQueryIndexediv when <target> is PRIMITIVES_GENERATED and <index> exceeds
	 limits of MAX_VERTEX_STREAMS */

	glw::GLint max_vertex_streams = 0;

	gl.getIntegerv(GL_MAX_VERTEX_STREAMS, &max_vertex_streams);

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

	if (max_vertex_streams == 0)
	{
		/* Nothing returned. */
		throw 0;
	}

	++max_vertex_streams;

	static const glw::GLenum  target[]	 = { GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_PRIMITIVES_GENERATED };
	static const glw::GLchar* target_str[] = { STR(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN),
											   STR(GL_PRIMITIVES_GENERATED) };
	static const glw::GLuint target_count = sizeof(target) / sizeof(target[0]);

	for (glw::GLuint i = 0; i < target_count; ++i)
	{
		gl.beginQueryIndexed(target[i], max_vertex_streams, m_query_object);

		if (GL_INVALID_VALUE != gl.getError())
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "INVALID_VALUE was not generated by BeginQueryIndexed, EndQueryIndexed and"
											"GetQueryIndexediv when <target> was "
				<< target_str[i] << " and "
									"<index> exceeded limits of MAX_VERTEX_STREAMS."
				<< tcu::TestLog::EndMessage;
			return false;
		}

		gl.endQueryIndexed(target[i], max_vertex_streams);

		if (GL_INVALID_VALUE != gl.getError())
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message
												<< "INVALID_VALUE was not generated by EndQueryIndexed "
												   "when <target> was "
												<< target_str[i] << " and "
																	"<index> exceeded limits of MAX_VERTEX_STREAMS."
												<< tcu::TestLog::EndMessage;
			return false;
		}

		glw::GLint param = 0;

		gl.getQueryIndexediv(target[i], max_vertex_streams, GL_QUERY_COUNTER_BITS, &param);

		if (GL_INVALID_VALUE != gl.getError())
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "INVALID_VALUE was not generated by "
																			"GetQueryIndexediv when <target> was "
												<< target_str[i] << " and "
																	"<index> exceeded limits of MAX_VERTEX_STREAMS."
												<< tcu::TestLog::EndMessage;
			return false;
		}
	}

	/*  INVALID_OPERATION is generated by EndQueryIndexed when name of active
	 query at <index> of <target> is zero */

	gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, 0);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by EndQueryIndexed when name of active "
										"query at <index> of <target> is zero"
			<< tcu::TestLog::EndMessage;
		return false;
	}

	/*  INVALID_VALUE is generated by DrawTransformFeedbackStream when <stream>
	 exceeds limits of MAX_VERTEX_STREAMS */

	gl.drawTransformFeedbackStream(GL_POINTS, m_transform_feedback_object_0, max_vertex_streams);

	if (GL_INVALID_VALUE != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "INVALID_VALUE was not generated by DrawTransformFeedbackStream when <stream> "
										"exceeded limits of MAX_VERTEX_STREAMS"
			<< tcu::TestLog::EndMessage;
		return false;
	}

	/*  INVALID_OPERATION is generated by TransformFeedbackVaryings when
	 <varyings> contains any of the special names while <bufferMode> is not
	 INTERLEAVED_ATTRIBS */

	static const glw::GLchar* tf_varying_names[] = { "gl_NextBuffer", "gl_SkipComponents1", "gl_SkipComponents2",
													 "gl_SkipComponents3", "gl_SkipComponents4" };
	static const glw::GLuint tf_varying_names_count = sizeof(tf_varying_names) / sizeof(tf_varying_names[0]);

	for (glw::GLuint i = 0; i < tf_varying_names_count; ++i)
	{
		gl.transformFeedbackVaryings(m_program_id_with_output, 1, &tf_varying_names[i], GL_SEPARATE_ATTRIBS);

		if (GL_INVALID_OPERATION != gl.getError())
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by TransformFeedbackVaryings when "
											"<varyings> contained any of the special names while <bufferMode> was "
											"GL_SEPARATE_ATTRIBS."
				<< tcu::TestLog::EndMessage;
			return false;
		}
	}

	/*  INVALID_OPERATION is generated by TransformFeedbackVaryings when
	 <varyings> contains more "gl_NextBuffer" entries than allowed limit of
	 MAX_TRANSFORM_FEEDBACK_BUFFERS */

	glw::GLint max_transform_feedback_buffers = 0;

	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);

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

	if (max_transform_feedback_buffers == 0)
	{
		/* Nothing returned. */
		throw 0;
	}

	glw::GLint more_than_max_transform_feedback_buffers = max_transform_feedback_buffers + 1;

	const glw::GLchar** tf_next_buffer_varying_names = new const glw::GLchar*[more_than_max_transform_feedback_buffers];

	if (DE_NULL == tf_next_buffer_varying_names)
	{
		/* Allocation error. */
		throw 0;
	}

	for (glw::GLint i = 0; i < more_than_max_transform_feedback_buffers; ++i)
	{
		tf_next_buffer_varying_names[i] = tf_varying_names[0];
	}

	gl.transformFeedbackVaryings(m_program_id_with_output, more_than_max_transform_feedback_buffers,
								 tf_next_buffer_varying_names, GL_INTERLEAVED_ATTRIBS);

	delete[] tf_next_buffer_varying_names;

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by TransformFeedbackVaryings when "
										"<varyings> contained more \"gl_NextBuffer\" entries than allowed limit of "
										"MAX_TRANSFORM_FEEDBACK_BUFFER."
			<< tcu::TestLog::EndMessage;
		return false;
	}

	return true;
}

bool gl3cts::TransformFeedback::APIErrors::testInstanced(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/*  INVALID_ENUM is generated by DrawTransformFeedbackInstanced and
	 DrawTransformFeedbackStreamInstanced if <mode> is invalid */

	glw::GLenum _supported_mode[] = { GL_POINTS,
									  GL_LINE_STRIP,
									  GL_LINE_LOOP,
									  GL_LINES,
									  GL_LINE_STRIP_ADJACENCY,
									  GL_LINES_ADJACENCY,
									  GL_TRIANGLE_STRIP,
									  GL_TRIANGLE_FAN,
									  GL_TRIANGLES,
									  GL_TRIANGLE_STRIP_ADJACENCY,
									  GL_TRIANGLES_ADJACENCY,
									  GL_PATCHES };

	std::set<glw::GLenum> supported_mode(_supported_mode,
										 _supported_mode + sizeof(_supported_mode) / sizeof(_supported_mode[0]));

	int mode = 0;

	while (supported_mode.find(mode) != supported_mode.end())
	{
		mode++;
	}

	gl.drawTransformFeedbackInstanced(mode, m_transform_feedback_object_0, 1);

	if (GL_INVALID_ENUM != gl.getError())
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_ENUM was not generated by DrawTransformFeedbackInstanced and "
											   "DrawTransformFeedbackStreamInstanced when <mode> was invalid."
											<< tcu::TestLog::EndMessage;
		return false;
	}

	gl.drawTransformFeedbackStreamInstanced(mode, m_transform_feedback_object_0, 0, 1);

	if (GL_INVALID_ENUM != gl.getError())
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "INVALID_ENUM was not generated by DrawTransformFeedbackInstanced and "
											   "DrawTransformFeedbackStreamInstanced when <mode> was invalid."
											<< tcu::TestLog::EndMessage;
		return false;
	}

	/*  INVALID_OPERATION is generated by DrawTransformFeedbackInstanced and
	 DrawTransformFeedbackStreamInstanced if <mode> does not match geometry
	 shader */

	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_transform_feedback_object_0);

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

	gl.useProgram(m_program_id_with_geometry_shader);

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

	gl.bindVertexArray(m_vertex_array_object);

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

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);

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

	gl.beginTransformFeedback(GL_POINTS);

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

	gl.drawArrays(GL_POINTS, 0, 1);

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

	gl.endTransformFeedback();

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

	gl.drawTransformFeedbackInstanced(GL_LINES, m_transform_feedback_object_0, 1);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by DrawTransformFeedbackInstanced and "
										"DrawTransformFeedbackStreamInstanced if <mode> did not match geometry shader."
			<< tcu::TestLog::EndMessage;
		return false;
	}

	gl.drawTransformFeedbackStreamInstanced(GL_LINES, m_transform_feedback_object_0, 0, 1);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by DrawTransformFeedbackInstanced and "
										"DrawTransformFeedbackStreamInstanced if <mode> did not match geometry shader."
			<< tcu::TestLog::EndMessage;
		return false;
	}

	/*  INVALID_OPERATION is generated by DrawTransformFeedbackInstanced and
	 DrawTransformFeedbackStreamInstanced if <mode> does not match tessellation */

	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_transform_feedback_object_0);

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

	gl.useProgram(m_program_id_with_tessellation_shaders);

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

	gl.bindVertexArray(m_vertex_array_object);

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

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);

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

	gl.beginTransformFeedback(GL_LINES);

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

	gl.drawArrays(GL_PATCHES, 0, 2);

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

	gl.endTransformFeedback();

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

	gl.drawTransformFeedbackInstanced(GL_POINTS, m_transform_feedback_object_0, 1);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by DrawTransformFeedbackInstanced and "
										"DrawTransformFeedbackStreamInstanced if <mode> did not match geometry shader."
			<< tcu::TestLog::EndMessage;
		return false;
	}

	gl.drawTransformFeedbackStreamInstanced(GL_POINTS, m_transform_feedback_object_0, 0, 1);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by DrawTransformFeedbackInstanced and "
										"DrawTransformFeedbackStreamInstanced if <mode> did not match geometry shader."
			<< tcu::TestLog::EndMessage;
		return false;
	}

	/*  INVALID_VALUE is generated by DrawTransformFeedbackStreamInstanced if
	 <stream> is greater than or equal to MAX_VERTEX_STREAMS */

	glw::GLint max_vertex_streams = 0;

	gl.getIntegerv(GL_MAX_VERTEX_STREAMS, &max_vertex_streams);

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

	if (max_vertex_streams == 0)
	{
		/* Failed to query GL_MAX_VERTEX_STREAMS. */
		throw 0;
	}

	glw::GLint more_than_max_vertex_streams = max_vertex_streams + 1;

	gl.drawTransformFeedbackStreamInstanced(GL_PATCHES, m_transform_feedback_object_0, more_than_max_vertex_streams, 1);

	if (GL_INVALID_VALUE != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by DrawTransformFeedbackInstanced and "
										"DrawTransformFeedbackStreamInstanced if <mode> did not match geometry shader."
			<< tcu::TestLog::EndMessage;
		return false;
	}

	/*  INVALID_VALUE is generated by DrawTransformFeedbackInstanced and
	 DrawTransformFeedbackStreamInstanced if <id> is not name of transform
	 feedback object */

	unsigned short int invalid_name = 1;

	while (gl.isTransformFeedback(invalid_name))
	{
		++invalid_name;

		/* Make sure that this loop ends someday, bad day. */
		if (invalid_name == USHRT_MAX)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "Cannot find unused trnasform feedback object." << tcu::TestLog::EndMessage;
			throw 0;
		}
	}

	gl.drawTransformFeedbackInstanced(GL_PATCHES, (glw::GLuint)invalid_name, 1);

	if (GL_INVALID_VALUE != gl.getError())
	{
		gl.endTransformFeedback();

		return false;
	}

	gl.drawTransformFeedbackStreamInstanced(GL_PATCHES, (glw::GLuint)invalid_name, 0, 1);

	if (GL_INVALID_VALUE != gl.getError())
	{
		gl.endTransformFeedback();

		return false;
	}

	/*  INVALID_OPERATION is generated if by DrawTransformFeedbackStreamInstanced
	 if EndTransformFeedback was never called for the object named <id>.
	 return true */

	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_transform_feedback_object_1);

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

	gl.drawTransformFeedbackStreamInstanced(GL_PATCHES, m_transform_feedback_object_1, 0, 1);

	if (GL_INVALID_OPERATION != gl.getError())
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by DrawTransformFeedbackInstanced and "
										"DrawTransformFeedbackStreamInstanced if <mode> did not match geometry shader."
			<< tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

const glw::GLchar* gl3cts::TransformFeedback::APIErrors::m_tessellation_control_shader =
	"#version 400\n"
	"\n"
	"layout (vertices = 2 ) out;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    gl_TessLevelOuter[1]                = 3.0;\n"
	"    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::APIErrors::m_tessellation_evaluation_shader =
	"#version 400\n"
	"\n"
	"layout(isolines, equal_spacing, ccw) in;\n"
	"\n"
	"out float result;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    result      = 0.5;\n"
	"    gl_Position = gl_in[0].gl_Position + gl_in[1].gl_Position + gl_in[2].gl_Position;\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::APIErrors::m_geometry_shader =
	"#version 150\n"
	"\n"
	"layout(points) in;\n"
	"layout(points, max_vertices = 2) out;\n"
	"\n"
	"out float result;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.0, 0.0, 0.0);\n"
	"    result = 0.0;\n"
	"    EmitVertex();\n"
	"\n"
	"    gl_Position = gl_in[0].gl_Position + vec4(1.0, 0.0, 0.0, 0.0);\n"
	"    result = 1.0;\n"
	"    EmitVertex();\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::APIErrors::s_vertex_shader_with_output =
	"#version 130\n"
	"\n"
	"out float result;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    result      = float(gl_VertexID);\n"
	"    gl_Position = vec4(1.0);\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::APIErrors::s_vertex_shader_with_input_output =
	"#version 130\n"
	"\n"
	"in float v_input;\n"
	"\n"
	"out float result;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    result      = float(gl_VertexID);\n"
	"    gl_Position = vec4(v_input);\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::APIErrors::s_vertex_shader_without_output =
	"#version 130\n"
	"\n"
	"void main()\n"
	"{\n"
	"    gl_Position = vec4(1.0);\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::APIErrors::s_fragment_shader = "#version 130\n"
																			 "\n"
																			 "out vec4 color;\n"
																			 "\n"
																			 "void main()\n"
																			 "{\n"
																			 "    color = vec4(1.0);\n"
																			 "}\n";

const glw::GLchar* gl3cts::TransformFeedback::APIErrors::m_varying_name = "result";

const glw::GLfloat gl3cts::TransformFeedback::APIErrors::m_buffer_1_data[] = { 3.14159265359f, 2.7182818f };

const glw::GLsizei gl3cts::TransformFeedback::APIErrors::m_buffer_1_size =
	sizeof(gl3cts::TransformFeedback::APIErrors::m_buffer_1_data);

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::LinkingErrors::LinkingErrors(deqp::Context& context)
	: deqp::TestCase(context, "linking_errors_test", "Transform Feedback Linking Errors Test"), m_context(context)
{
	/* Left intentionally blank. */
}

gl3cts::TransformFeedback::LinkingErrors::~LinkingErrors(void)
{
}

tcu::TestNode::IterateResult gl3cts::TransformFeedback::LinkingErrors::iterate(void)
{
	bool is_ok		= true;
	bool test_error = false;

	try
	{
		is_ok = is_ok && testNoVertexNoGeometry();
		is_ok = is_ok && testInvalidVarying();
		is_ok = is_ok && testRepeatedVarying();
		is_ok = is_ok && testTooManyVaryings();
	}
	catch (...)
	{
		is_ok	  = false;
		test_error = true;
	}

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

	return STOP;
}

bool gl3cts::TransformFeedback::LinkingErrors::testNoVertexNoGeometry(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/*  Check if link process fails under the following conditions:
	 <count> specified by TransformFeedbackVaryings is non-zero and program has
	 neither vertex nor geometry shader; */

	glw::GLint linking_status = 1;

	glw::GLuint program = gl3cts::TransformFeedback::Utilities::buildProgram(
		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, NULL, s_fragment_shader,
		&s_valid_transform_feedback_varying, 1, GL_INTERLEAVED_ATTRIBS, false, &linking_status);

	if ((GL_FALSE != linking_status) || program)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Linking unexpectedly succeded when Transform Feedback varying was "
											   "specified but program had neither vertex nor geometry shader stages."
											<< tcu::TestLog::EndMessage;

		if (program)
		{
			gl.deleteProgram(program);
		}

		return false;
	}

	/* Log success. */
	m_context.getTestContext().getLog() << tcu::TestLog::Message
										<< "Linking failed as expected when Transform Feedback varying was specified "
										   "but program had neither vertex nor geometry shader stages."
										<< tcu::TestLog::EndMessage;

	return true;
}

bool gl3cts::TransformFeedback::LinkingErrors::testInvalidVarying(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/*  Check if link process fails under the following conditions:
	 <varyings> specified by TransformFeedbackVaryings contains name of
	 variable that is not available for capture; */

	std::string vertex_shader(s_vertex_shader_template);

	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
		vertex_shader, "TEMPLATE_INPUT_OUTPUT_DECLARATIONS", "in float data;\n");
	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(vertex_shader, "TEMPLATE_OUTPUT_SETTERS", "");

	glw::GLint linking_status = 1;

	glw::GLuint program = gl3cts::TransformFeedback::Utilities::buildProgram(
		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, vertex_shader.c_str(), s_fragment_shader,
		&s_invalid_transform_feedback_varying, 1, GL_INTERLEAVED_ATTRIBS, false, &linking_status);

	if ((GL_FALSE != linking_status) || program)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "Linking unexpectedly succeded when Transform Feedback varying was specified with name of variable ("
			<< s_invalid_transform_feedback_varying << ") that is not available for capture."
			<< tcu::TestLog::EndMessage;

		if (program)
		{
			gl.deleteProgram(program);
		}

		return false;
	}

	/* Log success. */
	m_context.getTestContext().getLog()
		<< tcu::TestLog::Message
		<< "Linking failed as expected when Transform Feedback varying was specified with name of variable ("
		<< s_invalid_transform_feedback_varying << ") that is not available for capture." << tcu::TestLog::EndMessage;

	return true;
}

bool gl3cts::TransformFeedback::LinkingErrors::testRepeatedVarying(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/*  Check if link process fails under the following conditions:
	 <varyings> specified by TransformFeedbackVaryings contains name of
	 variable more than once; */

	std::string vertex_shader(s_vertex_shader_template);

	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
		vertex_shader, "TEMPLATE_INPUT_OUTPUT_DECLARATIONS", "out float result;\n");
	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(vertex_shader, "TEMPLATE_OUTPUT_SETTERS",
																		 "    result = 0.577215664901532;\n");

	glw::GLint linking_status = 1;

	glw::GLuint program = gl3cts::TransformFeedback::Utilities::buildProgram(
		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, vertex_shader.c_str(), s_fragment_shader,
		s_repeated_transform_feedback_varying, s_repeated_transform_feedback_varying_count, GL_INTERLEAVED_ATTRIBS,
		false, &linking_status);

	if ((GL_FALSE != linking_status) || program)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "Linking unexpectedly succeded when Transform Feedback varying was specified twice."
			<< tcu::TestLog::EndMessage;

		if (program)
		{
			gl.deleteProgram(program);
		}

		return false;
	}

	/* Log success. */
	m_context.getTestContext().getLog()
		<< tcu::TestLog::Message << "Linking failed as expected when Transform Feedback varying was specified twice."
		<< tcu::TestLog::EndMessage;

	return true;
}

bool gl3cts::TransformFeedback::LinkingErrors::testTooManyVaryings(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/*  Check if link process fails under the following conditions:
	 number of components specified to capture exceeds limits
	 MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS or
	 MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. */

	/* Fetching limits. */
	glw::GLint max_transform_feedback_separate_components	= 0;
	glw::GLint max_transform_feedback_interleaved_components = 0;

	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_transform_feedback_separate_components);

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

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

	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);

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

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

	glw::GLint more_than_max_transform_feedback_components =
		deMax32(max_transform_feedback_separate_components, max_transform_feedback_interleaved_components) + 1;

	/* Preparing source code. */
	std::string						vertex_shader(s_vertex_shader_template);
	std::string						transform_feedback_variable_declarations("");
	std::string						transform_feedback_variable_setters("");
	std::vector<std::string>		transform_feedback_varyings(more_than_max_transform_feedback_components);
	std::vector<const glw::GLchar*> transform_feedback_varyings_c(more_than_max_transform_feedback_components);

	for (glw::GLint i = 0; i < more_than_max_transform_feedback_components; ++i)
	{
		std::string varying = "result_";
		varying.append(gl3cts::TransformFeedback::Utilities::itoa(i));

		transform_feedback_varyings[i] = varying;

		transform_feedback_varyings_c[i] = transform_feedback_varyings[i].c_str();

		transform_feedback_variable_declarations.append("out float ");
		transform_feedback_variable_declarations.append(varying);
		transform_feedback_variable_declarations.append(";\n");

		transform_feedback_variable_setters.append("    ");
		transform_feedback_variable_setters.append(varying);
		transform_feedback_variable_setters.append(" = ");
		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * i));
		transform_feedback_variable_setters.append(".0;\n");
	}

	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
		vertex_shader, "TEMPLATE_INPUT_OUTPUT_DECLARATIONS", transform_feedback_variable_declarations);
	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(vertex_shader, "TEMPLATE_OUTPUT_SETTERS",
																		 transform_feedback_variable_setters);

	glw::GLuint program = gl3cts::TransformFeedback::Utilities::buildProgram(
		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, vertex_shader.c_str(), s_fragment_shader,
		&transform_feedback_varyings_c[0], more_than_max_transform_feedback_components, GL_INTERLEAVED_ATTRIBS);

	/* Note: we check for program as not only linking shall fail, but also glTransformFeedbackVaryings shall return an error. */

	if (program)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Linking unexpectedly succeded when too many Transform Feedback varying "
											   "were specified in INTERLEAVED mode."
											<< tcu::TestLog::EndMessage;

		if (program)
		{
			gl.deleteProgram(program);
		}

		return false;
	}

	program = gl3cts::TransformFeedback::Utilities::buildProgram(
		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, vertex_shader.c_str(), s_fragment_shader,
		&transform_feedback_varyings_c[0], more_than_max_transform_feedback_components, GL_SEPARATE_ATTRIBS);

	if (program)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Linking unexpectedly succeded when too many Transform Feedback "
											   "varyings were specified in SEPARATE mode."
											<< tcu::TestLog::EndMessage;

		if (program)
		{
			gl.deleteProgram(program);
		}

		return false;
	}

	/* Log success. */
	m_context.getTestContext().getLog()
		<< tcu::TestLog::Message
		<< "Linking failed as expected when too many Transform Feedback varyings were specified."
		<< tcu::TestLog::EndMessage;

	return true;
}

const glw::GLchar* gl3cts::TransformFeedback::LinkingErrors::s_fragment_shader = "#version 130\n"
																				 "\n"
																				 "out vec4 color;\n"
																				 "\n"
																				 "void main()\n"
																				 "{\n"
																				 "    color = vec4(1.0);\n"
																				 "}\n";

const glw::GLchar* gl3cts::TransformFeedback::LinkingErrors::s_vertex_shader_template =
	"#version 130\n"
	"\n"
	"TEMPLATE_INPUT_OUTPUT_DECLARATIONS"
	"\n"
	"void main()\n"
	"{\n"
	"TEMPLATE_OUTPUT_SETTERS"
	"\n"
	"    gl_Position = vec4(1.618033988749);\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::LinkingErrors::s_valid_transform_feedback_varying = "result";

const glw::GLchar* gl3cts::TransformFeedback::LinkingErrors::s_invalid_transform_feedback_varying = "data";

const glw::GLchar* gl3cts::TransformFeedback::LinkingErrors::s_repeated_transform_feedback_varying[] = { "result",
																										 "result" };

const glw::GLsizei gl3cts::TransformFeedback::LinkingErrors::s_repeated_transform_feedback_varying_count =
	sizeof(s_repeated_transform_feedback_varying) / sizeof(s_repeated_transform_feedback_varying[0]);

/*-----------------------------------------------------------------------------------------------*/

const glw::GLint gl3cts::TransformFeedback::Limits::s_min_value_of_max_transform_feedback_interleaved_components = 64;
const glw::GLint gl3cts::TransformFeedback::Limits::s_min_value_of_max_transform_feedback_separate_attribs		 = 4;
const glw::GLint gl3cts::TransformFeedback::Limits::s_min_value_of_max_transform_feedback_separate_components	= 4;
const glw::GLint gl3cts::TransformFeedback::Limits::s_min_value_of_max_transform_feedback_buffers				 = 4;
const glw::GLint gl3cts::TransformFeedback::Limits::s_min_value_of_max_vertex_streams							 = 1;

gl3cts::TransformFeedback::Limits::Limits(deqp::Context& context)
	: deqp::TestCase(context, "limits_test", "Transform Feedback Limits Test"), m_context(context)
{
}

gl3cts::TransformFeedback::Limits::~Limits(void)
{
}

tcu::TestNode::IterateResult gl3cts::TransformFeedback::Limits::iterate(void)
{
	/* Initializations. */
	bool is_at_least_gl_30 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)));
	bool is_at_least_gl_40 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));

	bool is_ext_tf_1 = m_context.getContextInfo().isExtensionSupported("GL_EXT_transform_feedback");
	bool is_arb_tf_3 = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback3");

	bool is_ok		= true;
	bool test_error = false;

	/* Tests. */
	try
	{
		if (is_at_least_gl_30 || is_ext_tf_1)
		{
			is_ok = is_ok && test_max_transform_feedback_interleaved_components();
			is_ok = is_ok && test_max_transform_feedback_separate_attribs();
			is_ok = is_ok && test_max_transform_feedback_separate_components();
		}

		if (is_at_least_gl_40 || is_arb_tf_3)
		{
			is_ok = is_ok && test_max_transform_feedback_buffers();
			is_ok = is_ok && test_max_vertex_streams();
		}
	}
	catch (...)
	{
		is_ok	  = false;
		test_error = true;
	}

	/* Result's setup. */
	if (is_ok)
	{
		/* Log success. */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Limits are in range of specification."
											<< tcu::TestLog::EndMessage;

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

	return STOP;
}

bool gl3cts::TransformFeedback::Limits::test_max_transform_feedback_interleaved_components(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check that MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS is at least 64. */
	glw::GLint max_transform_feedback_interleaved_components = 0;

	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);

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

	if (max_transform_feedback_interleaved_components < s_min_value_of_max_transform_feedback_interleaved_components)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS is equal to "
			<< max_transform_feedback_interleaved_components << " which is less than expected "
			<< s_min_value_of_max_transform_feedback_interleaved_components << "." << tcu::TestLog::EndMessage;
		return false;
	}

	return true;
}

bool gl3cts::TransformFeedback::Limits::test_max_transform_feedback_separate_attribs(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check that MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS is at least 4. */
	glw::GLint max_transform_feedback_separate_attribs = 0;

	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &max_transform_feedback_separate_attribs);

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

	if (max_transform_feedback_separate_attribs < s_min_value_of_max_transform_feedback_separate_attribs)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS is equal to "
			<< max_transform_feedback_separate_attribs << " which is less than expected "
			<< s_min_value_of_max_transform_feedback_separate_attribs << "." << tcu::TestLog::EndMessage;
		return false;
	}

	return true;
}

bool gl3cts::TransformFeedback::Limits::test_max_transform_feedback_separate_components(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check that MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS is at least 4. */
	glw::GLint max_transform_feedback_separate_components = 0;

	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_transform_feedback_separate_components);

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

	if (max_transform_feedback_separate_components < s_min_value_of_max_transform_feedback_separate_components)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS is equal to "
			<< max_transform_feedback_separate_components << " which is less than expected "
			<< s_min_value_of_max_transform_feedback_separate_components << "." << tcu::TestLog::EndMessage;
		return false;
	}

	return true;
}

bool gl3cts::TransformFeedback::Limits::test_max_transform_feedback_buffers(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check that MAX_TRANSFORM_FEEDBACK_BUFFERS is at least 4. */
	glw::GLint max_transform_feedback_buffers = 0;

	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);

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

	if (max_transform_feedback_buffers < s_min_value_of_max_transform_feedback_buffers)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "MAX_TRANSFORM_FEEDBACK_BUFFERS is equal to "
											<< max_transform_feedback_buffers << " which is less than expected "
											<< s_min_value_of_max_transform_feedback_buffers << "."
											<< tcu::TestLog::EndMessage;
		return false;
	}

	return true;
}

bool gl3cts::TransformFeedback::Limits::test_max_vertex_streams(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check that MAX_VERTEX_STREAMS is at least 1. */
	glw::GLint max_vertex_streams = 0;

	gl.getIntegerv(GL_MAX_VERTEX_STREAMS, &max_vertex_streams);

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

	if (max_vertex_streams < s_min_value_of_max_vertex_streams)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "MAX_VERTEX_STREAMS is equal to "
											<< max_vertex_streams << " which is less than expected "
											<< s_min_value_of_max_vertex_streams << "." << tcu::TestLog::EndMessage;
		return false;
	}

	return true;
}

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::CaptureVertexInterleaved::CaptureVertexInterleaved(deqp::Context& context,
																			  const char*	test_name,
																			  const char*	test_description)
	: deqp::TestCase(context, test_name, test_description)
	, m_context(context)
	, m_program(0)
	, m_framebuffer(0)
	, m_renderbuffer(0)
	, m_buffer(0)
	, m_buffer_size(0)
	, m_vertex_array_object(0)
	, m_max_transform_feedback_components(0)
	, m_attrib_type(GL_INTERLEAVED_ATTRIBS)
	, m_max_vertices_drawn(8)
	, m_glBindBufferOffsetEXT(DE_NULL)
{
}

gl3cts::TransformFeedback::CaptureVertexInterleaved::~CaptureVertexInterleaved(void)
{
}

tcu::TestNode::IterateResult gl3cts::TransformFeedback::CaptureVertexInterleaved::iterate(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Initializations. */
	bool is_at_least_gl_30 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)));
	bool is_ext_tf_1	   = m_context.getContextInfo().isExtensionSupported("GL_EXT_transform_feedback");

	bool is_ok		= true;
	bool test_error = false;

	try
	{
		if (is_ext_tf_1)
		{
			/* Extension query. */
			m_glBindBufferOffsetEXT =
				(BindBufferOffsetEXT_ProcAddress)m_context.getRenderContext().getProcAddress("glBindBufferOffsetEXT");

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

		if (is_at_least_gl_30 || is_ext_tf_1)
		{
			fetchLimits();
			buildProgram();
			createFramebuffer();
			createTransformFeedbackBuffer();
			createVertexArrayObject();

			gl.useProgram(m_program);

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

			for (glw::GLint i_bind_case = 0; (i_bind_case < BIND_BUFFER_CASES_COUNT) && is_ok; ++i_bind_case)
			{
				if ((i_bind_case == BIND_BUFFER_OFFSET_CASE) && (DE_NULL == m_glBindBufferOffsetEXT))
				{
					continue;
				}

				bindBuffer((BindBufferCase)i_bind_case);

				for (glw::GLuint i_primitive_case = 0; (i_primitive_case < s_primitive_cases_count) && is_ok;
					 ++i_primitive_case)
				{
					draw(i_primitive_case);

					is_ok = is_ok && checkFramebuffer(s_primitive_cases[i_primitive_case]);
					is_ok = is_ok && checkTransformFeedbackBuffer((BindBufferCase)i_bind_case,
																  s_primitive_cases[i_primitive_case]);
				}
			}
		}
	}
	catch (...)
	{
		is_ok	  = false;
		test_error = true;
	}

	/* Clean objects. */
	clean();

	/* Result's setup. */
	if (is_ok)
	{
		/* Log success. */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Capture Vertex have passed."
											<< tcu::TestLog::EndMessage;

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

	return STOP;
}

void gl3cts::TransformFeedback::CaptureVertexInterleaved::fetchLimits(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Fetching limits. */
	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &m_max_transform_feedback_components);

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

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

	glw::GLint max_varyings_components = 0;

	gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings_components);

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

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

	if (m_max_transform_feedback_components > max_varyings_components)
	{
		m_max_transform_feedback_components = max_varyings_components;
	}
}

void gl3cts::TransformFeedback::CaptureVertexInterleaved::buildProgram(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Preparing source code. */
	std::string vertex_shader(s_vertex_shader_source_code_template); /* Storage for vertex shader source code. */
	std::string transform_feedback_variable_declarations(
		""); /* String to contain all custom outputs from vertex shader. */
	std::string transform_feedback_variable_setters(
		""); /* String containing all initializations of custom outputs from vertex shader. */
	std::vector<std::string> transform_feedback_varyings(m_max_transform_feedback_components); /* Varyings array. */
	std::vector<const glw::GLchar*> transform_feedback_varyings_c(
		m_max_transform_feedback_components); /* Varyings array in C form to pass to the GL. */

	glw::GLint user_defined_transform_feedback_interleaved_varyings_count =
		m_max_transform_feedback_components /* total max to be written by the shader */
			/ 4								/* components per vec4 */
		- 1 /* gl_Position */;

	glw::GLint all_transform_feedback_interleaved_varyings_count =
		user_defined_transform_feedback_interleaved_varyings_count + 1 /* gl_Position */;

	/* Most of varyings is declarated output variables. */
	for (glw::GLint i = 0; i < user_defined_transform_feedback_interleaved_varyings_count; ++i)
	{
		std::string varying = "result_";
		varying.append(gl3cts::TransformFeedback::Utilities::itoa(i));

		transform_feedback_varyings[i] = varying;

		transform_feedback_varyings_c[i] = transform_feedback_varyings[i].c_str();

		transform_feedback_variable_declarations.append("out vec4 ");
		transform_feedback_variable_declarations.append(varying);
		transform_feedback_variable_declarations.append(";\n");

		transform_feedback_variable_setters.append("    ");
		transform_feedback_variable_setters.append(varying);
		transform_feedback_variable_setters.append(" = vec4(");
		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4));
		transform_feedback_variable_setters.append(".0, ");
		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 1));
		transform_feedback_variable_setters.append(".0, ");
		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 2));
		transform_feedback_variable_setters.append(".0, ");
		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 3));
		transform_feedback_variable_setters.append(".0);\n");
	}

	/* Last four varying components are gl_Position components. */
	transform_feedback_varyings[user_defined_transform_feedback_interleaved_varyings_count] = "gl_Position";

	transform_feedback_varyings_c[user_defined_transform_feedback_interleaved_varyings_count] =
		transform_feedback_varyings[user_defined_transform_feedback_interleaved_varyings_count].c_str();

	/* Preprocess vertex shader source code template. */
	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
		vertex_shader, "TEMPLATE_INPUT_OUTPUT_DECLARATIONS", transform_feedback_variable_declarations);
	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(vertex_shader, "TEMPLATE_OUTPUT_SETTERS",
																		 transform_feedback_variable_setters);
	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
		vertex_shader, "TEMPLATE_RASTERIZATION_EPSILON",
		gl3cts::TransformFeedback::Utilities::ftoa(s_rasterization_epsilon));

	/* Compile, link and check. */
	m_program = gl3cts::TransformFeedback::Utilities::buildProgram(
		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, vertex_shader.c_str(), s_fragment_shader_source_code,
		&transform_feedback_varyings_c[0], all_transform_feedback_interleaved_varyings_count, m_attrib_type);

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

void gl3cts::TransformFeedback::CaptureVertexInterleaved::createFramebuffer(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Setting clear color */
	gl.clearColor(0.f, 0.f, 0.f, 1.f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");

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

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

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

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

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32F, s_framebuffer_size, s_framebuffer_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");

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

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

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

void gl3cts::TransformFeedback::CaptureVertexInterleaved::createTransformFeedbackBuffer(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Creating xfb buffer */
	gl.genBuffers(1, &m_buffer);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

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

	m_buffer_size =
		static_cast<glw::GLuint>(m_max_transform_feedback_components * m_max_vertices_drawn * sizeof(glw::GLfloat));

	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer_size, NULL, GL_DYNAMIC_READ);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
}

void gl3cts::TransformFeedback::CaptureVertexInterleaved::createVertexArrayObject(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* VAO Creations */
	gl.genVertexArrays(1, &m_vertex_array_object);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

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

void gl3cts::TransformFeedback::CaptureVertexInterleaved::draw(glw::GLuint primitive_case)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

	gl.beginTransformFeedback(s_primitive_cases_xfb[primitive_case]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedbac call failed.");

	gl.drawElements(s_primitive_cases[primitive_case], s_element_indices_counts[primitive_case], GL_UNSIGNED_INT,
					s_element_indices[primitive_case]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawElements call failed.");

	gl.endTransformFeedback();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedbac call failed.");
}

bool gl3cts::TransformFeedback::CaptureVertexInterleaved::checkFramebuffer(glw::GLenum primitive_type UNUSED)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Fetch framebuffer. */
	std::vector<glw::GLfloat> pixels(s_framebuffer_size * s_framebuffer_size);

	if ((s_framebuffer_size > 0) && (s_framebuffer_size > 0))
	{
		gl.readPixels(0, 0, s_framebuffer_size, s_framebuffer_size, GL_RED, GL_FLOAT, pixels.data());
		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
	}

	/* Check results.
	 Note: assuming that s_buffer_size == 2 -> then all points shall be drawn. */
	for (std::vector<glw::GLfloat>::iterator i = pixels.begin(); i != pixels.end(); ++i)
	{
		if (fabs(*i - 0.5f) > 0.0625f /* precision */)
		{
			return false;
		}
	}

	return true;
}

bool gl3cts::TransformFeedback::CaptureVertexInterleaved::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
																					   glw::GLenum primitive_type)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check */
	glw::GLuint number_of_vertices = 0;

	switch (primitive_type)
	{
	case GL_POINTS:
		number_of_vertices = 4;
		break;
	case GL_LINES:
		number_of_vertices = 4;
		break;
	case GL_LINE_LOOP:
		number_of_vertices = 8;
		break;
	case GL_LINE_STRIP:
		number_of_vertices = 6;
		break;
	case GL_TRIANGLES:
		number_of_vertices = 6;
		break;
	case GL_TRIANGLE_STRIP:
		number_of_vertices = 6;
		break;
	case GL_TRIANGLE_FAN:
		number_of_vertices = 6;
		break;
	default:
		throw 0;
	}

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

	bool is_ok = true;

	for (glw::GLuint j = 0; (j < number_of_vertices) && is_ok; ++j)
	{
		for (glw::GLint i = 0; i < m_max_transform_feedback_components - 4; ++i)
		{
			glw::GLfloat result	= results[i + j * m_max_transform_feedback_components];
			glw::GLfloat reference = (glw::GLfloat)(i);

			if (fabs(result - reference) > 0.125 /* precision */)
			{
				is_ok = false;

				break;
			}
		}

		/* gl_Position */
		glw::GLfloat result[4] = { results[(j + 1) * m_max_transform_feedback_components - 4],
								   results[(j + 1) * m_max_transform_feedback_components - 3],
								   results[(j + 1) * m_max_transform_feedback_components - 2],
								   results[(j + 1) * m_max_transform_feedback_components - 1] };

		if ((fabs(fabs(result[0]) - 1.0 + s_rasterization_epsilon) > 0.125 /* precision */) ||
			(fabs(fabs(result[1]) - 1.0 + s_rasterization_epsilon) > 0.125 /* precision */) ||
			(fabs(result[2]) > 0.125 /* precision */) || (fabs(result[3] - 1.0) > 0.125 /* precision */))
		{
			is_ok = false;

			break;
		}
	}

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

	return is_ok;
}

void gl3cts::TransformFeedback::CaptureVertexInterleaved::bindBuffer(BindBufferCase bind_case)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	switch (bind_case)
	{
	case BIND_BUFFER_BASE_CASE:
		gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer);
		break;
	case BIND_BUFFER_RANGE_CASE:
		gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer, 0, m_buffer_size);
		break;
	case BIND_BUFFER_OFFSET_CASE:
		if (DE_NULL == m_glBindBufferOffsetEXT)
		{
			throw 0;
		}
		m_glBindBufferOffsetEXT(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer, 0);
		break;
	default:
		throw 0;
	}
}

void gl3cts::TransformFeedback::CaptureVertexInterleaved::clean(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_program)
	{
		gl.deleteProgram(m_program);

		m_program = 0;
	}

	if (m_framebuffer)
	{
		gl.deleteFramebuffers(1, &m_framebuffer);

		m_framebuffer = 0;
	}

	if (m_renderbuffer)
	{
		gl.deleteRenderbuffers(1, &m_renderbuffer);

		m_renderbuffer = 0;
	}

	cleanBuffer();

	if (m_vertex_array_object)
	{
		gl.deleteVertexArrays(1, &m_vertex_array_object);

		m_vertex_array_object = 0;
	}
}

void gl3cts::TransformFeedback::CaptureVertexInterleaved::cleanBuffer(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

		m_buffer = 0;
	}
}

const glw::GLchar* gl3cts::TransformFeedback::CaptureVertexInterleaved::s_vertex_shader_source_code_template =
	"#version 130\n"
	"\n"
	"TEMPLATE_INPUT_OUTPUT_DECLARATIONS"
	"\n"
	"void main()\n"
	"{\n"
	"TEMPLATE_OUTPUT_SETTERS"
	"\n"
	"    vec4 position = vec4(0.0);\n"
	"\n"
	"    /* Note: The points are moved 0.0625 from the borders to\n"
	"             reduce non-XFB related rasterization problems. */\n"
	"    switch(gl_VertexID)\n"
	"    {\n"
	"        case 0:\n"
	"            position = vec4(-1.0 + TEMPLATE_RASTERIZATION_EPSILON,  1.0 - TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
	"1.0);\n"
	"            break;\n"
	"        case 1:\n"
	"            position = vec4( 1.0 - TEMPLATE_RASTERIZATION_EPSILON,  1.0 - TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
	"1.0);\n"
	"            break;\n"
	"        case 2:\n"
	"            position = vec4(-1.0 + TEMPLATE_RASTERIZATION_EPSILON, -1.0 + TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
	"1.0);\n"
	"            break;\n"
	"        case 3:\n"
	"            position = vec4( 1.0 - TEMPLATE_RASTERIZATION_EPSILON, -1.0 + TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
	"1.0);\n"
	"            break;\n"
	"    }\n"
	"\n"
	"    gl_Position = position;\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::CaptureVertexInterleaved::s_fragment_shader_source_code =
	"#version 130\n"
	"\n"
	"out vec4 color;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    color = vec4(0.5);\n"
	"}\n";

const glw::GLuint
	gl3cts::TransformFeedback::CaptureVertexInterleaved::s_element_indices[][s_max_element_indices_count] = {
		{ 0, 1, 2, 3 },		  { 0, 1, 2, 3 }, { 0, 1, 3, 2 }, { 0, 1, 3, 2 },
		{ 2, 0, 1, 2, 1, 3 }, { 0, 1, 2, 3 }, { 2, 0, 1, 3 }
	};

const glw::GLuint gl3cts::TransformFeedback::CaptureVertexInterleaved::s_primitive_cases_count =
	sizeof(s_element_indices) / sizeof(s_element_indices[0]);

const glw::GLenum gl3cts::TransformFeedback::CaptureVertexInterleaved::s_primitive_cases[] = {
	GL_POINTS, GL_LINES, GL_LINE_LOOP, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN
};

const glw::GLenum gl3cts::TransformFeedback::CaptureVertexInterleaved::s_primitive_cases_xfb[] = {
	GL_POINTS, GL_LINES, GL_LINES, GL_LINES, GL_TRIANGLES, GL_TRIANGLES, GL_TRIANGLES
};

const glw::GLuint gl3cts::TransformFeedback::CaptureVertexInterleaved::s_element_indices_counts[] = { 4, 4, 4, 4,
																									  6, 4, 4 };

const glw::GLuint gl3cts::TransformFeedback::CaptureVertexInterleaved::s_framebuffer_size =
	2; /* If you change this, update checkFramebuffer function according. */

const glw::GLfloat gl3cts::TransformFeedback::CaptureVertexInterleaved::s_rasterization_epsilon = 0.0625;

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::CaptureGeometryInterleaved::CaptureGeometryInterleaved(deqp::Context& context,
																				  const char*	test_name,
																				  const char*	test_description)
	: CaptureVertexInterleaved(context, test_name, test_description)
{
}

gl3cts::TransformFeedback::CaptureGeometryInterleaved::~CaptureGeometryInterleaved(void)
{
}

tcu::TestNode::IterateResult gl3cts::TransformFeedback::CaptureGeometryInterleaved::iterate(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Initializations. */
	bool is_at_least_gl_30 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)));
	bool is_at_least_gl_32 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 2)));
	bool is_ext_tf_1	   = m_context.getContextInfo().isExtensionSupported("GL_EXT_transform_feedback");
	bool is_arb_gs_4	   = m_context.getContextInfo().isExtensionSupported("GL_ARB_geometry_shader4");

	bool is_ok		= true;
	bool test_error = false;

	/* Tests. */
	try
	{
		if ((is_at_least_gl_30 || is_ext_tf_1) && (is_at_least_gl_32 || is_arb_gs_4))
		{
			fetchLimits();
			createFramebuffer();
			createTransformFeedbackBuffer();
			createVertexArrayObject();

			for (glw::GLuint i_primitive_case = 0;
				 (i_primitive_case < s_geometry_interleaved_primitive_cases_count) && is_ok; ++i_primitive_case)
			{
				buildProgram(i_primitive_case);

				gl.useProgram(m_program);

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

				for (glw::GLint i_bind_case = 0; (i_bind_case < BIND_BUFFER_CASES_COUNT) && is_ok; ++i_bind_case)
				{
					if ((i_bind_case == BIND_BUFFER_OFFSET_CASE) && (DE_NULL == m_glBindBufferOffsetEXT))
					{
						continue;
					}

					bindBuffer((BindBufferCase)i_bind_case);

					draw(i_primitive_case);

					is_ok = is_ok && checkFramebuffer(s_primitive_cases[i_primitive_case]);
					is_ok = is_ok &&
							checkTransformFeedbackBuffer((BindBufferCase)i_bind_case,
														 s_geometry_interleaved_primitive_cases_xfb[i_primitive_case]);
				}

				gl.deleteProgram(m_program);

				m_program = 0;

				GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram call failed.");
			}
		}
	}
	catch (...)
	{
		is_ok	  = false;
		test_error = true;
	}

	/* Clean objects. */
	clean();

	/* Result's setup. */
	if (is_ok)
	{
		/* Log success. */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Capture Geometry have passed."
											<< tcu::TestLog::EndMessage;

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

	return STOP;
}

void gl3cts::TransformFeedback::CaptureGeometryInterleaved::fetchLimits(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Fetching limits. */
	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &m_max_transform_feedback_components);

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

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

	glw::GLint max_geometry_total_components = 0;

	gl.getIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &max_geometry_total_components);

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

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

	if (m_max_transform_feedback_components * 4 > max_geometry_total_components)
	{
		m_max_transform_feedback_components = max_geometry_total_components / 4;
	}
}

void gl3cts::TransformFeedback::CaptureGeometryInterleaved::buildProgram(glw::GLuint primitive_case)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Preparing source code. */
	std::string geometry_shader(s_geometry_shader_source_code_template); /* Storage for vertex shader source code. */
	std::string transform_feedback_variable_declarations(
		""); /* String to contain all custom outputs from vertex shader. */
	std::string transform_feedback_variable_setters(
		""); /* String containing all initializations of custom outputs from vertex shader. */
	std::vector<std::string> transform_feedback_varyings(m_max_transform_feedback_components); /* Varyings array. */
	std::vector<const glw::GLchar*> transform_feedback_varyings_c(
		m_max_transform_feedback_components); /* Varyings array in C form to pass to the GL. */

	glw::GLint user_defined_transform_feedback_interleaved_varyings_count =
		m_max_transform_feedback_components /* total max to be written by the shader */
			/ 4								/* components per vec4 */
		//                                                                          / 4 /* number of vertices */
		- 1 /* gl_Position */;

	glw::GLint all_transform_feedback_interleaved_varyings_count =
		user_defined_transform_feedback_interleaved_varyings_count + 1 /* gl_Position */;

	/* Most of varyings is declarated output variables. */
	for (glw::GLint i = 0; i < user_defined_transform_feedback_interleaved_varyings_count; ++i)
	{
		/* Preparing variable name. */
		std::string varying = "result_";
		varying.append(gl3cts::TransformFeedback::Utilities::itoa(i));

		transform_feedback_varyings[i] = varying;

		transform_feedback_varyings_c[i] = transform_feedback_varyings[i].c_str();

		/* Preparing variable declaration. */
		transform_feedback_variable_declarations.append("out vec4 ");
		transform_feedback_variable_declarations.append(varying);
		transform_feedback_variable_declarations.append(";\n");

		/* Preparing variable setters. */
		transform_feedback_variable_setters.append("    ");
		transform_feedback_variable_setters.append(varying);
		transform_feedback_variable_setters.append(" = vec4(");
		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4));
		transform_feedback_variable_setters.append(".0, ");
		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 1));
		transform_feedback_variable_setters.append(".0, ");
		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 2));
		transform_feedback_variable_setters.append(".0, ");
		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 3));
		transform_feedback_variable_setters.append(".0);\n");
	}

	/* Last four varying components are gl_Position components. */
	transform_feedback_varyings[user_defined_transform_feedback_interleaved_varyings_count /* gl_Position */] =
		"gl_Position";

	transform_feedback_varyings_c[user_defined_transform_feedback_interleaved_varyings_count /* gl_Position */] =
		transform_feedback_varyings[user_defined_transform_feedback_interleaved_varyings_count /* gl_Position */]
			.c_str();

	/* Preprocess vertex shader source code template. */
	geometry_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
		geometry_shader, "TEMPLATE_PRIMITIVE_TYPE", s_geometry_interleaved_primitive_cases[primitive_case]);
	geometry_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
		geometry_shader, "TEMPLATE_INPUT_OUTPUT_DECLARATIONS", transform_feedback_variable_declarations);
	geometry_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(geometry_shader, "TEMPLATE_OUTPUT_SETTERS",
																		   transform_feedback_variable_setters);
	geometry_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
		geometry_shader, "TEMPLATE_RASTERIZATION_EPSILON",
		gl3cts::TransformFeedback::Utilities::ftoa(s_rasterization_epsilon));

	/* Compile, link and check. */
	m_program = gl3cts::TransformFeedback::Utilities::buildProgram(
		gl, m_context.getTestContext().getLog(), geometry_shader.c_str(), NULL, NULL, s_blank_vertex_shader_source_code,
		s_fragment_shader_source_code, &transform_feedback_varyings_c[0],
		all_transform_feedback_interleaved_varyings_count, m_attrib_type);

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

void gl3cts::TransformFeedback::CaptureGeometryInterleaved::draw(glw::GLuint primitive_case)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

	gl.beginTransformFeedback(s_geometry_interleaved_primitive_cases_xfb[primitive_case]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");

	gl.drawArrays(GL_POINTS, 0, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");

	gl.endTransformFeedback();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedbac call failed.");
}

const glw::GLchar* gl3cts::TransformFeedback::CaptureGeometryInterleaved::s_geometry_shader_source_code_template =
	"#version 150\n"
	"\n"
	"layout(points) in;\n"
	"layout(TEMPLATE_PRIMITIVE_TYPE, max_vertices = 4) out;\n"
	"\n"
	"TEMPLATE_INPUT_OUTPUT_DECLARATIONS"
	"\n"
	"void main()\n"
	"{\n"
	"    /* Note: The points are moved 0.0625 from the borders to\n"
	"             reduce non-XFB related rasterization problems. */\n"
	"\n"
	"    gl_Position = vec4(-1.0 + TEMPLATE_RASTERIZATION_EPSILON,  1.0 - TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
	"1.0);\n"
	"TEMPLATE_OUTPUT_SETTERS"
	"    EmitVertex();\n"
	"\n"
	"    gl_Position = vec4( 1.0 - TEMPLATE_RASTERIZATION_EPSILON,  1.0 - TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
	"1.0);\n"
	"TEMPLATE_OUTPUT_SETTERS"
	"    EmitVertex();\n"
	"\n"
	"    gl_Position = vec4(-1.0 + TEMPLATE_RASTERIZATION_EPSILON, -1.0 + TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
	"1.0);\n"
	"TEMPLATE_OUTPUT_SETTERS"
	"    EmitVertex();\n"
	"\n"
	"    gl_Position = vec4( 1.0 - TEMPLATE_RASTERIZATION_EPSILON, -1.0 + TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
	"1.0);\n"
	"TEMPLATE_OUTPUT_SETTERS"
	"    EmitVertex();\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::CaptureGeometryInterleaved::s_blank_vertex_shader_source_code =
	"#version 130\n"
	"\n"
	"void main()\n"
	"{\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::CaptureGeometryInterleaved::s_geometry_interleaved_primitive_cases[] = {
	"points", "line_strip", "triangle_strip"
};

const glw::GLenum gl3cts::TransformFeedback::CaptureGeometryInterleaved::s_geometry_interleaved_primitive_cases_xfb[] =
	{ GL_POINTS, GL_LINES, GL_TRIANGLES };

const glw::GLuint gl3cts::TransformFeedback::CaptureGeometryInterleaved::s_geometry_interleaved_primitive_cases_count =
	sizeof(s_geometry_interleaved_primitive_cases) / sizeof(s_geometry_interleaved_primitive_cases[0]);

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::CaptureVertexSeparate::CaptureVertexSeparate(deqp::Context& context, const char* test_name,
																		const char* test_description)
	: CaptureVertexInterleaved(context, test_name, test_description)
	, m_buffers(DE_NULL)
	, m_max_transform_feedback_separate_attribs(0)
{
	m_attrib_type = GL_SEPARATE_ATTRIBS;
}

void gl3cts::TransformFeedback::CaptureVertexSeparate::fetchLimits(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Fetching limits. */
	glw::GLint max_transform_feedback_separate_components;

	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_transform_feedback_separate_components);

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

	if (max_transform_feedback_separate_components < 4)
	{
		throw 0;
	}

	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &m_max_transform_feedback_separate_attribs);

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

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

	m_max_transform_feedback_components = m_max_transform_feedback_separate_attribs * 4 /* vec4 is used */;

	glw::GLint max_varyings_components = 0;

	gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings_components);

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

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

	if (m_max_transform_feedback_components > max_varyings_components)
	{
		m_max_transform_feedback_components = max_varyings_components;
	}
}

void gl3cts::TransformFeedback::CaptureVertexSeparate::createTransformFeedbackBuffer(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	m_buffers = new glw::GLuint[m_max_transform_feedback_components];

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

	gl.genBuffers(m_max_transform_feedback_separate_attribs, m_buffers);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

	m_buffer_size = static_cast<glw::GLuint>(m_max_vertices_drawn * 4 /* vec4 */ * sizeof(glw::GLfloat));

	for (glw::GLint i = 0; i < m_max_transform_feedback_separate_attribs; ++i)
	{
		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffers[i]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer_size, NULL, GL_DYNAMIC_READ);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
	}
}

void gl3cts::TransformFeedback::CaptureVertexSeparate::bindBuffer(BindBufferCase bind_case)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	switch (bind_case)
	{
	case BIND_BUFFER_BASE_CASE:
		for (glw::GLint i = 0; i < m_max_transform_feedback_separate_attribs; ++i)
		{
			gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_buffers[i]);
		}
		break;
	case BIND_BUFFER_RANGE_CASE:
		for (glw::GLint i = 0; i < m_max_transform_feedback_separate_attribs; ++i)
		{
			gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_buffers[i], 0, m_buffer_size);
		}
		break;
	case BIND_BUFFER_OFFSET_CASE:
		for (glw::GLint i = 0; i < m_max_transform_feedback_separate_attribs; ++i)
		{
			m_glBindBufferOffsetEXT(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_buffers[i], 0);
		}
		break;
	default:
		throw 0;
	}
}

void gl3cts::TransformFeedback::CaptureVertexSeparate::cleanBuffer(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (DE_NULL != m_buffers)
	{
		gl.deleteBuffers(m_max_transform_feedback_separate_attribs, m_buffers);

		delete[] m_buffers;

		m_buffers = DE_NULL;
	}
}

bool gl3cts::TransformFeedback::CaptureVertexSeparate::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
																					glw::GLenum primitive_type)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLuint number_of_vertices = 0;

	switch (primitive_type)
	{
	case GL_POINTS:
		number_of_vertices = 4;
		break;
	case GL_LINES:
		number_of_vertices = 4;
		break;
	case GL_LINE_LOOP:
		number_of_vertices = 8;
		break;
	case GL_LINE_STRIP:
		number_of_vertices = 6;
		break;
	case GL_TRIANGLES:
		number_of_vertices = 6;
		break;
	case GL_TRIANGLE_STRIP:
		number_of_vertices = 6;
		break;
	case GL_TRIANGLE_FAN:
		number_of_vertices = 6;
		break;
	default:
		throw 0;
	}

	bool is_ok = true;

	for (glw::GLint i = 0; i < m_max_transform_feedback_separate_attribs - 1; ++i)
	{
		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffers[i]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

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

		for (glw::GLuint j = 0; (j < number_of_vertices) && is_ok; ++j)
		{
			for (glw::GLuint k = 0; k < 4 /* vec4 */; ++k)
			{
				glw::GLfloat result	= results[j * 4 + k];
				glw::GLfloat reference = (glw::GLfloat)(i * 4 + k);

				if (fabs(result - reference) > 0.125 /* precision */)
				{
					is_ok = false;

					break;
				}
			}
		}

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

	/* gl_Position */
	if (is_ok)
	{
		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffers[m_max_transform_feedback_separate_attribs - 1]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

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

		for (glw::GLuint j = 0; (j < number_of_vertices) && is_ok; ++j)
		{
			glw::GLfloat result[4] = { results[j * 4], results[j * 4 + 1], results[j * 4 + 2], results[j * 4 + 3] };

			if ((fabs(fabs(result[0]) - 1.0 + s_rasterization_epsilon) > 0.125 /* precision */) ||
				(fabs(fabs(result[1]) - 1.0 + s_rasterization_epsilon) > 0.125 /* precision */) ||
				(fabs(result[2]) > 0.125 /* precision */) || (fabs(result[3] - 1.0) > 0.125 /* precision */))
			{
				is_ok = false;

				break;
			}
		}

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

	return is_ok;
}

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::CaptureGeometrySeparate::CaptureGeometrySeparate(deqp::Context& context,
																			const char*	test_name,
																			const char*	test_description)
	: CaptureVertexInterleaved(context, test_name, test_description)
	, CaptureVertexSeparate(context, test_name, test_description)
	, CaptureGeometryInterleaved(context, test_name, test_description)
	, m_buffers(DE_NULL)
	, m_max_transform_feedback_separate_attribs(0)
{
}

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::CheckGetXFBVarying::CheckGetXFBVarying(deqp::Context& context, const char* test_name,
																  const char* test_description)
	: deqp::TestCase(context, test_name, test_description)
	, m_context(context)
	, m_max_xfb_interleaved_components(0)
	, m_max_xfb_separate_attributes(0)
	, m_max_xfb_separate_components(0)
	, m_max_varying_components(0)
	, m_max_varying_vectors(0)
	, m_max_geometry_total_output_components(0)
{
}

gl3cts::TransformFeedback::CheckGetXFBVarying::~CheckGetXFBVarying(void)
{
}

void gl3cts::TransformFeedback::CheckGetXFBVarying::fetchLimits(void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Fetching limits. */
	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &m_max_xfb_interleaved_components);
	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &m_max_xfb_separate_attributes);
	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &m_max_xfb_separate_components);
	gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &m_max_varying_components);
	gl.getIntegerv(GL_MAX_VARYING_VECTORS, &m_max_varying_vectors);
	gl.getIntegerv(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, &m_max_geometry_total_output_components);

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

glw::GLuint gl3cts::TransformFeedback::CheckGetXFBVarying::numberOfAttributes(glw::GLuint capture_way,
																			  glw::GLuint shader_case,
																			  glw::GLuint varying_type)
{
	/* Setup limits of the case. */
	const glw::GLuint max_total_components =
		((s_shader_cases[shader_case].geometry_shader == DE_NULL) ? m_max_varying_components :
																	m_max_geometry_total_output_components) -
		4 /* gl_Position is not captured */;

	const glw::GLuint attribute_components = s_varying_types[varying_type].components_count;
	const glw::GLuint max_xfb_components   = (s_capture_ways[capture_way] == GL_INTERLEAVED_ATTRIBS) ?
											   m_max_xfb_interleaved_components :
											   (attribute_components * m_max_xfb_separate_components);

	if (s_capture_ways[capture_way] == GL_SEPARATE_ATTRIBS)
	{
		if (attribute_components > glw::GLuint(m_max_xfb_separate_components))
		{
			return 0;
		}
	}

	/* Setup number of attributes. */
	glw::GLuint number_of_attributes = max_xfb_components / attribute_components;

	if (s_capture_ways[capture_way] == GL_SEPARATE_ATTRIBS &&
		number_of_attributes > glw::GLuint(m_max_xfb_separate_attributes))
	{
		number_of_attributes = m_max_xfb_separate_attributes;
	}

	/* Clamp to limits. */
	if (number_of_attributes * attribute_components > max_total_components)
	{
		number_of_attributes = max_total_components / attribute_components;
	}

	/* Vectors limit. */
	if (attribute_components <= 4)
	{
		if (number_of_attributes > glw::GLuint(m_max_varying_vectors))
		{
			number_of_attributes = m_max_varying_vectors;
		}
	}
	else
	{
		if (number_of_attributes > glw::GLuint(m_max_varying_vectors) / 4)
		{
			number_of_attributes = glw::GLuint(m_max_varying_vectors) / 4;
		}
	}

	/* Return. */
	return number_of_attributes;
}

tcu::TestNode::IterateResult gl3cts::TransformFeedback::CheckGetXFBVarying::iterate(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Initializations. */
	bool is_at_least_gl_30 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)));
	bool is_ext_tf_1	   = m_context.getContextInfo().isExtensionSupported("GL_EXT_transform_feedback");

	bool is_ok		= true;
	bool test_error = false;

	glw::GLuint program = 0;

	/* Tests. */
	try
	{
		if (is_at_least_gl_30 || is_ext_tf_1)
		{
			fetchLimits();

			for (glw::GLuint i = 0; (i < s_capture_ways_count) && is_ok; ++i)
			{
				for (glw::GLuint j = 0; (j < s_shader_cases_count) && is_ok; ++j)
				{
					for (glw::GLuint k = 0; (k < s_varying_types_count) && is_ok; ++k)
					{
						glw::GLuint n = numberOfAttributes(i, j, k);

						if (n)
						{
							program = buildProgram(i, j, k, n);

							is_ok = is_ok && (program != 0);

							is_ok = is_ok && check(program, i, j, k, n);

							gl.deleteProgram(program);

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

							program = 0;
						}
					}
				}
			}
		}
	}
	catch (...)
	{
		is_ok	  = false;
		test_error = true;

		if (program)
		{
			gl.deleteProgram(program);

			program = 0;
		}
	}

	/* Result's setup. */
	if (is_ok)
	{
		/* Log success. */
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Test checking Get Transform Feedback Varying have passed."
											<< tcu::TestLog::EndMessage;

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

	return STOP;
}

glw::GLuint gl3cts::TransformFeedback::CheckGetXFBVarying::buildProgram(glw::GLuint capture_way,
																		glw::GLuint shader_case,
																		glw::GLuint varying_type,
																		glw::GLuint number_of_attributes)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Preparing source code. */
	std::string						xfb_variable_declarations("");
	std::string						xfb_variable_setters("");
	std::vector<std::string>		xfb_varyings(number_of_attributes);
	std::vector<const glw::GLchar*> xfb_varyings_c(number_of_attributes);

	/* Most of varyings is declarated output variables. */
	for (glw::GLuint i = 0; i < number_of_attributes; ++i)
	{
		/* Varying name: result_# */
		std::string varying = "result_";
		varying.append(gl3cts::TransformFeedback::Utilities::itoa(i));

		xfb_varyings[i]   = varying;
		xfb_varyings_c[i] = xfb_varyings[i].c_str();

		/* Varying declaration: out TYPE result_#;*/
		xfb_variable_declarations.append("out ");
		xfb_variable_declarations.append(s_varying_types[varying_type].name);
		xfb_variable_declarations.append(" ");
		xfb_variable_declarations.append(varying);
		xfb_variable_declarations.append(";\n");

		/* Varying setter: result_# = TYPE(#); */
		xfb_variable_setters.append("    ");
		xfb_variable_setters.append(varying);
		xfb_variable_setters.append(" = ");
		xfb_variable_setters.append(s_varying_types[varying_type].name);
		xfb_variable_setters.append("(");
		xfb_variable_setters.append("2"); //gl3cts::TransformFeedback::Utilities::itoa(i));
		if (s_varying_types[varying_type].float_component)
		{
			/* if varying is float varying setter is: result_# = TYPE(#.0); */
			xfb_variable_setters.append(".0");
		}
		xfb_variable_setters.append(");\n");
	}

	/* Preprocess vertex shader source code template. */
	const glw::GLchar* vertex_shader   = s_shader_cases[shader_case].vertex_shader;
	const glw::GLchar* geometry_shader = s_shader_cases[shader_case].geometry_shader;

	std::string xfb_shader;

	if (DE_NULL == s_shader_cases[shader_case].geometry_shader)
	{
		/* XFB tested in vertex shader. */
		xfb_shader = vertex_shader;
	}
	else
	{
		/* XFB tested in geometry shader. */
		xfb_shader = geometry_shader;
	}

	/* Preprocess shader. */
	xfb_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(xfb_shader, "TEMPLATE_OUTPUT_DECLARATIONS",
																	  xfb_variable_declarations);
	xfb_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(xfb_shader, "TEMPLATE_OUTPUT_SETTERS",
																	  xfb_variable_setters);

	if (DE_NULL == s_shader_cases[shader_case].geometry_shader)
	{
		/* XFB tested in vertex shader. */
		vertex_shader = xfb_shader.c_str();
	}
	else
	{
		/* XFB tested in geometry shader. */
		geometry_shader = xfb_shader.c_str();
	}

	/* Compile, link and check. */
	glw::GLuint program = gl3cts::TransformFeedback::Utilities::buildProgram(
		gl, m_context.getTestContext().getLog(), geometry_shader, NULL, NULL, vertex_shader, s_generic_fragment_shader,
		&xfb_varyings_c[0], number_of_attributes, s_capture_ways[capture_way]);

	/* Check compilation status. */
	if (0 == program)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Building program has failed.\nVertex shader:\n"
											<< vertex_shader << "Geometry shader:\n"
											<< ((DE_NULL == geometry_shader) ? "" : geometry_shader)
											<< "Fragment shader:\n"
											<< s_generic_fragment_shader << tcu::TestLog::EndMessage;

		throw 0;
	}

	return program;
}

bool gl3cts::TransformFeedback::CheckGetXFBVarying::check(glw::GLuint program, glw::GLuint capture_way,
														  glw::GLuint shader_case UNUSED, glw::GLuint varying_type,
														  glw::GLuint number_of_attributes)
{
	/* Functions handler */
	const glw::Functions& gl		 = m_context.getRenderContext().getFunctions();
	glw::GLuint			  max_length = 0;

	/* Inspect glGetTransformFeedbackVarying. */
	for (glw::GLuint i = 0; i < number_of_attributes; ++i)
	{
		const glw::GLsizei bufSize  = 18;
		glw::GLsizei	   length   = 0;
		glw::GLsizei	   size		= 0;
		glw::GLenum		   type		= GL_NONE;
		glw::GLchar		   name[18] = { 0 }; /* Size of bufSize. */

		gl.getTransformFeedbackVarying(program, i, bufSize, &length, &size, &type, name);

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

		max_length = deMaxu32(max_length, glw::GLuint(length));

		/* Check name. */
		if (length)
		{
			std::string varying		= name;
			std::string varying_ref = "result_";
			varying_ref.append(gl3cts::TransformFeedback::Utilities::itoa(i));

			if (0 != varying.compare(varying_ref))
			{
				return false;
			}
		}
		else
		{
			return false;
		}

		/* Check size. */
		const glw::GLuint size_ref = 1;

		if (size != size_ref)
		{
			return false;
		}

		/* Check type. */
		if (type != s_varying_types[varying_type].type)
		{
			return false;
		}
	}

	/* Inspect glGetProgramiv. */
	glw::GLint xfb_varyings			  = 0;
	glw::GLint xfb_mode				  = 0;
	glw::GLint xfb_varying_max_length = 0;

	gl.getProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYINGS, &xfb_varyings);
	gl.getProgramiv(program, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, &xfb_mode);
	gl.getProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &xfb_varying_max_length);

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

	if (glw::GLuint(xfb_varyings) != number_of_attributes)
	{
		return false;
	}

	if (glw::GLenum(xfb_mode) != s_capture_ways[capture_way])
	{
		return false;
	}

	if (glw::GLuint(xfb_varying_max_length) < max_length)
	{
		return false;
	}

	return true;
}

const glw::GLchar* gl3cts::TransformFeedback::CheckGetXFBVarying::s_generic_fragment_shader = "#version 130\n"
																							  "\n"
																							  "out vec4 color;\n"
																							  "\n"
																							  "void main()\n"
																							  "{\n"
																							  "    color = vec4(1.0);\n"
																							  "}\n";

const struct gl3cts::TransformFeedback::CheckGetXFBVarying::ShaderCase
	gl3cts::TransformFeedback::CheckGetXFBVarying::s_shader_cases[] = { { /* Vertex Shader. */
																		  "#version 130\n"
																		  "\n"
																		  "TEMPLATE_OUTPUT_DECLARATIONS"
																		  "\n"
																		  "void main()\n"
																		  "{\n"
																		  "    gl_Position = vec4(1.0);\n"
																		  "TEMPLATE_OUTPUT_SETTERS"
																		  "}\n",

																		  /* Geometry Shader. */
																		  NULL },
																		{ /* Vertex Shader. */
																		  "#version 130\n"
																		  "\n"
																		  "void main()\n"
																		  "{\n"
																		  "}\n",

																		  /* Geometry Shader. */
																		  "#version 150\n"
																		  "\n"
																		  "layout(points) in;\n"
																		  "layout(points, max_vertices = 1) out;\n"
																		  "\n"
																		  "TEMPLATE_OUTPUT_DECLARATIONS"
																		  "\n"
																		  "void main()\n"
																		  "{\n"
																		  "    gl_Position = vec4(1.0);\n"
																		  "TEMPLATE_OUTPUT_SETTERS"
																		  "    EmitVertex();\n"
																		  "}\n" } };

const glw::GLuint gl3cts::TransformFeedback::CheckGetXFBVarying::s_shader_cases_count =
	sizeof(s_shader_cases) / sizeof(s_shader_cases[0]);

const struct gl3cts::TransformFeedback::CheckGetXFBVarying::VaryingType
	gl3cts::TransformFeedback::CheckGetXFBVarying::s_varying_types[] = {
		/* type,				name,		#components,	is component float */
		{ GL_FLOAT, "float", 1, true },
		{ GL_FLOAT_VEC2, "vec2", 2, true },
		{ GL_FLOAT_VEC3, "vec3", 3, true },
		{ GL_FLOAT_VEC4, "vec4", 4, true },
		{ GL_INT, "int", 1, false },
		{ GL_INT_VEC2, "ivec2", 2, false },
		{ GL_INT_VEC3, "ivec3", 3, false },
		{ GL_INT_VEC4, "ivec4", 4, false },
		{ GL_UNSIGNED_INT, "uint", 1, false },
		{ GL_UNSIGNED_INT_VEC2, "uvec2", 2, false },
		{ GL_UNSIGNED_INT_VEC3, "uvec3", 3, false },
		{ GL_UNSIGNED_INT_VEC4, "uvec4", 4, false },
		{ GL_FLOAT_MAT2, "mat2", 4, true },
		{ GL_FLOAT_MAT3, "mat3", 9, true },
		{ GL_FLOAT_MAT4, "mat4", 16, true }
	};

const glw::GLuint gl3cts::TransformFeedback::CheckGetXFBVarying::s_varying_types_count =
	sizeof(s_varying_types) / sizeof(s_varying_types[0]);

const glw::GLenum gl3cts::TransformFeedback::CheckGetXFBVarying::s_capture_ways[] = { GL_INTERLEAVED_ATTRIBS,
																					  GL_SEPARATE_ATTRIBS };

const glw::GLuint gl3cts::TransformFeedback::CheckGetXFBVarying::s_capture_ways_count =
	sizeof(s_capture_ways) / sizeof(s_capture_ways[0]);

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::QueryVertexInterleaved::QueryVertexInterleaved(deqp::Context& context, const char* test_name,
																		  const char* test_description)
	: CaptureVertexInterleaved(context, test_name, test_description), m_query_object(0)
{
	m_max_vertices_drawn = 3; /* Make buffer smaller up to 3 vertices. */
}

void gl3cts::TransformFeedback::QueryVertexInterleaved::createTransformFeedbackBuffer(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Create buffer object. */
	gl3cts::TransformFeedback::CaptureVertexInterleaved::createTransformFeedbackBuffer();

	/* Create query object. */
	gl.genQueries(1, &m_query_object);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries call failed.");
}

void gl3cts::TransformFeedback::QueryVertexInterleaved::draw(glw::GLuint primitive_case)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.beginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, m_query_object);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery call failed.");

	gl3cts::TransformFeedback::CaptureVertexInterleaved::draw(primitive_case);

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

bool gl3cts::TransformFeedback::QueryVertexInterleaved::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
																					 glw::GLenum primitive_type)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLuint number_of_primitives;

	gl.getQueryObjectuiv(m_query_object, GL_QUERY_RESULT, &number_of_primitives);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv call failed.");

	/* expected result */
	glw::GLuint number_of_primitives_reference = (primitive_type == GL_POINTS) ? 3 : 1; /* m_max_vertices_drawn == 3 */

	if (number_of_primitives_reference != number_of_primitives)
	{
		return false;
	}

	return true;
}

void gl3cts::TransformFeedback::QueryVertexInterleaved::clean(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

	/* Other */
	gl3cts::TransformFeedback::CaptureVertexInterleaved::clean();
}

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::QueryGeometryInterleaved::QueryGeometryInterleaved(deqp::Context& context,
																			  const char*	test_name,
																			  const char*	test_description)
	: CaptureVertexInterleaved(context, test_name, test_description)
	, CaptureGeometryInterleaved(context, test_name, test_description)
{
	m_query_object		 = 0;
	m_max_vertices_drawn = 3; /* Make buffer smaller up to 3 vertices. */
}

void gl3cts::TransformFeedback::QueryGeometryInterleaved::createTransformFeedbackBuffer(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Create buffer object. */
	gl3cts::TransformFeedback::CaptureGeometryInterleaved::createTransformFeedbackBuffer();

	/* Create query object. */
	gl.genQueries(1, &m_query_object);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries call failed.");
}

void gl3cts::TransformFeedback::QueryGeometryInterleaved::draw(glw::GLuint primitive_case)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.beginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, m_query_object);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery call failed.");

	gl3cts::TransformFeedback::CaptureGeometryInterleaved::draw(primitive_case);

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

bool gl3cts::TransformFeedback::QueryGeometryInterleaved::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
																					   glw::GLenum primitive_type)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLuint number_of_primitives;

	gl.getQueryObjectuiv(m_query_object, GL_QUERY_RESULT, &number_of_primitives);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv call failed.");

	/* expected result */
	glw::GLuint number_of_primitives_reference = (primitive_type == GL_POINTS) ? 3 : 1; /* m_max_vertices_drawn == 3 */

	if (number_of_primitives_reference != number_of_primitives)
	{
		return false;
	}

	return true;
}

void gl3cts::TransformFeedback::QueryGeometryInterleaved::clean(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

	/* Other. */
	gl3cts::TransformFeedback::CaptureGeometryInterleaved::clean();
}

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::QueryVertexSeparate::QueryVertexSeparate(deqp::Context& context, const char* test_name,
																	const char* test_description)
	: CaptureVertexInterleaved(context, test_name, test_description)
	, CaptureVertexSeparate(context, test_name, test_description)
{
	m_query_object		 = 0;
	m_max_vertices_drawn = 3; /* Make buffer smaller up to 3 vertices. */
}

void gl3cts::TransformFeedback::QueryVertexSeparate::createTransformFeedbackBuffer(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Create buffer object. */
	gl3cts::TransformFeedback::CaptureVertexSeparate::createTransformFeedbackBuffer();

	/* Create query object. */
	gl.genQueries(1, &m_query_object);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries call failed.");
}

void gl3cts::TransformFeedback::QueryVertexSeparate::draw(glw::GLuint primitive_case)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.beginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, m_query_object);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery call failed.");

	gl3cts::TransformFeedback::CaptureVertexSeparate::draw(primitive_case);

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

bool gl3cts::TransformFeedback::QueryVertexSeparate::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
																				  glw::GLenum primitive_type)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLuint number_of_primitives;

	gl.getQueryObjectuiv(m_query_object, GL_QUERY_RESULT, &number_of_primitives);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv call failed.");

	/* expected result */
	glw::GLuint number_of_primitives_reference = (primitive_type == GL_POINTS) ? 3 : 1; /* m_max_vertices_drawn == 3 */

	if (number_of_primitives_reference != number_of_primitives)
	{
		return false;
	}

	return true;
}

void gl3cts::TransformFeedback::QueryVertexSeparate::clean(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

	/* Other */
	gl3cts::TransformFeedback::CaptureVertexSeparate::clean();
}

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::QueryGeometrySeparate::QueryGeometrySeparate(deqp::Context& context, const char* test_name,
																		const char* test_description)
	: CaptureVertexInterleaved(context, test_name, test_description)
	, CaptureVertexSeparate(context, test_name, test_description)
	, CaptureGeometrySeparate(context, test_name, test_description)
{
	m_query_object		 = 0;
	m_max_vertices_drawn = 3; /* Make buffer smaller up to 3 vertices. */
}

void gl3cts::TransformFeedback::QueryGeometrySeparate::createTransformFeedbackBuffer(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Create buffer object. */
	gl3cts::TransformFeedback::CaptureGeometrySeparate::createTransformFeedbackBuffer();

	/* Create query object. */
	gl.genQueries(1, &m_query_object);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries call failed.");
}

void gl3cts::TransformFeedback::QueryGeometrySeparate::draw(glw::GLuint primitive_case)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.beginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, m_query_object);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery call failed.");

	gl3cts::TransformFeedback::CaptureGeometrySeparate::draw(primitive_case);

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

bool gl3cts::TransformFeedback::QueryGeometrySeparate::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
																					glw::GLenum primitive_type)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLuint number_of_primitives;

	gl.getQueryObjectuiv(m_query_object, GL_QUERY_RESULT, &number_of_primitives);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv call failed.");

	/* expected result */
	glw::GLuint number_of_primitives_reference = (primitive_type == GL_POINTS) ? 3 : 1; /* m_max_vertices_drawn == 3 */

	if (number_of_primitives_reference != number_of_primitives)
	{
		return false;
	}

	return true;
}

void gl3cts::TransformFeedback::QueryGeometrySeparate::clean(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

	/* Other */
	gl3cts::TransformFeedback::CaptureGeometrySeparate::clean();
}

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::DiscardVertex::DiscardVertex(deqp::Context& context, const char* test_name,
														const char* test_description)
	: CaptureVertexInterleaved(context, test_name, test_description)
{
}

void gl3cts::TransformFeedback::DiscardVertex::draw(glw::GLuint primitive_case)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Must clear before rasterizer discard */
	gl.clear(GL_COLOR_BUFFER_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");

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

	gl3cts::TransformFeedback::CaptureVertexInterleaved::draw(primitive_case);

	gl.disable(GL_RASTERIZER_DISCARD);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
}

bool gl3cts::TransformFeedback::DiscardVertex::checkFramebuffer(glw::GLuint primitive_case UNUSED)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Fetch framebuffer. */
	std::vector<glw::GLfloat> pixels(s_framebuffer_size * s_framebuffer_size);

	if ((s_framebuffer_size > 0) && (s_framebuffer_size > 0))
	{
		gl.readPixels(0, 0, s_framebuffer_size, s_framebuffer_size, GL_RED, GL_FLOAT, pixels.data());
		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
	}

	/* Check results.
	 Note: assuming that s_buffer_size == 2 -> then all points shall be drawn. */
	for (std::vector<glw::GLfloat>::iterator i = pixels.begin(); i != pixels.end(); ++i)
	{
		if (fabs(*i) > 0.0625f /* precision */)
		{
			return false;
		}
	}

	return true;
}

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::DiscardGeometry::DiscardGeometry(deqp::Context& context, const char* test_name,
															const char* test_description)
	: CaptureVertexInterleaved(context, test_name, test_description)
	, CaptureGeometryInterleaved(context, test_name, test_description)
{
}

void gl3cts::TransformFeedback::DiscardGeometry::draw(glw::GLuint primitive_case)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Must clear before rasterizer discard */
	gl.clear(GL_COLOR_BUFFER_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");

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

	gl3cts::TransformFeedback::CaptureGeometryInterleaved::draw(primitive_case);

	gl.disable(GL_RASTERIZER_DISCARD);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
}

bool gl3cts::TransformFeedback::DiscardGeometry::checkFramebuffer(glw::GLuint primitive_case UNUSED)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Fetch framebuffer. */
	std::vector<glw::GLfloat> pixels(s_framebuffer_size * s_framebuffer_size);

	if ((s_framebuffer_size > 0) && (s_framebuffer_size > 0))
	{
		gl.readPixels(0, 0, s_framebuffer_size, s_framebuffer_size, GL_RED, GL_FLOAT, pixels.data());
		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
	}

	/* Check results.
	 Note: assuming that s_buffer_size == 2 -> then all points shall be drawn. */
	for (std::vector<glw::GLfloat>::iterator i = pixels.begin(); i != pixels.end(); ++i)
	{
		if (fabs(*i) > 0.0625f /* precision */)
		{
			return false;
		}
	}

	return true;
}

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::DrawXFB::DrawXFB(deqp::Context& context, const char* test_name, const char* test_description)
	: deqp::TestCase(context, test_name, test_description)
	, m_context(context)
	, m_program_id_xfb(0)
	, m_program_id_draw(0)
	, m_fbo_id(0)
	, m_rbo_id(0)
	, m_vao_id(0)
{
	memset(m_xfb_id, 0, sizeof(m_xfb_id));
	memset(m_bo_id, 0, sizeof(m_bo_id));
}

gl3cts::TransformFeedback::DrawXFB::~DrawXFB(void)
{
}

tcu::TestNode::IterateResult gl3cts::TransformFeedback::DrawXFB::iterate(void)
{
	/* Initializations. */
	bool is_at_least_gl_40 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
	bool is_arb_tf_2	   = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback2");

	bool is_ok		= true;
	bool test_error = false;

	/* Tests. */
	try
	{
		if (is_at_least_gl_40 || is_arb_tf_2)
		{
			for (glw::GLuint i = 0; (i < s_capture_modes_count) && is_ok; ++i)
			{
				prepare(s_capture_modes[i]);

				bindVAO(m_vao_id);
				useProgram(m_program_id_xfb);

				for (glw::GLuint j = 0; (j < s_xfb_count) && is_ok; ++j)
				{
					bindXFB(m_xfb_id[j]);
					bindBOForXFB(s_capture_modes[i], m_bo_id[j]);
					useColour(m_program_id_xfb, s_colours[j][0], s_colours[j][1], s_colours[j][2], s_colours[j][3]);
					useGeometrySet(m_program_id_xfb, false);
					drawForCapture(true, true, false, false);

					is_ok = is_ok && inspectXFBState(true, true);
				}

				for (glw::GLuint j = 0; (j < s_xfb_count) && is_ok; ++j)
				{
					bindXFB(m_xfb_id[j]);
					useColour(m_program_id_xfb, s_colours[j][0], s_colours[j][1], s_colours[j][2], s_colours[j][3]);
					useGeometrySet(m_program_id_xfb, true);
					drawForCapture(false, false, true, true);

					is_ok = is_ok && inspectXFBState(false, false);
				}

				useProgram(m_program_id_draw);

				for (glw::GLuint j = 0; (j < s_xfb_count) && is_ok; ++j)
				{
					bindXFB(m_xfb_id[j]);
					bindBOForDraw(m_program_id_draw, s_capture_modes[i], m_bo_id[j]);
					drawToFramebuffer(m_xfb_id[j]);

					is_ok =
						is_ok && checkFramebuffer(s_colours[j][0], s_colours[j][1], s_colours[j][2], s_colours[j][3]);
				}

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

	/* Result's setup. */
	if (is_ok)
	{
		/* Log success. */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB have passed."
											<< tcu::TestLog::EndMessage;

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (test_error)
		{
			/* Log error. */
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB have approached error."
												<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			/* Log fail. */
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB have failed."
												<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

void gl3cts::TransformFeedback::DrawXFB::prepare(glw::GLenum capture_mode)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare programs. */
	m_program_id_xfb = gl3cts::TransformFeedback::Utilities::buildProgram(
		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_xfb, s_fragment_shader,
		s_xfb_varyings, s_xfb_varyings_count, capture_mode);

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

	m_program_id_draw = gl3cts::TransformFeedback::Utilities::buildProgram(gl, m_context.getTestContext().getLog(),
																		   NULL, NULL, NULL, s_vertex_shader_draw,
																		   s_fragment_shader, NULL, 0, capture_mode);

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

	/* Prepare transform feedbacks. */
	gl.genTransformFeedbacks(s_xfb_count, m_xfb_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");

	/* Prepare buffer objects. */
	gl.genBuffers(s_xfb_count, m_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

	for (glw::GLuint i = 0; i < s_xfb_count; ++i)
	{
		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id[i]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_capture_size, NULL, GL_DYNAMIC_COPY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
	}

	/* Prepare framebuffer. */
	gl.clearColor(0.f, 0.f, 0.f, 1.f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");

	gl.genFramebuffers(1, &m_fbo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");

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

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

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

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, s_view_size, s_view_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");

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

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

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

	/* Create empty Vertex Array Object */
	gl.genVertexArrays(1, &m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
}

void gl3cts::TransformFeedback::DrawXFB::bindXFB(glw::GLuint xfb_id)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, xfb_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback call failed.");
}

void gl3cts::TransformFeedback::DrawXFB::bindVAO(glw::GLuint vao_id)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

void gl3cts::TransformFeedback::DrawXFB::bindBOForXFB(glw::GLenum capture_mode, glw::GLuint bo_id)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	switch (capture_mode)
	{
	case GL_INTERLEAVED_ATTRIBS:
		gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, bo_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
		break;
	case GL_SEPARATE_ATTRIBS:
		for (glw::GLuint i = 0; i < s_xfb_varyings_count; ++i)
		{
			gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, bo_id, i * s_capture_size / s_xfb_varyings_count,
							   (i + 1) * s_capture_size / s_xfb_varyings_count);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
		}
		break;
	default:
		throw 0;
	};
}

void gl3cts::TransformFeedback::DrawXFB::bindBOForDraw(glw::GLuint program_id, glw::GLenum capture_mode,
													   glw::GLuint bo_id)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bindBuffer(GL_ARRAY_BUFFER, bo_id);

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

	glw::GLuint position_location = gl.getAttribLocation(program_id, "position");
	glw::GLuint color_location	= gl.getAttribLocation(program_id, "color");

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

	glw::GLvoid* color_offset = (capture_mode == GL_INTERLEAVED_ATTRIBS) ?
									(glw::GLvoid*)(4 /* components */ * sizeof(glw::GLfloat)) :
									(glw::GLvoid*)(4 /* components */ * 6 /* vertices */ * sizeof(glw::GLfloat));

	glw::GLuint stride =
		static_cast<glw::GLuint>((capture_mode == GL_INTERLEAVED_ATTRIBS) ?
									 (4 /* components */ * 2 /* position and color */ * sizeof(glw::GLfloat)) :
									 (4 /* components */ * sizeof(glw::GLfloat)));

	gl.vertexAttribPointer(position_location, 4, GL_FLOAT, GL_FALSE, stride, NULL);
	gl.vertexAttribPointer(color_location, 4, GL_FLOAT, GL_FALSE, stride, color_offset);

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

	gl.enableVertexAttribArray(position_location);
	gl.enableVertexAttribArray(color_location);

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

void gl3cts::TransformFeedback::DrawXFB::useProgram(glw::GLuint program_id)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

void gl3cts::TransformFeedback::DrawXFB::useColour(glw::GLuint program_id, glw::GLfloat r, glw::GLfloat g,
												   glw::GLfloat b, glw::GLfloat a)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLint location = gl.getUniformLocation(program_id, "color");
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation call failed.");

	gl.uniform4f(location, r, g, b, a);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4f call failed.");
}

void gl3cts::TransformFeedback::DrawXFB::useGeometrySet(glw::GLuint program_id, bool invert_sign)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLint location = gl.getUniformLocation(program_id, "invert_sign");
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation call failed.");

	gl.uniform1f(location, invert_sign ? -1.f : 1.f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4f call failed.");
}

void gl3cts::TransformFeedback::DrawXFB::clean()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.useProgram(0);

	if (m_program_id_xfb)
	{
		gl.deleteProgram(m_program_id_xfb);

		m_program_id_xfb = 0;
	}

	if (m_program_id_draw)
	{
		gl.deleteProgram(m_program_id_draw);

		m_program_id_draw = 1;
	}

	for (glw::GLuint i = 0; i < s_xfb_count; ++i)
	{
		if (m_xfb_id[i])
		{
			gl.deleteTransformFeedbacks(1, &m_xfb_id[i]);

			m_xfb_id[i] = 0;
		}
	}

	for (glw::GLuint i = 0; i < s_xfb_count; ++i)
	{
		if (m_bo_id[i])
		{
			gl.deleteBuffers(1, &m_bo_id[i]);

			m_bo_id[i] = 0;
		}
	}

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

		m_vao_id = 0;
	}

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

		m_fbo_id = 0;
	}

	if (m_rbo_id)
	{
		gl.deleteRenderbuffers(1, &m_rbo_id);

		m_rbo_id = 0;
	}
}

void gl3cts::TransformFeedback::DrawXFB::drawForCapture(bool begin_xfb, bool pause_xfb, bool resume_xfb, bool end_xfb)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

	if (begin_xfb)
	{
		gl.beginTransformFeedback(GL_POINTS);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
	}

	if (resume_xfb)
	{
		gl.resumeTransformFeedback();
		GLU_EXPECT_NO_ERROR(gl.getError(), "glResumeTransformFeedback call failed.");
	}

	gl.drawArrays(GL_POINTS, 0, 3);

	if (pause_xfb)
	{
		gl.pauseTransformFeedback();
		GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback call failed.");
	}

	if (end_xfb)
	{
		gl.endTransformFeedback();
		GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
	}

	gl.disable(GL_RASTERIZER_DISCARD);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
}

void gl3cts::TransformFeedback::DrawXFB::drawToFramebuffer(glw::GLuint xfb_id)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.clearColor(0.f, 0.f, 0.f, 0.f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");

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

	gl.drawTransformFeedback(GL_TRIANGLES, xfb_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawTransformFeedback call failed.");
}

bool gl3cts::TransformFeedback::DrawXFB::checkFramebuffer(glw::GLfloat r, glw::GLfloat g, glw::GLfloat b,
														  glw::GLfloat a)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Number of pixels. */
	const glw::GLuint number_of_pixels = s_view_size * s_view_size;

	/* Fetch framebuffer. */
	std::vector<glw::GLubyte> pixels(number_of_pixels * 4 /* components */);

	if ((s_view_size > 0) && (s_view_size > 0))
	{
		gl.readPixels(0, 0, s_view_size, s_view_size, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
	}

	/* Convert color to integer. */
	glw::GLubyte ir = (glw::GLubyte)(255.f * r);
	glw::GLubyte ig = (glw::GLubyte)(255.f * g);
	glw::GLubyte ib = (glw::GLubyte)(255.f * b);
	glw::GLubyte ia = (glw::GLubyte)(255.f * a);

	/* Check results. */
	for (glw::GLuint i = 0; i < number_of_pixels; ++i)
	{
		if ((pixels[i * 4 /* components */] != ir) || (pixels[i * 4 /* components */ + 1] != ig) ||
			(pixels[i * 4 /* components */ + 2] != ib) || (pixels[i * 4 /* components */ + 3] != ia))
		{
			return false;
		}
	}

	return true;
}

bool gl3cts::TransformFeedback::DrawXFB::inspectXFBState(bool shall_be_paused, bool shall_be_active)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLint is_paused = 0;
	glw::GLint is_active = 0;

	gl.getIntegerv(GL_TRANSFORM_FEEDBACK_PAUSED, &is_paused);
	gl.getIntegerv(GL_TRANSFORM_FEEDBACK_ACTIVE, &is_active);

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

	if ((is_paused == -1) || (is_active == -1))
	{
		throw 0;
	}

	if (shall_be_paused ^ (is_paused == GL_TRUE))
	{
		return false;
	}

	if (shall_be_active ^ (is_active == GL_TRUE))
	{
		return false;
	}

	return true;
}

const glw::GLchar* gl3cts::TransformFeedback::DrawXFB::s_vertex_shader_xfb =
	"#version 130\n"
	"\n"
	"uniform vec4 color;\n"
	"uniform float invert_sign;\n"
	"out     vec4 colour;\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 * invert_sign,  1.0,              0.0,  1.0);\n"
	"        break;\n"
	"        case 2:\n"
	"            gl_Position = vec4( 1.0,                1.0 * invert_sign, 0.0,  1.0);\n"
	"        break;\n"
	"    }\n"
	"\n"
	"    colour = color;\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFB::s_vertex_shader_draw = "#version 130\n"
																			  "\n"
																			  "in  vec4 color;\n"
																			  "in  vec4 position;\n"
																			  "out vec4 colour;\n"
																			  "\n"
																			  "void main()\n"
																			  "{\n"
																			  "    gl_Position = position;\n"
																			  "    colour      = color;\n"
																			  "}\n";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFB::s_fragment_shader = "#version 130\n"
																		   "\n"
																		   "in  vec4 colour;\n"
																		   "out vec4 pixel;\n"
																		   "\n"
																		   "void main()\n"
																		   "{\n"
																		   "    pixel = colour;\n"
																		   "}\n";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFB::s_xfb_varyings[s_xfb_varyings_count] = { "gl_Position",
																								"colour" };

const glw::GLenum gl3cts::TransformFeedback::DrawXFB::s_capture_modes[] = { GL_INTERLEAVED_ATTRIBS,
																			GL_SEPARATE_ATTRIBS };
const glw::GLuint gl3cts::TransformFeedback::DrawXFB::s_capture_modes_count =
	sizeof(s_capture_modes) / sizeof(s_capture_modes[0]);

const glw::GLfloat gl3cts::TransformFeedback::DrawXFB::s_colours[s_xfb_count][4] = { { 1.f, 0.f, 0.f, 1.f },
																					 { 0.f, 1.f, 0.f, 1.f },
																					 { 0.f, 0.f, 1.f, 1.f } };

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::DrawXFBFeedback::DrawXFBFeedback(deqp::Context& context, const char* test_name,
															const char* test_description)
	: deqp::TestCase(context, test_name, test_description)
	, m_context(context)
	, m_program_id(0)
	, m_xfb_id(0)
	, m_source_bo_index(0)
{
	memset(m_bo_id, 1, sizeof(m_bo_id));
	memset(m_bo_id, 1, sizeof(m_vao_id));
}

gl3cts::TransformFeedback::DrawXFBFeedback::~DrawXFBFeedback(void)
{
}

tcu::TestNode::IterateResult gl3cts::TransformFeedback::DrawXFBFeedback::iterate(void)
{
	/* Initializations. */
	bool is_at_least_gl_40 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
	bool is_arb_tf_2	   = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback2");

	bool is_ok		= true;
	bool test_error = false;

	/* Tests. */
	try
	{
		if (is_at_least_gl_40 || is_arb_tf_2)
		{
			prepareAndBind();
			draw(true);
			swapBuffers();
			draw(false);
			swapBuffers();
			draw(false);

			is_ok = is_ok && check();
		}
	}
	catch (...)
	{
		is_ok	  = false;
		test_error = true;
	}

	/* Clean GL objects. */
	clean();

	/* Result's setup. */
	if (is_ok)
	{
		/* Log success. */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Feedback have passed."
											<< tcu::TestLog::EndMessage;

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (test_error)
		{
			/* Log error. */
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Feedback have approached error."
												<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			/* Log fail. */
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Feedback have failed."
												<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

void gl3cts::TransformFeedback::DrawXFBFeedback::prepareAndBind()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare programs. */
	m_program_id = gl3cts::TransformFeedback::Utilities::buildProgram(gl, m_context.getTestContext().getLog(), NULL,
																	  NULL, NULL, s_vertex_shader, s_fragment_shader,
																	  &s_xfb_varying, 1, GL_INTERLEAVED_ATTRIBS);

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

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

	/* Prepare transform feedbacks. */
	gl.genTransformFeedbacks(1, &m_xfb_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");

	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedbacks call failed.");

	/* Prepare buffer objects. */
	gl.genBuffers(s_bo_count, m_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id[0]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

	gl.bufferData(GL_ARRAY_BUFFER, s_bo_size, s_initial_data, GL_DYNAMIC_COPY);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_id[1]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

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

	/* Setup vertex arrays. */
	gl.genVertexArrays(s_bo_count, m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

	glw::GLuint position_location = gl.getAttribLocation(m_program_id, "position");
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");

	for (glw::GLuint i = 0; i < 2; ++i)
	{
		gl.bindVertexArray(m_vao_id[i]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

		gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id[i]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

		gl.vertexAttribPointer(position_location, 4, GL_FLOAT, GL_FALSE, 0, NULL);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");

		gl.enableVertexAttribArray(position_location);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
	}

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

	gl.bindVertexArray(m_vao_id[0]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
}

void gl3cts::TransformFeedback::DrawXFBFeedback::swapBuffers()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_id[m_source_bo_index]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

	m_source_bo_index = (m_source_bo_index + 1) % 2;

	gl.bindVertexArray(m_vao_id[(m_source_bo_index)]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
}

void gl3cts::TransformFeedback::DrawXFBFeedback::draw(bool is_first_draw)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

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

	if (is_first_draw)
	{
		gl.drawArrays(GL_POINTS, 0, 1);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
	}
	else
	{
		gl.drawTransformFeedback(GL_POINTS, m_xfb_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawTransformFeedback call failed.");
	}

	gl.endTransformFeedback();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");

	gl.disable(GL_RASTERIZER_DISCARD);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
}

bool gl3cts::TransformFeedback::DrawXFBFeedback::check()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLfloat* results =
		(glw::GLfloat*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, s_bo_size, GL_MAP_READ_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange call failed.");

	bool is_ok = false;

	if (results)
	{
		if ((results[0] == 8.f) && (results[1] == 16.f) && (results[2] == 24.f) && (results[3] == 32.f))
		{
			is_ok = true;
		}

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

	return is_ok;
}

void gl3cts::TransformFeedback::DrawXFBFeedback::clean()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.useProgram(0);

	if (m_program_id)
	{
		gl.deleteProgram(m_program_id);

		m_program_id = 0;
	}

	if (m_xfb_id)
	{
		gl.deleteTransformFeedbacks(1, &m_xfb_id);

		m_xfb_id = 0;
	}

	for (glw::GLuint i = 0; i < s_bo_count; ++i)
	{
		if (m_bo_id[i])
		{
			gl.deleteBuffers(1, &m_bo_id[i]);

			m_bo_id[i] = 0;
		}
	}

	for (glw::GLuint i = 0; i < s_bo_count; ++i)
	{
		if (m_vao_id[i])
		{
			gl.deleteVertexArrays(1, &m_vao_id[i]);

			m_vao_id[i] = 0;
		}
	}
}

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBFeedback::s_vertex_shader = "#version 130\n"
																				 "\n"
																				 "in  vec4 position;\n"
																				 "\n"
																				 "void main()\n"
																				 "{\n"
																				 "    gl_Position = position * 2.0;\n"
																				 "}\n";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBFeedback::s_fragment_shader = "#version 130\n"
																				   "\n"
																				   "out vec4 pixel;\n"
																				   "\n"
																				   "void main()\n"
																				   "{\n"
																				   "    pixel = vec4(1.0);\n"
																				   "}\n";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBFeedback::s_xfb_varying = "gl_Position";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBFeedback::s_attrib = "position";

const glw::GLfloat gl3cts::TransformFeedback::DrawXFBFeedback::s_initial_data[] = { 1.f, 2.f, 3.f, 4.f };

const glw::GLuint gl3cts::TransformFeedback::DrawXFBFeedback::s_draw_vertex_count =
	sizeof(s_initial_data) / sizeof(s_initial_data[0]) / 4 /* components */;

const glw::GLuint gl3cts::TransformFeedback::DrawXFBFeedback::s_bo_size = sizeof(s_initial_data);

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::CaptureSpecialInterleaved::CaptureSpecialInterleaved(deqp::Context& context,
																				const char*	test_name,
																				const char*	test_description)
	: deqp::TestCase(context, test_name, test_description)
	, m_context(context)
	, m_program_id(0)
	, m_vao_id(0)
	, m_xfb_id(0)
{
	memset(m_bo_id, 0, sizeof(m_bo_id));
}

gl3cts::TransformFeedback::CaptureSpecialInterleaved::~CaptureSpecialInterleaved(void)
{
}

tcu::TestNode::IterateResult gl3cts::TransformFeedback::CaptureSpecialInterleaved::iterate(void)
{
	/* Initializations. */
	bool is_at_least_gl_40 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
	bool is_arb_tf_3	   = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback3");

	bool is_ok		= true;
	bool test_error = false;

	/* Tests. */
	try
	{
		if (is_at_least_gl_40 || is_arb_tf_3)
		{
			prepareAndBind();
			draw();

			is_ok = is_ok && check();
		}
	}
	catch (...)
	{
		is_ok	  = false;
		test_error = true;
	}

	/* Clean GL objects. */
	clean();

	/* Result's setup. */
	if (is_ok)
	{
		/* Log success. */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Capture Special Interleaved have passed."
											<< tcu::TestLog::EndMessage;

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (test_error)
		{
			/* Log error. */
			m_context.getTestContext().getLog() << tcu::TestLog::Message
												<< "Capture Special Interleaved have approached error."
												<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			/* Log fail. */
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Capture Special Interleaved have failed."
												<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

void gl3cts::TransformFeedback::CaptureSpecialInterleaved::prepareAndBind()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare programs. */
	m_program_id = gl3cts::TransformFeedback::Utilities::buildProgram(
		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader, s_fragment_shader, s_xfb_varyings,
		s_xfb_varyings_count, GL_INTERLEAVED_ATTRIBS);

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

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

	/* Prepare transform feedbacks. */
	gl.genTransformFeedbacks(1, &m_xfb_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");

	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedbacks call failed.");

	/* Create empty Vertex Array Object */
	gl.genVertexArrays(1, &m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

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

	/* Prepare buffer objects. */
	gl.genBuffers(s_bo_ids_count, m_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

	for (glw::GLuint i = 0; i < s_bo_ids_count; ++i)
	{
		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id[i]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, NULL, GL_DYNAMIC_COPY); /* allocation */
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

		gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_bo_id[i]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");
	}
}

void gl3cts::TransformFeedback::CaptureSpecialInterleaved::draw()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

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

	gl.drawArrays(GL_POINTS, 0, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");

	gl.endTransformFeedback();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");

	gl.disable(GL_RASTERIZER_DISCARD);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
}

bool gl3cts::TransformFeedback::CaptureSpecialInterleaved::check()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	bool is_ok = true;

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

	glw::GLfloat* results =
		(glw::GLfloat*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, s_bo_size, GL_MAP_READ_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange call failed.");

	if ((results[0] != 1.0) || (results[1] != 2.0) || (results[2] != 3.0) || (results[3] != 4.0) ||
		/* gl_SkipComponents4 here */
		(results[8] != 5.0) || (results[9] != 6.0) || (results[10] != 7.0) || (results[11] != 8.0))
	{
		is_ok = false;
	}

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

	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id[1]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

	results = (glw::GLfloat*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, s_bo_size, GL_MAP_READ_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange call failed.");

	if ((results[0] != 9.0) || (results[1] != 10.0) || (results[2] != 11.0) || (results[3] != 12.0) ||
		/* gl_SkipComponents4 here */
		(results[8] != 13.0) || (results[9] != 14.0) || (results[10] != 15.0) || (results[11] != 16.0))
	{
		is_ok = false;
	}

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

	return is_ok;
}

void gl3cts::TransformFeedback::CaptureSpecialInterleaved::clean()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.useProgram(0);

	if (m_program_id)
	{
		gl.deleteProgram(m_program_id);

		m_program_id = 0;
	}

	if (m_xfb_id)
	{
		gl.deleteTransformFeedbacks(1, &m_xfb_id);

		m_xfb_id = 0;
	}

	for (glw::GLuint i = 0; i < s_bo_ids_count; ++i)
	{
		if (m_bo_id[i])
		{
			gl.deleteBuffers(1, &m_bo_id[i]);

			m_bo_id[i] = 0;
		}
	}

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

		m_vao_id = 0;
	}
}

const glw::GLchar* gl3cts::TransformFeedback::CaptureSpecialInterleaved::s_vertex_shader =
	"#version 130\n"
	"\n"
	"out vec4 variable_1;\n"
	"out vec4 variable_2;\n"
	"out vec4 variable_3;\n"
	"out vec4 variable_4;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    variable_1 = vec4(1.0, 2.0, 3.0, 4.0);\n"
	"    variable_2 = vec4(5.0, 6.0, 7.0, 8.0);\n"
	"    variable_3 = vec4(9.0, 10.0, 11.0, 12.0);\n"
	"    variable_4 = vec4(13.0, 14.0, 15.0, 16.0);\n"
	"\n"
	"    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::CaptureSpecialInterleaved::s_fragment_shader = "#version 130\n"
																							 "\n"
																							 "out vec4 pixel;\n"
																							 "\n"
																							 "void main()\n"
																							 "{\n"
																							 "    pixel = vec4(1.0);\n"
																							 "}\n";

const glw::GLchar* gl3cts::TransformFeedback::CaptureSpecialInterleaved::s_xfb_varyings[] =
	{ "variable_1", "gl_SkipComponents4", "variable_2", "gl_NextBuffer",
	  "variable_3", "gl_SkipComponents4", "variable_4" };

const glw::GLuint gl3cts::TransformFeedback::CaptureSpecialInterleaved::s_xfb_varyings_count =
	sizeof(s_xfb_varyings) / sizeof(s_xfb_varyings[0]);

const glw::GLuint gl3cts::TransformFeedback::CaptureSpecialInterleaved::s_bo_size =
	3 /*number of variables / empty places */ * 4 /* vec4 */
	* sizeof(glw::GLfloat);

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::DrawXFBStream::DrawXFBStream(deqp::Context& context, const char* test_name,
														const char* test_description)
	: deqp::TestCase(context, test_name, test_description)
	, m_context(context)
	, m_program_id_generate(0)
	, m_program_id_draw(0)
	, m_vao_id(0)
	, m_xfb_id(0)
	, m_fbo_id(0)
	, m_rbo_id(0)
{
	memset(m_bo_id, 0, sizeof(m_bo_id));
	memset(m_qo_id, 0, sizeof(m_qo_id));
}

gl3cts::TransformFeedback::DrawXFBStream::~DrawXFBStream(void)
{
}

tcu::TestNode::IterateResult gl3cts::TransformFeedback::DrawXFBStream::iterate(void)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Initializations. */
	bool is_at_least_gl_40  = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
	bool is_arb_tf_3		= m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback3");
	bool is_arb_gpu_shader5 = m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader5");

	glw::GLint max_vertex_streams = 0;

	bool is_ok		= true;
	bool test_error = false;

	/* Tests. */
	try
	{
		if (is_at_least_gl_40 || (is_arb_tf_3 && is_arb_gpu_shader5))
		{
			gl.getIntegerv(GL_MAX_VERTEX_STREAMS, &max_vertex_streams);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");

			if (max_vertex_streams >= 2)
			{
				prepareObjects();

				useProgram(m_program_id_generate);

				drawForXFB();

				is_ok = is_ok && inspectQueries();

				useProgram(m_program_id_draw);

				setupVertexArray(m_bo_id[0]);

				drawForFramebuffer(0);

				setupVertexArray(m_bo_id[1]);

				drawForFramebuffer(1);

				is_ok = is_ok && check();
			}
		}
	}
	catch (...)
	{
		is_ok	  = false;
		test_error = true;
	}

	/* Clean GL objects. */
	clean();

	/* Result's setup. */
	if (is_ok)
	{
		/* Log success. */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Stream have passed."
											<< tcu::TestLog::EndMessage;

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (test_error)
		{
			/* Log error. */
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Stream have approached error."
												<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			/* Log fail. */
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Stream have failed."
												<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

void gl3cts::TransformFeedback::DrawXFBStream::prepareObjects()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare programs. */
	m_program_id_generate = gl3cts::TransformFeedback::Utilities::buildProgram(
		gl, m_context.getTestContext().getLog(), s_geometry_shader, NULL, NULL, s_vertex_shader_blank,
		s_fragment_shader, s_xfb_varyings, s_xfb_varyings_count, GL_INTERLEAVED_ATTRIBS);

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

	m_program_id_draw = gl3cts::TransformFeedback::Utilities::buildProgram(
		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_pass, s_fragment_shader, NULL, 0,
		GL_INTERLEAVED_ATTRIBS);

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

	/* Prepare transform feedbacks. */
	gl.genTransformFeedbacks(1, &m_xfb_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");

	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedbacks call failed.");

	/* Create empty Vertex Array Object */
	gl.genVertexArrays(1, &m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

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

	/* Prepare buffer objects. */
	gl.genBuffers(s_bo_ids_count, m_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

	for (glw::GLuint i = 0; i < s_bo_ids_count; ++i)
	{
		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id[i]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, NULL, GL_DYNAMIC_COPY); /* allocation */
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

		gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_bo_id[i]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");
	}

	/* Generate queries */
	gl.genQueries(s_qo_ids_count, m_qo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries call failed.");

	/* Prepare framebuffer. */
	gl.clearColor(0.f, 0.f, 0.f, 1.f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");

	gl.genFramebuffers(1, &m_fbo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");

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

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

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

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, s_view_size, s_view_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");

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

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

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

void gl3cts::TransformFeedback::DrawXFBStream::setupVertexArray(glw::GLuint bo_id)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

	glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");

	gl.vertexAttribPointer(position_location, 4, GL_FLOAT, GL_FALSE, 0, NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");

	gl.enableVertexAttribArray(position_location);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
}

void gl3cts::TransformFeedback::DrawXFBStream::useProgram(glw::GLuint program_id)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

void gl3cts::TransformFeedback::DrawXFBStream::drawForXFB()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

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

	gl.beginQueryIndexed(GL_PRIMITIVES_GENERATED, 0, m_qo_id[0]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQueryIndexed call failed.");

	gl.beginQueryIndexed(GL_PRIMITIVES_GENERATED, 1, m_qo_id[1]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQueryIndexed call failed.");

	gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, 0, m_qo_id[2]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQueryIndexed call failed.");

	gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, 1, m_qo_id[3]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQueryIndexed call failed.");

	gl.drawArrays(GL_POINTS, 0, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");

	gl.endQueryIndexed(GL_PRIMITIVES_GENERATED, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQueryIndexed call failed.");

	gl.endQueryIndexed(GL_PRIMITIVES_GENERATED, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQueryIndexed call failed.");

	gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQueryIndexed call failed.");

	gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQueryIndexed call failed.");

	gl.endTransformFeedback();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");

	gl.disable(GL_RASTERIZER_DISCARD);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
}

void gl3cts::TransformFeedback::DrawXFBStream::drawForFramebuffer(glw::GLuint stream)
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.drawTransformFeedbackStream(GL_TRIANGLES, m_xfb_id, stream);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawTransformFeedbackStream call failed.");
}

bool gl3cts::TransformFeedback::DrawXFBStream::inspectQueries()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLint generated_primitives_to_stream_0 = 0;
	glw::GLint generated_primitives_to_stream_1 = 0;

	gl.getQueryObjectiv(m_qo_id[0], GL_QUERY_RESULT, &generated_primitives_to_stream_0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryIndexediv call failed.");

	gl.getQueryObjectiv(m_qo_id[1], GL_QUERY_RESULT, &generated_primitives_to_stream_1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryIndexediv call failed.");

	glw::GLint primitives_written_to_xfb_to_stream_0 = 0;
	glw::GLint primitives_written_to_xfb_to_stream_1 = 0;

	gl.getQueryObjectiv(m_qo_id[2], GL_QUERY_RESULT, &primitives_written_to_xfb_to_stream_0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryIndexediv call failed.");

	gl.getQueryObjectiv(m_qo_id[3], GL_QUERY_RESULT, &primitives_written_to_xfb_to_stream_1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryIndexediv call failed.");

	if ((generated_primitives_to_stream_0 == 3) && (generated_primitives_to_stream_1 == 3) &&
		(primitives_written_to_xfb_to_stream_0 == 3) && (primitives_written_to_xfb_to_stream_1 == 3))
	{
		return true;
	}

	return false;
}

bool gl3cts::TransformFeedback::DrawXFBStream::check()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Number of pixels. */
	const glw::GLuint number_of_pixels = s_view_size * s_view_size;

	/* Fetch framebuffer. */
	std::vector<glw::GLfloat> pixels(number_of_pixels);

	gl.readPixels(0, 0, s_view_size, s_view_size, GL_RED, GL_FLOAT, &pixels[0]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");

	/* Check results. */
	for (glw::GLuint i = 0; i < number_of_pixels; ++i)
	{
		if (fabs(pixels[i] - 1.f) > 0.0625 /* precision, expected result == 1.0 */)
		{
			return false;
		}
	}

	return true;
}

void gl3cts::TransformFeedback::DrawXFBStream::clean()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.useProgram(0);

	if (m_program_id_generate)
	{
		gl.deleteProgram(m_program_id_generate);

		m_program_id_generate = 0;
	}

	if (m_program_id_draw)
	{
		glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");

		gl.disableVertexAttribArray(position_location);

		gl.deleteProgram(m_program_id_draw);

		m_program_id_draw = 0;
	}

	if (m_xfb_id)
	{
		gl.deleteTransformFeedbacks(1, &m_xfb_id);

		m_xfb_id = 0;
	}

	for (glw::GLuint i = 0; i < s_bo_ids_count; ++i)
	{
		if (m_bo_id[i])
		{
			gl.deleteBuffers(1, &m_bo_id[i]);

			m_bo_id[i] = 0;
		}
	}

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

		m_vao_id = 0;
	}

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

		m_fbo_id = 0;
	}

	if (m_rbo_id)
	{
		gl.deleteRenderbuffers(1, &m_rbo_id);

		m_rbo_id = 0;
	}
}

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStream::s_vertex_shader_blank = "#version 130\n"
																					 "\n"
																					 "void main()\n"
																					 "{\n"
																					 "}\n";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStream::s_vertex_shader_pass = "#version 130\n"
																					"\n"
																					"in vec4 position;\n"
																					"\n"
																					"void main()\n"
																					"{\n"
																					"    gl_Position = position;\n"
																					"}\n";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStream::s_geometry_shader =
	"#version 400\n"
	"\n"
	"layout(points) in;\n"
	"layout(points, max_vertices = 6) out;\n"
	"\n"
	"layout(stream = 1) out vec4 position;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
	"    EmitStreamVertex(0);\n"
	"    gl_Position = vec4( 1.0, -1.0, 0.0, 1.0);\n"
	"    EmitStreamVertex(0);\n"
	"    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
	"    EmitStreamVertex(0);\n"
	"\n"
	"    position = vec4( 1.0, -1.0, 0.0, 1.0);\n"
	"    EmitStreamVertex(1);\n"
	"    position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
	"    EmitStreamVertex(1);\n"
	"    position = vec4( 1.0,  1.0, 0.0, 1.0);\n"
	"    EmitStreamVertex(1);\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStream::s_fragment_shader = "#version 130\n"
																				 "\n"
																				 "out vec4 pixel;\n"
																				 "\n"
																				 "void main()\n"
																				 "{\n"
																				 "    pixel = vec4(1.0);\n"
																				 "}\n";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStream::s_xfb_varyings[] = { "gl_Position", "gl_NextBuffer",
																				  "position" };

const glw::GLuint gl3cts::TransformFeedback::DrawXFBStream::s_xfb_varyings_count =
	sizeof(s_xfb_varyings) / sizeof(s_xfb_varyings[0]);

const glw::GLuint gl3cts::TransformFeedback::DrawXFBStream::s_bo_size =
	3 /* triangles */ * 4 /* vec4 */ * sizeof(glw::GLfloat);

const glw::GLuint gl3cts::TransformFeedback::DrawXFBStream::s_view_size = 2;

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::DrawXFBInstanced::DrawXFBInstanced(deqp::Context& context, const char* test_name,
															  const char* test_description)
	: deqp::TestCase(context, test_name, test_description)
	, m_context(context)
	, m_program_id_generate(0)
	, m_program_id_draw(0)
	, m_vao_id(0)
	, m_xfb_id(0)
	, m_bo_id_xfb(0)
	, m_bo_id_uniform(0)
	, m_fbo_id(0)
	, m_rbo_id(0)
	, m_glGetUniformBlockIndex(DE_NULL)
	, m_glUniformBlockBinding(DE_NULL)
{
}

gl3cts::TransformFeedback::DrawXFBInstanced::~DrawXFBInstanced(void)
{
}

tcu::TestNode::IterateResult gl3cts::TransformFeedback::DrawXFBInstanced::iterate(void)
{
	/* Initializations. */
	bool is_at_least_gl_42   = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 2)));
	bool is_at_least_gl_31   = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 1)));
	bool is_arb_tf_instanced = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback_instanced");
	bool is_arb_ubo			 = m_context.getContextInfo().isExtensionSupported("GL_ARB_uniform_buffer_object");

	bool is_ok		= true;
	bool test_error = false;

	if (is_arb_ubo)
	{
		m_glGetUniformBlockIndex =
			(GetUniformBlockIndex_ProcAddress)m_context.getRenderContext().getProcAddress("glGetUniformBlockIndex");

		m_glUniformBlockBinding =
			(UniformBlockBinding_ProcAddress)m_context.getRenderContext().getProcAddress("glUniformBlockBinding");

		if (DE_NULL == m_glGetUniformBlockIndex || DE_NULL == m_glUniformBlockBinding)
		{
			throw 0;
		}
	}

	try
	{
		if (is_at_least_gl_42 || ((is_at_least_gl_31 || is_arb_ubo) && is_arb_tf_instanced))
		{
			prepareObjects();
			drawForXFB();
			drawInstanced();

			is_ok = is_ok && check();
		}
	}
	catch (...)
	{
		is_ok	  = false;
		test_error = true;
	}

	/* Clean GL objects */
	clean();

	/* Result's setup. */
	if (is_ok)
	{
		/* Log success. */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Instanced have passed."
											<< tcu::TestLog::EndMessage;

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (test_error)
		{
			/* Log error. */
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Instanced have approached error."
												<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			/* Log fail. */
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Instanced have failed."
												<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

void gl3cts::TransformFeedback::DrawXFBInstanced::prepareObjects()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare programs. */
	m_program_id_generate = gl3cts::TransformFeedback::Utilities::buildProgram(
		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_generate, s_fragment_shader,
		&s_xfb_varying, 1, GL_INTERLEAVED_ATTRIBS);

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

	m_program_id_draw = gl3cts::TransformFeedback::Utilities::buildProgram(
		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_draw, s_fragment_shader, NULL, 0,
		GL_INTERLEAVED_ATTRIBS);

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

	/* Prepare transform feedbacks. */
	gl.genTransformFeedbacks(1, &m_xfb_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");

	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedbacks call failed.");

	/* Create empty Vertex Array Object */
	gl.genVertexArrays(1, &m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

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

	/* Prepare xfb buffer object. */
	gl.genBuffers(1, &m_bo_id_xfb);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

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

	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_xfb_size, NULL, GL_DYNAMIC_COPY); /* allocation */
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_id_xfb);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");

	/* Prepare uniform buffer object. */
	gl.genBuffers(1, &m_bo_id_uniform);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

	gl.bindBuffer(GL_UNIFORM_BUFFER, m_bo_id_uniform);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

	gl.bufferData(GL_UNIFORM_BUFFER, s_bo_uniform_size, s_bo_uniform_data, GL_DYNAMIC_COPY); /* allocation */
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

	gl.bindBufferBase(GL_UNIFORM_BUFFER, 0, m_bo_id_uniform);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");

	glw::GLuint uniform_index = m_glGetUniformBlockIndex(m_program_id_draw, s_uniform);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformBlockIndex call failed.");

	if (GL_INVALID_INDEX == uniform_index)
	{
		throw 0;
	}

	m_glUniformBlockBinding(m_program_id_draw, uniform_index, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformBlockBinding call failed.");

	/* Prepare framebuffer. */
	gl.clearColor(0.f, 0.f, 0.f, 1.f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");

	gl.genFramebuffers(1, &m_fbo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");

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

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

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

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, s_view_size, s_view_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");

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

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

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

void gl3cts::TransformFeedback::DrawXFBInstanced::drawForXFB()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

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

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

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

	gl.endTransformFeedback();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");

	gl.disable(GL_RASTERIZER_DISCARD);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
}

void gl3cts::TransformFeedback::DrawXFBInstanced::drawInstanced()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

	glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");

	gl.vertexAttribPointer(position_location, 4, GL_FLOAT, GL_FALSE, 0, NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");

	gl.enableVertexAttribArray(position_location);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

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

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

	gl.drawTransformFeedbackInstanced(GL_TRIANGLE_STRIP, m_xfb_id, 4);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
}

bool gl3cts::TransformFeedback::DrawXFBInstanced::check()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Number of pixels. */
	const glw::GLuint number_of_pixels = s_view_size * s_view_size;

	/* Fetch framebuffer. */
	std::vector<glw::GLfloat> pixels(number_of_pixels);

	gl.readPixels(0, 0, s_view_size, s_view_size, GL_RED, GL_FLOAT, &pixels[0]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");

	/* Check results. */
	for (glw::GLuint i = 0; i < number_of_pixels; ++i)
	{
		if (fabs(pixels[i] - 1.f) > 0.0625 /* precision, expected result == 1.0 */)
		{
			return false;
		}
	}

	return true;
}

void gl3cts::TransformFeedback::DrawXFBInstanced::clean()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.useProgram(0);

	if (m_program_id_generate)
	{
		gl.deleteProgram(m_program_id_generate);

		m_program_id_generate = 0;
	}

	if (m_program_id_draw)
	{
		glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");

		gl.disableVertexAttribArray(position_location);

		gl.deleteProgram(m_program_id_draw);

		m_program_id_draw = 0;
	}

	if (m_xfb_id)
	{
		gl.deleteTransformFeedbacks(1, &m_xfb_id);

		m_xfb_id = 0;
	}

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

		m_bo_id_xfb = 0;
	}

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

		m_bo_id_uniform = 0;
	}

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

		m_vao_id = 0;
	}

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

		m_fbo_id = 0;
	}

	if (m_rbo_id)
	{
		gl.deleteRenderbuffers(1, &m_rbo_id);

		m_rbo_id = 0;
	}
}

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBInstanced::s_vertex_shader_generate =
	"#version 140\n"
	"\n"
	"void main()\n"
	"{\n"
	"    switch(gl_VertexID % 4)\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";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBInstanced::s_vertex_shader_draw =
	"#version 140\n"
	"\n"
	"uniform MatrixBlock\n"
	"{\n"
	"    mat4 transformation_0;\n"
	"    mat4 transformation_1;\n"
	"    mat4 transformation_2;\n"
	"    mat4 transformation_3;\n"
	"};\n"
	"\n"
	"in vec4 position;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    switch(gl_InstanceID % 4)\n"
	"    {\n"
	"    case 0:\n"
	"       gl_Position = position * transformation_0;\n"
	"       break;\n"
	"    case 1:\n"
	"       gl_Position = position * transformation_1;\n"
	"       break;\n"
	"    case 2:\n"
	"       gl_Position = position * transformation_2;\n"
	"       break;\n"
	"    case 3:\n"
	"       gl_Position = position * transformation_3;\n"
	"       break;\n"
	"    }\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBInstanced::s_fragment_shader = "#version 130\n"
																					"\n"
																					"out vec4 pixel;\n"
																					"\n"
																					"void main()\n"
																					"{\n"
																					"    pixel = vec4(1.0);\n"
																					"}\n";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBInstanced::s_xfb_varying = "gl_Position";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBInstanced::s_uniform = "MatrixBlock";

const glw::GLuint gl3cts::TransformFeedback::DrawXFBInstanced::s_bo_xfb_size =
	4 /* vertex count */ * 4 /* vec4 components */
	* sizeof(glw::GLfloat) /* data type size */;

const glw::GLfloat gl3cts::TransformFeedback::DrawXFBInstanced::s_bo_uniform_data[] = {
	0.5f, 0.0f, 0.0f, 0.5f,  0.0f, 0.5f, 0.0f, 0.5f,  0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,

	0.5f, 0.0f, 0.0f, -0.5f, 0.0f, 0.5f, 0.0f, 0.5f,  0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,

	0.5f, 0.0f, 0.0f, -0.5f, 0.0f, 0.5f, 0.0f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,

	0.5f, 0.0f, 0.0f, 0.5f,  0.0f, 0.5f, 0.0f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
};

const glw::GLuint gl3cts::TransformFeedback::DrawXFBInstanced::s_bo_uniform_size = sizeof(s_bo_uniform_data);

const glw::GLuint gl3cts::TransformFeedback::DrawXFBInstanced::s_view_size = 4;

/*-----------------------------------------------------------------------------------------------*/

gl3cts::TransformFeedback::DrawXFBStreamInstanced::DrawXFBStreamInstanced(deqp::Context& context, const char* test_name,
																		  const char* test_description)
	: deqp::TestCase(context, test_name, test_description)
	, m_context(context)
	, m_program_id_generate(0)
	, m_program_id_draw(0)
	, m_vao_id(0)
	, m_xfb_id(0)
	, m_bo_id_xfb_position(0)
	, m_bo_id_xfb_color(0)
	, m_bo_id_uniform(0)
	, m_fbo_id(0)
	, m_rbo_id(0)
	, m_glGetUniformBlockIndex(DE_NULL)
	, m_glUniformBlockBinding(DE_NULL)
{
}

gl3cts::TransformFeedback::DrawXFBStreamInstanced::~DrawXFBStreamInstanced(void)
{
}

tcu::TestNode::IterateResult gl3cts::TransformFeedback::DrawXFBStreamInstanced::iterate(void)
{
	/* Initializations. */
	bool is_at_least_gl_31   = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 1)));
	bool is_at_least_gl_40   = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
	bool is_at_least_gl_42   = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 2)));
	bool is_arb_tf_instanced = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback_instanced");
	bool is_arb_ubo			 = m_context.getContextInfo().isExtensionSupported("GL_ARB_uniform_buffer_object");
	bool is_arb_gpu_shader5  = m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader5");

	bool is_ok		= true;
	bool test_error = false;

	if (is_arb_ubo)
	{
		m_glGetUniformBlockIndex =
			(GetUniformBlockIndex_ProcAddress)m_context.getRenderContext().getProcAddress("glGetUniformBlockIndex");

		m_glUniformBlockBinding =
			(UniformBlockBinding_ProcAddress)m_context.getRenderContext().getProcAddress("glUniformBlockBinding");

		if (DE_NULL == m_glGetUniformBlockIndex || DE_NULL == m_glUniformBlockBinding)
		{
			throw 0;
		}
	}

	/* Test. */
	try
	{
		if (is_at_least_gl_42 || ((is_at_least_gl_31 || is_arb_ubo) && is_arb_gpu_shader5 && is_arb_tf_instanced) ||
			(is_at_least_gl_40 && is_arb_tf_instanced))
		{
			prepareObjects();
			drawForXFB();
			drawStreamInstanced();

			is_ok = is_ok && check();
		}
	}
	catch (...)
	{
		is_ok	  = false;
		test_error = true;
	}

	/* Clean GL objects */
	clean();

	/* Result's setup. */
	if (is_ok)
	{
		/* Log success. */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Stream Instanced have passed."
											<< tcu::TestLog::EndMessage;

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (test_error)
		{
			/* Log error. */
			m_context.getTestContext().getLog() << tcu::TestLog::Message
												<< "Draw XFB Stream Instanced have approached error."
												<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			/* Log fail. */
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Stream Instanced have failed."
												<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

void gl3cts::TransformFeedback::DrawXFBStreamInstanced::prepareObjects()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare programs. */
	m_program_id_generate = gl3cts::TransformFeedback::Utilities::buildProgram(
		gl, m_context.getTestContext().getLog(), s_geometry_shader_generate, NULL, NULL, s_vertex_shader_blank,
		s_fragment_shader_blank, s_xfb_varyings, s_xfb_varyings_count, GL_INTERLEAVED_ATTRIBS);

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

	m_program_id_draw = gl3cts::TransformFeedback::Utilities::buildProgram(
		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_draw, s_fragment_shader_draw, NULL,
		0, GL_INTERLEAVED_ATTRIBS);

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

	/* Prepare transform feedbacks. */
	gl.genTransformFeedbacks(1, &m_xfb_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");

	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedbacks call failed.");

	/* Create empty Vertex Array Object */
	gl.genVertexArrays(1, &m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

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

	/* Prepare xfb buffer objects. */
	gl.genBuffers(1, &m_bo_id_xfb_position);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

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

	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_xfb_size, NULL, GL_DYNAMIC_COPY); /* allocation */
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_id_xfb_position);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");

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

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

	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_xfb_size, NULL, GL_DYNAMIC_COPY); /* allocation */
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 1, m_bo_id_xfb_color);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");

	/* Prepare uniform buffer object. */
	gl.genBuffers(1, &m_bo_id_uniform);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

	gl.bindBuffer(GL_UNIFORM_BUFFER, m_bo_id_uniform);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

	gl.bufferData(GL_UNIFORM_BUFFER, s_bo_uniform_size, s_bo_uniform_data, GL_DYNAMIC_COPY); /* allocation */
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

	gl.bindBufferBase(GL_UNIFORM_BUFFER, 0, m_bo_id_uniform);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");

	glw::GLuint uniform_index = m_glGetUniformBlockIndex(m_program_id_draw, s_uniform);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformBlockIndex call failed.");

	if (GL_INVALID_INDEX == uniform_index)
	{
		throw 0;
	}

	m_glUniformBlockBinding(m_program_id_draw, uniform_index, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformBlockBinding call failed.");

	/* Prepare framebuffer. */
	gl.clearColor(0.f, 0.f, 0.f, 1.f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");

	gl.genFramebuffers(1, &m_fbo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");

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

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

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

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, s_view_size, s_view_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");

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

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

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

void gl3cts::TransformFeedback::DrawXFBStreamInstanced::drawForXFB()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

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

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

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

	gl.endTransformFeedback();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");

	gl.disable(GL_RASTERIZER_DISCARD);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
}

void gl3cts::TransformFeedback::DrawXFBStreamInstanced::drawStreamInstanced()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

	glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");

	gl.vertexAttribPointer(position_location, 4, GL_FLOAT, GL_FALSE, 0, NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");

	gl.enableVertexAttribArray(position_location);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

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

	glw::GLuint color_location = gl.getAttribLocation(m_program_id_draw, "color");
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");

	gl.vertexAttribPointer(color_location, 4, GL_FLOAT, GL_FALSE, 0, NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");

	gl.enableVertexAttribArray(color_location);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

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

	gl.drawTransformFeedbackStreamInstanced(GL_TRIANGLE_STRIP, m_xfb_id, 0, 4);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
}

bool gl3cts::TransformFeedback::DrawXFBStreamInstanced::check()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Number of pixels. */
	const glw::GLuint number_of_pixels = s_view_size * s_view_size;

	/* Fetch framebuffer. */
	std::vector<glw::GLfloat> pixels(number_of_pixels);

	gl.readPixels(0, 0, s_view_size, s_view_size, GL_RED, GL_FLOAT, &pixels[0]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");

	/* Check results. */
	for (glw::GLuint i = 0; i < number_of_pixels; ++i)
	{
		if (fabs(pixels[i] - 1.f) > 0.0625 /* precision, expected result == 1.0 */)
		{
			return false;
		}
	}

	return true;
}

void gl3cts::TransformFeedback::DrawXFBStreamInstanced::clean()
{
	/* Functions handler */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.useProgram(0);

	if (m_program_id_generate)
	{
		gl.deleteProgram(m_program_id_generate);

		m_program_id_generate = 0;
	}

	if (m_program_id_draw)
	{
		glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");

		gl.disableVertexAttribArray(position_location);

		glw::GLuint color_location = gl.getAttribLocation(m_program_id_draw, "color");

		gl.disableVertexAttribArray(color_location);

		gl.deleteProgram(m_program_id_draw);

		m_program_id_draw = 0;
	}

	if (m_xfb_id)
	{
		gl.deleteTransformFeedbacks(1, &m_xfb_id);

		m_xfb_id = 0;
	}

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

		m_bo_id_xfb_position = 0;
	}

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

		m_bo_id_xfb_position = 0;
	}

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

		m_bo_id_uniform = 0;
	}

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

		m_vao_id = 0;
	}

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

		m_fbo_id = 0;
	}

	if (m_rbo_id)
	{
		gl.deleteRenderbuffers(1, &m_rbo_id);

		m_rbo_id = 0;
	}
}

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_vertex_shader_blank = "#version 140\n"
																							  "\n"
																							  "void main()\n"
																							  "{\n"
																							  "}\n";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_geometry_shader_generate =
	"#version 400\n"
	"\n"
	"layout(points) in;\n"
	"layout(points, max_vertices = 8) out;\n"
	"\n"
	"layout(stream = 1) out vec4 color;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
	"    EmitStreamVertex(0);\n"
	"    gl_Position = vec4( 1.0, -1.0, 0.0, 1.0);\n"
	"    EmitStreamVertex(0);\n"
	"    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
	"    EmitStreamVertex(0);\n"
	"    gl_Position = vec4( 1.0,  1.0, 0.0, 1.0);\n"
	"    EmitStreamVertex(0);\n"
	"\n"
	"    color = vec4(1.0, 1.0, 1.0, 1.0);\n"
	"    EmitStreamVertex(1);\n"
	"    color = vec4(1.0, 1.0, 1.0, 1.0);\n"
	"    EmitStreamVertex(1);\n"
	"    color = vec4(1.0, 1.0, 1.0, 1.0);\n"
	"    EmitStreamVertex(1);\n"
	"    color = vec4(1.0, 1.0, 1.0, 1.0);\n"
	"    EmitStreamVertex(1);\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_vertex_shader_draw =
	"#version 140\n"
	"\n"
	"uniform MatrixBlock\n"
	"{\n"
	"    mat4 transformation_0;\n"
	"    mat4 transformation_1;\n"
	"    mat4 transformation_2;\n"
	"    mat4 transformation_3;\n"
	"};\n"
	"\n"
	"in  vec4 position;\n"
	"in  vec4 color;\n"
	"out vec4 colour;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    switch(gl_InstanceID % 4)\n"
	"    {\n"
	"    case 0:\n"
	"       gl_Position = position * transformation_0;\n"
	"       break;\n"
	"    case 1:\n"
	"       gl_Position = position * transformation_1;\n"
	"       break;\n"
	"    case 2:\n"
	"       gl_Position = position * transformation_2;\n"
	"       break;\n"
	"    case 3:\n"
	"       gl_Position = position * transformation_3;\n"
	"       break;\n"
	"    }\n"
	"    colour = color;\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_fragment_shader_blank =
	"#version 130\n"
	"\n"
	"out vec4 pixel;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    pixel = vec4(1.0);\n"
	"}\n";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_fragment_shader_draw = "#version 130\n"
																							   "\n"
																							   "in vec4 colour;\n"
																							   "out vec4 pixel;\n"
																							   "\n"
																							   "void main()\n"
																							   "{\n"
																							   "    pixel = colour;\n"
																							   "}\n";

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_xfb_varyings[] = { "gl_Position",
																						   "gl_NextBuffer", "color" };

const glw::GLuint gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_xfb_varyings_count =
	sizeof(s_xfb_varyings) / sizeof(s_xfb_varyings[0]);

const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_uniform = "MatrixBlock";

const glw::GLuint gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_bo_xfb_size =
	4 /* vertex count */ * 4 /* vec4 components */
	* sizeof(glw::GLfloat) /* data type size */;

const glw::GLfloat gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_bo_uniform_data[] = {
	0.5f, 0.0f, 0.0f, 0.5f,  0.0f, 0.5f, 0.0f, 0.5f,  0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,

	0.5f, 0.0f, 0.0f, -0.5f, 0.0f, 0.5f, 0.0f, 0.5f,  0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,

	0.5f, 0.0f, 0.0f, -0.5f, 0.0f, 0.5f, 0.0f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,

	0.5f, 0.0f, 0.0f, 0.5f,  0.0f, 0.5f, 0.0f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
};

const glw::GLuint gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_bo_uniform_size = sizeof(s_bo_uniform_data);

const glw::GLuint gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_view_size = 4;

/*-----------------------------------------------------------------------------------------------*/

glw::GLuint gl3cts::TransformFeedback::Utilities::buildProgram(
	glw::Functions const& gl, tcu::TestLog& log, glw::GLchar const* const geometry_shader_source,
	glw::GLchar const* const tessellation_control_shader_source,
	glw::GLchar const* const tessellation_evaluation_shader_source, glw::GLchar const* const vertex_shader_source,
	glw::GLchar const* const fragment_shader_source, glw::GLchar const* const* const transform_feedback_varyings,
	glw::GLsizei const transform_feedback_varyings_count, glw::GLenum const transform_feedback_varyings_mode,
	bool const do_not_detach, glw::GLint* linking_status)
{
	glw::GLuint program = 0;

	struct Shader
	{
		glw::GLchar const* const source;
		glw::GLenum const		 type;
		glw::GLuint				 id;
	} shader[] = { { geometry_shader_source, GL_GEOMETRY_SHADER, 0 },
				   { tessellation_control_shader_source, GL_TESS_CONTROL_SHADER, 0 },
				   { tessellation_evaluation_shader_source, GL_TESS_EVALUATION_SHADER, 0 },
				   { vertex_shader_source, GL_VERTEX_SHADER, 0 },
				   { fragment_shader_source, GL_FRAGMENT_SHADER, 0 } };

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

	try
	{
		/* Create program. */
		program = 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(program, 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]);

					log << 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;
				}
			}
		}

		/* Link. */
		if (transform_feedback_varyings_count)
		{
			gl.transformFeedbackVaryings(program, transform_feedback_varyings_count, transform_feedback_varyings,
										 transform_feedback_varyings_mode);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
		}

		gl.linkProgram(program);

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

		glw::GLint status = GL_FALSE;

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

		if (DE_NULL != linking_status)
		{
			*linking_status = status;
		}

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

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

			gl.getProgramiv(program, 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(program, log_size, NULL, &log_text[0]);

			log << 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 (program)
		{
			gl.deleteProgram(program);

			program = 0;
		}
	}

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

			shader[i].id = 0;
		}
	}

	return program;
}

/** @brief Substitute key with value within source code.
 *
 *  @param [in] source      Source code to be prerocessed.
 *  @param [in] key         Key to be substituted.
 *  @param [in] value       Value to be inserted.
 *
 *  @return Resulting string.
 */
std::string gl3cts::TransformFeedback::Utilities::preprocessCode(std::string source, std::string key, std::string value)
{
	std::string destination = source;

	while (true)
	{
		/* Find token in source code. */
		size_t position = destination.find(key, 0);

		/* No more occurences of this key. */
		if (position == std::string::npos)
		{
			break;
		}

		/* Replace token with sub_code. */
		destination.replace(position, key.size(), value);
	}

	return destination;
}

/** @brief Convert an integer to a string.
 *
 *  @param [in] i       Integer to be converted.
 *
 *  @return String representing integer.
 */
std::string gl3cts::TransformFeedback::Utilities::itoa(glw::GLint i)
{
	std::stringstream stream;

	stream << i;

	return stream.str();
}

/** @brief Convert an float to a string.
 *
 *  @param [in] f       Float to be converted.
 *
 *  @return String representing integer.
 */
std::string gl3cts::TransformFeedback::Utilities::ftoa(glw::GLfloat f)
{
	std::stringstream stream;

	stream << f;

	return stream.str();
}
