/*-------------------------------------------------------------------------
 * 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 = (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_FATAL("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 = (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 */
