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

namespace glcts
{

/** Constructor
 *
 * @param context Test context
 **/
TessellationShadersIsolines::TessellationShadersIsolines(Context& context, const ExtParameters& extParams)
	: TestCaseBase(context, extParams, "isolines_tessellation",
				   "Verifies that the number of isolines generated during tessellation is "
				   "derived from the first outer tessellation level.\n"
				   "Makes sure that the number of segments in each isoline is derived from "
				   "the second outer tessellation level.\n"
				   "Makes sure that both inner tessellation levels and the 3rd and the 4th "
				   "outer tessellation levels do not affect the tessellation process.\n"
				   "Makes sure that equal_spacing vertex spacing mode does not affect amount"
				   " of generated isolines.\n"
				   "Makes sure no line is drawn between (0, 1) and (1, 1) in (u, v) domain.")
	, m_irrelevant_tess_value_1(0.0f)
	, m_irrelevant_tess_value_2(0.0f)
	, m_utils_ptr(DE_NULL)
	, m_vao_id(0)
{
	/* Left blank on purpose */
}

/** Checks that amount of isolines generated during tessellation corresponds to the
 *  first outer tessellation level.
 *
 *  This check needs not to operate over all test results generated for a particular
 *  vertex spacing mode.
 *
 *  @param test_result Value of MAX_TESS_GEN_LEVEL token. For ES3.1 it will be equal to
 *                     GL_MAX_TESS_GEN_LEVEL_EXT and for ES3.2 to GL_MAX_TESS_GEN_LEVEL.
 *
 **/
void TessellationShadersIsolines::checkFirstOuterTessellationLevelEffect(_test_result&	 test_result,
																		 const glw::GLenum glMaxTessGenLevelToken)
{
	glcts::Context&		  context					  = test_result.parent->parent->getContext();
	const glw::Functions& gl						  = context.getRenderContext().getFunctions();
	glw::GLint			  gl_max_tess_gen_level_value = 0;
	unsigned int		  n_isolines_expected		  = 0;

	if (test_result.n_vertices != 0)
	{
		/* Calculate how many isolines we're expecting */
		gl.getIntegerv(glMaxTessGenLevelToken, &gl_max_tess_gen_level_value);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_TESS_GEN_LEVEL_EXT pname");

		/* NOTE: Amount of isolines should always be based on TESSELLATION_SHADER_VERTEX_SPACING_EQUAL
		 *       vertex spacing mode, even if a different one is defined in TE stage.
		 */
		float outer_zero_tess_level_clamped_rounded = 0.0f;

		TessellationShaderUtils::getTessellationLevelAfterVertexSpacing(
			TESSELLATION_SHADER_VERTEX_SPACING_EQUAL, test_result.parent->outer_tess_levels[0],
			gl_max_tess_gen_level_value, DE_NULL, /* out_clamped */
			&outer_zero_tess_level_clamped_rounded);

		n_isolines_expected = (unsigned int)outer_zero_tess_level_clamped_rounded;

		if (test_result.n_isolines != n_isolines_expected)
		{
			tcu::TestContext& test = test_result.parent->parent->getTestContext();

			test.getLog() << tcu::TestLog::Message
						  << "Tessellator generated an invalid amount of isolines:" << test_result.n_isolines
						  << " instead of the expected amount:" << n_isolines_expected
						  << " for the following inner tessellation level configuration:"
						  << " (" << test_result.parent->inner_tess_levels[0] << ", "
						  << test_result.parent->inner_tess_levels[1] << ")"
						  << " and the following outer tesellation level configuration:"
						  << " (" << test_result.parent->outer_tess_levels[0] << ", "
						  << test_result.parent->outer_tess_levels[1] << ", "
						  << test_result.parent->outer_tess_levels[2] << ", "
						  << test_result.parent->outer_tess_levels[3] << ")" << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid amount of isolines generated by tessellator");
		}
	} /* if (test_run.n_vertices != 0) */
}

/** Makes sure that tessellation coordinates generated for inner+outer tessellation level
 *  configurations, between which irrelevant levels have been defined, are exactly the same.
 *
 *  This check needs to operate over all test results generated for a particular
 *  vertex spacing mode.
 *
 *  This function throws a TestError exception if the check fails.
 **/
void TessellationShadersIsolines::checkIrrelevantTessellationLevelsHaveNoEffect()
{
	/* Make sure that two example data sets, for which irrelevant tessellation levels have
	 * been changed, are exactly the same
	 */
	DE_ASSERT(m_test_results.find(TESSELLATION_SHADER_VERTEX_SPACING_EQUAL) != m_test_results.end());

	const float			   epsilon								  = 1e-5f;
	float				   irrelevant_tess_level1_rounded_clamped = 0.0f;
	int					   irrelevant_tess_level1				  = 0;
	float				   irrelevant_tess_level2_rounded_clamped = 0.0f;
	int					   irrelevant_tess_level2				  = 0;
	_test_results_iterator test_result_iterator_start =
		m_test_results[TESSELLATION_SHADER_VERTEX_SPACING_EQUAL].begin();
	_test_results_iterator test_result_iterator_end = m_test_results[TESSELLATION_SHADER_VERTEX_SPACING_EQUAL].end();

	/* Calculate two tessellation level values that we've used in init() */
	const glw::Functions& gl						  = m_context.getRenderContext().getFunctions();
	glw::GLint			  gl_max_tess_gen_level_value = 0;

	gl.getIntegerv(m_glExtTokens.MAX_TESS_GEN_LEVEL, &gl_max_tess_gen_level_value);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_TESS_GEN_LEVEL_EXT pname");

	TessellationShaderUtils::getTessellationLevelAfterVertexSpacing(
		TESSELLATION_SHADER_VERTEX_SPACING_EQUAL, m_irrelevant_tess_value_1, gl_max_tess_gen_level_value,
		DE_NULL, /* out_clamped */
		&irrelevant_tess_level1_rounded_clamped);
	TessellationShaderUtils::getTessellationLevelAfterVertexSpacing(
		TESSELLATION_SHADER_VERTEX_SPACING_EQUAL, m_irrelevant_tess_value_2, gl_max_tess_gen_level_value,
		DE_NULL, /* out_clamped */
		&irrelevant_tess_level2_rounded_clamped);

	irrelevant_tess_level1 = (int)irrelevant_tess_level1_rounded_clamped;
	irrelevant_tess_level2 = (int)irrelevant_tess_level2_rounded_clamped;

	DE_ASSERT(de::abs(irrelevant_tess_level1 - irrelevant_tess_level2) > 0);

	/* Iterate through all test runs for equal spacing */
	for (_test_results_iterator test_result_iterator = test_result_iterator_start;
		 test_result_iterator != test_result_iterator_end; test_result_iterator++)
	{
		_test_result test_result = *test_result_iterator;

		if (test_result.irrelevant_tess_level == irrelevant_tess_level1)
		{
			_test_result test_result_reference =
				findTestResult(irrelevant_tess_level2, test_result.outer1_tess_level, test_result.outer2_tess_level,
							   TESSELLATION_SHADER_VERTEX_SPACING_EQUAL);

			/* data for current test run and the reference one should match */
			DE_ASSERT(test_result.n_vertices == test_result_reference.n_vertices);

			for (unsigned int n_vertex = 0; n_vertex < test_result.n_vertices; ++n_vertex)
			{
				const float* vertex_data_1 = (&test_result.rendered_data[0]) + n_vertex * 3;		   /* components */
				const float* vertex_data_2 = (&test_result_reference.rendered_data[0]) + n_vertex * 3; /* components */

				if (de::abs(vertex_data_1[0] - vertex_data_2[0]) > epsilon ||
					de::abs(vertex_data_1[1] - vertex_data_2[1]) > epsilon ||
					de::abs(vertex_data_1[2] - vertex_data_2[2]) > epsilon)
				{
					tcu::TestContext& test = test_result_iterator->parent->parent->getTestContext();

					test.getLog()
						<< tcu::TestLog::Message
						<< "Tessellator generated non-matching data for different tessellation level configurations, "
						   "where only irrelevant tessellation levels have been changed; "
						<< " data generated for {inner:"
						<< " (" << test_result.parent->inner_tess_levels[0] << ", "
						<< test_result.parent->inner_tess_levels[1] << ")"
						<< " outer:"
						<< " (" << test_result.parent->outer_tess_levels[0] << ", "
						<< test_result.parent->outer_tess_levels[1] << ", " << test_result.parent->outer_tess_levels[2]
						<< ", " << test_result.parent->outer_tess_levels[3] << ")"
						<< "}:"
						<< " (" << vertex_data_1[0] << ", " << vertex_data_1[1] << ", " << vertex_data_1[2] << ")"
						<< ", data generated for {inner:"
						<< " (" << test_result_reference.parent->inner_tess_levels[0] << ", "
						<< test_result_reference.parent->inner_tess_levels[1] << ")"
						<< " outer:"
						<< " (" << test_result_reference.parent->outer_tess_levels[0] << ", "
						<< test_result_reference.parent->outer_tess_levels[1] << ", "
						<< test_result_reference.parent->outer_tess_levels[2] << ", "
						<< test_result_reference.parent->outer_tess_levels[3] << ")"
						<< "}:"
						<< " (" << vertex_data_2[0] << ", " << vertex_data_2[1] << ", " << vertex_data_2[2] << ")"
						<< tcu::TestLog::EndMessage;

					TCU_FAIL("Invalid amount of unique line segments generated by tessellator");
				} /* if (equal and fractional_even data mismatch) */
			}	 /* for (all vertices) */
		}		  /* if (current test result's irrelelvant tessellation levels match what we're after) */
	}			  /* for (all test runs) */
}

/** Checks that the amount of line segments generated per isoline is as defined by
 *  second outer tessellation level.
 *
 *  This check needs not to operate over all test results generated for a particular
 *  vertex spacing mode.
 *
 *  This function throws a TestError exception if the check fails.
 *
 *  @param test_result Test result descriptor to perform the check on.
 *
 **/
void TessellationShadersIsolines::checkSecondOuterTessellationLevelEffect(_test_result&		test_result,
																		  const glw::GLenum glMaxTessGenLevelToken)
{
	typedef float _line_segment_x;
	typedef std::pair<_line_segment_x, _line_segment_x> _line_segment;
	typedef std::vector<_line_segment> _line_segments;
	typedef _line_segments::iterator   _line_segments_iterator;

	glcts::Context&		  context = test_result.parent->parent->getContext();
	const float			  epsilon = 1e-5f;
	_line_segments		  found_line_segments;
	const glw::Functions& gl								   = context.getRenderContext().getFunctions();
	glw::GLint			  gl_max_tess_gen_level_value		   = 0;
	float				  outer_tess_levels1_clamped_rounded   = 0.0f;
	unsigned int		  n_line_segments_per_isoline_expected = 0;
	unsigned int		  n_unique_line_segments_found		   = 0;

	if (test_result.n_vertices != 0)
	{
		/* Calculate how many isolines we're expecting */
		gl.getIntegerv(glMaxTessGenLevelToken, &gl_max_tess_gen_level_value);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_TESS_GEN_LEVEL_EXT pname");

		TessellationShaderUtils::getTessellationLevelAfterVertexSpacing(
			test_result.parent->vertex_spacing_mode, test_result.parent->outer_tess_levels[1],
			gl_max_tess_gen_level_value, DE_NULL, /* out_clamped */
			&outer_tess_levels1_clamped_rounded);

		n_line_segments_per_isoline_expected = (unsigned int)outer_tess_levels1_clamped_rounded;

		/* Count unique line segments found in all the line segments making up the result data set.  */
		for (unsigned int n_vertex = 0; n_vertex < test_result.n_vertices;
			 n_vertex += 2 /* vertices per line segment */)
		{
			bool		 was_line_segment_found = false;
			const float* vertex1				= (&test_result.rendered_data[0]) + n_vertex * 3; /* components */
			float		 vertex1_x				= vertex1[0];
			const float* vertex2				= (&test_result.rendered_data[0]) + (n_vertex + 1) * 3; /* components */
			float		 vertex2_x				= vertex2[0];

			for (_line_segments_iterator found_line_segments_iterator = found_line_segments.begin();
				 found_line_segments_iterator != found_line_segments.end(); found_line_segments_iterator++)
			{
				float& found_vertex1_x = found_line_segments_iterator->first;
				float& found_vertex2_x = found_line_segments_iterator->second;

				if (de::abs(found_vertex1_x - vertex1_x) < epsilon && de::abs(found_vertex2_x - vertex2_x) < epsilon)
				{
					was_line_segment_found = true;

					break;
				}
			} /* for (all found Ys) */

			if (!was_line_segment_found)
			{
				found_line_segments.push_back(_line_segment(vertex1_x, vertex2_x));
			}
		} /* for (all vertices) */

		/* Compare the values */
		n_unique_line_segments_found = (unsigned int)found_line_segments.size();

		if (n_unique_line_segments_found != n_line_segments_per_isoline_expected)
		{
			tcu::TestContext& test = test_result.parent->parent->getTestContext();

			test.getLog() << tcu::TestLog::Message << "Tessellator generated an invalid amount of unique line segments:"
						  << n_unique_line_segments_found
						  << " instead of the expected amount:" << n_line_segments_per_isoline_expected
						  << " for the following inner tessellation level configuration:"
						  << " (" << test_result.parent->inner_tess_levels[0] << ", "
						  << test_result.parent->inner_tess_levels[1] << ")"
						  << " and the following outer tesellation level configuration:"
						  << " (" << test_result.parent->outer_tess_levels[0] << ", "
						  << test_result.parent->outer_tess_levels[1] << ", "
						  << test_result.parent->outer_tess_levels[2] << ", "
						  << test_result.parent->outer_tess_levels[3] << ")"
						  << " and the following vertex spacing mode: " << test_result.parent->vertex_spacing_mode
						  << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid amount of unique line segments generated by tessellator");
		}
	} /* if (test_run.n_vertices != 0) */
}

/** Verifies that no vertex making up any of the line segments outputted by the
 *  tessellator is located at height equal to -1.
 *
 *  This check needs not to operate over all test results generated for a particular
 *  vertex spacing mode.
 *
 *  This function throws a TestError exception if the check fails.
 *
 *  @param test_result Test result descriptor to perform the check on.
 *
 **/
void TessellationShadersIsolines::checkNoLineSegmentIsDefinedAtHeightOne(_test_result& test_result, glw::GLenum unused)
{
	(void)unused; // suppress warning

	const float epsilon = 1e-5f;

	for (unsigned int n_vertex = 0; n_vertex < test_result.n_vertices; ++n_vertex)
	{
		const float* vertex = (&test_result.rendered_data[0]) + n_vertex * 3; /* components */

		if (de::abs(vertex[1] - 1.0f) < epsilon)
		{
			tcu::TestContext& test = test_result.parent->parent->getTestContext();

			test.getLog() << tcu::TestLog::Message << "Tessellator generated the following coordinate:"
						  << " (" << vertex[0] << ", " << vertex[1] << ", " << vertex[2] << ")"
						  << " for the following inner tessellation level configuration:"
						  << " (" << test_result.parent->inner_tess_levels[0] << ", "
						  << test_result.parent->inner_tess_levels[1] << ")"
						  << " and the following outer tesellation level configuration:"
						  << " (" << test_result.parent->outer_tess_levels[0] << ", "
						  << test_result.parent->outer_tess_levels[1] << ", "
						  << test_result.parent->outer_tess_levels[2] << ", "
						  << test_result.parent->outer_tess_levels[3] << ")"
						  << " which is invalid: Y must never be equal to 1." << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid line segment generated by tessellator");
		} /* If the Y coordinate is set at 1 */
	}	 /* for (all vertices) */
}

/** Verifies that amount of isolines generated for the same inner+outer level
 *  configurations but for different vertex spacing modes is exactly the same.
 *
 *  This check needs to operate over all test results generated for a particular
 *  vertex spacing mode.
 *
 *  This function throws a TestError exception if the check fails.
 *
 **/
void TessellationShadersIsolines::checkVertexSpacingDoesNotAffectAmountOfGeneratedIsolines()
{
	DE_ASSERT(m_tests.find(TESSELLATION_SHADER_VERTEX_SPACING_EQUAL) != m_tests.end());

	_test_results_iterator test_result_iterator_start =
		m_test_results[TESSELLATION_SHADER_VERTEX_SPACING_EQUAL].begin();
	_test_results_iterator test_result_iterator_end = m_test_results[TESSELLATION_SHADER_VERTEX_SPACING_EQUAL].end();

	for (_test_results_iterator test_result_iterator = test_result_iterator_start;
		 test_result_iterator != test_result_iterator_end; test_result_iterator++)
	{
		_test_result& test_result_equal = *test_result_iterator;
		_test_result  test_result_fe;
		_test_result  test_result_fo;

		/* Find a corresponding fractional_even test run descriptor */
		test_result_fe =
			findTestResult(test_result_equal.irrelevant_tess_level, test_result_equal.outer1_tess_level,
						   test_result_equal.outer2_tess_level, TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_EVEN);
		test_result_fo =
			findTestResult(test_result_equal.irrelevant_tess_level, test_result_equal.outer1_tess_level,
						   test_result_equal.outer2_tess_level, TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_ODD);

		/* Make sure the amounts match */
		if (test_result_equal.n_isolines != test_result_fe.n_isolines ||
			test_result_fe.n_isolines != test_result_fo.n_isolines)
		{
			tcu::TestContext& test = test_result_iterator->parent->parent->getTestContext();

			test.getLog() << tcu::TestLog::Message << "Tessellator generated different amount of isolines for EQUAL/"
													  "FRACTIONAL_EVEN/FRACTIONAL_ODD vertex spacing modes which is "
													  "invalid."
						  << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid amount of unique isolines generated by tessellator");
		} /* if (amount of generated isolines does not match) */
	}	 /* for (all test runs) */
}

/** Counts amount of unique isolines in the captured data set and updates
 *  n_isolines field of user-provided @param test_result instance.
 *
 *  @param test_result Test result instance to update.
 */
void TessellationShadersIsolines::countIsolines(_test_result& test_result)
{
	const float		   epsilon = 1e-5f;
	std::vector<float> found_ys;

	for (unsigned int n_vertex = 0; n_vertex < test_result.n_vertices; ++n_vertex)
	{
		bool		 was_y_found = false;
		const float* vertex		 = (&test_result.rendered_data[0]) + n_vertex * 3; /* components */
		float		 vertex_y	= vertex[1];

		for (std::vector<float>::iterator found_ys_iterator = found_ys.begin(); found_ys_iterator != found_ys.end();
			 found_ys_iterator++)
		{
			float& found_y = *found_ys_iterator;

			if (de::abs(vertex_y - found_y) < epsilon)
			{
				was_y_found = true;

				break;
			}
		} /* for (all found Ys) */

		if (!was_y_found)
		{
			found_ys.push_back(vertex_y);
		}
	} /* for (all vertices) */

	/* Store the value */
	test_result.n_isolines = (unsigned int)found_ys.size();
}

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

