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

namespace glcts
{

/** Constructor
 *
 * @param context Test context
 **/
TessellationShaderTrianglesTests::TessellationShaderTrianglesTests(glcts::Context&		context,
																   const ExtParameters& extParams)
	: TestCaseGroupBase(context, extParams, "tessellation_shader_triangles_tessellation",
						"Verifies triangle tessellation functionality")
{
	/* No implementation needed */
}

/**
 * Initializes test groups for geometry shader tests
 **/
void TessellationShaderTrianglesTests::init(void)
{
	addChild(new glcts::TessellationShaderTrianglesDegenerateTriangle(m_context, m_extParams));
	addChild(new glcts::TessellationShaderTrianglesIdenticalTriangles(m_context, m_extParams));
	addChild(new glcts::TessellationShaderTrianglesInnerTessellationLevelRounding(m_context, m_extParams));
}

/** Constructor
 *
 * @param context Test context
 **/
TessellationShaderTrianglesDegenerateTriangle::TessellationShaderTrianglesDegenerateTriangle(
	Context& context, const ExtParameters& extParams)
	: TestCaseBase(context, extParams, "degenerate_triangle",
				   "Verifies a degenerate triangle is generated by tessellator "
				   "under a specific configuration of inner/outer tessellation "
				   "levels & vertex spacing modes.")
	, m_bo_id(0)
	, m_fs_id(0)
	, m_tc_id(0)
	, m_vs_id(0)
	, m_vao_id(0)
{
	/* Left blank on purpose */
}

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

	if (!m_is_tessellation_shader_supported)
	{
		return;
	}

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

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

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

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

	/* Free all ES objects we allocated for the test */
	if (m_bo_id != 0)
	{
		gl.deleteBuffers(1, &m_bo_id);

		m_bo_id = 0;
	}

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

		m_fs_id = 0;
	}

	if (m_tc_id != 0)
	{
		gl.deleteShader(m_tc_id);

		m_tc_id = 0;
	}

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

		m_vs_id = 0;
	}

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

		m_vao_id = 0;
	}

	/* Deinitialize all test descriptors */
	for (_tests::iterator it = m_tests.begin(); it != m_tests.end(); ++it)
	{
		deinitTestDescriptor(*it);
	}
	m_tests.clear();
}

/** Deinitialize all test pass-specific ES objects.
 *
 *  @param test Descriptor of a test pass to deinitialize.
 **/
void TessellationShaderTrianglesDegenerateTriangle::deinitTestDescriptor(_test_descriptor& test)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (test.po_id != 0)
	{
		gl.deleteProgram(test.po_id);

		test.po_id = 0;
	}

	if (test.te_id != 0)
	{
		gl.deleteShader(test.te_id);

		test.te_id = 0;
	}
}

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

	/* Generate all test-wide objects needed for test execution */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	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!");

	gl.genBuffers(1, &m_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed");

	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
	m_tc_id = gl.createShader(m_glExtTokens.TESS_CONTROL_SHADER);
	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() failed");

	/* Configure fragment shader body */
	const char* fs_body = "${VERSION}\n"
						  "\n"
						  "void main()\n"
						  "{\n"
						  "}\n";

	shaderSourceSpecialized(m_fs_id, 1 /* count */, &fs_body);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() failed for fragment shader");

	/* Configure tessellation control shader body */
	const char* tc_body = "${VERSION}\n"
						  "\n"
						  "${TESSELLATION_SHADER_REQUIRE}\n"
						  "\n"
						  "layout (vertices=3) out;\n"
						  "\n"
						  "void main()\n"
						  "{\n"
						  "    gl_out [gl_InvocationID].gl_Position = gl_in[0].gl_Position;\n"
						  "\n"
						  "    gl_TessLevelInner[0] = 1.0;\n"
						  "    gl_TessLevelOuter[0] = 1.0;\n"
						  "    gl_TessLevelOuter[1] = 1.0;\n"
						  "    gl_TessLevelOuter[2] = 1.0;\n"
						  "}\n";

	shaderSourceSpecialized(m_tc_id, 1 /* count */, &tc_body);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() failed for tessellation control shader");

	/* Configure vertex shader body */
	const char* vs_body = "${VERSION}\n"
						  "\n"
						  "void main()\n"
						  "{\n"
						  "    gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
						  "}\n";

	shaderSourceSpecialized(m_vs_id, 1 /* count */, &vs_body);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() failed for vertex shader");

	/* Compile all the shaders */
	const glw::GLuint  shaders[] = { m_fs_id, m_tc_id, m_vs_id };
	const unsigned int n_shaders = sizeof(shaders) / sizeof(shaders[0]);

	for (unsigned int n_shader = 0; n_shader < n_shaders; ++n_shader)
	{
		glw::GLuint shader = shaders[n_shader];

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

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

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

			if (compile_status != GL_TRUE)
			{
				TCU_FAIL("Shader compilation failed");
			}
		}
	} /* for (all shaders) */

	/* Initialize all test passes */
	_test_descriptor test_equal_spacing;
	_test_descriptor test_fractional_odd_spacing;

	initTestDescriptor(test_equal_spacing, TESSELLATION_SHADER_VERTEX_SPACING_EQUAL);
	initTestDescriptor(test_fractional_odd_spacing, TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_ODD);

	m_tests.push_back(test_equal_spacing);
	m_tests.push_back(test_fractional_odd_spacing);

	/* Set up buffer object storage */
	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed");

	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(float) * 3 /* components */ * 3 /* UVW sets */, NULL, /* data */
				  GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed");

	/* Bind the buffer object to indiced TF binding point */
	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() failed");
}

