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

#include "esextcTessellationShaderUtils.hpp"
#include "deMath.h"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuTestLog.hpp"
#include <sstream>

namespace glcts
{

/** Constructor
 *
 *  @param gl         DEQP container for ES entry-points
 *  @param parentTest Pointer to owning test instance.
 **/
TessellationShaderUtils::TessellationShaderUtils(const glw::Functions& gl, glcts::TestCaseBase* parentTest)
	: m_gl(gl), m_bo_id(0), m_fs_id(0), m_qo_pg_id(0), m_vs_id(0), m_parent_test(parentTest)
{
	init();
}

/** Destructor */
TessellationShaderUtils::~TessellationShaderUtils()
{
	deinit();
}

/** Captures data generated by the tessellator when a geometry is drawn
 *  for user-provided vertex counter program.
 *
 *  @param program Vertex counter program to use.
 **/
void TessellationShaderUtils::captureTessellationData(_tessellation_vertex_counter_program& program)
{
	/* Cache current program object ID before we continue */
	glw::GLint current_po_id = 0;

	m_gl.getIntegerv(GL_CURRENT_PROGRAM, &current_po_id);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetIntegerv() failed for GL_CURRENT_PROGRAM pname");

	/* Cache current GL_PATCH_VERTICES_EXT setting before continuing */
	glw::GLint current_patch_vertices = 0;

	m_gl.getIntegerv(GL_PATCH_VERTICES, &current_patch_vertices);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetIntegerv() failed for GL_PATCH_VERTICES_EXT pname");

	/* Activate the program object and the query object */
	m_gl.useProgram(program.po_id);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() failed");

	m_gl.beginQuery(m_parent_test->m_glExtTokens.PRIMITIVES_GENERATED, m_qo_pg_id);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBeginQuery() called for target GL_PRIMITIVES_GENERATED_EXT failed");

	/* Disable rasterization, if it's enabled */
	glw::GLboolean is_rasterization_disabled = m_gl.isEnabled(GL_RASTERIZER_DISCARD);

	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glIsEnabled(GL_RASTERIZER_DISCARD) failed");

	if (is_rasterization_disabled)
	{
		m_gl.enable(GL_RASTERIZER_DISCARD);

		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) failed");
	}

	/* Update GL_PATCH_VERTICES_EXT */
	m_gl.patchParameteri(m_parent_test->m_glExtTokens.PATCH_VERTICES, program.n_patch_vertices);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glPatchParameteriEXT() failed");

	/* Draw the test geometry */
	m_gl.drawArrays(m_parent_test->m_glExtTokens.PATCHES, 0, /* first */
					program.n_patch_vertices);				 /* count */
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawArrays() failed");

	/* End the query and retrieve the result */
	glw::GLuint queryValue = 0;

	m_gl.endQuery(m_parent_test->m_glExtTokens.PRIMITIVES_GENERATED);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glEndQuery(GL_PRIMITIVES_GENERATED_EXT) failed");

	m_gl.getQueryObjectuiv(m_qo_pg_id, GL_QUERY_RESULT, &queryValue);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetQueryiv() failed");

	/* Store amount of primitives under result */
	program.n_data_vertices = ((unsigned int)queryValue);

	if (!program.is_point_mode_enabled)
	{
		/* Quads get tessellated into triangles, meaning our primitives counter tells how
		 * many triangles were generated for both triangles and quads; isolines get
		 * tessellated into line segments.
		 */
		if (program.primitive_mode == TESSELLATION_SHADER_PRIMITIVE_MODE_QUADS ||
			program.primitive_mode == TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES)
		{
			program.n_data_vertices *= 3; /* each triangle gets 3 vertices */
		}
		else
		{
			program.n_data_vertices *= 2; /* each isoline gets 2 vertices */
		}
	} /* if (!is_point_mode_enabled) */

	if (program.n_data_vertices != 0)
	{
		/* Now that we now, how many vertices we need to allocate space for, set up TF */
		glw::GLint bo_size = static_cast<glw::GLint>(sizeof(float) * 3 /* components */ * program.n_data_vertices);

		m_gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer() failed");

		m_gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_bo_id);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBufferBase() failed");

		m_gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bo_size, DE_NULL, /* data */
						GL_STATIC_DRAW);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferData() failed");

		/* Set up TF */
		glw::GLenum tf_mode =
			TessellationShaderUtils::getTFModeForPrimitiveMode(program.primitive_mode, program.is_point_mode_enabled);

		m_gl.beginTransformFeedback(tf_mode);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBeginTransformFeedback() failed");

		m_gl.drawArrays(m_parent_test->m_glExtTokens.PATCHES, 0, /* first */
						program.n_patch_vertices);				 /* count */
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawArrays() failed");

		m_gl.endTransformFeedback();
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glEndTransformFeedback() failed");

		/* Map the BO and copy the contents */
		const void* xfb_data = m_gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, /* offset */
												   bo_size, GL_MAP_READ_BIT);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMapBufferRange() failed");

		program.m_data.resize(bo_size);

		memcpy(&program.m_data[0], xfb_data, bo_size);

		m_gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUnmapBuffer() failed");
	} /* if (program.n_data_vertices != 0) */

	/* Bring the rasterization back up, if it was enabled prior to this call */
	if (!is_rasterization_disabled)
	{
		m_gl.disable(GL_RASTERIZER_DISCARD);

		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDisable(GL_RASTERIZER_DISCARD) failed");
	}

	/* Activate the pre-call program object*/
	m_gl.useProgram(current_po_id);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() failed");

	/* Bring back pre-call GL_PATCH_VERTICES_EXT setting */
	m_gl.patchParameteri(m_parent_test->m_glExtTokens.PATCH_VERTICES, current_patch_vertices);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glPatchParameteriEXT() failed");
}

/** Compiles all requested shaders. Should any of the shaders not compile,
 *  TestError exception can be thrown if @param should_succeed is set to true.
 *
 *  @param n_shaders      Amount of shader IDs passed in @param shaders argument.
 *  @param shaders        IDs of shader objects to compile.
 *  @param should_succeed True if the shaders are expected to compile, false if
 *                        it's fine for them to not to compile successfully.
 **/