	if (!m_is_tessellation_shader_supported)
	{
		return;
	}

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

	/* Reset GL_PATCH_VERTICES_EXT to default value */
	gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 3);

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

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

	/* Release Utilities instance */
	if (m_utils_ptr != NULL)
	{
		delete m_utils_ptr;

		m_utils_ptr = DE_NULL;
	}

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

		m_vao_id = 0;
	}

	/* Free the data structures we allocated for the test */
	m_tests.clear();
}

/** Retrieves test result structure for a particular set of properties.
 *
 *  @param irrelevant_tess_level Irrelevant tessellation level the test result descriptor should be using.
 *  @param outer1_tess_level     First outer tessellation level value  the test result descriptor should be using.
 *  @param outer2_tess_level     Second outer tessellation level value the test result descriptor should be using.
 *  @param vertex_spacing_mode   Vertex spacing mode the test result descriptor should be using.
 *
 *  This function throws a TestError exception if the test result descriptor the caller is after is not found.
 *
 *  @return Test result descriptor of interest.
 **/
TessellationShadersIsolines::_test_result TessellationShadersIsolines::findTestResult(
	_irrelevant_tess_level irrelevant_tess_level, _outer1_tess_level outer1_tess_level,
	_outer2_tess_level outer2_tess_level, _tessellation_shader_vertex_spacing vertex_spacing_mode)
{
	DE_ASSERT(m_tests.find(vertex_spacing_mode) != m_tests.end());

	_test_results&							  test_results = m_test_results[vertex_spacing_mode];
	bool									  has_found	= false;
	TessellationShadersIsolines::_test_result result;

	for (_test_results_iterator test_results_iterator = test_results.begin();
		 test_results_iterator != test_results.end(); test_results_iterator++)
	{
		if (test_results_iterator->irrelevant_tess_level == irrelevant_tess_level &&
			test_results_iterator->outer1_tess_level == outer1_tess_level &&
			test_results_iterator->outer2_tess_level == outer2_tess_level)
		{
			has_found = true;
			result	= *test_results_iterator;

			break;
		}
	} /* for (all test runs) */

	if (!has_found)
	{
		TCU_FAIL("Requested test run was not found.");
	}

	return result;
}

