/*-------------------------------------------------------------------------
 * 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_33 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 3)));
	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);

		is_ok = is_ok && m_program_id_with_input_output && m_program_id_with_output && m_program_id_without_output;

		if (is_at_least_gl_33) {
			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);

			is_ok = is_ok && m_program_id_with_geometry_shader;
		}

        if (is_at_least_gl_40) {
			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_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();

	bool is_at_least_gl_40 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
	bool is_tessellation = m_context.getContextInfo().isExtensionSupported("GL_ARB_tessellation_shader");

	bool has_patches = is_at_least_gl_40 || is_tessellation;

	/*  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_QUADS,
									  GL_PATCHES };

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

	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;
	}

	if (m_program_id_with_geometry_shader != 0) {
		/*  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;
		}
	}

	/* All of the below tests concern themselves with GL_PATCHES and
	 * tessellation shaders */
	if (m_program_id_with_tessellation_shaders == 0)
	{
		return true;
	}

	/*  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)
	{
		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)
	{
		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)
	{
		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)
	{
		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();
}