void TessellationShaderUtils::compileShaders(glw::GLint n_shaders, const glw::GLuint* shaders, bool should_succeed)
{
	for (glw::GLint n_shader = 0; n_shader < n_shaders; ++n_shader)
	{
		glw::GLuint shader = shaders[n_shader];

		if (shader != 0)
		{
			glw::GLint compile_status = GL_FALSE;

			m_gl.compileShader(shader);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCompileShader() failed");

			m_gl.getShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetShaderiv() failed");

			if (should_succeed && compile_status != GL_TRUE)
			{
				std::string info_log	  = m_parent_test->getCompilationInfoLog(shader);
				std::string shader_source = m_parent_test->getShaderSource(shader);

				m_parent_test->m_context.getTestContext().getLog() << tcu::TestLog::Message
																   << "Compilation failure:\n\n"
																   << info_log << "\n\n"
																   << "Source:\n\n"
																   << shader_source << "\n\n"
																   << tcu::TestLog::EndMessage;
				TCU_FAIL("Shader compilation failed");
			}
			else if (!should_succeed && compile_status == GL_TRUE)
			{
				std::string shader_source = m_parent_test->getShaderSource(shader);
				m_parent_test->m_context.getTestContext().getLog() << tcu::TestLog::Message
																   << "Compilation failure expected.\nSource:\n\n"
																   << shader_source << "\n\n"
																   << tcu::TestLog::EndMessage;
				TCU_FAIL("Shader compiled successfully, even though it was "
						 "expected to fail.");
			}
		}
	} /* for (all shaders) */
}

/** Converts input barycentric coordinates to Cartesian coordinate system. The function assumes
 *  a triangle basis built of the following verticeS: (0.5, 0), (1, 1), (0, 1).
 *
 *  @param barycentric_coordinates   Three FP values storing barycentric coordinates of a point. Must
 *                                   NOT be NULL.
 *  @param out_cartesian_coordinates Deref will be used to store two result FP values. Must not be NULL.
 **/
void TessellationShaderUtils::convertBarycentricCoordinatesToCartesian(const float* barycentric_coordinates,
																	   float*		out_cartesian_coordinates)
{
	/* Assume output triangle uses the following base:
	 *
	 * (0.5, 0)
	 * (1,   1)
	 * (0,   1)
	 */
	const float triangle_vertex1_cartesian[2] = { 0.5f, 0.0f };
	const float triangle_vertex2_cartesian[2] = { 1.0f, 1.0f };
	const float triangle_vertex3_cartesian[2] = { 0.0f, 1.0f };

	out_cartesian_coordinates[0] = (float)((double)barycentric_coordinates[0] * (double)triangle_vertex1_cartesian[0] +
										   (double)barycentric_coordinates[1] * (double)triangle_vertex2_cartesian[0] +
										   (double)barycentric_coordinates[2] * (double)triangle_vertex3_cartesian[0]);
	out_cartesian_coordinates[1] = barycentric_coordinates[0] * triangle_vertex1_cartesian[1] +
								   barycentric_coordinates[1] * triangle_vertex2_cartesian[1] +
								   barycentric_coordinates[2] * triangle_vertex3_cartesian[1];
}

/** Converts input Cartesian coordinates to barycentric coordinate system. The function assumes
 *  a triangle basis built of the following verticeS: (0.5, 0), (1, 1), (0, 1).
 *
 *  @param cartesian_coordinates       Two FP values storing Cartesian coordinates of a point. Must NOT
 *                                     be NULL.
 *  @param out_barycentric_coordinates Deref will be used to store three result FP values. Must NOT be NULL.
 **/
void TessellationShaderUtils::convertCartesianCoordinatesToBarycentric(const float* cartesian_coordinates,
																	   float*		out_barycentric_coordinates)
{
	/* Assume input triangle uses the following base:
	 *
	 * (0.5, 0)
	 * (1,   1)
	 * (0,   1)
	 */
	const float x1 = 0.5f;
	const float x2 = 1.0f;
	const float x3 = 0.0f;
	const float y1 = 0.0f;
	const float y2 = 1.0f;
	const float y3 = 1.0f;

	out_barycentric_coordinates[0] =
		((y2 - y3) * (cartesian_coordinates[0] - x3) + (x3 - x2) * (cartesian_coordinates[1] - y3)) /
		((y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3));
	out_barycentric_coordinates[1] =
		((y3 - y1) * (cartesian_coordinates[0] - x3) + (x1 - x3) * (cartesian_coordinates[1] - y3)) /
		((y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3));
	out_barycentric_coordinates[2] = 1.0f - out_barycentric_coordinates[0] - out_barycentric_coordinates[1];
}

/** Deinitializes ES objects created for TessellationShaderUtils
 *  instance.
 **/
void TessellationShaderUtils::deinit()
{
	if (!m_parent_test->m_is_tessellation_shader_supported)
	{
		return;
	}

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

		m_bo_id = 0;
	}

	if (m_fs_id != 0)
	{
		m_gl.deleteShader(m_fs_id);

		m_fs_id = 0;
	}

	if (m_qo_pg_id != 0)
	{
		m_gl.deleteQueries(1, &m_qo_pg_id);

		m_qo_pg_id = 0;
	}

	if (m_vs_id != 0)
	{
		m_gl.deleteShader(m_vs_id);

		m_vs_id = 0;
	}

	/* Revert TF buffer object bindings */
	m_gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* buffer */);
	m_gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, 0 /* buffer */);

	/* Disable GL_RASTERIZER_DISCARD mode */
	m_gl.disable(GL_RASTERIZER_DISCARD);

	/* Restore GL_PATCH_VERTICES_EXT value */
	m_gl.patchParameteri(m_parent_test->m_glExtTokens.PATCH_VERTICES, 3);
}

/** Retrieves generic tessellation control shader source code.
 *  The shader users user-specified amount of output patch vertices and:
 *
 *  - sets gl_Position to gl_in[0].gl_Position if second argument is set to false.
 *  - sets gl_Position to gl_in[gl_InvocationID].gl_Position otherwise.
 *
 *  @param n_patch_vertices                        Amount of output patch vertices
 *                                                 to use in the shader.
 *  @param should_use_glInvocationID_indexed_input See above.
 *
 *  @return Requested string.
 */