/** Initializes all ES objects necessary to run a specific test pass.
 *
 *  @param test           Test descriptor to fill with IDs of initialized objects.
 *  @param vertex_spacing Vertex spacing mode to use for the run.
 **/
void TessellationShaderTrianglesDegenerateTriangle::initTestDescriptor(
	_test_descriptor& test, _tessellation_shader_vertex_spacing vertex_spacing)
{
	test.vertex_spacing = vertex_spacing;

	/* Set up a program object for the descriptor */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	test.po_id = gl.createProgram();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() failed");

	/* Set up a pass-specific tessellation evaluation shader object. */
	test.te_id = gl.createShader(m_glExtTokens.TESS_EVALUATION_SHADER);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() failed");

	/* Configure tessellation evaluation shader body */
	const char* te_template = "${VERSION}\n"
							  "\n"
							  "${TESSELLATION_SHADER_REQUIRE}\n"
							  "\n"
							  "layout (triangles, VERTEX_SPACING_MODE) in;\n"
							  "\n"
							  "out vec3 result_uvw;\n"
							  "\n"
							  "void main()\n"
							  "{\n"
							  "    gl_Position = gl_in[0].gl_Position;\n"
							  "    result_uvw  = gl_TessCoord;\n"
							  "}\n";

	const char* te_body_raw_ptr = DE_NULL;
	std::string te_body_string  = te_template;
	std::string vertex_spacing_mode_string;
	const char* vertex_spacing_token	   = "VERTEX_SPACING_MODE";
	std::size_t vertex_spacing_token_index = std::string::npos;

	switch (vertex_spacing)
	{
	case TESSELLATION_SHADER_VERTEX_SPACING_EQUAL:
	{
		vertex_spacing_mode_string = "equal_spacing";

		break;
	}

	case TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_ODD:
	{
		vertex_spacing_mode_string = "fractional_odd_spacing";

		break;
	}

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

	while ((vertex_spacing_token_index = te_body_string.find(vertex_spacing_token)) != std::string::npos)
	{
		te_body_string = te_body_string.replace(vertex_spacing_token_index, strlen(vertex_spacing_token),
												vertex_spacing_mode_string);

		vertex_spacing_token_index = te_body_string.find(vertex_spacing_token);
	}

	te_body_raw_ptr = te_body_string.c_str();

	shaderSourceSpecialized(test.te_id, 1 /* count */, &te_body_raw_ptr);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() failed for tessellation evaluation shader");

	/* Compile the tessellation evaluation shader */
	glw::GLint compile_status = GL_FALSE;

	gl.compileShader(test.te_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() failed for tessellation evaluation shader");

	gl.getShaderiv(test.te_id, GL_COMPILE_STATUS, &compile_status);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() failed for tessellation evaluation shader");

	if (compile_status != GL_TRUE)
	{
		TCU_FAIL("Tessellation evaluation shader compilation failed");
	}

	/* Attach all shader to the program object */
	gl.attachShader(test.po_id, m_fs_id);
	gl.attachShader(test.po_id, m_tc_id);
	gl.attachShader(test.po_id, test.te_id);
	gl.attachShader(test.po_id, m_vs_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() failed");

	/* Set up XFB */
	const char*		   varyings[] = { "result_uvw" };
	const unsigned int n_varyings = sizeof(varyings) / sizeof(varyings[0]);

	gl.transformFeedbackVaryings(test.po_id, n_varyings, varyings, GL_INTERLEAVED_ATTRIBS);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() failed");

	/* Link the program object */
	glw::GLint link_status = GL_FALSE;

	gl.linkProgram(test.po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() failed");

	gl.getProgramiv(test.po_id, GL_LINK_STATUS, &link_status);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() failed");

	if (link_status != GL_TRUE)
	{
		TCU_FAIL("Program linking failed");
	}
}

/** 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 TessellationShaderTrianglesDegenerateTriangle::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 ES test objects */
	initTest();

	/* We only need to use one vertex per so go for it */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameteriEXT() failed for GL_PATCH_VERTICES_EXT pname");

	/* Iterate through all tests configured */
	for (_tests_const_iterator test_iterator = m_tests.begin(); test_iterator != m_tests.end(); test_iterator++)
	{
		const _test_descriptor& test = *test_iterator;

		/* Run the iteration */
		gl.useProgram(test.po_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed");

		/* Draw the test geometry */
		gl.beginTransformFeedback(GL_TRIANGLES);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback(GL_TRIANGLES) failed.");

		gl.drawArrays(m_glExtTokens.PATCHES, 0 /* first */, 1 /* count */);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed");

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

		/* Map the BO with result data into user space */
		const float* triangle_vertex_data =
			(const float*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, /* offset */
											sizeof(float) * 3 /* vec3 */ * 3 /* points */, GL_MAP_READ_BIT);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed");

		/* Make sure the triangle data is correct. Since we cannot rely on any specific order
		 * of the result vertices, raise corresponding flag for each of the expected vertices.
		 */
		const float epsilon					 = 1e-5f;
		bool		is_zero_zero_one_present = false;
		bool		is_zero_one_zero_present = false;
		bool		is_one_zero_zero_present = false;

		for (unsigned int n_vertex = 0; n_vertex < 3 /* vertices */; ++n_vertex)
		{
			const float* triangle_ptr = triangle_vertex_data + 3 * n_vertex;

			if (de::abs(triangle_ptr[0]) < epsilon && de::abs(triangle_ptr[1]) < epsilon &&
				de::abs(triangle_ptr[2] - 1.0f) < epsilon)
			{
				if (!is_zero_zero_one_present)
				{
					is_zero_zero_one_present = true;
				}
				else
				{
					TCU_FAIL("(0, 0, 1) vertex outputted more than once");
				}
			}
			else if (de::abs(triangle_ptr[0]) < epsilon && de::abs(triangle_ptr[1] - 1.0f) < epsilon &&
					 de::abs(triangle_ptr[2]) < epsilon)
			{
				if (!is_zero_one_zero_present)
				{
					is_zero_one_zero_present = true;
				}
				else
				{
					TCU_FAIL("(0, 1, 0) vertex outputted more than once");
				}
			}
			else if (de::abs(triangle_ptr[0] - 1.0f) < epsilon && de::abs(triangle_ptr[1]) < epsilon &&
					 de::abs(triangle_ptr[2]) < epsilon)
			{
				if (!is_one_zero_zero_present)
				{
					is_one_zero_zero_present = true;
				}
				else
				{
					TCU_FAIL("(1, 0, 0) vertex outputted more than once");
				}
			}
			else
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Unexpected vertex"
								   << " (" << triangle_vertex_data[0] << ", " << triangle_vertex_data[1] << ", "
								   << triangle_vertex_data[2] << ")"
								   << " encountered for a degenerate triangle." << tcu::TestLog::EndMessage;

				TCU_FAIL("Invalid vertex was generated by the tessellator");
			}
		} /* for (all vertices) */

		/* Unmap the BO */
		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed");
	}

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

/** Constructor
 *
 * @param context Test context
 **/
TessellationShaderTrianglesIdenticalTriangles::TessellationShaderTrianglesIdenticalTriangles(
	Context& context, const ExtParameters& extParams)
	: TestCaseBase(context, extParams, "identical_triangles",
				   "Verifies that tessellation coordinates generated by the tessellator "
				   "running in triangles mode do not change if second inner or fourth "
				   "outer tessellation level is changed")
	, m_vao_id(0)
	, m_utils(DE_NULL)
{
	/* Left blank on purpose */
}

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

	if (!m_is_tessellation_shader_supported)
	{
		return;
	}

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

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

	/* Deallocate test variables */
	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;
	}
}

/** Initializes ES objects necessary to run the test. */
void TessellationShaderTrianglesIdenticalTriangles::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 */
	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() call failed for GL_MAX_TESS_GEN_LEVEL_EXT pname");

	/* Initialize all test runs */
	_tessellation_level_set_filter filter =
		(_tessellation_level_set_filter)((int)TESSELLATION_LEVEL_SET_FILTER_ALL_COMBINATIONS |
										 (int)TESSELLATION_LEVEL_SET_FILTER_EXCLUDE_NEGATIVE_BASE_VALUE);

	_tessellation_levels_set levels_sets = TessellationShaderUtils::getTessellationLevelSetForPrimitiveMode(
		TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, gl_max_tess_gen_level_value, filter);

	for (_tessellation_levels_set_const_iterator set_iterator = levels_sets.begin(); set_iterator != levels_sets.end();
		 set_iterator++)
	{
		_run						run;
		const _tessellation_levels& set = *set_iterator;

		memcpy(run.base_inner, set.inner, sizeof(run.base_inner));
		memcpy(run.base_outer, set.outer, sizeof(run.base_outer));

		run.reference_inner[0] = run.base_inner[0];
		run.reference_inner[1] = run.base_inner[1] * 0.25f;

		run.reference_outer[0] = run.base_outer[0];
		run.reference_outer[1] = run.base_outer[1];
		run.reference_outer[2] = run.base_outer[2];
		run.reference_outer[3] = run.base_outer[3] * 0.25f;

		/* Retrieve vertex data for both passes */
		glw::GLint n_base_vertices		= 0;
		glw::GLint n_reference_vertices = 0;

		n_base_vertices = m_utils->getAmountOfVerticesGeneratedByTessellator(
			TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, run.base_inner, run.base_outer,
			TESSELLATION_SHADER_VERTEX_SPACING_EQUAL, false);
		n_reference_vertices = m_utils->getAmountOfVerticesGeneratedByTessellator(
			TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, run.reference_inner, run.reference_outer,
			TESSELLATION_SHADER_VERTEX_SPACING_EQUAL, false); /* is_point_mode_enabled */

		if (n_base_vertices == 0)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "No vertices were generated by tessellator for: "
														   "inner tess levels:"
														   "["
							   << run.base_inner[0] << ", " << run.base_inner[1] << "]"
																					", outer tess levels:"
																					"["
							   << run.base_outer[0] << ", " << run.base_outer[1] << ", " << run.base_outer[2] << ", "
							   << run.base_outer[3] << "]"
													   ", primitive mode: triangles, vertex spacing: equal."
							   << tcu::TestLog::EndMessage;

			TCU_FAIL("Zero vertices were generated by tessellator for base test pass");
		}

		if (n_reference_vertices == 0)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "No vertices were generated by tessellator for: "
														   "inner tess levels:"
														   "["
							   << run.reference_inner[0] << ", " << run.reference_inner[1] << "]"
																							  ", outer tess levels:"
																							  "["
							   << run.reference_outer[0] << ", " << run.reference_outer[1] << ", "
							   << run.reference_outer[2] << ", " << run.reference_outer[3]
							   << "]"
								  ", primitive mode: triangles, vertex spacing: equal."
							   << tcu::TestLog::EndMessage;

			TCU_FAIL("Zero vertices were generated by tessellator for reference test pass");
		}

		if (n_base_vertices != n_reference_vertices)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Amount of vertices generated by the tessellator differs"
														   " for the following inner/outer configs: "
														   "inner tess levels:"
														   "["
							   << run.base_inner[0] << ", " << run.base_inner[1] << "]"
																					", outer tess levels:"
																					"["
							   << run.base_outer[0] << ", " << run.base_outer[1] << ", " << run.base_outer[2] << ", "
							   << run.base_outer[3] << "]"
													   " and inner tess levels:"
													   "["
							   << run.reference_inner[0] << ", " << run.reference_inner[1] << "]"
																							  ", outer tess levels:"
																							  "["
							   << run.reference_outer[0] << ", " << run.reference_outer[1] << ", "
							   << run.reference_outer[2] << ", " << run.reference_outer[3]
							   << "]"
								  ", primitive mode: triangles, vertex spacing: equal."
							   << tcu::TestLog::EndMessage;

			TCU_FAIL("Amount of vertices generated by tessellator differs between base and references passes");
		}

		run.n_vertices = n_base_vertices;

		run.base_data = m_utils->getDataGeneratedByTessellator(
			run.base_inner, false, /* is_point_mode_enabled */
			TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, TESSELLATION_SHADER_VERTEX_ORDERING_CCW,
			TESSELLATION_SHADER_VERTEX_SPACING_EQUAL, run.base_outer);
		run.reference_data = m_utils->getDataGeneratedByTessellator(
			run.reference_inner, false, /* is_point_mode_enabled */
			TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, TESSELLATION_SHADER_VERTEX_ORDERING_CCW,
			TESSELLATION_SHADER_VERTEX_SPACING_EQUAL, run.reference_outer);

		/* Store the run data */
		m_runs.push_back(run);
	} /* for (all sets) */
}

