/*-------------------------------------------------------------------------
 * 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 "esextcTessellationShaderVertexSpacing.hpp"
#include "esextcTessellationShaderUtils.hpp"
#include "gluContextInfo.hpp"
#include "gluDefs.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuTestLog.hpp"
#include <algorithm>

/* Precision, with which the test should be executed. */
const float epsilon = 1e-3f;

namespace glcts
{
/** Compares two barycentric/cartesian coordinates, using test-wide epsilon.
 *
 *  @param in Coordinate to compare current instance against.
 *
 *  @return true if the coordinates are equal, false otherwise.
 **/
bool TessellationShaderVertexSpacing::_tess_coordinate::operator==(
	const TessellationShaderVertexSpacing::_tess_coordinate& in) const
{
	if (de::abs(this->u - in.u) < epsilon && de::abs(this->v - in.v) < epsilon && de::abs(this->w - in.w) < epsilon)
	{
		return true;
	}
	else
	{
		return false;
	}
}

/** Compares two Cartesian coordinates, using test-wide epsilon.
 *
 *  @param in Coordinate to compare current instance against.
 *
 *  @return true if the coordinates are equal, false otherwise.
 **/
bool TessellationShaderVertexSpacing::_tess_coordinate_cartesian::operator==(
	const TessellationShaderVertexSpacing::_tess_coordinate_cartesian& in) const
{
	if (de::abs(this->x - in.x) < epsilon && de::abs(this->y - in.y) < epsilon)
	{
		return true;
	}
	else
	{
		return false;
	}
}

/** Constructor
 *
 * @param context Test context
 **/
TessellationShaderVertexSpacing::TessellationShaderVertexSpacing(Context& context, const ExtParameters& extParams)
	: TestCaseBase(context, extParams, "vertex_spacing", "Verifies vertex spacing qualifier behaves as specified")
	, m_gl_max_tess_gen_level_value(0)
	, m_vao_id(0)
	, m_utils(DE_NULL)
{
	/* Left blank on purpose */
}

/** Comparator function, used to compare two _tess_coordinate_cartesian
 *  instances by their X components.
 *
 *  @param a First coordinate to use for comparison;
 *  @param b Second coordinate to use for comparison.
 *
 *  @return true  if X component of @param a is lower than b's;
 *          false otherwise.
 **/
bool TessellationShaderVertexSpacing::compareEdgeByX(_tess_coordinate_cartesian a, _tess_coordinate_cartesian b)
{
	return a.x < b.x;
}

/** Comparator function, used to compare two _tess_coordinate_cartesian
 *  instances by their Y components.
 *
 *  @param a First coordinate to use for comparison;
 *  @param b Second coordinate to use for comparison.
 *
 *  @return true  if Y component of @param a is lower than b's;
 *          false otherwise.
 **/
bool TessellationShaderVertexSpacing::compareEdgeByY(_tess_coordinate_cartesian a, _tess_coordinate_cartesian b)
{
	return a.y < b.y;
}

/** Deinitializes ES objects created for the test. */
void TessellationShaderVertexSpacing::deinit()
{
	/* Call base class' deinit() */
	TestCaseBase::deinit();

	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Unbind vertex array object */
	gl.bindVertexArray(0);

	/* Delete vertex array object */
	if (m_vao_id != 0)
	{
		gl.deleteVertexArrays(1, &m_vao_id);

		m_vao_id = 0;
	}

	/* Deinitialize utils instance */
	if (m_utils != DE_NULL)
	{
		delete m_utils;

		m_utils = DE_NULL;
	}
}

/**  Takes data generated by tessellator for a specific run configuration and
 *  converts it into a set of edges that correspond to subsequent isolines.
 *  This function asserts that the run uses a 'isolines' primitive mode.
 *
 *  @param run Test run properties.
 *
 *  @return A vector storing found edges.
 **/
TessellationShaderVertexSpacing::_tess_edges TessellationShaderVertexSpacing::getEdgesForIsolinesTessellation(
	const _run& run)
{
	_tess_edges result;

	/* First convert the array data to a vector of edges, where each edge
	 * is a vector of points with the same V component. After this is done,
	 * points for each edge need to be sorted by U component.
	 */
	for (unsigned int n_vertex = 0; n_vertex < run.n_vertices; ++n_vertex)
	{
		/* Isolines are simple - we only need to create a new edge per each unique height */
		const float*			   coordinate = (const float*)(&run.data[0]) + 3 /* components */ * n_vertex;
		_tess_coordinate_cartesian new_item;

		new_item.x = coordinate[0];
		new_item.y = coordinate[1];

		/* Is V recognized? */
		_tess_edges_iterator edges_iterator;

		for (edges_iterator = result.begin(); edges_iterator != result.end(); edges_iterator++)
		{
			_tess_edge& edge = *edges_iterator;

			/* Each edge uses the same Y component, so we only need to check the first entry */
			if (de::abs(edge.points[0].y - coordinate[1]) < epsilon)
			{
				/* Add the new point to the vector */
				edge.points.push_back(new_item);

				break;
			}
		} /* for (all edges) */

		if (edges_iterator == result.end())
		{
			/* New edge starts at this point.
			 *
			 * Note that outermost tessellation level does not apply to this
			 * primitive mode.
			 **/
			_tess_edge new_edge(run.outer[1], run.outer[1], 1.0f);

			new_edge.points.push_back(new_item);

			result.push_back(new_edge);
		}
	} /* for (all vertices) */

	/* For each edge, sort the points by U coordinate */
	for (_tess_edges_iterator edges_iterator = result.begin(); edges_iterator != result.end(); ++edges_iterator)
	{
		_tess_edge_points& edge_points = edges_iterator->points;

		std::sort(edge_points.begin(), edge_points.end(), compareEdgeByX);
	}

	/* Done */
	return result;
}

/**  Takes data generated by tessellator for a specific run configuration and
 *  converts it into a set of edges that define the outer and inner quad.
 *  This function asserts that the run uses a 'quads' primitive mode.
 *
 *  @param run Test run properties.
 *
 *  @return A vector storing found edges.
 **/
TessellationShaderVertexSpacing::_tess_edges TessellationShaderVertexSpacing::getEdgesForQuadsTessellation(
	const _run& run)
{
	_tess_edges result;

	/* First, convert the raw coordinate array into a vector of cartesian coordinates.
	 * For this method, we will need to take out vertices in no specific order. */
	std::vector<_tess_coordinate_cartesian> coordinates;

	for (unsigned int n_vertex = 0; n_vertex < run.n_vertices; ++n_vertex)
	{
		_tess_coordinate_cartesian new_coordinate;
		const float*			   vertex_data = (const float*)(&run.data[0]) + 3 /* components */ * n_vertex;

		new_coordinate.x = vertex_data[0];
		new_coordinate.y = vertex_data[1];

		coordinates.push_back(new_coordinate);
	}

	/* Data set is expected to describe an outer and inner rectangles. We will execute the quad extraction
	 * process in two iterations:
	 *
	 * - first iteration will determine all coordinates that are part of the outer quad;
	 * - second iteration will focus on the inner quad.
	 *
	 * Each iteration will start from identifying corner vertices:
	 *
	 * - top-left corner     (x delta from (0.5, 0.5) should be negative, y delta from (0.5, 0.5) should be positive);
	 * - top-right corner    (x delta from (0.5, 0.5) should be positive, y delta from (0.5, 0.5) should be positive);
	 * - bottom-left corner  (x delta from (0.5, 0.5) should be negative, y delta from (0.5, 0.5) should be negative);
	 * - bottom-right corner (x delta from (0.5, 0.5) should be positive, y delta from (0.5, 0.5) should be negative);
	 *
	 * Once we know where the corner vertices are, we will remove them from the data set and iterate again over the
	 * data set to identify all points that are part of edges connecting the edge corners. After the loop is done,
	 * these vertices will have been associated with relevant edges and removed from the data sets.
	 *
	 * Once two iterations are complete, we're done.
	 */
	const unsigned int n_iterations = (run.inner[0] > 1) ? 2 : 1;

	for (unsigned int n_iteration = 0; n_iteration < n_iterations; ++n_iteration)
	{
		_tess_coordinate_cartesian current_tl_point;
		float					   current_tl_point_delta = 0.0f;
		_tess_coordinate_cartesian current_tr_point;
		float					   current_tr_point_delta = 0.0f;
		_tess_coordinate_cartesian current_bl_point;
		float					   current_bl_point_delta = 0.0f;
		_tess_coordinate_cartesian current_br_point;
		float					   current_br_point_delta = 0.0f;

		/* Iterate over all points */
		for (std::vector<_tess_coordinate_cartesian>::const_iterator coordinate_iterator = coordinates.begin();
			 coordinate_iterator != coordinates.end(); coordinate_iterator++)
		{
			const _tess_coordinate_cartesian& coordinate = *coordinate_iterator;
			float							  delta_x	= coordinate.x - 0.5f;
			float							  delta_y	= coordinate.y - 0.5f;
			float							  delta		 = deFloatSqrt(delta_x * delta_x + delta_y * delta_y);

			/* top-left corner (x delta from (0.5, 0.5) should be negative, y delta from (0.5, 0.5) should be positive); */
			if (delta_x <= 0.0f && delta_y >= 0.0f)
			{
				if (delta > current_tl_point_delta)
				{
					current_tl_point	   = coordinate;
					current_tl_point_delta = delta;
				}
			}

			/* top-right corner (x delta from (0.5, 0.5) should be positive, y delta from (0.5, 0.5) should be positive); */
			if (delta_x >= 0.0f && delta_y >= 0.0f)
			{
				if (delta > current_tr_point_delta)
				{
					current_tr_point	   = coordinate;
					current_tr_point_delta = delta;
				}
			}

			/* bottom-left corner (x delta from (0.5, 0.5) should be negative, y delta from (0.5, 0.5) should be negative); */
			if (delta_x <= 0.0f && delta_y <= 0.0f)
			{
				if (delta > current_bl_point_delta)
				{
					current_bl_point	   = coordinate;
					current_bl_point_delta = delta;
				}
			}

			/* bottom-right corner (x delta from (0.5, 0.5) should be positive, y delta from (0.5, 0.5) should be negative); */
			if (delta_x >= 0.0f && delta_y <= 0.0f)
			{
				if (delta > current_br_point_delta)
				{
					current_br_point	   = coordinate;
					current_br_point_delta = delta;
				}
			}
		} /* for (all coordinates) */

		/* Note: If any of the outer tessellation level is 1, at least
		 *       two "current" points will refer to the same point.
		 *
		 * Now that we know where the corner vertices are, remove them from the data set
		 */
		const _tess_coordinate_cartesian* corner_coordinate_ptrs[] = { &current_tl_point, &current_tr_point,
																	   &current_bl_point, &current_br_point };
		const unsigned int n_corner_coordinate_ptrs =
			sizeof(corner_coordinate_ptrs) / sizeof(corner_coordinate_ptrs[0]);

		for (unsigned int n_corner_coordinate = 0; n_corner_coordinate < n_corner_coordinate_ptrs;
			 ++n_corner_coordinate)
		{
			const _tess_coordinate_cartesian& corner_coordinate = *(corner_coordinate_ptrs[n_corner_coordinate]);
			std::vector<_tess_coordinate_cartesian>::iterator iterator =
				std::find(coordinates.begin(), coordinates.end(), corner_coordinate);

			/* Iterator can be invalid at this point of any of the corner coordinates
			 * referred more than once to the same point. */
			if (iterator != coordinates.end())
			{
				coordinates.erase(iterator);
			}
		} /* for (all corner coordinates) */

		/* Proceed with identification of coordinates describing the edges.
		 *
		 * Note: for inner quad, we need to subtract 2 segments connecting outer and inner coordinates */
		float tl_tr_delta =
			deFloatSqrt((current_tl_point.x - current_tr_point.x) * (current_tl_point.x - current_tr_point.x) +
						(current_tl_point.y - current_tr_point.y) * (current_tl_point.y - current_tr_point.y));
		float tr_br_delta =
			deFloatSqrt((current_tr_point.x - current_br_point.x) * (current_tr_point.x - current_br_point.x) +
						(current_tr_point.y - current_br_point.y) * (current_tr_point.y - current_br_point.y));
		float br_bl_delta =
			deFloatSqrt((current_br_point.x - current_bl_point.x) * (current_br_point.x - current_bl_point.x) +
						(current_br_point.y - current_bl_point.y) * (current_br_point.y - current_bl_point.y));
		float bl_tl_delta =
			deFloatSqrt((current_bl_point.x - current_tl_point.x) * (current_bl_point.x - current_tl_point.x) +
						(current_bl_point.y - current_tl_point.y) * (current_bl_point.y - current_tl_point.y));

		_tess_edge tl_tr_edge(0, 0, tl_tr_delta);
		_tess_edge tr_br_edge(0, 0, tr_br_delta);
		_tess_edge br_bl_edge(0, 0, br_bl_delta);
		_tess_edge bl_tl_edge(0, 0, bl_tl_delta);

		tl_tr_edge.outermost_tess_level = run.outer[3];
		tr_br_edge.outermost_tess_level = run.outer[2];
		br_bl_edge.outermost_tess_level = run.outer[1];
		bl_tl_edge.outermost_tess_level = run.outer[0];

		if (n_iteration == 0)
		{
			tl_tr_edge.tess_level = run.outer[3];
			tr_br_edge.tess_level = run.outer[2];
			br_bl_edge.tess_level = run.outer[1];
			bl_tl_edge.tess_level = run.outer[0];
		}
		else
		{
			tl_tr_edge.tess_level = run.inner[0] - 2 /* segments between inner and outer edges */;
			br_bl_edge.tess_level = run.inner[0] - 2 /* segments between inner and outer edges */;
			tr_br_edge.tess_level = run.inner[1] - 2 /* segments between inner and outer edges */;
			bl_tl_edge.tess_level = run.inner[1] - 2 /* segments between inner and outer edges */;
		}

		/* Add corner points to edge descriptors. Do *NOT* add the same point twice, as
		 * that will confuse verifyEdges() and cause incorrect failures.
		 */
		tl_tr_edge.points.push_back(current_tl_point);

		if (!(current_tl_point == current_tr_point))
		{
			tl_tr_edge.points.push_back(current_tr_point);
		}

		tr_br_edge.points.push_back(current_tr_point);

		if (!(current_tr_point == current_br_point))
		{
			tr_br_edge.points.push_back(current_br_point);
		}

		br_bl_edge.points.push_back(current_br_point);

		if (!(current_br_point == current_bl_point))
		{
			br_bl_edge.points.push_back(current_bl_point);
		}

		bl_tl_edge.points.push_back(current_bl_point);

		if (!(current_bl_point == current_tl_point))
		{
			bl_tl_edge.points.push_back(current_tl_point);
		}

		/* Identify points that lie on any of the edges considered */
		_tess_edge*		   edge_ptrs[] = { &tl_tr_edge, &tr_br_edge, &br_bl_edge, &bl_tl_edge };
		const unsigned int n_edge_ptrs = sizeof(edge_ptrs) / sizeof(edge_ptrs[0]);

		for (unsigned int n_edge = 0; n_edge < n_edge_ptrs; ++n_edge)
		{
			_tess_edge& edge = *(edge_ptrs[n_edge]);

			/* Degenerate edges will only consist of one point, for which the following
			 * code needs not be executed */
			if (edge.points.size() > 1)
			{
				/* Retrieve edge's start & end points */
				_tess_coordinate_cartesian edge_start_point = edge.points[0];
				_tess_coordinate_cartesian edge_end_point   = edge.points[1];

				/* Iterate over the data set */
				for (std::vector<_tess_coordinate_cartesian>::const_iterator iterator = coordinates.begin();
					 iterator != coordinates.end(); iterator++)
				{
					const _tess_coordinate_cartesian& coordinate = *iterator;

					if (isPointOnLine(edge_start_point, edge_end_point, coordinate) &&
						!(edge_start_point == coordinate) && !(edge_end_point == coordinate))
					{
						/* Make sure the point has not already been added. If this happens,
						 * it is very likely there is a bug in the way the implementation's
						 * support of point mode */
						if (std::find_if(edge.points.begin(), edge.points.end(),
										 _comparator_exact_tess_coordinate_match(coordinate)) == edge.points.end())
						{
							edge.points.push_back(coordinate);
						}
						else
						{
							std::string primitive_mode_string =
								TessellationShaderUtils::getESTokenForPrimitiveMode(run.primitive_mode);
							std::string vertex_spacing_string =
								TessellationShaderUtils::getESTokenForVertexSpacingMode(run.vertex_spacing);

							m_testCtx.getLog()
								<< tcu::TestLog::Message << "A duplicate vertex"
								<< " (" << coordinate.x << ", " << coordinate.y
								<< ") was found in set of coordinates generated for the following configuration:"
								<< " inner tessellation levels:(" << run.inner[0] << ", " << run.inner[1]
								<< ") outer tessellation levels:(" << run.outer[0] << ", " << run.outer[1] << ", "
								<< run.outer[2] << ", " << run.outer[3] << ") primitive mode:" << primitive_mode_string
								<< " vertex spacing mode:" << vertex_spacing_string << " point mode:yes"
								<< tcu::TestLog::EndMessage;

							TCU_FAIL("A duplicate vertex was found in generated tessellation coordinate set "
									 "when point mode was used");
						}
					}
				} /* for (all coordinates in the data set) */

				/* Sort all points in the edge relative to the start point */
				std::sort(edge.points.begin(), edge.points.end(), _comparator_relative_to_base_point(edge_start_point));
			}
		} /* for (all edges) */

		/* Remove all coordinates associated to edges from the data set */
		for (unsigned int n_edge = 0; n_edge < n_edge_ptrs; ++n_edge)
		{
			_tess_edge& edge = *(edge_ptrs[n_edge]);

			for (std::vector<_tess_coordinate_cartesian>::const_iterator iterator = edge.points.begin();
				 iterator != edge.points.end(); iterator++)
			{
				const _tess_coordinate_cartesian&				  coordinate = *iterator;
				std::vector<_tess_coordinate_cartesian>::iterator dataset_iterator =
					std::find(coordinates.begin(), coordinates.end(), coordinate);

				if (dataset_iterator != coordinates.end())
				{
					coordinates.erase(dataset_iterator);
				}
			} /* for (all edge points) */
		}	 /* for (all edges) */

		/* Store the edges */
		for (unsigned int n_edge = 0; n_edge < n_edge_ptrs; ++n_edge)
		{
			_tess_edge& edge = *(edge_ptrs[n_edge]);

			result.push_back(edge);
		}
	} /* for (both iterations) */

	return result;
}

/**  Takes data generated by tessellator for a specific run configuration and
 *  converts it into a set of edges that correspond to subsequent triangles.
 *  This function asserts that the run uses a 'triangles' primitive mode.
 *
 *  This function throws a TestError, should an error occur or the data is found
 *  to be incorrect.
 *
 *  @param run Test run properties.
 *
 *  @return A vector storing found edges.
 **/
TessellationShaderVertexSpacing::_tess_edges TessellationShaderVertexSpacing::getEdgesForTrianglesTessellation(
	const _run& run)
{
	DE_ASSERT(run.data_cartesian != DE_NULL);

	/* Before we proceed, convert the raw arrayed data into a vector. We'll need to take items out
	 * in an undefined order */
	std::vector<_tess_coordinate_cartesian> coordinates;

	for (unsigned int n_vertex = 0; n_vertex < run.n_vertices; ++n_vertex)
	{
		const float* vertex_data_cartesian = (const float*)run.data_cartesian + n_vertex * 2; /* components */

		_tess_coordinate_cartesian cartesian;

		cartesian.x = vertex_data_cartesian[0];
		cartesian.y = vertex_data_cartesian[1];

		coordinates.push_back(cartesian);
	}

	/* The function iterates over the data set generated by the tessellator and:
	 *
	 * 1) Finds three corner vertices. These coordinates are considered to correspond to corner vertices
	 *    of the outermost triangle. The coordinates are removed from the data set. Note that it is an
	 *    error if less than three coordinates are available in the data set at this point.
	 * 2) Iterates over remaining points in the data set and associates them with AB, BC and CA edges.
	 *    Each point found to be a part of any of the edges considered is removed from the data set.
	 * 3) If more than 0 coordinates are still available in the data set at this point, implementation
	 *    returns to step 1)
	 *
	 * After the implementation runs out of tessellation coordinates, a few sanity checks are executed
	 * and the function returns to the caller.
	 */
	float		 base_tess_level  = 0.0f;
	unsigned int tess_level_delta = 0;
	_tess_edges  result;

	/* Make sure to follow the cited extension spec language:
	 *
	 * If the inner tessellation level is one and any of the outer tessellation
	 * levels is greater than one, the inner tessellation level is treated as
	 * though it were originally specified as 1+epsilon and will be rounded up to
	 * result in a two- or three-segment subdivision according to the
	 * tessellation spacing.
	 *
	 */
	float inner0_round_clamped_value = 0;

	TessellationShaderUtils::getTessellationLevelAfterVertexSpacing(
		run.vertex_spacing, run.inner[0], m_gl_max_tess_gen_level_value, DE_NULL, /* out_clamped */
		&inner0_round_clamped_value);

	if (inner0_round_clamped_value == 1.0f && (run.outer[0] > 1.0f || run.outer[1] > 1.0f || run.outer[2] > 1.0f))
	{
		TessellationShaderUtils::getTessellationLevelAfterVertexSpacing(
			run.vertex_spacing, inner0_round_clamped_value + 1.0f /* epsilon */, m_gl_max_tess_gen_level_value,
			DE_NULL, /* out_clamped */
			&base_tess_level);
	}
	else
	{
		TessellationShaderUtils::getTessellationLevelAfterVertexSpacing(
			run.vertex_spacing, run.inner[0], m_gl_max_tess_gen_level_value, DE_NULL, /* out_clamped */
			&base_tess_level);
	}

	while (coordinates.size() > 0)
	{
		/* If we're using an odd tessellation level, it is an error if less than three coordinates are
		 * available at this point.
		 * If it's an even tessellation level, we must have at least three coordinates at hand OR
		 * one, in which case the only coordinate left is the degenerate one. Should that happen,
		 * it's time to leave. */
		if ((((int)base_tess_level) % 2 == 0) && (coordinates.size() == 1))
		{
			/* We're left with the degenerate vertex. Leave the loop */
			break;
		}

		if (coordinates.size() < 3)
		{
			TCU_FAIL("Could not extract three corner vertices that would make up a triangle");
		}

		/* Iterate over all vertices left and identify three corner vertices. For the outermost triangle,
		 * these will be represented by (1, 0, 0), (0, 1, 0) and (0, 0, 1) barycentric coordinates, which
		 * correspond to the following coordinates in Euclidean space: (0.5, 0), (1, 1), (0, 1) (as defined
		 * in TessellationShaderUtils::convertCartesianCoordinatesToBarycentric() ).
		 *
		 * The idea here is to identify vertices that are the closest to the ideal coordinates, not necessarily
		 * to find a perfect match. */
		unsigned int curr_index			= 0;
		float		 delta_v1			= 0.0f; /* barycentric:(1, 0, 0) -> Euclidean:(0.5, 0.0) */
		float		 delta_v2			= 0.0f; /* barycentric:(0, 1, 0) -> Euclidean:(1.0, 1.0) */
		float		 delta_v3			= 0.0f; /* barycentric:(0, 0, 1) -> Euclidean:(0.0, 1.0) */
		bool		 is_first_iteration = true;
		unsigned int selected_v1_index  = 0;
		unsigned int selected_v2_index  = 0;
		unsigned int selected_v3_index  = 0;

		for (std::vector<_tess_coordinate_cartesian>::const_iterator iterator = coordinates.begin();
			 iterator != coordinates.end(); iterator++, curr_index++)
		{
			const _tess_coordinate_cartesian& cartesian_coordinate = *iterator;

			float curr_delta_v1 = deFloatSqrt((cartesian_coordinate.x - 0.5f) * (cartesian_coordinate.x - 0.5f) +
											  (cartesian_coordinate.y - 0.0f) * (cartesian_coordinate.y - 0.0f));
			float curr_delta_v2 = deFloatSqrt((cartesian_coordinate.x - 1.0f) * (cartesian_coordinate.x - 1.0f) +
											  (cartesian_coordinate.y - 1.0f) * (cartesian_coordinate.y - 1.0f));
			float curr_delta_v3 = deFloatSqrt((cartesian_coordinate.x - 0.0f) * (cartesian_coordinate.x - 0.0f) +
											  (cartesian_coordinate.y - 1.0f) * (cartesian_coordinate.y - 1.0f));

			if (is_first_iteration)
			{
				delta_v1 = curr_delta_v1;
				delta_v2 = curr_delta_v2;
				delta_v3 = curr_delta_v3;

				/* No need to update selected vertex indices, since this is the very first iteration */
				is_first_iteration = false;
			}
			else
			{
				if (curr_delta_v1 < delta_v1)
				{
					delta_v1		  = curr_delta_v1;
					selected_v1_index = curr_index;
				}

				if (curr_delta_v2 < delta_v2)
				{
					delta_v2		  = curr_delta_v2;
					selected_v2_index = curr_index;
				}

				if (curr_delta_v3 < delta_v3)
				{
					delta_v3		  = curr_delta_v3;
					selected_v3_index = curr_index;
				}
			}
		} /* for (all remaining coordinates) */

		/* Extract the vertices out of the data set */
		_tess_coordinate_cartesian corner_vertices[] = { *(coordinates.begin() + selected_v1_index),
														 *(coordinates.begin() + selected_v2_index),
														 *(coordinates.begin() + selected_v3_index) };
		const unsigned int n_corner_vertices = sizeof(corner_vertices) / sizeof(corner_vertices[0]);

		/* Remove the vertices from the data set */
		for (unsigned int n_corner_vertex = 0; n_corner_vertex < n_corner_vertices; ++n_corner_vertex)
		{
			const _tess_coordinate_cartesian&				  vertex = corner_vertices[n_corner_vertex];
			std::vector<_tess_coordinate_cartesian>::iterator iterator =
				std::find(coordinates.begin(), coordinates.end(), vertex);

			DE_ASSERT(iterator != coordinates.end());
			if (iterator != coordinates.end())
			{
				coordinates.erase(iterator);
			}
		} /* for (all corner vertices) */

		/* Now that we know where the corner vertices are, identify all points that lie
		 * on edges defined by these vertices */
		std::vector<_tess_coordinate_cartesian> edge_v1_v2_vertices;
		std::vector<_tess_coordinate_cartesian> edge_v2_v3_vertices;
		std::vector<_tess_coordinate_cartesian> edge_v3_v1_vertices;
		const _tess_coordinate_cartesian&		v1 = corner_vertices[0];
		const _tess_coordinate_cartesian&		v2 = corner_vertices[1];
		const _tess_coordinate_cartesian&		v3 = corner_vertices[2];

		for (std::vector<_tess_coordinate_cartesian>::const_iterator iterator = coordinates.begin();
			 iterator != coordinates.end(); iterator++, curr_index++)
		{
			const _tess_coordinate_cartesian& cartesian_coordinate = *iterator;

			if (isPointOnLine(v1, v2, cartesian_coordinate))
			{
				edge_v1_v2_vertices.push_back(*iterator);
			}

			if (isPointOnLine(v2, v3, cartesian_coordinate))
			{
				edge_v2_v3_vertices.push_back(*iterator);
			}

			if (isPointOnLine(v3, v1, cartesian_coordinate))
			{
				edge_v3_v1_vertices.push_back(*iterator);
			}
		} /* for (all coordinates in data set) */

		/* Now that edge vertices have been identified, remove them from the data set */
		const std::vector<_tess_coordinate_cartesian>* edge_ptrs[] = { &edge_v1_v2_vertices, &edge_v2_v3_vertices,
																	   &edge_v3_v1_vertices };
		const unsigned int n_edge_ptrs = sizeof(edge_ptrs) / sizeof(edge_ptrs[0]);

		for (unsigned int n_edge_ptr = 0; n_edge_ptr < n_edge_ptrs; ++n_edge_ptr)
		{
			const std::vector<_tess_coordinate_cartesian>& edge			   = *edge_ptrs[n_edge_ptr];
			const unsigned int							   n_edge_vertices = (const unsigned int)edge.size();

			for (unsigned int n_edge_vertex = 0; n_edge_vertex < n_edge_vertices; ++n_edge_vertex)
			{
				const _tess_coordinate_cartesian&				  coordinate = edge[n_edge_vertex];
				std::vector<_tess_coordinate_cartesian>::iterator iterator =
					std::find(coordinates.begin(), coordinates.end(), coordinate);

				if (iterator != coordinates.end())
				{
					coordinates.erase(iterator);
				}
			} /* for (all edge vertices) */
		}	 /* for (all edges) */

		/* Add corner coordinates to our vectors, but only if they are not
		 * already there.
		 */
		if (std::find(edge_v1_v2_vertices.begin(), edge_v1_v2_vertices.end(), v1) == edge_v1_v2_vertices.end())
		{
			edge_v1_v2_vertices.push_back(v1);
		}

		if (std::find(edge_v1_v2_vertices.begin(), edge_v1_v2_vertices.end(), v2) == edge_v1_v2_vertices.end())
		{
			edge_v1_v2_vertices.push_back(v2);
		}

		if (std::find(edge_v2_v3_vertices.begin(), edge_v2_v3_vertices.end(), v2) == edge_v2_v3_vertices.end())
		{
			edge_v2_v3_vertices.push_back(v2);
		}

		if (std::find(edge_v2_v3_vertices.begin(), edge_v2_v3_vertices.end(), v3) == edge_v2_v3_vertices.end())
		{
			edge_v2_v3_vertices.push_back(v3);
		}

		if (std::find(edge_v3_v1_vertices.begin(), edge_v3_v1_vertices.end(), v3) == edge_v3_v1_vertices.end())
		{
			edge_v3_v1_vertices.push_back(v3);
		}

		if (std::find(edge_v3_v1_vertices.begin(), edge_v3_v1_vertices.end(), v1) == edge_v3_v1_vertices.end())
		{
			edge_v3_v1_vertices.push_back(v1);
		}

		/* Sort all points relative to corner point */
		std::sort(edge_v1_v2_vertices.begin(), edge_v1_v2_vertices.end(), _comparator_relative_to_base_point(v1));

		std::sort(edge_v2_v3_vertices.begin(), edge_v2_v3_vertices.end(), _comparator_relative_to_base_point(v2));

		std::sort(edge_v3_v1_vertices.begin(), edge_v3_v1_vertices.end(), _comparator_relative_to_base_point(v3));

		/* We now have all the data to update the result vector with new edge data */
		for (unsigned int n_edge_ptr = 0; n_edge_ptr < n_edge_ptrs; ++n_edge_ptr)
		{
			/* Compute tessellation level values for the edge */
			glw::GLfloat curr_tess_level	  = 0.0f;
			glw::GLfloat outermost_tess_level = 0.0f;

			if (tess_level_delta == 0)
			{
				switch (n_edge_ptr)
				{
				/* Assuming:
				 *
				 * v1 = (1, 0, 0)
				 * v2 = (0, 1, 0)
				 * v3 = (0, 0, 1)
				 */
				case 0: /* v1->v2 */
				{
					curr_tess_level		 = run.outer[2];
					outermost_tess_level = run.outer[2];

					break;
				}

				case 1: /* v2->v3 */
				{
					curr_tess_level		 = run.outer[0];
					outermost_tess_level = run.outer[0];

					break;
				}

				case 2: /* v3->v1 */
				{
					curr_tess_level		 = run.outer[1];
					outermost_tess_level = run.outer[1];

					break;
				}

				default:
				{
					DE_ASSERT("Invalid edge index");
				}
				} /* switch (n_edge_ptr) */
			}
			else
			{
				curr_tess_level		 = base_tess_level - (float)tess_level_delta;
				outermost_tess_level = base_tess_level;
			}

			/* Convert internal representation to _tess_edge */
			const std::vector<_tess_coordinate_cartesian>& edge				= *edge_ptrs[n_edge_ptr];
			const _tess_coordinate_cartesian&			   edge_start_point = *edge.begin();
			const _tess_coordinate_cartesian&			   edge_end_point   = *(edge.begin() + (edge.size() - 1));
			float										   edge_length =
				deFloatSqrt((edge_end_point.x - edge_start_point.x) * (edge_end_point.x - edge_start_point.x) +
							(edge_end_point.y - edge_start_point.y) * (edge_end_point.y - edge_start_point.y));
			_tess_edge result_edge(curr_tess_level, outermost_tess_level, edge_length);

			for (std::vector<_tess_coordinate_cartesian>::const_iterator edge_point_iterator = edge.begin();
				 edge_point_iterator != edge.end(); edge_point_iterator++)
			{
				const _tess_coordinate_cartesian& edge_point = *edge_point_iterator;

				result_edge.points.push_back(edge_point);
			}

			/* Good to store the edge now */
			result.push_back(result_edge);
		} /* for (all edges) */

		/* Moving on with next inner triangle. As per spec, reduce tessellation level by 2 */
		tess_level_delta += 2;
	} /* while (run.n_vertices > 0) */

	return result;
}

/** Tells whether given two-dimensional point is located on a two-dimensional line defined
 *  by two points.
 *
 *  @param line_v1 First vertex defining the line;
 *  @param line_v2 Second vertex defining the line;
 *  @param point   Point to check.
 *
 *  @return true  if the point was determned to be a part of the line,
 *          false otherwise.
 **/
bool TessellationShaderVertexSpacing::isPointOnLine(const _tess_coordinate_cartesian& line_v1,
													const _tess_coordinate_cartesian& line_v2,
													const _tess_coordinate_cartesian& point)

{
	bool result = false;

	/* Calculate distance from a point to a line passing through two points */
	float Dx		  = line_v1.x - line_v2.x;
	float Dy		  = line_v1.y - line_v2.y;
	float denominator = deFloatSqrt(Dx * Dx + Dy * Dy);
	float d = de::abs(Dy * point.x - Dx * point.y + line_v1.x * line_v2.y - line_v2.x * line_v1.y) / denominator;

	if (de::abs(d) < epsilon)
	{
		result = true;
	}

	return result;
}

/** Initializes ES objects necessary to run the test. */
void TessellationShaderVertexSpacing::initTest()
{
	/* Skip if required extensions are not supported. */
	if (!m_is_tessellation_shader_supported)
	{
		throw tcu::NotSupportedError(TESSELLATION_SHADER_EXTENSION_NOT_SUPPORTED);
	}

	/* Initialize Utils instance */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	m_utils = new TessellationShaderUtils(gl, this);

	/* Initialize vertex array object */
	gl.genVertexArrays(1, &m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate vertex array object");

	gl.bindVertexArray(m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding vertex array object!");

	/* Retrieve GL_MAX_TESS_GEN_LEVEL_EXT value */
	gl.getIntegerv(m_glExtTokens.MAX_TESS_GEN_LEVEL, &m_gl_max_tess_gen_level_value);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_TESS_GEN_LEVEL_EXT pname");

	const _tessellation_shader_vertex_spacing vs_modes[] = { TESSELLATION_SHADER_VERTEX_SPACING_EQUAL,
															 TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_EVEN,
															 TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_ODD,
															 TESSELLATION_SHADER_VERTEX_SPACING_DEFAULT };
	const unsigned int n_vs_modes = sizeof(vs_modes) / sizeof(vs_modes[0]);

	const _tessellation_primitive_mode primitive_modes[] = { TESSELLATION_SHADER_PRIMITIVE_MODE_ISOLINES,
															 TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES,
															 TESSELLATION_SHADER_PRIMITIVE_MODE_QUADS };
	const unsigned int n_primitive_modes = sizeof(primitive_modes) / sizeof(primitive_modes[0]);

	/* Iterate through all primitive modes */
	for (unsigned int n_primitive_mode = 0; n_primitive_mode < n_primitive_modes; ++n_primitive_mode)
	{
		_tessellation_primitive_mode primitive_mode = primitive_modes[n_primitive_mode];

		/* Generate tessellation level set for current primitive mode */
		_tessellation_levels_set tess_levels_set;

		tess_levels_set = TessellationShaderUtils::getTessellationLevelSetForPrimitiveMode(
			primitive_mode, m_gl_max_tess_gen_level_value,
			TESSELLATION_LEVEL_SET_FILTER_INNER_AND_OUTER_LEVELS_USE_DIFFERENT_VALUES);

		/* Iterate through all vertex spacing modes */
		for (unsigned int n_vs_mode = 0; n_vs_mode < n_vs_modes; ++n_vs_mode)
		{
			_tessellation_shader_vertex_spacing vs_mode = vs_modes[n_vs_mode];

			/* Iterate through all tessellation level combinations */
			for (_tessellation_levels_set_const_iterator tess_levels_set_iterator = tess_levels_set.begin();
				 tess_levels_set_iterator != tess_levels_set.end(); tess_levels_set_iterator++)
			{
				const _tessellation_levels& tess_levels = *tess_levels_set_iterator;
				_run						run;

				/* Skip border cases that this test cannot handle */
				if (primitive_mode == TESSELLATION_SHADER_PRIMITIVE_MODE_QUADS &&
					vs_mode == TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_ODD &&
					(tess_levels.inner[0] <= 1 || tess_levels.inner[1] <= 1))
				{
					continue;
				}

				/* Fill run descriptor */
				memcpy(run.inner, tess_levels.inner, sizeof(run.inner));
				memcpy(run.outer, tess_levels.outer, sizeof(run.outer));

				run.primitive_mode = primitive_mode;
				run.vertex_spacing = vs_mode;

				/* Retrieve vertex data for both passes */
				run.n_vertices = m_utils->getAmountOfVerticesGeneratedByTessellator(
					run.primitive_mode, run.inner, run.outer, run.vertex_spacing, true); /* is_point_mode_enabled */

				if (run.n_vertices == 0)
				{
					std::string primitive_mode_string =
						TessellationShaderUtils::getESTokenForPrimitiveMode(primitive_mode);
					std::string vs_mode_string = TessellationShaderUtils::getESTokenForVertexSpacingMode(vs_mode);

					m_testCtx.getLog() << tcu::TestLog::Message << "No vertices were generated by tessellator for: "
																   "inner tess levels:"
																   "["
									   << run.inner[0] << ", " << run.inner[1] << "]"
																				  ", outer tess levels:"
																				  "["
									   << run.outer[0] << ", " << run.outer[1] << ", " << run.outer[2] << ", "
									   << run.outer[3] << "]"
														  ", primitive mode: "
									   << primitive_mode_string << ", vertex spacing: " << vs_mode_string
									   << tcu::TestLog::EndMessage;

					TCU_FAIL("Zero vertices were generated by tessellator");
				}

				/* Retrieve the data buffers */
				run.data = m_utils->getDataGeneratedByTessellator(
					run.inner, true, /* is_point_mode_enabled */
					run.primitive_mode, TESSELLATION_SHADER_VERTEX_ORDERING_CCW, run.vertex_spacing, run.outer);

				/* 'triangles' tessellation data is expressed in barycentric coordinates. Before we can
				 * continue, we need to convert the data to Euclidean space */
				if (run.primitive_mode == TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES)
				{
					run.data_cartesian = new float[run.n_vertices * 2 /* components */];

					for (unsigned int n_vertex = 0; n_vertex < run.n_vertices; ++n_vertex)
					{
						const float* barycentric_vertex_data =
							(const float*)(&run.data[0]) + n_vertex * 3;						  /* components */
						float* cartesian_vertex_data = (float*)run.data_cartesian + n_vertex * 2; /* components */

						TessellationShaderUtils::convertBarycentricCoordinatesToCartesian(barycentric_vertex_data,
																						  cartesian_vertex_data);
					}
				} /* if (run.primitive_mode == TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES) */
				else
				{
					run.data_cartesian = DE_NULL;
				}

				/* Store the run data */
				m_runs.push_back(run);
			} /* for (all tessellation level values ) */
		}	 /* for (all primitive modes) */
	}		  /* for (all vertex spacing modes) */
}

/** Executes the test.
 *
 *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
 *
 *  Note the function throws exception should an error occur!
 *
 *  @return STOP if the test has finished, CONTINUE to indicate iterate() should be called once again.
 **/
tcu::TestNode::IterateResult TessellationShaderVertexSpacing::iterate(void)
{
	/* Do not execute if required extensions are not supported. */
	if (!m_is_tessellation_shader_supported)
	{
		throw tcu::NotSupportedError(TESSELLATION_SHADER_EXTENSION_NOT_SUPPORTED);
	}

	/* Initialize the test */
	initTest();

	/* Iterate through all runs */
	for (_runs_const_iterator run_iterator = m_runs.begin(); run_iterator != m_runs.end(); run_iterator++)
	{
		_tess_edges edges;
		const _run& run = *run_iterator;

		switch (run.primitive_mode)
		{
		case TESSELLATION_SHADER_PRIMITIVE_MODE_ISOLINES:
		{
			edges = getEdgesForIsolinesTessellation(run);

			break;
		}

		case TESSELLATION_SHADER_PRIMITIVE_MODE_QUADS:
		{
			edges = getEdgesForQuadsTessellation(run);

			break;
		}

		case TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES:
		{
			edges = getEdgesForTrianglesTessellation(run);

			break;
		}

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

		verifyEdges(edges, run);
	} /* for (all runs) */

	/* All done */
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	return STOP;
}

/* Verifies that user-provided edges follow the vertex spacing convention, as
 * defined in the extension specification.
 *
 * This function throws a TestError, should an error occur or the data is found
 * to be incorrect.
 *
 * @param edges Data of all edges to run the check against.
 * @param run   Test run properties.
 **/
void TessellationShaderVertexSpacing::verifyEdges(const _tess_edges& edges, const _run& run)
{
	/* Cache strings that may be used by logging the routines */
	const std::string primitive_mode_string = TessellationShaderUtils::getESTokenForPrimitiveMode(run.primitive_mode);
	const std::string vertex_spacing_string =
		TessellationShaderUtils::getESTokenForVertexSpacingMode(run.vertex_spacing);

	/* Iterate through all edges */
	unsigned int n_edge = 0;

	for (_tess_edges_const_iterator edges_iterator = edges.begin(); edges_iterator != edges.end();
		 edges_iterator++, n_edge++)
	{
		const _tess_edge&		edge									  = *edges_iterator;
		float					edge_clamped_tess_level					  = 0.0f;
		float					edge_clamped_rounded_tess_level			  = 0.0f;
		float					outermost_edge_tess_level_clamped_rounded = 0.0f;
		_tess_coordinate_deltas segment_deltas;

		TessellationShaderUtils::getTessellationLevelAfterVertexSpacing(
			run.vertex_spacing, edge.outermost_tess_level, m_gl_max_tess_gen_level_value, DE_NULL, /* out_clamped */
			&outermost_edge_tess_level_clamped_rounded);

		/* Retrieve amount of segments the edge should consist of */
		TessellationShaderUtils::getTessellationLevelAfterVertexSpacing(
			run.vertex_spacing, edge.tess_level, m_gl_max_tess_gen_level_value, &edge_clamped_tess_level,
			&edge_clamped_rounded_tess_level);

		/* Take two subsequent points if they are available. Vertex spacing has no meaning
		 * in a world of degenerate edges, so skip the check if we have just encountered one.
		 */
		const unsigned int n_points = (const unsigned int)edge.points.size();

		if (n_points < 2)
		{
			continue;
		}

		/* Compute segment deltas */
		for (unsigned int n_base_point = 0; n_base_point < n_points - 1; n_base_point++)
		{
			const _tess_coordinate_cartesian& point_a = edge.points[n_base_point + 0];
			const _tess_coordinate_cartesian& point_b = edge.points[n_base_point + 1];

			/* Calculate the distance between the points */
			float distance_nonsqrt = 0.0f;
			float distance		   = 0.0f;

			distance_nonsqrt =
				(point_a.x - point_b.x) * (point_a.x - point_b.x) + (point_a.y - point_b.y) * (point_a.y - point_b.y);

			distance = deFloatSqrt(distance_nonsqrt);

			/* Check if the distance is not already recognized. */
			_tess_coordinate_deltas_iterator deltas_iterator;

			for (deltas_iterator = segment_deltas.begin(); deltas_iterator != segment_deltas.end(); deltas_iterator++)
			{
				if (de::abs(deltas_iterator->delta - distance) < epsilon)
				{
					/* Increment the counter and leave */
					deltas_iterator->counter++;

					break;
				}
			}

			if (deltas_iterator == segment_deltas.end())
			{
				/* This is the first time we're encountering a segment of this specific length. */
				_tess_coordinate_delta new_item;

				new_item.counter = 1;
				new_item.delta   = distance;

				segment_deltas.push_back(new_item);
			}
		} /* for (all base points) */

		DE_ASSERT(segment_deltas.size() != 0);

		switch (run.vertex_spacing)
		{
		case TESSELLATION_SHADER_VERTEX_SPACING_DEFAULT:
		case TESSELLATION_SHADER_VERTEX_SPACING_EQUAL:
		{
			/* For equal vertex spacings, we should end up with a single _tess_coordinate_delta instance
			 * of a predefined length, describing exactly edge_clamped_rounded_tess_level invocations */
			float expected_delta = edge.edge_length / edge_clamped_rounded_tess_level;

			if (segment_deltas.size() != 1)
			{
				m_testCtx.getLog() << tcu::TestLog::Message
								   << "More than one segment delta was generated for the following tessellation"
									  " configuration: "
									  "primitive mode:"
								   << primitive_mode_string << "vertex spacing mode:" << vertex_spacing_string
								   << "inner tessellation levels: (" << run.inner[0] << ", " << run.inner[1]
								   << ")"
									  ", outer tessellation levels: ("
								   << run.outer[0] << ", " << run.outer[1] << ", " << run.outer[2] << ", "
								   << run.outer[3] << ")" << tcu::TestLog::EndMessage;

				TCU_FAIL("Equal vertex spacing mode tessellation generated segment edges of varying lengths, "
						 "whereas only one was expected.");
			}

			if (de::abs(segment_deltas[0].delta - expected_delta) > epsilon)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Invalid segment delta (expected:" << expected_delta
								   << ", found: " << segment_deltas[0].delta
								   << ") was generated for the following tessellation configuration: "
									  "primitive mode:"
								   << primitive_mode_string << "vertex spacing mode:" << vertex_spacing_string
								   << "inner tessellation levels: (" << run.inner[0] << ", " << run.inner[1]
								   << ")"
									  ", outer tessellation levels: ("
								   << run.outer[0] << ", " << run.outer[1] << ", " << run.outer[2] << ", "
								   << run.outer[3] << ")" << tcu::TestLog::EndMessage;

				TCU_FAIL("Invalid delta between segments generated by the tessellator configured to run "
						 "in equal vertex spacing mode");
			}

			if (segment_deltas[0].counter != (unsigned int)edge_clamped_rounded_tess_level)
			{
				m_testCtx.getLog() << tcu::TestLog::Message
								   << "Invalid amount of segments (expected:" << (int)edge_clamped_rounded_tess_level
								   << ", found: " << segment_deltas[0].counter
								   << ") "
									  "was generated for the following tessellation configuration: "
									  "primitive mode:"
								   << primitive_mode_string << "vertex spacing mode:" << vertex_spacing_string
								   << "inner tessellation levels: (" << run.inner[0] << ", " << run.inner[1]
								   << ")"
									  ", outer tessellation levels: ("
								   << run.outer[0] << ", " << run.outer[1] << ", " << run.outer[2] << ", "
								   << run.outer[3] << ")" << tcu::TestLog::EndMessage;

				TCU_FAIL("Invalid amount of segments generated for equal vertex spacing mode");
			}

			break;
		} /* default/equal vertex spacing */

		case TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_EVEN:
		case TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_ODD:
		{
			/* For fractional vertex spacings, situation is more tricky. The extension specification
			 * is very liberal when it comes to defining segment lengths. Hence the only thing we
			 * should be testing here is that:
			 *
			 * a) No more than 2 deltas are generated for a single edge.
			 *
			 * b) If a single delta is generated, it should:
			 *
			 *    1. define exactly edge_clamped_rounded_tess_level-2 segments if
			 *    |edge_clamped_rounded_tess_level - edge_clamped_tess_level| == 2.0f,
			 *
			 *    2. define exactly edge_clamped_rounded_tess_level segments otherwise.
			 *
			 * c) If two deltas are generated, one of them should define 2 segments, and the other
			 *    one should define edge_clamped_rounded_tess_level-2 segments.
			 */

			if (segment_deltas.size() > 2)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "More than two segment deltas (" << segment_deltas.size()
								   << ") were generated for the following tessellation configuration: "
									  "primitive mode:"
								   << primitive_mode_string << "vertex spacing mode:" << vertex_spacing_string
								   << "inner tessellation levels: (" << run.inner[0] << ", " << run.inner[1]
								   << ")"
									  ", outer tessellation levels: ("
								   << run.outer[0] << ", " << run.outer[1] << ", " << run.outer[2] << ", "
								   << run.outer[3] << ")" << tcu::TestLog::EndMessage;

				TCU_FAIL("Fractional spacing mode tessellated edges to segments of more than two "
						 "differentiable lengths");
			}

			if (segment_deltas.size() == 1)
			{
				int expected_counter = 0;

				if (run.primitive_mode == TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES)
				{
					/* With each triangle level, 2 segments go out. Each triangle consists of 3 edges */
					expected_counter = (int)outermost_edge_tess_level_clamped_rounded - 2 * (n_edge / 3);
				}
				else
				{
					expected_counter = (int)edge_clamped_rounded_tess_level;
					if (run.primitive_mode == TESSELLATION_SHADER_PRIMITIVE_MODE_QUADS &&
						run.vertex_spacing == TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_ODD)
					{
						/* 8 edges expected in total; we should expect 2 segments less for the inner quad */
						expected_counter = (int)edge_clamped_rounded_tess_level - 2 * (n_edge / 4);
					}

					/* For degenerate cases, always assume exactly one segment should be generated */
					if (edge.tess_level <= 0.0f)
					{
						expected_counter = 1;
					}
				}

				if (segment_deltas[0].counter != (unsigned int)expected_counter)
				{
					m_testCtx.getLog() << tcu::TestLog::Message
									   << "Invalid amount of segments (expected:" << expected_counter
									   << ", found: " << segment_deltas[0].counter
									   << ") "
										  "was generated for the following tessellation configuration: "
										  "primitive mode:"
									   << primitive_mode_string << "vertex spacing mode:" << vertex_spacing_string
									   << "inner tessellation levels: (" << run.inner[0] << ", " << run.inner[1]
									   << ")"
										  ", outer tessellation levels: ("
									   << run.outer[0] << ", " << run.outer[1] << ", " << run.outer[2] << ", "
									   << run.outer[3] << ")" << tcu::TestLog::EndMessage;

					TCU_FAIL("Invalid amount of segments generated for fractional vertex spacing mode");
				}
			}
			else
			{
				DE_ASSERT(segment_deltas.size() == 2);

				if (!((segment_deltas[0].counter == 2 &&
					   segment_deltas[1].counter == ((unsigned int)edge_clamped_rounded_tess_level - 2)) ||
					  (segment_deltas[1].counter == 2 &&
					   segment_deltas[0].counter == ((unsigned int)edge_clamped_rounded_tess_level - 2))))
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "Invalid number of segments with different deltas ("
									   << segment_deltas[0].delta << " and " << segment_deltas[1].delta
									   << ") was generated. "
										  "primitive mode:"
									   << primitive_mode_string << "vertex spacing mode:" << vertex_spacing_string
									   << "inner tessellation levels: (" << run.inner[0] << ", " << run.inner[1]
									   << ")"
										  ", outer tessellation levels: ("
									   << run.outer[0] << ", " << run.outer[1] << ", " << run.outer[2] << ", "
									   << run.outer[3] << ")" << tcu::TestLog::EndMessage;

					TCU_FAIL("Equal amount of segments was generated for segments of different deltas");
				}

				if (segment_deltas[0].counter != 2 && segment_deltas[1].counter != 2)
				{
					m_testCtx.getLog() << tcu::TestLog::Message
									   << "Neither of the segments generated by the tessellator was defined "
										  "exactly twice."
										  "primitive mode:"
									   << primitive_mode_string << "vertex spacing mode:" << vertex_spacing_string
									   << "inner tessellation levels: (" << run.inner[0] << ", " << run.inner[1]
									   << ")"
										  ", outer tessellation levels: ("
									   << run.outer[0] << ", " << run.outer[1] << ", " << run.outer[2] << ", "
									   << run.outer[3] << ")" << tcu::TestLog::EndMessage;

					TCU_FAIL("Neither of the generated segments was repeated exactly twice "
							 "for fractional vertex spacing mode");
				}
			}

			break;
		} /* fractional even/odd vertex spacing types */

		default:
		{
			TCU_FAIL("Unrecognized vertex spacing mode");
		}
		} /* switch (run.vertex_spacing) */
	}	 /* for (all edges) */
}
}

/* namespace glcts */