std::string TessellationShaderUtils::getGenericTCCode(unsigned int n_patch_vertices,
													  bool		   should_use_glInvocationID_indexed_input)
{
	std::string result;
	const char* tc_body_false = "${VERSION}\n"
								"\n"
								"${TESSELLATION_SHADER_REQUIRE}\n"
								"\n"
								"layout (vertices = MAX_VERTICES) out;\n"
								"\n"
								"uniform vec2 inner_tess_level;\n"
								"uniform vec4 outer_tess_level;\n"
								"\n"
								"void main()\n"
								"{\n"
								"    gl_out[gl_InvocationID].gl_Position = gl_in[0].gl_Position;\n"
								"\n"
								"    gl_TessLevelInner[0] = inner_tess_level.x;\n"
								"    gl_TessLevelInner[1] = inner_tess_level.y;\n"
								"    gl_TessLevelOuter[0] = outer_tess_level.x;\n"
								"    gl_TessLevelOuter[1] = outer_tess_level.y;\n"
								"    gl_TessLevelOuter[2] = outer_tess_level.z;\n"
								"    gl_TessLevelOuter[3] = outer_tess_level.w;\n"
								"}\n";

	const char* tc_body_true = "${VERSION}\n"
							   "\n"
							   "${TESSELLATION_SHADER_REQUIRE}\n"
							   "\n"
							   "layout (vertices = MAX_VERTICES) out;\n"
							   "\n"
							   "uniform vec2 inner_tess_level;\n"
							   "uniform vec4 outer_tess_level;\n"
							   "\n"
							   "void main()\n"
							   "{\n"
							   "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
							   "\n"
							   "    gl_TessLevelInner[0] = inner_tess_level.x;\n"
							   "    gl_TessLevelInner[1] = inner_tess_level.y;\n"
							   "    gl_TessLevelOuter[0] = outer_tess_level.x;\n"
							   "    gl_TessLevelOuter[1] = outer_tess_level.y;\n"
							   "    gl_TessLevelOuter[2] = outer_tess_level.z;\n"
							   "    gl_TessLevelOuter[3] = outer_tess_level.w;\n"
							   "}\n";

	const char*		  n_patch_vertices_raw_ptr = NULL;
	std::stringstream n_patch_vertices_sstream;
	std::string		  n_patch_vertices_string;
	std::string		  token		  = "MAX_VERTICES";
	std::size_t		  token_index = std::string::npos;

	n_patch_vertices_sstream << n_patch_vertices;
	n_patch_vertices_string  = n_patch_vertices_sstream.str();
	n_patch_vertices_raw_ptr = n_patch_vertices_string.c_str();

	result = (should_use_glInvocationID_indexed_input) ? tc_body_true : tc_body_false;

	while ((token_index = result.find(token)) != std::string::npos)
	{
		result = result.replace(token_index, token.length(), n_patch_vertices_raw_ptr);

		token_index = result.find(token);
	}

	return result;
}

/** Retrieves generic tessellation evaluation shader source code.
 *  The shader users user-specified tessellation properties.
 *
 *  @param vertex_spacing Vertex spacing mode to use in the shader.
 *  @param primitive_mode Primitive mode to use in the shader.
 *  @param point_mode     true to use point_mode in the shader, false
 *                        to omit it.
 *
 *  @return Requested string.
 */
std::string TessellationShaderUtils::getGenericTECode(_tessellation_shader_vertex_spacing  vertex_spacing,
													  _tessellation_primitive_mode		   primitive_mode,
													  _tessellation_shader_vertex_ordering vertex_ordering,
													  bool								   point_mode)
{
	std::string result;
	const char* te_body = "${VERSION}\n"
						  "\n"
						  "${TESSELLATION_SHADER_REQUIRE}\n"
						  "\n"
						  "layout (TESSELLATOR_PRIMITIVE_MODE VERTEX_SPACING_MODE VERTEX_ORDERING POINT_MODE) in;\n"
						  "\n"
						  "out vec3 result_uvw;\n"
						  "\n"
						  "void main()\n"
						  "{\n"
						  "    gl_Position = gl_in[0].gl_Position;\n"
						  "    result_uvw  = gl_TessCoord;\n"
						  "}\n";

	const char* point_mode_token		   = "POINT_MODE";
	std::size_t point_mode_token_index	 = std::string::npos;
	std::string primitive_mode_string	  = TessellationShaderUtils::getESTokenForPrimitiveMode(primitive_mode);
	const char* primitive_mode_token	   = "TESSELLATOR_PRIMITIVE_MODE";
	std::size_t primitive_mode_token_index = std::string::npos;
	std::string vertex_ordering_string;
	const char* vertex_ordering_token		= "VERTEX_ORDERING";
	std::size_t vertex_ordering_token_index = std::string::npos;
	std::string vertex_spacing_mode_string;
	const char* vertex_spacing_token	   = "VERTEX_SPACING_MODE";
	std::size_t vertex_spacing_token_index = std::string::npos;

	result = te_body;

	/* Prepare the vertex ordering token. We need to do this manually, because the default vertex spacing
	 * mode translates to empty string and the shader would fail to compile if we hadn't taken care of the
	 * comma
	 */
	if (vertex_ordering == TESSELLATION_SHADER_VERTEX_ORDERING_DEFAULT)
	{
		vertex_ordering_string = TessellationShaderUtils::getESTokenForVertexOrderingMode(vertex_ordering);
	}
	else
	{
		std::stringstream helper_sstream;

		helper_sstream << ", " << TessellationShaderUtils::getESTokenForVertexOrderingMode(vertex_ordering);

		vertex_ordering_string = helper_sstream.str();
	}

	/* Do the same for vertex spacing token */
	if (vertex_spacing == TESSELLATION_SHADER_VERTEX_SPACING_DEFAULT)
	{
		vertex_spacing_mode_string = TessellationShaderUtils::getESTokenForVertexSpacingMode(vertex_spacing);
	}
	else
	{
		std::stringstream helper_sstream;

		helper_sstream << ", " << TessellationShaderUtils::getESTokenForVertexSpacingMode(vertex_spacing);

		vertex_spacing_mode_string = helper_sstream.str();
	}

	/* Primitive mode */
	while ((primitive_mode_token_index = result.find(primitive_mode_token)) != std::string::npos)
	{
		result = result.replace(primitive_mode_token_index, strlen(primitive_mode_token), primitive_mode_string);

		primitive_mode_token_index = result.find(primitive_mode_token);
	}

	/* Vertex ordering */
	while ((vertex_ordering_token_index = result.find(vertex_ordering_token)) != std::string::npos)
	{
		result = result.replace(vertex_ordering_token_index, strlen(vertex_ordering_token), vertex_ordering_string);

		vertex_ordering_token_index = result.find(vertex_ordering_token);
	}

	/* Vertex spacing */
	while ((vertex_spacing_token_index = result.find(vertex_spacing_token)) != std::string::npos)
	{
		result = result.replace(vertex_spacing_token_index, strlen(vertex_spacing_token), vertex_spacing_mode_string);

		vertex_spacing_token_index = result.find(vertex_spacing_token);
	}

	/* Point mode */
	while ((point_mode_token_index = result.find(point_mode_token)) != std::string::npos)
	{
		result = result.replace(point_mode_token_index, strlen(point_mode_token), (point_mode) ? ", point_mode" : "");

		point_mode_token_index = result.find(point_mode_token);
	}

	return result;
}

/** Initializes ES objects that will be needed for non-static calls
 *
 *  This function throws TestError exception if an error occurs.
 *
 **/