/** Retrieves rendering context associated with the test instance.
 *
 *  @return Rendering context.
 *
 **/
Context& TessellationShadersIsolines::getContext()
{
	return m_context;
}

/** Initializes ES objects necessary to run the test. */
void TessellationShadersIsolines::initTest()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Skip if required extensions are not supported. */
	if (!m_is_tessellation_shader_supported)
	{
		throw tcu::NotSupportedError(TESSELLATION_SHADER_EXTENSION_NOT_SUPPORTED);
	}

	/* Generate Utilities instance */
	m_utils_ptr = new TessellationShaderUtils(gl, this);

	/* Set up 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 */
	glw::GLint gl_max_tess_gen_level_value = 0;

	gl.getIntegerv(m_glExtTokens.MAX_TESS_GEN_LEVEL, &gl_max_tess_gen_level_value);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_TESS_GEN_LEVEL_EXT pname");

	/* Initialize reference tessellation values */
	const glw::GLfloat tess_levels[] = { -1.0f, 4.0f, float(gl_max_tess_gen_level_value) * 0.5f,
										 float(gl_max_tess_gen_level_value) };
	const unsigned int n_tess_levels = sizeof(tess_levels) / sizeof(tess_levels[0]);

	m_irrelevant_tess_value_1 = tess_levels[0];
	m_irrelevant_tess_value_2 = tess_levels[1];

	/* Initialize all test passes.
	 *
	 * Make sure each relevant outer tessellation level iterates through values
	 * of our interest
	 */
	for (unsigned int outer1_tess_level_index = 0; outer1_tess_level_index < n_tess_levels; ++outer1_tess_level_index)
	{
		for (unsigned int outer2_tess_level_index = 0; outer2_tess_level_index < n_tess_levels;
			 ++outer2_tess_level_index)
		{
			/* To make the test execute in a reasonable time frame, just use
			 * two different levels for the outer tessellation levels */
			DE_STATIC_ASSERT(n_tess_levels >= 2);

			for (unsigned int other_tess_level_index = 0; other_tess_level_index < 2 /* see comment */;
				 ++other_tess_level_index)
			{
				float inner_tess_levels[2] = { tess_levels[other_tess_level_index],
											   tess_levels[other_tess_level_index] };
				float outer_tess_levels[4] = { tess_levels[outer1_tess_level_index],
											   tess_levels[outer2_tess_level_index],
											   tess_levels[other_tess_level_index],
											   tess_levels[other_tess_level_index] };

				/* Finally, iterate over three vertex spacing modes */
				_tessellation_shader_vertex_spacing vertex_spacing_mode;

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

				for (int n_vs_mode = 0; n_vs_mode < n_vs_modes; ++n_vs_mode)
				{
					vertex_spacing_mode = vs_modes[n_vs_mode];

					_test_descriptor test;

					initTestDescriptor(vertex_spacing_mode, inner_tess_levels, outer_tess_levels,
									   tess_levels[other_tess_level_index], test);

					m_tests[vertex_spacing_mode].push_back(test);
				} /* for (all available vertex spacing modes) */
			}	 /* for (all irrelevant tessellation levels) */
		}		  /* for (all defined second outer tessellation levels) */
	}			  /* for (all defined first outer tessellation levels) */
}