/** 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 TessellationShaderTrianglesIdenticalTriangles::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++)
	{
		const _run& run = *run_iterator;

		/* Make sure the vertex data generated for two passes matches */
		const glw::GLint n_triangles = run.n_vertices / 3 /* vertices per triangle */;

		for (int n_triangle = 0; n_triangle < n_triangles; ++n_triangle)
		{
			const float* triangle_a = (const float*)(&run.base_data[0]) +
									  n_triangle * 3 /* vertices */
										  * 3;		 /* components */
			const float* triangle_b = (const float*)(&run.reference_data[0]) +
									  n_triangle * 3 /* vertices */
										  * 3;		 /* components */

			if (!TessellationShaderUtils::isTriangleDefined(triangle_a, triangle_b))
			{
				m_testCtx.getLog() << tcu::TestLog::Message
								   << "The following triangle, generated in the first pass, was not "
									  "generated in the other. "
									  "First pass' configuration: inner tess levels:"
									  "["
								   << run.base_inner[0] << ", " << run.base_inner[1] << "]"
																						", outer tess levels:"
																						"["
								   << run.base_outer[0] << ", " << run.base_outer[1] << ", " << run.base_outer[2]
								   << ", " << run.base_outer[3] << "]"
																   "; second pass' configuration: inner tess levels:"
																   "["
								   << run.reference_inner[0] << ", " << run.reference_inner[1] << "]"
																								  ", outer tess levels:"
																								  "["
								   << run.reference_outer[0] << ", " << run.reference_outer[1] << ", "
								   << run.reference_outer[2] << ", " << run.reference_outer[3]
								   << "]"
									  ", primitive mode: triangles, vertex spacing: equal."
								   << tcu::TestLog::EndMessage;

				TCU_FAIL("A triangle from base vertex data set was not found in reference vertex data set.");
			}
		} /* for (all vertices) */
	}	 /* for (all runs) */

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