void TessellationShaderUtils::init()
{
	if (!m_parent_test->m_is_tessellation_shader_supported)
	{
		throw tcu::NotSupportedError(TESSELLATION_SHADER_EXTENSION_NOT_SUPPORTED);
	}

	/* Create buffer object used to hold XFB data */
	m_gl.genBuffers(1, &m_bo_id);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers() failed");

	/* Create query object */
	m_gl.genQueries(1, &m_qo_pg_id);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenQueries() failed");

	/* Initialize shader objects */
	m_fs_id = m_gl.createShader(GL_FRAGMENT_SHADER);
	m_vs_id = m_gl.createShader(GL_VERTEX_SHADER);

	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCreateShader() failed");

	/* Initialize bodies of the shaders and try to compile them */
	const glw::GLuint  shaders[] = { m_fs_id, m_vs_id };
	const unsigned int n_shaders = DE_LENGTH_OF_ARRAY(shaders);

	const char* fs_body = "${VERSION}\n"
						  "\n"
						  "void main()\n"
						  "{\n"
						  "}\n";
	const char* vs_body = "${VERSION}\n"
						  "\n"
						  "void main()\n"
						  "{\n"
						  "    gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
						  "}\n";

	m_parent_test->shaderSourceSpecialized(m_fs_id, 1 /* count */, &fs_body);
	m_parent_test->shaderSourceSpecialized(m_vs_id, 1 /* count */, &vs_body);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glShaderSource() failed");

	compileShaders(n_shaders, shaders, true);
}

/** Retrieves amount of vertices that will be generated for a draw call
 *  that uses a program object, which is built of (at least) one tessellation
 *  stage.
 *
 *  NOTE: This function can temporarily unbind active program object.
 *        This function throws TestError exception if an error occurs.
 *
 *  @param primitive_mode           Primitive mode used for the tessellation.
 *  @param inner_tessellation_level Two FP values that define inner tessellation levels.
 *                                  Must NOT be NULL.
 *  @param outer_tessellation_level Four FP values that define outer tessellation levels.
 *                                  Must NOT be NULL.
 *  @param vertex_spacing           Vertex spacing mode used for the tessellation.
 *  @param is_point_mode_enabled    true if point_mode should be enabled for the query,
 *                                  false otherwise.
 *
 *  This function REQUIRES GL_EXT_geometry_shader support.
 *  This function throws TestError exception, should an error occur.
 *
 *  @return Amount of vertices that would be generated by the tessellator unit for
 *          a particular draw call.
 **/
unsigned int TessellationShaderUtils::getAmountOfVerticesGeneratedByTessellator(
	_tessellation_primitive_mode primitive_mode, const float* inner_tessellation_level,
	const float* outer_tessellation_level, _tessellation_shader_vertex_spacing vertex_spacing,
	bool is_point_mode_enabled)
{
	unsigned int result = 0;

	switch (primitive_mode)
	{
	case TESSELLATION_SHADER_PRIMITIVE_MODE_ISOLINES:
	case TESSELLATION_SHADER_PRIMITIVE_MODE_QUADS:
	case TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES:
	{
		/* We refer to a counter program, TC and TE stages are configured as specified
		 * by the caller. Before we issue the draw call, we begin a query introduced in
		 * GL_EXT_geometry_shader that allows us to count how many primitives would have been generated. Doing so
		 * allows us to determine how many vertices were generated during the processed.
		 */
		const glw::GLint					 test_n_patch_vertices = 1;
		_tessellation_vertex_counter_program test_program(m_gl);

		initTessellationVertexCounterProgram(inner_tessellation_level, outer_tessellation_level, test_n_patch_vertices,
											 vertex_spacing, primitive_mode, is_point_mode_enabled, test_program);

		result = test_program.n_data_vertices;
		break;
	}

	default:
	{
		TCU_FAIL("Unrecognized primitive mode");
	}
	} /* switch (primitive_mode) */

	return result;
}

/** Retrieves data generated by a tessellator for a particular tessellation configuration.
 *
 *  @param inner           Two FP values defining inner tessellation values to be used for tessellation.
 *                         Must not be NULL.
 *  @param point_mode      true if point mode is to be used for tessellation, false otherwise.
 *  @param primitive_mode  Primitive mode to be used for tessellation.
 *  @param vertex_ordering Vertex ordering to be used for tessellation.
 *  @param vertex_spacing  Vertex spacing to be used for tessellation.
 *  @param outer           Four FP values defining outer tessellation values to be used for tessellation.
 *                         Must not be NULL.
 *
 *  @return Pointer to buffer containing tessellated coordinates.
 **/
std::vector<char> TessellationShaderUtils::getDataGeneratedByTessellator(
	const float* inner, bool point_mode, _tessellation_primitive_mode primitive_mode,
	_tessellation_shader_vertex_ordering vertex_ordering, _tessellation_shader_vertex_spacing vertex_spacing,
	const float* outer)
{
	(void)vertex_ordering;

	glw::GLint							 test_n_patch_vertices = getPatchVerticesForPrimitiveMode(primitive_mode);
	_tessellation_vertex_counter_program test_program(m_gl);

	initTessellationVertexCounterProgram(inner, outer, test_n_patch_vertices, vertex_spacing, primitive_mode,
										 point_mode, test_program);
	return test_program.m_data;
}

/** Retrieves ESSL token corresponding to particular primitive mode.
 *  Will throw TestError exception if @param primitive_mode is not
 *  valid.
 *
 *  @param primitive_mode Primitive mode to consider.
 *
 *  @return String telling how the primitive mode would be expressed in
 *          ES SL.
 **/
std::string TessellationShaderUtils::getESTokenForPrimitiveMode(_tessellation_primitive_mode primitive_mode)
{
	std::string result = "?";

	switch (primitive_mode)
	{
	case TESSELLATION_SHADER_PRIMITIVE_MODE_ISOLINES:
	{
		result = "isolines";

		break;
	}

	case TESSELLATION_SHADER_PRIMITIVE_MODE_QUADS:
	{
		result = "quads";

		break;
	}

	case TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES:
	{
		result = "triangles";

		break;
	}

	default:
	{
		TCU_FAIL("Unrecognized tessellation primitive mode");
	}
	}

	return result;
}

/** Retrieves ESSL token corresponding to particular vertex ordering.
 *  Will throw TestError exception if @param vertex_ordering is not
 *  valid.
 *
 *  @param vertex_ordering Vertex ordering to consider.
 *
 *  @return String telling how the vertex mode would be expressed in
 *          ES SL.
 **/
std::string TessellationShaderUtils::getESTokenForVertexOrderingMode(
	_tessellation_shader_vertex_ordering vertex_ordering)
{
	std::string result;

	switch (vertex_ordering)
	{
	case TESSELLATION_SHADER_VERTEX_ORDERING_CCW:
	{
		result = "ccw";

		break;
	}

	case TESSELLATION_SHADER_VERTEX_ORDERING_CW:
	{
		result = "cw";

		break;
	}

	case TESSELLATION_SHADER_VERTEX_ORDERING_DEFAULT:
	{
		/* Simply return an empty token */
		result = "";

		break;
	}

	default:
	{
		TCU_FAIL("Unrecognized tessellation shader vertex ordering");
	}
	} /* switch (vertex_ordering) */

	return result;
}