/** Initializes all ES objects necessary to run a specific test pass.
 *
 *  @param vertex_spacing        Vertex spacing mode to initialize the test descriptor with.
 *  @param inner_tess_levels     Two FP values defining subsequent inner tessellation levels
 *                               to be used for initializing the test descriptor. Must NOT be
 *                               NULL.
 *  @param outer_tess_levels     Four FP values defining subsequent outer tessellation levels
 *                               to be used for initializing the test descriptor. Must NOT be
 *                               NULL.
 *  @param irrelevant_tess_level Value to be used to set irrelevant tessellation level values.
 *  @param test                  Test descriptor to fill with IDs of initialized objects.
 **/
void TessellationShadersIsolines::initTestDescriptor(_tessellation_shader_vertex_spacing vertex_spacing,
													 const float* inner_tess_levels, const float* outer_tess_levels,
													 float irrelevant_tess_level, _test_descriptor& test)
{
	memcpy(test.inner_tess_levels, inner_tess_levels, sizeof(test.inner_tess_levels));
	memcpy(test.outer_tess_levels, outer_tess_levels, sizeof(test.outer_tess_levels));

	test.parent				   = this;
	test.irrelevant_tess_level = irrelevant_tess_level;
	test.vertex_spacing_mode   = vertex_spacing;
}