/** Constructor
 *
 * @param context Test context
 **/
TessellationShaderTrianglesInnerTessellationLevelRounding::TessellationShaderTrianglesInnerTessellationLevelRounding(
	Context& context, const ExtParameters& extParams)
	: TestCaseBase(context, extParams, "inner_tessellation_level_rounding",
				   "Verifies that inner tessellation level is rounded to 1 or 2,"
				   " when the tessellator is run in triangles primitive mode and "
				   "inner tessellation level is set to 1 and any of the outer "
				   "tessellation levels is greater than one.")
	, m_vao_id(0)
	, m_utils(DE_NULL)
{
	/* Left blank on purpose */
}

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

	if (!m_is_tessellation_shader_supported)
	{
		return;
	}

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

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

	/* Deallocate test variables */
	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;
	}
}

/** 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 TessellationShaderTrianglesInnerTessellationLevelRounding::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);
	}

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

	/* 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!");

	/* Initialize and run test iterations. In later part, we will verify the generated data. */
	runTestIterations();

	/* Iterate through all runs */

	for (_runs_const_iterator run_iterator = m_runs.begin(); run_iterator != m_runs.end(); run_iterator++)
	{
		const _run& run = *run_iterator;

		if (run.vertex_spacing == TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_ODD &&
			de::abs(run.set1_inner[0] - run.set2_inner[0]) > 1e-5f &&
			de::min(run.set1_inner[0], run.set2_inner[0]) >= 1.0f)
		{
			/* In fractional_odd_spacing mode with inner level <f> >= 1.0f, the clamped
			 and rounded integer level <n> is at least 3.

			 These results in inner subdivision into at least <n>-2=1 segment and
			 two additional, typically shorter segments.

			 The length of these two additional segments relative to the others will
			 decrease monotonically with the value of <n>-<f>, so if different <f> levels
			 were used, we cannot proceed with matching the exact vertex data. */

			continue;
		}

		/* Make sure the vertex data generated for two passes matches */
		const glw::GLint n_triangles = run.n_vertices / 3 /* vertices per triangle */;

		for (int n_triangle = 0; n_triangle < n_triangles; ++n_triangle)
		{
			const float* triangle_a = (const float*)(&run.set1_data[0]) +
									  n_triangle * 3 /* vertices */
										  * 3;		 /* components */
			const float* triangle_b = (const float*)(&run.set2_data[0]) +
									  n_triangle * 3 /* vertices */
										  * 3;		 /* components */

			if (!TessellationShaderUtils::isTriangleDefined(triangle_a, triangle_b))
			{
				std::string vs_mode_string =
					TessellationShaderUtils::getESTokenForVertexSpacingMode(run.vertex_spacing);

				m_testCtx.getLog() << tcu::TestLog::Message
								   << "The following triangle, generated in the first pass, was not "
									  "generated in the second one. "
									  "First pass' configuration: inner tess levels:"
									  "["
								   << run.set1_inner[0] << ", " << run.set1_inner[1] << "]"
																						", outer tess levels:"
																						"["
								   << run.set1_outer[0] << ", " << run.set1_outer[1] << ", " << run.set1_outer[2]
								   << ", " << run.set1_outer[3] << "]"
																   "; second pass' configuration: inner tess levels:"
																   "["
								   << run.set2_inner[0] << ", " << run.set2_inner[1] << "]"
																						", outer tess levels:"
																						"["
								   << run.set2_outer[0] << ", " << run.set2_outer[1] << ", " << run.set2_outer[2]
								   << ", " << run.set2_outer[3] << "]"
																   ", primitive mode: triangles, vertex spacing: "
								   << vs_mode_string << tcu::TestLog::EndMessage;

				TCU_FAIL("A triangle from first pass' data set was not found in second pass' data set.");
			}
		} /* for (all vertices) */
	}	 /* for (all runs) */

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