/** Retrieves ESSL token corresponding to particular vertex spacing mode.
 *  Will throw TestError exception if @param vertex_spacing is not
 *  valid.
 *
 *  @param vertex_spacing Vertex spacing mode to consider.
 *
 *  @return String telling how the vertex spacing mode would be expressed in
 *          ES SL.
 **/
std::string TessellationShaderUtils::getESTokenForVertexSpacingMode(_tessellation_shader_vertex_spacing vertex_spacing)
{
	std::string result;

	switch (vertex_spacing)
	{
	case TESSELLATION_SHADER_VERTEX_SPACING_DEFAULT:
	{
		result = "";

		break;
	}

	case TESSELLATION_SHADER_VERTEX_SPACING_EQUAL:
	{
		result = "equal_spacing";

		break;
	}

	case TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_EVEN:
	{
		result = "fractional_even_spacing";

		break;
	}

	case TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_ODD:
	{
		result = "fractional_odd_spacing";

		break;
	}

	default:
	{
		TCU_FAIL("Invalid vertex spacing mode requested");
	}
	}

	return result;
}

/** Tells how many vertices should be passed in a single patch for
 *  particular primitive mode to work for tessellation stage.
 *
 *  Throws TestError exception if @param primitive_mode is invalid.
 *
 *  @param primitive_mode Primitive mode to consider.
 *
 *  @return Requested value.
 **/
glw::GLint TessellationShaderUtils::getPatchVerticesForPrimitiveMode(_tessellation_primitive_mode primitive_mode)
{
	glw::GLint result = 0;

	switch (primitive_mode)
	{
	case TESSELLATION_SHADER_PRIMITIVE_MODE_ISOLINES:
		result = 4;
		break;
	case TESSELLATION_SHADER_PRIMITIVE_MODE_QUADS:
		result = 4;
		break;
	case TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES:
		result = 3;
		break;

	default:
	{
		TCU_FAIL("Unrecognized primitive mode");
	}
	} /* switch (primitive_mode) */

	return result;
}

/** Retrieves tessellation level used by the tessellator, given
 *  vertex spacing setting.
 *
 *  @param vertex_spacing              Vertex spacing used for tessellation
 *                                     evaluation stage;
 *  @param level                       Tessellation level as defined in TC
 *                                     stage OR as configured with
 *                                     GL_PATCH_DEFAULT_*_LEVEL pnames.
 *  @param gl_max_tess_gen_level_value GL_MAX_TESS_GEN_LEVEL_EXT pname value,
 *                                     as reported by the implementation.
 *  @param out_clamped                 Deref will be used to store clamped (but
 *                                     not rounded) representation. Can be NULL.
 *  @param out_clamped_and_rounded     Deref will be used to store clamped and
 *                                     rounded representation. Can be NULL.
 **/
void TessellationShaderUtils::getTessellationLevelAfterVertexSpacing(_tessellation_shader_vertex_spacing vertex_spacing,
																	 float								 level,
																	 glw::GLint gl_max_tess_gen_level_value,
																	 float* out_clamped, float* out_clamped_and_rounded)
{
	/* Behavior is as per EXT_tessellation_shader spec */
	switch (vertex_spacing)
	{
	case TESSELLATION_SHADER_VERTEX_SPACING_DEFAULT:
	case TESSELLATION_SHADER_VERTEX_SPACING_EQUAL:
	{
		if (level < 1.0f)
		{
			level = 1.0f;
		}
		else if (level > (float)gl_max_tess_gen_level_value)
		{
			level = (float)gl_max_tess_gen_level_value;
		}

		if (out_clamped != DE_NULL)
		{
			*out_clamped = level;
		}

		/* Round *up* to nearest integer */
		level = (float)((int)(deFloatCeil(level) + 0.5f));

		if (out_clamped_and_rounded != DE_NULL)
		{
			*out_clamped_and_rounded = level;
		}

		break;
	}

	case TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_EVEN:
	{
		if (level < 2.0f)
		{
			level = 2.0f;
		}
		else if (level > (float)gl_max_tess_gen_level_value)
		{
			level = (float)gl_max_tess_gen_level_value;
		}

		if (out_clamped != DE_NULL)
		{
			*out_clamped = level;
		}

		/* Round *up* to nearest *even* integer */
		int level_temp = (int)(deFloatCeil(level) + 0.5f);

		if ((level_temp % 2) != 0)
		{
			level_temp++;
		}

		if (out_clamped_and_rounded != DE_NULL)
		{
			*out_clamped_and_rounded = (float)level_temp;
		}

		break;
	}

	case TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_ODD:
	{
		if (level < 1.0f)
		{
			level = 1.0f;
		}
		else if (level > (float)(gl_max_tess_gen_level_value - 1))
		{
			level = (float)(gl_max_tess_gen_level_value - 1);
		}

		if (out_clamped != DE_NULL)
		{
			*out_clamped = level;
		}

		/* Round to *up* nearest *odd* integer */
		int level_temp = (int)(deFloatCeil(level) + 0.5f);

		if ((level_temp % 2) != 1)
		{
			level_temp++;
		}

		if (out_clamped_and_rounded != DE_NULL)
		{
			*out_clamped_and_rounded = (float)level_temp;
		}

		break;
	}

	default:
	{
		TCU_FAIL("Unrecognized vertex spacing mode");
	}
	} /* switch(vertex_spacing) */
}

/** Returns a vector of _tessellation_levels instances with different level values.
 *
 *  @param primitive_mode              Primitive mode to consider.
 *  @param gl_max_tess_gen_level_value Implementation-specific GL_MAX_TESS_GEN_LEVEL_EXT value.
 *  @param filter                      Condition which all generated tuples should meet in
 *                                     order to land in the result vector.
 *
 *  @return _tessellation_levels_set instance storing described values.
 **/