/** 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 TessellationShadersIsolines::iterate(void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	initTest();

	/* We only need to use one vertex per so go for it */
	gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameteriEXT() failed for GL_PATCH_VERTICES_EXT pname");

	/* We don't need to rasterize anything in this test */
	gl.enable(GL_RASTERIZER_DISCARD);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) failed");

	/* Retrieve GL_MAX_TESS_GEN_LEVEL_EXT value before we continue */
	glw::GLint gl_max_tess_gen_level_value = 0;

	gl.getIntegerv(m_glExtTokens.MAX_TESS_GEN_LEVEL, &gl_max_tess_gen_level_value);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_TESS_GEN_LEVEL_EXT pname.");

	/* To perform actual tests, we need to first retrieve the tessellated coordinates data.
	 * Run all tests configured and fill per-test buffer with the information.
	 **/
	for (_tests_per_vertex_spacing_map_iterator vs_key_iterator = m_tests.begin(); vs_key_iterator != m_tests.end();
		 vs_key_iterator++)
	{
		for (_tests_const_iterator test_iterator = vs_key_iterator->second.begin();
			 test_iterator != vs_key_iterator->second.end(); test_iterator++)
		{
			const _test_descriptor& test = *test_iterator;

			/* Capture tessellation data for considered configuration */
			unsigned int n_rendered_vertices = m_utils_ptr->getAmountOfVerticesGeneratedByTessellator(
				TESSELLATION_SHADER_PRIMITIVE_MODE_ISOLINES, test.inner_tess_levels, test.outer_tess_levels,
				test.vertex_spacing_mode, false); /* is_point_mode_enabled */
			std::vector<char> rendered_data = m_utils_ptr->getDataGeneratedByTessellator(
				test.inner_tess_levels, false, /* point mode */
				TESSELLATION_SHADER_PRIMITIVE_MODE_ISOLINES, TESSELLATION_SHADER_VERTEX_ORDERING_CCW,
				test.vertex_spacing_mode, test.outer_tess_levels);

			/* Store the data in a test result descriptor */
			_test_result result;

			result.n_vertices			 = n_rendered_vertices;
			result.parent				 = &test;
			result.irrelevant_tess_level = (int)test.irrelevant_tess_level;
			result.outer1_tess_level	 = (int)test.outer_tess_levels[0];
			result.outer2_tess_level	 = (int)test.outer_tess_levels[1];
			result.rendered_data.resize(rendered_data.size() / sizeof(float));
			if (0 != rendered_data.size())
			{
				memcpy(&result.rendered_data[0], &rendered_data[0], rendered_data.size());
			}
			countIsolines(result);

			/* Store the test run descriptor. */
			m_test_results[test.vertex_spacing_mode].push_back(result);
		}
	}

	/* Now we can proceed with actual tests */
	/* (test 1): Make sure amount of isolines is determined by first outer tessellation level */
	runForAllTestResults(checkFirstOuterTessellationLevelEffect);

	/* (test 2): Make sure amount of line segments per height is determined by second outer
	 *           tessellation level.
	 */
	runForAllTestResults(checkSecondOuterTessellationLevelEffect);

	/* (test 3): Make sure 3rd, 4th outer tessellation levels, as well as all inner tessellation
	 *           levels have no impact on the tessellated coordinates */
	checkIrrelevantTessellationLevelsHaveNoEffect();

	/* (test 4): Make sure no matter what vertex spacing is requested in TC stage, it is always
	 *           equal_spacing that is applied.
	 */
	checkVertexSpacingDoesNotAffectAmountOfGeneratedIsolines();

	/* (test 5): Make sure that no data set features a line segment at height of 1. */
	runForAllTestResults(checkNoLineSegmentIsDefinedAtHeightOne);

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

/** Calls the caller-provided function provided for each test result descriptor
 *  created during pre-computation stage.
 *
 *  @param pProcessTestRun Function pointer to call. The function will be called
 *                         exactly once for each cached test result descriptor.
 *
 **/
void TessellationShadersIsolines::runForAllTestResults(PFNTESTRESULTPROCESSORPROC pProcessTestResult)
{
	for (_test_results_per_vertex_spacing_map_iterator vs_key_iterator = m_test_results.begin();
		 vs_key_iterator != m_test_results.end(); vs_key_iterator++)
	{
		for (_test_results_iterator test_results_iterator = vs_key_iterator->second.begin();
			 test_results_iterator != vs_key_iterator->second.end(); test_results_iterator++)
		{
			_test_result& test_result = *test_results_iterator;

			pProcessTestResult(test_result, m_glExtTokens.MAX_TESS_GEN_LEVEL);
		} /* for (all level3 keys) */
	}	 /* for (all vertex spacing modes) */
}

} /* namespace glcts */