/** Runs all test iterations needed to generate data for later verification. */
void TessellationShaderTrianglesInnerTessellationLevelRounding::runTestIterations()
{
	/* 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);

	/* 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() call failed for GL_MAX_TESS_GEN_LEVEL_EXT pname");

	/* Initialize all test runs */
	const glw::GLint   tess_levels[] = { 2, gl_max_tess_gen_level_value / 2, gl_max_tess_gen_level_value };
	const unsigned int n_tess_levels = sizeof(tess_levels) / sizeof(tess_levels[0]);

	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 unsigned int n_vs_modes = sizeof(vs_modes) / sizeof(vs_modes[0]);

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

		for (unsigned int n_tess_level = 0; n_tess_level < n_tess_levels; ++n_tess_level)
		{
			/* Set up the run descriptor */
			glw::GLint tess_level = tess_levels[n_tess_level];
			_run	   run;

			run.set1_inner[0] = 1.0f;
			run.set1_inner[1] = 0.0f;
			run.set2_inner[1] = 0.0f;

			TessellationShaderUtils::getTessellationLevelAfterVertexSpacing(vs_mode, 1.5f, gl_max_tess_gen_level_value,
																			DE_NULL, /* out_clamped */
																			run.set2_inner);
			run.set1_outer[0] = (glw::GLfloat)tess_level;
			run.set2_outer[0] = (glw::GLfloat)tess_level;
			run.set1_outer[1] = (glw::GLfloat)tess_level;
			run.set2_outer[1] = (glw::GLfloat)tess_level;
			run.set1_outer[2] = (glw::GLfloat)tess_level;
			run.set2_outer[2] = (glw::GLfloat)tess_level;
			run.set1_outer[3] = (glw::GLfloat)tess_level;
			run.set2_outer[3] = (glw::GLfloat)tess_level;

			run.vertex_spacing = vs_mode;

			/* Retrieve vertex data for both passes */
			glw::GLint n_set1_vertices = 0;
			glw::GLint n_set2_vertices = 0;

			n_set1_vertices = m_utils->getAmountOfVerticesGeneratedByTessellator(
				TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, run.set1_inner, run.set1_outer, run.vertex_spacing,
				false); /* is_point_mode_enabled */
			n_set2_vertices = m_utils->getAmountOfVerticesGeneratedByTessellator(
				TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, run.set2_inner, run.set2_outer, run.vertex_spacing,
				false); /* is_point_mode_enabled */

			if (n_set1_vertices == 0)
			{
				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.set1_inner[0] << ", " << run.set1_inner[1] << "]"
																						", outer tess levels:"
																						"["
								   << run.set1_outer[0] << ", " << run.set1_outer[1] << ", " << run.set1_outer[2]
								   << ", " << run.set1_outer[3] << "]"
																   ", primitive mode: triangles, "
																   "vertex spacing: "
								   << vs_mode_string << tcu::TestLog::EndMessage;

				TCU_FAIL("Zero vertices were generated by tessellator for first test pass");
			}

			if (n_set2_vertices == 0)
			{
				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.set2_inner[0] << ", " << run.set2_inner[1] << "]"
																						", outer tess levels:"
																						"["
								   << run.set2_outer[0] << ", " << run.set2_outer[1] << ", " << run.set2_outer[2]
								   << ", " << run.set2_outer[3] << "]"
																   ", primitive mode: triangles, "
																   "vertex spacing: "
								   << vs_mode_string << tcu::TestLog::EndMessage;

				TCU_FAIL("Zero vertices were generated by tessellator for second test pass");
			}

			if (n_set1_vertices != n_set2_vertices)
			{
				std::string vs_mode_string = TessellationShaderUtils::getESTokenForVertexSpacingMode(vs_mode);

				m_testCtx.getLog() << tcu::TestLog::Message << "Amount of vertices generated by the tessellator differs"
															   " for the following inner/outer configs: "
															   "inner tess levels:"
															   "["
								   << run.set1_inner[0] << ", " << run.set1_inner[1] << "]"
																						", outer tess levels:"
																						"["
								   << run.set1_outer[0] << ", " << run.set1_outer[1] << ", " << run.set1_outer[2]
								   << ", " << run.set1_outer[3] << "]"
																   " and inner tess levels:"
																   "["
								   << run.set2_inner[0] << ", " << run.set2_inner[1] << "]"
																						", outer tess levels:"
																						"["
								   << run.set2_outer[0] << ", " << run.set2_outer[1] << ", " << run.set2_outer[2]
								   << ", " << run.set2_outer[3] << "]"
																   ", primitive mode: triangles, vertex spacing: "
								   << vs_mode_string << tcu::TestLog::EndMessage;

				TCU_FAIL("Amount of vertices generated by tessellator differs between base and references passes");
			}

			run.n_vertices = n_set1_vertices;

			run.set1_data = m_utils->getDataGeneratedByTessellator(run.set1_inner, false, /* is_point_mode_enabled */
																   TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES,
																   TESSELLATION_SHADER_VERTEX_ORDERING_CCW,
																   run.vertex_spacing, run.set1_outer);
			run.set2_data = m_utils->getDataGeneratedByTessellator(run.set2_inner, false, /* is_point_mode_enabled */
																   TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES,
																   TESSELLATION_SHADER_VERTEX_ORDERING_CCW,
																   run.vertex_spacing, run.set2_outer);

			/* Store the run data */
			m_runs.push_back(run);
		} /* for (all sets) */
	}	 /* for (all vertex spacing modes) */
}

} /* namespace glcts */