_tessellation_levels_set TessellationShaderUtils::getTessellationLevelSetForPrimitiveMode(
	_tessellation_primitive_mode primitive_mode, glw::GLint gl_max_tess_gen_level_value,
	_tessellation_level_set_filter filter)
{
	/* As a starter value, use a tessellation level that is different for each
	 * primitive modes, just to make sure the implementation can correctly
	 * handle various tessellation level values */
	glw::GLint n_min_patch_vertices = getPatchVerticesForPrimitiveMode(primitive_mode);

	glw::GLint n_half_max_patch_vertices_mul_min = gl_max_tess_gen_level_value / 2;
	glw::GLint n_max_patch_vertices_mul_min		 = gl_max_tess_gen_level_value;

	if ((n_half_max_patch_vertices_mul_min % n_min_patch_vertices) != 0)
	{
		/* Round to nearest mul-of-min integer */
		n_half_max_patch_vertices_mul_min +=
			(n_min_patch_vertices - (gl_max_tess_gen_level_value / 2) % n_min_patch_vertices);
	}

	if ((n_max_patch_vertices_mul_min % n_min_patch_vertices) != 0)
	{
		/* Round to previous nearest mul-of-min integer */
		n_max_patch_vertices_mul_min -= (gl_max_tess_gen_level_value % n_min_patch_vertices);
	}

	/* Prepare the result vector items */
	_tessellation_levels_set result;

	if ((filter & TESSELLATION_LEVEL_SET_FILTER_ALL_LEVELS_USE_THE_SAME_VALUE) != 0)
	{
		/* Prepare the result vector items */
		_tessellation_levels item_1;
		_tessellation_levels item_2;
		_tessellation_levels item_3;

		item_1.inner[0] = float(n_min_patch_vertices);
		item_1.inner[1] = float(n_min_patch_vertices + 1);
		item_1.outer[0] = float(n_min_patch_vertices + 3);
		item_1.outer[1] = float(n_min_patch_vertices + 2);
		item_1.outer[2] = float(n_min_patch_vertices + 1);
		item_1.outer[3] = float(n_min_patch_vertices);

		item_2.inner[0] = float(n_half_max_patch_vertices_mul_min);
		item_2.inner[1] = float(n_half_max_patch_vertices_mul_min - 1);
		item_2.outer[0] = float(n_half_max_patch_vertices_mul_min - 3);
		item_2.outer[1] = float(n_half_max_patch_vertices_mul_min - 2);
		item_2.outer[2] = float(n_half_max_patch_vertices_mul_min - 1);
		item_2.outer[3] = float(n_half_max_patch_vertices_mul_min);

		item_3.inner[0] = float(n_max_patch_vertices_mul_min - 1);
		item_3.inner[1] = float(n_max_patch_vertices_mul_min - 2);
		item_3.outer[0] = float(n_max_patch_vertices_mul_min - 3);
		item_3.outer[1] = float(n_max_patch_vertices_mul_min - 4);
		item_3.outer[2] = float(n_max_patch_vertices_mul_min - 5);
		item_3.outer[3] = float(n_max_patch_vertices_mul_min - 6);

		/* Push the items onto result vector. */
		result.push_back(item_1);
		result.push_back(item_2);
		result.push_back(item_3);
	}
	else
	{
		DE_ASSERT((filter & TESSELLATION_LEVEL_SET_FILTER_ALL_COMBINATIONS) != 0 ||
				  (filter & TESSELLATION_LEVEL_SET_FILTER_INNER_AND_OUTER_LEVELS_USE_DIFFERENT_VALUES) != 0);

		const glw::GLint   base_values[] = { -1, 1, n_half_max_patch_vertices_mul_min, n_max_patch_vertices_mul_min };
		const unsigned int n_base_values = DE_LENGTH_OF_ARRAY(base_values);

		const unsigned int n_relevant_inner_tess_levels =
			(primitive_mode == TESSELLATION_SHADER_PRIMITIVE_MODE_ISOLINES) ?
				0 :
				(primitive_mode == TESSELLATION_SHADER_PRIMITIVE_MODE_QUADS) ? 2 : 1;

		const unsigned int n_relevant_outer_tess_levels =
			(primitive_mode == TESSELLATION_SHADER_PRIMITIVE_MODE_ISOLINES) ?
				2 :
				(primitive_mode == TESSELLATION_SHADER_PRIMITIVE_MODE_QUADS) ? 4 : 3;

		for (unsigned int n_inner0_base_value = 0;
			 n_inner0_base_value < ((n_relevant_inner_tess_levels > 0) ? n_base_values : 1); ++n_inner0_base_value)
		{
			const glw::GLint inner0_value = base_values[n_inner0_base_value];

			for (unsigned int n_inner1_base_value = 0;
				 n_inner1_base_value < ((n_relevant_inner_tess_levels > 1) ? n_base_values : 1); ++n_inner1_base_value)
			{
				const glw::GLint inner1_value = base_values[n_inner1_base_value];

				for (unsigned int n_outer0_base_value = 0;
					 n_outer0_base_value < ((n_relevant_outer_tess_levels > 0) ? n_base_values : 1);
					 ++n_outer0_base_value)
				{
					const glw::GLint outer0_value = base_values[n_outer0_base_value];

					for (unsigned int n_outer1_base_value = 0;
						 n_outer1_base_value < ((n_relevant_outer_tess_levels > 1) ? n_base_values : 1);
						 ++n_outer1_base_value)
					{
						const glw::GLint outer1_value = base_values[n_outer1_base_value];

						for (unsigned int n_outer2_base_value = 0;
							 n_outer2_base_value < ((n_relevant_outer_tess_levels > 2) ? n_base_values : 1);
							 ++n_outer2_base_value)
						{
							const glw::GLint outer2_value = base_values[n_outer2_base_value];

							for (unsigned int n_outer3_base_value = 0;
								 n_outer3_base_value < ((n_relevant_outer_tess_levels > 3) ? n_base_values : 1);
								 ++n_outer3_base_value)
							{
								const glw::GLint outer3_value = base_values[n_outer3_base_value];

								/* Skip combinations where any of the relevant outer tessellation level values
								 * is negative. These would cause no tessellation coordinates to be generated
								 * by the tessellator.
								 */
								if ((n_relevant_outer_tess_levels > 0 && outer0_value < 0) ||
									(n_relevant_outer_tess_levels > 1 && outer1_value < 0) ||
									(n_relevant_outer_tess_levels > 2 && outer2_value < 0) ||
									(n_relevant_outer_tess_levels > 3 && outer3_value < 0))
								{
									continue;
								}

								/* If TESSELLATION_LEVEL_SET_FILTER_INNER_AND_OUTER_LEVELS_USE_DIFFERENT_VALUES
								 * filter was requested, make sure the values used separately for inner and outer
								 * tess levels are actually different. */
								if ((filter &
									 TESSELLATION_LEVEL_SET_FILTER_INNER_AND_OUTER_LEVELS_USE_DIFFERENT_VALUES) != 0)
								{
									DE_ASSERT(n_base_values >= 4 /* outer tess levels supported */);

									if ((n_relevant_inner_tess_levels > 1 && inner0_value == inner1_value) ||
										(n_relevant_outer_tess_levels > 1 && outer0_value == outer1_value) ||
										(n_relevant_outer_tess_levels > 2 && outer1_value == outer2_value) ||
										(n_relevant_outer_tess_levels > 3 && outer2_value == outer3_value))
									{
										continue;
									}
								} /* if ((filter & TESSELLATION_LEVEL_SET_FILTER_INNER_AND_OUTER_LEVELS_USE_DIFFERENT_VALUES) != 0) */

								/* If TESSELLATION_LEVEL_SET_FILTER_EXCLUDE_NEGATIVE_BASE_VALUE, make sure
								 * no inner/outer tessellation level we're about to use is negative. */
								if ((filter & TESSELLATION_LEVEL_SET_FILTER_EXCLUDE_NEGATIVE_BASE_VALUE) != 0)
								{
									if ((n_relevant_inner_tess_levels > 0 && inner0_value < 0) ||
										(n_relevant_inner_tess_levels > 1 && inner1_value < 0) ||
										(n_relevant_outer_tess_levels > 0 && outer0_value < 0) ||
										(n_relevant_outer_tess_levels > 1 && outer1_value < 0) ||
										(n_relevant_outer_tess_levels > 2 && outer2_value < 0) ||
										(n_relevant_outer_tess_levels > 3 && outer3_value < 0))
									{
										continue;
									}
								}

								/* Construct the tess level combination */
								_tessellation_levels item;

								item.inner[0] = (glw::GLfloat)inner0_value;
								item.inner[1] = (glw::GLfloat)inner1_value;
								item.outer[0] = (glw::GLfloat)outer0_value;
								item.outer[1] = (glw::GLfloat)outer1_value;
								item.outer[2] = (glw::GLfloat)outer2_value;
								item.outer[3] = (glw::GLfloat)outer3_value;

								/* Store it */
								result.push_back(item);
							} /* for (all outer[3] base values) */
						}	 /* for (all outer[2] base values) */
					}		  /* for (all outer[1] base values) */
				}			  /* for (all outer[0] base values) */
			}				  /* for (all inner[1] base values) */
		}					  /* for (all inner[0] base values) */
	}

	return result;
}

/** Retrieves transform feedback mode that should be used for glBeginTransformFeedback()
 *  call, if TF is to be active while a tessellated draw call is made.
 *
 *  This function throws TestError exception if @param primitive_mode is invalid.
 *
 *  @param primitive_mode Primitive mode to consider
 *  @param is_point_mode  true if tessellation is run in point_mode mode, false otherwise.
 *
 *  @return Corresponding ES enum.
 **/
glw::GLenum TessellationShaderUtils::getTFModeForPrimitiveMode(_tessellation_primitive_mode primitive_mode,
															   bool							is_point_mode)
{
	glw::GLenum result = GL_NONE;

	if (is_point_mode)
	{
		result = GL_POINTS;
	}
	else
	{
		switch (primitive_mode)
		{
		case TESSELLATION_SHADER_PRIMITIVE_MODE_ISOLINES:
		{
			result = GL_LINES;

			break;
		}

		case TESSELLATION_SHADER_PRIMITIVE_MODE_QUADS:
		{
			result = GL_TRIANGLES;

			break;
		}

		case TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES:
		{
			result = GL_TRIANGLES;

			break;
		}

		default:
		{
			TCU_FAIL("Unrecognized primitive mode");
		}
		} /* switch (primitive_mode) */
	}

	return result;
}

/** Initializes a counter program.
 *
 *  This function throws a TestError exception, should an error occur.
 *
 *  @param inner_tess_level      Two FP values to be used for inner tessellation levels. Must not be NULL.
 *  @param outer_tess_level      Four FP values to be used for outer tessellation levels. Must not be NULL.
 *  @param n_patch_vertices      Amount of TC stage output patch vertices.
 *  @param vertex_spacing        Vertex spacing mode to be used for tessellation.
 *  @param primitive_mode        Primitive mode to be used for tessellation.
 *  @param is_point_mode_enabled true if the point mode should be enabled for the program, false otherwise.
 *  @param result_descriptor     Objects created during initialization will be stored in the referenced descriptor.
 *
 **/
void TessellationShaderUtils::initTessellationVertexCounterProgram(
	const float* inner_tess_level, const float* outer_tess_level, glw::GLint n_patch_vertices,
	_tessellation_shader_vertex_spacing vertex_spacing, _tessellation_primitive_mode primitive_mode,
	bool is_point_mode_enabled, _tessellation_vertex_counter_program& result_descriptor)
{
	glw::GLint po_id = 0;
	glw::GLint tc_id = 0;
	glw::GLint te_id = 0;

	/* Generate the shader objects */
	tc_id = m_gl.createShader(m_parent_test->m_glExtTokens.TESS_CONTROL_SHADER);
	te_id = m_gl.createShader(m_parent_test->m_glExtTokens.TESS_EVALUATION_SHADER);

	GLU_EXPECT_NO_ERROR(m_gl.getError(), "Could not create TC/TE shader objects");

	/* Generate the program object */
	po_id = m_gl.createProgram();

	GLU_EXPECT_NO_ERROR(m_gl.getError(), "Could not create a program object");

	/* Initialize the shaders.
	 *
	 * Note: it's fine to use CCW ordering here, since it does not affect the amount
	 *       of primitives generated by the tessellator.
	 **/
	std::string tc_code		= getGenericTCCode(n_patch_vertices, false);
	const char* tc_code_ptr = tc_code.c_str();
	std::string te_code		= getGenericTECode(vertex_spacing, primitive_mode, TESSELLATION_SHADER_VERTEX_ORDERING_CCW,
										   is_point_mode_enabled);
	const char* te_code_ptr = te_code.c_str();

	/* Set up XFB */
	const char* varyings[] = { "result_uvw" };

	m_gl.transformFeedbackVaryings(po_id, 1, /* count */
								   varyings, GL_INTERLEAVED_ATTRIBS);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glTransformFeedbackVaryings() call failed");

	/* Link the program and check that the linking has succeeded */
	bool build_success = m_parent_test->buildProgram(po_id, m_fs_id, 0 /* precompiled */, NULL, tc_id, 1, &tc_code_ptr,
													 te_id, 1, &te_code_ptr, m_vs_id, 0 /* precompiled */, NULL);

	if (!build_success)
	{
		TCU_FAIL("Compilation and/or linking failed");
	}

	/* Set up the inner/outer tess level uniforms */
	glw::GLint inner_tess_level_uniform_location = -1;
	glw::GLint outer_tess_level_uniform_location = -1;

	inner_tess_level_uniform_location = m_gl.getUniformLocation(po_id, "inner_tess_level");
	outer_tess_level_uniform_location = m_gl.getUniformLocation(po_id, "outer_tess_level");

	DE_ASSERT(inner_tess_level_uniform_location != -1);
	DE_ASSERT(outer_tess_level_uniform_location != -1);

	m_gl.useProgram(po_id);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() call failed");

	m_gl.uniform2fv(inner_tess_level_uniform_location, 1, /* count */
					inner_tess_level);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUniform2fv() call failed");

	m_gl.uniform4fv(outer_tess_level_uniform_location, 1, /* count */
					outer_tess_level);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUniform4fv() call failed");

	/* Initialize the test descriptor */
	memcpy(result_descriptor.inner_tess_level, inner_tess_level, sizeof(result_descriptor.inner_tess_level));
	memcpy(result_descriptor.outer_tess_level, outer_tess_level, sizeof(result_descriptor.outer_tess_level));

	result_descriptor.is_point_mode_enabled				= is_point_mode_enabled;
	result_descriptor.n_patch_vertices					= n_patch_vertices;
	result_descriptor.po_id								= po_id;
	result_descriptor.primitive_mode					= primitive_mode;
	result_descriptor.tc_id								= tc_id;
	result_descriptor.te_id								= te_id;
	result_descriptor.tess_level_inner_uniform_location = inner_tess_level_uniform_location;
	result_descriptor.tess_level_outer_uniform_location = outer_tess_level_uniform_location;
	result_descriptor.vertex_spacing					= vertex_spacing;

	captureTessellationData(result_descriptor);
}

/** Tells whether user-provided vertex (expressed in tessellation space) generated
 *  during triangle tessellation is an outer edge vertex.
 *
 *  @param primitive_mode          Primitive mode, for which the tessellated vertex
 *                                 data was generated.
 *  @param tessellated_vertex_data Vertex data to check. Must define 3 floats.
 *
 *  @return true if the vertex is a part of an outer edge, false otherwise.
 **/
bool TessellationShaderUtils::isOuterEdgeVertex(_tessellation_primitive_mode primitive_mode,
												const float*				 tessellated_vertex_data)
{
	const float epsilon = 1e-5f;
	bool		result  = false;

	switch (primitive_mode)
	{
	case TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES:
	{
		if (de::abs(tessellated_vertex_data[0]) < epsilon || de::abs(tessellated_vertex_data[0] - 1.0f) < epsilon ||
			de::abs(tessellated_vertex_data[1]) < epsilon || de::abs(tessellated_vertex_data[1] - 1.0f) < epsilon ||
			de::abs(tessellated_vertex_data[2]) < epsilon || de::abs(tessellated_vertex_data[2] - 1.0f) < epsilon)
		{
			/* Make sure vertex is inside the triangle */
			if (0.0f <= tessellated_vertex_data[0] && tessellated_vertex_data[0] <= 1.0f &&
				0.0f <= tessellated_vertex_data[1] && tessellated_vertex_data[1] <= 1.0f &&
				0.0f <= tessellated_vertex_data[2] && tessellated_vertex_data[2] <= 1.0f)
			{
				result = true;
			}
		}

		break;
	} /* case TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES: */

	case TESSELLATION_SHADER_PRIMITIVE_MODE_QUADS:
	{
		if (de::abs(tessellated_vertex_data[0]) < epsilon || de::abs(tessellated_vertex_data[0] - 1.0f) < epsilon ||
			de::abs(tessellated_vertex_data[1]) < epsilon || de::abs(tessellated_vertex_data[1] - 1.0f) < epsilon)
		{
			result = true;
		}

		break;
	} /* case TESSELLATION_SHADER_PRIMITIVE_MODE_QUADS: */

	default:
	{
		DE_ASSERT("Unrecognized primitive mode");
	}
	}

	return result;
}

/** Returns true if two triangles are the same. Takes potentially different
 *  vertex ordering into consideration.
 *
 *  @param triangle_vertex_data Reference 9 FP values defining a triangle
 *                              that the triangle defined by @param vertex_data
 *                              will be compared against.
 *  @param vertex_data          9 FP values defining a triangle, perhaps in
 *                              a different order, that @param triangle_vertex_data
 *                              will be checked against.
 *
 *  @return true if the triangles are the same; false otherwise.
 *
 **/
bool TessellationShaderUtils::isTriangleDefined(const float* triangle_vertex_data, const float* vertex_data)
{
	const float epsilon							= 1e-5f;
	bool		has_triangle_vertex1_been_found = false;
	bool		has_triangle_vertex2_been_found = false;
	bool		has_triangle_vertex3_been_found = false;
	bool		result							= false;

	if ((de::abs(triangle_vertex_data[0] - vertex_data[0]) < epsilon &&
		 de::abs(triangle_vertex_data[1] - vertex_data[1]) < epsilon &&
		 de::abs(triangle_vertex_data[2] - vertex_data[2]) < epsilon) ||
		(de::abs(triangle_vertex_data[3] - vertex_data[0]) < epsilon &&
		 de::abs(triangle_vertex_data[4] - vertex_data[1]) < epsilon &&
		 de::abs(triangle_vertex_data[5] - vertex_data[2]) < epsilon) ||
		(de::abs(triangle_vertex_data[6] - vertex_data[0]) < epsilon &&
		 de::abs(triangle_vertex_data[7] - vertex_data[1]) < epsilon &&
		 de::abs(triangle_vertex_data[8] - vertex_data[2]) < epsilon))
	{
		has_triangle_vertex1_been_found = true;
	}

	if ((de::abs(triangle_vertex_data[0] - vertex_data[3]) < epsilon &&
		 de::abs(triangle_vertex_data[1] - vertex_data[4]) < epsilon &&
		 de::abs(triangle_vertex_data[2] - vertex_data[5]) < epsilon) ||
		(de::abs(triangle_vertex_data[3] - vertex_data[3]) < epsilon &&
		 de::abs(triangle_vertex_data[4] - vertex_data[4]) < epsilon &&
		 de::abs(triangle_vertex_data[5] - vertex_data[5]) < epsilon) ||
		(de::abs(triangle_vertex_data[6] - vertex_data[3]) < epsilon &&
		 de::abs(triangle_vertex_data[7] - vertex_data[4]) < epsilon &&
		 de::abs(triangle_vertex_data[8] - vertex_data[5]) < epsilon))
	{
		has_triangle_vertex2_been_found = true;
	}

	if ((de::abs(triangle_vertex_data[0] - vertex_data[6]) < epsilon &&
		 de::abs(triangle_vertex_data[1] - vertex_data[7]) < epsilon &&
		 de::abs(triangle_vertex_data[2] - vertex_data[8]) < epsilon) ||
		(de::abs(triangle_vertex_data[3] - vertex_data[6]) < epsilon &&
		 de::abs(triangle_vertex_data[4] - vertex_data[7]) < epsilon &&
		 de::abs(triangle_vertex_data[5] - vertex_data[8]) < epsilon) ||
		(de::abs(triangle_vertex_data[6] - vertex_data[6]) < epsilon &&
		 de::abs(triangle_vertex_data[7] - vertex_data[7]) < epsilon &&
		 de::abs(triangle_vertex_data[8] - vertex_data[8]) < epsilon))
	{
		has_triangle_vertex3_been_found = true;
	}

	if (has_triangle_vertex1_been_found && has_triangle_vertex2_been_found && has_triangle_vertex3_been_found)
	{
		result = true;
	}

	return result;
}

} // namespace glcts
