/*-------------------------------------------------------------------------
 * 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 "esextcGeometryShaderInput.hpp"

#include "gluContextInfo.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuTestLog.hpp"
#include <cstring>

namespace glcts
{
/* Vertex shader for GeometryShader_gl_in_ArrayContents */
const char* const GeometryShader_gl_in_ArrayContentsTest::m_vertex_shader_code =
	"${VERSION}\n"
	"\n"
	"     out  vec2 vs_gs_a;\n"
	"flat out ivec4 vs_gs_b;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    vs_gs_a = vec2 (gl_VertexID, 0);\n"
	"    vs_gs_b = ivec4(0,           gl_VertexID, 0, 1);\n"
	"}\n";

/* Geometry shader for GeometryShader_gl_in_ArrayContents */
const char* const GeometryShader_gl_in_ArrayContentsTest::m_geometry_shader_preamble_code =
	"${VERSION}\n"
	"\n"
	"${GEOMETRY_SHADER_REQUIRE}\n"
	"\n"
	"layout(triangles)                      in;\n"
	"layout(triangle_strip, max_vertices=3) out;\n"
	"\n";

const char* const GeometryShader_gl_in_ArrayContentsTest::m_geometry_shader_code =
	"#ifdef USE_UNSIZED_ARRAYS\n"
	"         in  vec2 vs_gs_a[];\n"
	"    flat in ivec4 vs_gs_b[];\n"
	"#else\n"
	"         in  vec2 vs_gs_a[3];\n"
	"    flat in ivec4 vs_gs_b[3];\n"
	"#endif\n"
	"\n"
	"     out  vec2 gs_fs_a;\n"
	"flat out ivec4 gs_fs_b;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    gl_Position = vec4(-1, -1, 0, 1);\n"
	"    gs_fs_a     = vs_gs_a[0];\n"
	"    gs_fs_b     = vs_gs_b[0];\n"
	"    EmitVertex();\n"
	"    \n"
	"    gl_Position = vec4(-1, 1, 0, 1);\n"
	"    gs_fs_a     = vs_gs_a[1];\n"
	"    gs_fs_b     = vs_gs_b[1];\n"
	"    EmitVertex();\n"
	"    \n"
	"    gl_Position = vec4(1, 1, 0, 1);\n"
	"    gs_fs_a     = vs_gs_a[2];\n"
	"    gs_fs_b     = vs_gs_b[2];\n"
	"    EmitVertex();\n"
	"    \n"
	"    EndPrimitive();\n"
	"}\n";

/* Fragment shader for GeometryShader_gl_in_ArrayContents */
const char* const GeometryShader_gl_in_ArrayContentsTest::m_fragment_shader_code =
	"${VERSION}\n"
	"\n"
	"precision highp float;\n"
	"\n"
	"layout(location = 0) out vec4 fs_out_color;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    fs_out_color = vec4(1, 1, 1, 1);\n"
	"}\n";

/* Vertex Shader for GeometryShader_gl_in_ArrayLengthTest*/
const char* const GeometryShader_gl_in_ArrayLengthTest::m_vertex_shader_code =
	"${VERSION}\n"
	"\n"
	"void main()\n"
	"{\n"
	"    gl_Position = vec4(gl_VertexID, 0, 0, 1);\n"
	"}\n";

/* Geometry shader body parts for GeometryShader_gl_in_ArrayLengthTest */
const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_preamble = "${VERSION}\n"
																						  "\n"
																						  "${GEOMETRY_SHADER_REQUIRE}\n"
																						  "\n";

const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_points =
	"layout(points)                     in;\n";

const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_lines =
	"layout(lines)                      in;\n";

const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_lines_with_adjacency =
	"layout(lines_adjacency)            in;\n";

const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_triangles =
	"layout(triangles)                  in;\n";

const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_triangles_with_adjacency =
	"layout(triangles_adjacency)        in;\n";

const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_output_points =
	"layout(points, max_vertices=1)     out;\n"
	"\n"
	"#define N_OUT_VERTICES (1)\n";

const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_output_line_strip =
	"layout(line_strip, max_vertices=2) out;\n"
	"\n"
	"#define N_OUT_VERTICES (2)\n";

const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_output_triangle_strip =
	"layout(triangle_strip, max_vertices=3) out;\n"
	"\n"
	"#define N_OUT_VERTICES (3)\n";

const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_main =
	"\n"
	"flat out int in_array_size;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    for (int n = 0; n < N_OUT_VERTICES; n++)\n"
	"    {\n"
	"        in_array_size = gl_in.length();\n"
	"        EmitVertex();\n"
	"    }\n"
	"\n"
	"    EndPrimitive();\n"
	"}\n";

/* Fragment Shader for GeometryShader_gl_in_ArrayLengthTest */
const char* const GeometryShader_gl_in_ArrayLengthTest::m_fragment_shader_code = "${VERSION}\n"
																				 "\n"
																				 "precision highp float;\n"
																				 "\n"
																				 "void main()\n"
																				 "{\n"
																				 "}\n";

/* Vertex Shader for GeometryShader_gl_PointSize_ValueTest */
const char* const GeometryShader_gl_PointSize_ValueTest::m_vertex_shader_code =
	"${VERSION}\n"
	"\n"
	"void main()\n"
	"{\n"
	"    // See test description for explanation of magic numbers\n"
	"    switch (gl_VertexID)\n"
	"    {\n"
	"        case 0:\n"
	"        {\n"
	"            gl_Position = vec4(-7.0/8.0, 0, 0, 1);\n"
	"\n"
	"            break;\n"
	"        }\n"
	"\n"
	"        case 1:\n"
	"        {\n"
	"            gl_Position = vec4(6.0/8.0, 0, 0, 1);\n"
	"\n"
	"            break;\n"
	"        }\n"
	"    }\n"
	"\n"
	"    gl_PointSize = float(2 * (gl_VertexID + 1));\n"
	"}\n";

/* Geometry Shader for GeometryShader_gl_PointSize_ValueTest */
const char* const GeometryShader_gl_PointSize_ValueTest::m_geometry_shader_code =
	"${VERSION}\n"
	"\n"
	"${GEOMETRY_SHADER_REQUIRE}\n"
	"${GEOMETRY_POINT_SIZE_REQUIRE}\n"
	"\n"
	"layout(points)                 in;\n"
	"layout(points, max_vertices=1) out;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    gl_Position  = gl_in[0].gl_Position;\n"
	"    gl_PointSize = gl_in[0].gl_PointSize * 2.0;\n"
	"    EmitVertex();\n"
	"    \n"
	"    EndPrimitive();\n"
	"}\n";

/* Fragment Shader for GeometryShader_gl_PointSize_ValueTest */
const char* const GeometryShader_gl_PointSize_ValueTest::m_fragment_shader_code =
	"${VERSION}\n"
	"\n"
	"precision highp float;\n"
	"\n"
	"layout(location = 0) out vec4 fs_out_color;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    fs_out_color = vec4(1, 1, 1, 1);\n"
	"}\n";

/* Vertex Shader for GeometryShader_gl_Position_ValueTest */
const char* const GeometryShader_gl_Position_ValueTest::m_vertex_shader_code =
	"${VERSION}\n"
	"\n"
	"void main()\n"
	"{\n"
	"    gl_Position = vec4(gl_VertexID, gl_VertexID, 0, 1);\n"
	"\n"
	"}\n";

/* Geometry Shader for GeometryShader_gl_Position_ValueTest */
const char* const GeometryShader_gl_Position_ValueTest::m_geometry_shader_code =
	"${VERSION}\n"
	"\n"
	"${GEOMETRY_SHADER_REQUIRE}\n"
	"${GEOMETRY_POINT_SIZE_REQUIRE}\n"
	"\n"
	"layout(points)                 in;\n"
	"layout(points, max_vertices=1) out;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    // See test description for discussion on the magic numbers\n"
	"    gl_Position  = vec4(-1.0 + 4.0/32.0 + gl_in[0].gl_Position.x / 4.0, 0, 0, 1);\n"
	"    gl_PointSize = 8.0;\n"
	"    EmitVertex();\n"
	"\n"
	"    EndPrimitive();\n"
	"}\n";

/* Fragment Shader for GeometryShader_gl_Position_ValueTest */
const char* const GeometryShader_gl_Position_ValueTest::m_fragment_shader_code =
	"${VERSION}\n"
	"\n"
	"precision highp float;\n"
	"\n"
	"layout(location = 0) out vec4 fs_out_color;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    fs_out_color = vec4(1, 1, 1, 1);\n"
	"}\n";

/* Constants for GeometryShader_gl_in_ArrayContentsTest */
const unsigned int GeometryShader_gl_in_ArrayContentsTest::m_n_bytes_emitted_per_vertex =
	2 * sizeof(glw::GLfloat) + 4 * sizeof(glw::GLint);
const unsigned int GeometryShader_gl_in_ArrayContentsTest::m_n_emitted_primitives			  = 1;
const unsigned int GeometryShader_gl_in_ArrayContentsTest::m_n_vertices_emitted_per_primitive = 3;

const unsigned int GeometryShader_gl_in_ArrayContentsTest::m_buffer_size =
	GeometryShader_gl_in_ArrayContentsTest::m_n_bytes_emitted_per_vertex *
	GeometryShader_gl_in_ArrayContentsTest::m_n_vertices_emitted_per_primitive *
	GeometryShader_gl_in_ArrayContentsTest::m_n_emitted_primitives;

/* Constants for GeometryShader_gl_in_ArrayLengthTest */
const glw::GLuint GeometryShader_gl_in_ArrayLengthTest::m_max_primitive_emitted = 6;
const glw::GLuint GeometryShader_gl_in_ArrayLengthTest::m_buffer_size = sizeof(glw::GLint) * m_max_primitive_emitted;

/* Constants for GeometryShader_gl_PointSize_ValueTest */
const glw::GLuint GeometryShader_gl_PointSize_ValueTest::m_texture_height	 = 16;
const glw::GLuint GeometryShader_gl_PointSize_ValueTest::m_texture_pixel_size = 4;
const glw::GLuint GeometryShader_gl_PointSize_ValueTest::m_texture_width	  = 16;

/* Constants for GeometryShader_gl_Position_ValueTest */
const glw::GLuint GeometryShader_gl_Position_ValueTest::m_texture_height	 = 64;
const glw::GLuint GeometryShader_gl_Position_ValueTest::m_texture_pixel_size = 4;
const glw::GLuint GeometryShader_gl_Position_ValueTest::m_texture_width		 = 64;

/** Constructor
 *
 * @param context       Test context
 * @param name          Test case's name
 * @param description   Test case's desricption
 **/
GeometryShader_gl_in_ArrayContentsTest::GeometryShader_gl_in_ArrayContentsTest(Context&				context,
																			   const ExtParameters& extParams,
																			   const char*			name,
																			   const char*			description)
	: TestCaseBase(context, extParams, name, description)
	, m_fragment_shader_id(0)
	, m_geometry_shader_sized_arrays_id(0)
	, m_geometry_shader_unsized_arrays_id(0)
	, m_program_object_sized_arrays_id(0)
	, m_program_object_unsized_arrays_id(0)
	, m_vertex_shader_id(0)
	, m_buffer_object_id(0)
	, m_vertex_array_object_id(0)
{
	/* Nothing to be done here */
}

/** Initializes GLES objects used during the test.
 *
 **/
void GeometryShader_gl_in_ArrayContentsTest::initTest()
{
	/* Varing names */
	const glw::GLchar* const captured_varyings[] = {
		"gs_fs_a", "gs_fs_b",
	};

	/* Number of varings */
	const glw::GLuint n_captured_varyings_size = sizeof(captured_varyings) / sizeof(captured_varyings[0]);

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

	/* Create program and shaders */
	m_program_object_sized_arrays_id   = gl.createProgram();
	m_program_object_unsized_arrays_id = gl.createProgram();

	m_fragment_shader_id				= gl.createShader(GL_FRAGMENT_SHADER);
	m_geometry_shader_unsized_arrays_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
	m_geometry_shader_sized_arrays_id   = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
	m_vertex_shader_id					= gl.createShader(GL_VERTEX_SHADER);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program");

	/* Set up transform feedback */
	gl.transformFeedbackVaryings(m_program_object_sized_arrays_id, n_captured_varyings_size, captured_varyings,
								 GL_INTERLEAVED_ATTRIBS);
	gl.transformFeedbackVaryings(m_program_object_unsized_arrays_id, n_captured_varyings_size, captured_varyings,
								 GL_INTERLEAVED_ATTRIBS);

	/* Build programs */
	const char* geometry_shader_unsized_arrays_code[] = { m_geometry_shader_preamble_code,
														  "#define USE_UNSIZED_ARRAYS\n", m_geometry_shader_code };
	const char* geometry_shader_sized_arrays_code[] = { m_geometry_shader_preamble_code, m_geometry_shader_code };

	if (false ==
		buildProgram(m_program_object_unsized_arrays_id, m_fragment_shader_id, 1 /* number of fragment shader parts */,
					 &m_fragment_shader_code, m_geometry_shader_unsized_arrays_id,
					 DE_LENGTH_OF_ARRAY(geometry_shader_unsized_arrays_code), geometry_shader_unsized_arrays_code,
					 m_vertex_shader_id, 1 /* number of vertex shader parts */, &m_vertex_shader_code))
	{
		TCU_FAIL("Could not create a program from valid vertex/geometry (unsized arrays version)/fragment shaders");
	}

	if (false == buildProgram(m_program_object_sized_arrays_id, m_fragment_shader_id,
							  1 /* number of fragment shader parts */, &m_fragment_shader_code,
							  m_geometry_shader_sized_arrays_id, DE_LENGTH_OF_ARRAY(geometry_shader_sized_arrays_code),
							  geometry_shader_sized_arrays_code, m_vertex_shader_id,
							  1 /* number of vertex shader parts */, &m_vertex_shader_code))
	{
		TCU_FAIL("Could not create a program from valid vertex/geometry (sized arrays version)/fragment shaders");
	}

	/* Generate, bind and allocate buffer */
	gl.genBuffers(1, &m_buffer_object_id);
	gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer_object_id);
	gl.bufferData(GL_ARRAY_BUFFER, m_buffer_size, 0 /* no start data */, GL_STATIC_DRAW);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create buffer object");

	/* Generate and bind VAO */
	gl.genVertexArrays(1, &m_vertex_array_object_id);
	gl.bindVertexArray(m_vertex_array_object_id);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object");
}

/** Executes the test.
 *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
 *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
 *  Note the function throws exception should an error occur!
 **/
tcu::TestCase::IterateResult GeometryShader_gl_in_ArrayContentsTest::iterate()
{
	/* This test should only run if EXT_geometry_shader is supported */
	if (true != m_is_geometry_shader_extension_supported)
	{
		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
	}

	initTest();

	const glw::Functions& gl							= m_context.getRenderContext().getFunctions();
	unsigned char		  reference_data[m_buffer_size] = { 0 };
	bool				  result						= true;

	/* Prepare reference data */
	{
		glw::GLint*   ivec4_data_ptr;
		glw::GLfloat* vec2_data_ptr;

		const unsigned int ivec4_offset_from_vertex = 2 * sizeof(glw::GLfloat);
		const unsigned int vec2_offset_from_vertex  = 0;

		/* Expected data for vertex:
		 * vec2  = {VertexID, 0.0f}
		 * ivec4 = {0,        VertexID, 0, 1}
		 */
		for (unsigned int vertex_id = 0; vertex_id < m_n_vertices_emitted_per_primitive * m_n_emitted_primitives;
			 ++vertex_id)
		{
			const unsigned int vertex_offset = vertex_id * m_n_bytes_emitted_per_vertex;
			const unsigned int ivec4_offset  = vertex_offset + ivec4_offset_from_vertex;
			const unsigned int vec2_offset   = vertex_offset + vec2_offset_from_vertex;

			ivec4_data_ptr = (glw::GLint*)(reference_data + ivec4_offset);
			vec2_data_ptr  = (glw::GLfloat*)(reference_data + vec2_offset);

			ivec4_data_ptr[0] = 0;
			ivec4_data_ptr[1] = vertex_id;
			ivec4_data_ptr[2] = 0;
			ivec4_data_ptr[3] = 1;

			vec2_data_ptr[0] = (float)vertex_id;
			vec2_data_ptr[1] = 0.0f;
		}
	}

	/* Setup transform feedback */
	gl.enable(GL_RASTERIZER_DISCARD);
	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_object_id);

	/* Draw the geometry */
	for (int n_case = 0; n_case < 2 /* unsized/sized array cases */; ++n_case)
	{
		glw::GLuint po_id = (n_case == 0) ? m_program_object_unsized_arrays_id : m_program_object_sized_arrays_id;

		gl.useProgram(po_id);
		gl.beginTransformFeedback(GL_TRIANGLES);
		{
			gl.drawArrays(GL_TRIANGLES, 0 /* first */, 3 /* one triangle */);
		}
		gl.endTransformFeedback();

		GLU_EXPECT_NO_ERROR(gl.getError(), "Error doing a draw call");

		/* Map buffer object storage holding XFB result into process space. */
		glw::GLchar* transform_feedback_data = (glw::GLchar*)gl.mapBufferRange(
			GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */, m_buffer_size, GL_MAP_READ_BIT);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not map the buffer object into process space");

		/* Verify data extracted from transform feedback */
		if (0 != memcmp(transform_feedback_data, reference_data, m_buffer_size))
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Data extracted from transform feedback is invalid."
							   << tcu::TestLog::EndMessage;

			result = false;
		}

		/* Unmap the buffer object. */
		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Error unmapping the buffer object");

		/* Verify results */
		if (true != result)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
			return STOP;
		}
	}

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	return STOP;
}

/** Deinitializes GLES objects created during the test.
 *
 */
void GeometryShader_gl_in_ArrayContentsTest::deinit()
{
	/* GL */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Bind default values */
	gl.useProgram(0);
	gl.bindVertexArray(0);
	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */, 0 /* id */);
	gl.bindBuffer(GL_ARRAY_BUFFER, 0);

	/* Delete everything */
	if (0 != m_vertex_array_object_id)
	{
		gl.deleteVertexArrays(1, &m_vertex_array_object_id);
	}

	if (0 != m_buffer_object_id)
	{
		gl.deleteBuffers(1, &m_buffer_object_id);
	}

	if (0 != m_program_object_sized_arrays_id)
	{
		gl.deleteProgram(m_program_object_sized_arrays_id);
	}

	if (0 != m_program_object_unsized_arrays_id)
	{
		gl.deleteProgram(m_program_object_unsized_arrays_id);
	}

	if (0 != m_fragment_shader_id)
	{
		gl.deleteShader(m_fragment_shader_id);
	}

	if (0 != m_geometry_shader_sized_arrays_id)
	{
		gl.deleteShader(m_geometry_shader_sized_arrays_id);
	}

	if (0 != m_geometry_shader_unsized_arrays_id)
	{
		gl.deleteShader(m_geometry_shader_unsized_arrays_id);
	}

	if (0 != m_vertex_shader_id)
	{
		gl.deleteShader(m_vertex_shader_id);
	}

	/* Deinitialize Base */
	TestCaseBase::deinit();
}

/** Constructor
 *
 * @param context       Test context
 * @param name          Test case's name
 * @param description   Test case's desricption
 **/
GeometryShader_gl_in_ArrayLengthTest::GeometryShader_gl_in_ArrayLengthTest(Context&				context,
																		   const ExtParameters& extParams,
																		   const char* name, const char* description)
	: TestCaseBase(context, extParams, name, description), m_buffer_object_id(0), m_vertex_array_object_id(0)
{
	/* Nothing to be done here */
}

/** Initialize test case
 *
 **/
void GeometryShader_gl_in_ArrayLengthTest::init()
{
	/* Initialize Base */
	TestCaseBase::init();

	/* Captured variables */
	const char* captured_varyings[] = { "in_array_size" };

	/* This test should only run if EXT_geometry_shader is supported */
	if (true != m_is_geometry_shader_extension_supported)
	{
		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
	}

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

	/* Set up test descriptors */
	initCase(m_test_lines, GL_LINES, 2, /* number of vertices */
			 2,							/* as per spec */
			 GL_POINTS, m_geometry_shader_code_input_lines, m_geometry_shader_code_output_points);

	m_tests.push_back(&m_test_lines);

	initCase(m_test_lines_adjacency, m_glExtTokens.LINES_ADJACENCY, 4, /* number of vertices */
			 4,														   /* as per spec */
			 GL_POINTS, m_geometry_shader_code_input_lines_with_adjacency, m_geometry_shader_code_output_points);

	m_tests.push_back(&m_test_lines_adjacency);

	initCase(m_test_points, GL_POINTS, 1, /* number of vertices */
			 1,							  /* as per spec */
			 GL_POINTS, m_geometry_shader_code_input_points, m_geometry_shader_code_output_points);

	m_tests.push_back(&m_test_points);

	initCase(m_test_triangles, GL_TRIANGLES, 3, /* number of vertices */
			 3,									/* as per spec */
			 GL_POINTS, m_geometry_shader_code_input_triangles, m_geometry_shader_code_output_points);

	m_tests.push_back(&m_test_triangles);

	initCase(m_test_triangles_adjacency, m_glExtTokens.TRIANGLE_STRIP_ADJACENCY, 6, /* number of vertices */
			 6,																		/* as per spec */
			 GL_POINTS, m_geometry_shader_code_input_triangles_with_adjacency, m_geometry_shader_code_output_points);

	m_tests.push_back(&m_test_triangles_adjacency);

	initCase(m_test_lines_adjacency_to_line_strip, m_glExtTokens.LINES_ADJACENCY, 4 /* number of vertices */,
			 4 /* expected array length */, GL_LINES, m_geometry_shader_code_input_lines_with_adjacency,
			 m_geometry_shader_code_output_line_strip);

	m_tests.push_back(&m_test_lines_adjacency_to_line_strip);

	initCase(m_test_triangles_adjacency_to_triangle_strip, m_glExtTokens.TRIANGLE_STRIP_ADJACENCY,
			 6 /* number of vertices */, 6 /* expected array length */, GL_TRIANGLES,
			 m_geometry_shader_code_input_triangles_with_adjacency, m_geometry_shader_code_output_triangle_strip);

	m_tests.push_back(&m_test_triangles_adjacency_to_triangle_strip);

	/* Initialize program objects */
	for (testContainer::iterator it = m_tests.begin(); it != m_tests.end(); ++it)
	{
		/* Case instance */
		Case* test = *it;

		/* Init program */
		initCaseProgram(*test, captured_varyings, sizeof(captured_varyings) / sizeof(captured_varyings[0]));
	}

	/* Generate, bind and allocate buffer */
	gl.genBuffers(1, &m_buffer_object_id);
	gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer_object_id);
	gl.bufferData(GL_ARRAY_BUFFER, m_buffer_size, 0 /* no start data */, GL_STATIC_DRAW);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create buffer object");

	/* Generate and bind VAO */
	gl.genVertexArrays(1, &m_vertex_array_object_id);
	gl.bindVertexArray(m_vertex_array_object_id);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object");
}

/** Executes the test.
 *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
 *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
 *  Note the function throws exception should an error occur!
 **/
tcu::TestCase::IterateResult GeometryShader_gl_in_ArrayLengthTest::iterate()
{
	/* GL */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* This test should only run if EXT_geometry_shader is supported */
	if (true != m_is_geometry_shader_extension_supported)
	{
		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
	}

	/* Setup transform feedback */
	gl.enable(GL_RASTERIZER_DISCARD);
	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_object_id);

	/* Execute tests */
	for (testContainer::iterator it = m_tests.begin(); it != m_tests.end(); ++it)
	{
		glw::GLint result_value = 0;
		Case*	  test			= *it;

		/* Execute */
		gl.useProgram(test->po_id);

		gl.beginTransformFeedback(test->tf_mode);
		{
			gl.drawArrays(test->draw_call_mode, 0, /* first */
						  test->draw_call_n_vertices);
		}
		gl.endTransformFeedback();

		GLU_EXPECT_NO_ERROR(gl.getError(), "Error doing a draw call");

		/* Map transform feedback results */
		glw::GLint* result = (glw::GLint*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */,
															sizeof(glw::GLint), GL_MAP_READ_BIT);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not map the buffer object into process space");

		/* Extract value from transform feedback */
		result_value = *result;

		/* Unmap transform feedback buffer */
		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Error unmapping the buffer object");

		/* Verify results */
		if (result_value != test->expected_array_length)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Expected array length: " << test->expected_array_length
							   << " but found: " << result_value << tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
			return STOP;
		}
	}

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	return STOP;
}

/** Deinitializes test case
 *
 **/
void GeometryShader_gl_in_ArrayLengthTest::deinit()
{
	/* GL */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Bind default values */
	gl.useProgram(0);
	gl.bindVertexArray(0);
	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */, 0 /* id */);
	gl.bindBuffer(GL_ARRAY_BUFFER, 0);
	/* Delete everything */
	if (0 != m_vertex_array_object_id)
	{
		gl.deleteVertexArrays(1, &m_vertex_array_object_id);
	}

	if (0 != m_buffer_object_id)
	{
		gl.deleteBuffers(1, &m_buffer_object_id);
	}

	/* Deinit test cases */
	for (testContainer::iterator it = m_tests.begin(); it != m_tests.end(); ++it)
	{
		Case* test = *it;

		deinitCase(*test);
	}

	m_tests.clear();

	/* Deinitialize Base */
	TestCaseBase::deinit();
}

/** Deinitialize test case instance
 *
 * @param info Case instance
 **/
void GeometryShader_gl_in_ArrayLengthTest::deinitCase(Case& info)
{
	/* GL */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Delete everything */
	if (0 != info.po_id)
	{
		gl.deleteProgram(info.po_id);
	}

	if (0 != info.vs_id)
	{
		gl.deleteShader(info.vs_id);
	}

	if (0 != info.gs_id)
	{
		gl.deleteShader(info.gs_id);
	}

	if (0 != info.fs_id)
	{
		gl.deleteShader(info.fs_id);
	}

	/* Clear case */
	resetCase(info);
}

/** Initialize test case instance with provided data.
 *
 * @param info                  Case instance;
 * @param draw_call_mode        Primitive type used by a draw call;
 * @param draw_call_n_vertices  Number of vertices used by a draw call;
 * @param expected_array_length Expected size of gl_in array;
 * @param tf_mode               Primitive type used by transform feedback;
 * @param input_body_part       Part of geometry shader which specifies input layout;
 * @param output_body_part      Part of geometry shader which specifies output layout;
 **/
void GeometryShader_gl_in_ArrayLengthTest::initCase(Case& info, glw::GLenum draw_call_mode,
													glw::GLint draw_call_n_vertices, glw::GLint expected_array_length,
													glw::GLenum tf_mode, const glw::GLchar* input_body_part,
													const glw::GLchar* output_body_part)
{
	/* Reset case descriptor */
	resetCase(info);

	/* Set fields */
	info.draw_call_mode		   = draw_call_mode;
	info.draw_call_n_vertices  = draw_call_n_vertices;
	info.expected_array_length = expected_array_length;
	info.input_body_part	   = input_body_part;
	info.output_body_part	  = output_body_part;
	info.tf_mode			   = tf_mode;
}

/** Creates and build program for given Case
 *
 * @param info                     Case instance
 * @param captured_varyings        Name of varyings captured by transform feedback
 * @param n_captured_varyings_size Number of varyings captured by transform feedback
 **/
void GeometryShader_gl_in_ArrayLengthTest::initCaseProgram(Case& info, const glw::GLchar** captured_varyings,
														   glw::GLuint n_captured_varyings_size)
{
	/* GL */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Create program and shader objects */
	info.po_id = gl.createProgram();

	info.vs_id = gl.createShader(GL_VERTEX_SHADER);
	info.gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
	info.fs_id = gl.createShader(GL_FRAGMENT_SHADER);

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

	/* Prepare geometry shader parts */
	const char* const geometry_shader_parts[] = { m_geometry_shader_code_preamble, info.input_body_part,
												  info.output_body_part, m_geometry_shader_code_main };

	/* Set up transform feedback */
	gl.transformFeedbackVaryings(info.po_id, n_captured_varyings_size, captured_varyings, GL_SEPARATE_ATTRIBS);

	/* Build program */
	if (false == buildProgram(info.po_id, info.fs_id, 1 /* number of fragment shader code parts */,
							  &m_fragment_shader_code, info.gs_id, DE_LENGTH_OF_ARRAY(geometry_shader_parts),
							  geometry_shader_parts, info.vs_id, 1 /* number of vertex shader code parts */,
							  &m_vertex_shader_code))
	{
		TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader");
	}
}

/** Reset Case instance descriptor's contents.
 *
 * @param info Case instance
 **/
void GeometryShader_gl_in_ArrayLengthTest::resetCase(Case& info)
{
	memset(&info, 0, sizeof(info));
}

/** Constructor
 *
 * @param context     Test context
 * @param name        Test case's name
 * @param description Test case's desricption
 **/
GeometryShader_gl_PointSize_ValueTest::GeometryShader_gl_PointSize_ValueTest(Context&			  context,
																			 const ExtParameters& extParams,
																			 const char* name, const char* description)
	: TestCaseBase(context, extParams, name, description)
	, m_fragment_shader_id(0)
	, m_geometry_shader_id(0)
	, m_program_object_id(0)
	, m_vertex_shader_id(0)
	, m_vertex_array_object_id(0)
	, m_color_texture_id(0)
	, m_framebuffer_object_id(0)
{
	/* Nothing to be done here */
}

/** Initialize test case
 *
 **/
void GeometryShader_gl_PointSize_ValueTest::init()
{
	/* Initialize Base */
	TestCaseBase::init();

	/* This test should only run if EXT_geometry_shader and EXT_geometry_point_size both are supported */
	if (true != m_is_geometry_shader_extension_supported)
	{
		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
	}

	if (true != m_is_geometry_shader_point_size_supported)
	{
		throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__);
	}

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

	/* Verify that point size range is supported */
	glw::GLfloat point_size_range[2] = { 0 };

	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
	{
		gl.getFloatv(GL_POINT_SIZE_RANGE, point_size_range);
	}
	else
	{
		gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, point_size_range);
	}

	if (8.0f > point_size_range[1])
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "Test requires a minimum maximum point size of 8, implementation reports a maximum of : "
						   << point_size_range[1] << tcu::TestLog::EndMessage;

		throw tcu::NotSupportedError("Not supported point size", "", __FILE__, __LINE__);
	}

	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
	{
		gl.enable(GL_PROGRAM_POINT_SIZE);
	}

	/* Create program and shaders */
	m_program_object_id = gl.createProgram();

	m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
	m_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
	m_vertex_shader_id   = gl.createShader(GL_VERTEX_SHADER);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program");

	/* Build program */
	if (false == buildProgram(m_program_object_id, m_fragment_shader_id, 1 /* fragment shader parts number */,
							  &m_fragment_shader_code, m_geometry_shader_id, 1 /* geometry shader parts number */,
							  &m_geometry_shader_code, m_vertex_shader_id, 1 /* vertex shader parts number */,
							  &m_vertex_shader_code))
	{
		TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader");
	}

	/* Set up texture object and a FBO */
	gl.genTextures(1, &m_color_texture_id);
	gl.genFramebuffers(1, &m_framebuffer_object_id);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create framebuffer");

	if (false == setupFramebufferWithTextureAsAttachment(m_framebuffer_object_id, m_color_texture_id, GL_RGBA8,
														 m_texture_width, m_texture_height))
	{
		TCU_FAIL("Failed to setup framebuffer");
	}

	/* Set up a vertex array object */
	gl.genVertexArrays(1, &m_vertex_array_object_id);
	gl.bindVertexArray(m_vertex_array_object_id);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object");
}

/** Executes the test.
 *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
 *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
 *  Note the function throws exception should an error occur!
 **/
tcu::TestCase::IterateResult GeometryShader_gl_PointSize_ValueTest::iterate()
{
	/* Buffer to store results of rendering */
	unsigned char result_image[m_texture_width * m_texture_height * m_texture_pixel_size];

	/* This test should only run if EXT_geometry_shader is supported */
	if (true != m_is_geometry_shader_extension_supported)
	{
		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
	}

	if (true != m_is_geometry_shader_point_size_supported)
	{
		throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__);
	}

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

	/* Render */
	gl.useProgram(m_program_object_id);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to use program");

	gl.clearColor(0 /* red */, 0 /* green */, 0 /* blue */, 0 /* alpha */);
	gl.clear(GL_COLOR_BUFFER_BIT);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not clear the color buffer");

	gl.drawArrays(GL_POINTS, 0 /* first */, 2 /* count */);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Call drawArrays() failed");

	/* Check if the data was modified during the rendering process */
	gl.readPixels(0 /* x */, 0 /* y */, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, result_image);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixels from color buffer");

	/* 1) pixel at (2,  8) is (255, 255, 255, 255) */
	unsigned int referencePixelCoordinates[2] = { 2, 8 };

	if (false == comparePixel(result_image, referencePixelCoordinates[0] /* x */, referencePixelCoordinates[1] /* y */,
							  m_texture_width, m_texture_height, m_texture_pixel_size, 255 /* red */, 255 /* green */,
							  255 /* blue */, 255 /* alpha */))
	{
		const unsigned int texel_offset = referencePixelCoordinates[1] * m_texture_width * m_texture_pixel_size +
										  referencePixelCoordinates[0] * m_texture_pixel_size;

		m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", "
						   << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", "
						   << result_image[texel_offset + 3] << "]"
						   << " is different from reference data [255, 255, 255, 255]!" << tcu::TestLog::EndMessage;

		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		return STOP;
	}

	/* 2) pixel at (14, 8) is (255, 255, 255, 255) */
	referencePixelCoordinates[0] = 14;
	referencePixelCoordinates[1] = 8;

	if (false == comparePixel(result_image, referencePixelCoordinates[0] /* x */, referencePixelCoordinates[1] /* y */,
							  m_texture_width, m_texture_height, m_texture_pixel_size, 255 /* red */, 255 /* green */,
							  255 /* blue */, 255 /* alpha */))
	{
		const unsigned int texel_offset = referencePixelCoordinates[1] * m_texture_width * m_texture_pixel_size +
										  referencePixelCoordinates[0] * m_texture_pixel_size;

		m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", "
						   << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", "
						   << result_image[texel_offset + 3] << "]"
						   << " is different from reference data [255, 255, 255, 255]!" << tcu::TestLog::EndMessage;

		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		return STOP;
	}

	/* 3) pixel at (6,  8) is (0,   0,   0,   0) */
	referencePixelCoordinates[0] = 6;
	referencePixelCoordinates[1] = 8;

	if (false == comparePixel(result_image, referencePixelCoordinates[0] /* x */, referencePixelCoordinates[1] /* y */,
							  m_texture_width, m_texture_height, m_texture_pixel_size, 0 /* red */, 0 /* green */,
							  0 /* blue */, 0 /* alpha */))
	{
		const unsigned int texel_offset = referencePixelCoordinates[1] * m_texture_width * m_texture_pixel_size +
										  referencePixelCoordinates[0] * m_texture_pixel_size;

		m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", "
						   << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", "
						   << result_image[texel_offset + 3] << "]"
						   << "is different from reference data [0, 0, 0, 0]!" << tcu::TestLog::EndMessage;

		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		return STOP;
	}

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

/** Deinitializes test case
 *
 **/
void GeometryShader_gl_PointSize_ValueTest::deinit()
{
	/* GL */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Bind defaults */
	gl.useProgram(0);
	gl.bindVertexArray(0);
	gl.bindTexture(GL_TEXTURE_2D, 0);
	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
	{
		gl.disable(GL_PROGRAM_POINT_SIZE);
	}

	/* Delete everything */
	if (m_program_object_id != 0)
	{
		gl.deleteProgram(m_program_object_id);
	}

	if (m_fragment_shader_id != 0)
	{
		gl.deleteShader(m_fragment_shader_id);
	}

	if (m_geometry_shader_id != 0)
	{
		gl.deleteShader(m_geometry_shader_id);
	}

	if (m_vertex_shader_id != 0)
	{
		gl.deleteShader(m_vertex_shader_id);
	}

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

	if (m_color_texture_id != 0)
	{
		gl.deleteTextures(1, &m_color_texture_id);
	}

	if (m_framebuffer_object_id != 0)
	{
		gl.deleteFramebuffers(1, &m_framebuffer_object_id);
	}

	/* Release base class */
	TestCaseBase::deinit();
}

/** Constructor
 *
 * @param context     Test context
 * @param name        Test case's name
 * @param description Test case's desricption
 **/
GeometryShader_gl_Position_ValueTest::GeometryShader_gl_Position_ValueTest(Context&				context,
																		   const ExtParameters& extParams,
																		   const char* name, const char* description)
	: TestCaseBase(context, extParams, name, description)
	, m_fragment_shader_id(0)
	, m_geometry_shader_id(0)
	, m_program_object_id(0)
	, m_vertex_shader_id(0)
	, m_vertex_array_object_id(0)
	, m_color_texture_id(0)
	, m_framebuffer_object_id(0)
{
	/* Nothing to be done here */
}

/** Initialize test case
 *
 **/
void GeometryShader_gl_Position_ValueTest::init()
{
	/* Initialize base */
	TestCaseBase::init();

	/* This test should only run if EXT_geometry_shader is supported */
	if (true != m_is_geometry_shader_extension_supported)
	{
		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
	}

	if (true != m_is_geometry_shader_point_size_supported)
	{
		throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__);
	}

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

	/* Verify that point size range is supported */
	glw::GLfloat point_size_range[2] = { 0 };

	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
	{
		gl.getFloatv(GL_POINT_SIZE_RANGE, point_size_range);
	}
	else
	{
		gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, point_size_range);
	}

	if (8.0f > point_size_range[1])
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "Test requires a minimum maximum point size of 8, implementation reports a maximum of : "
						   << point_size_range[1] << tcu::TestLog::EndMessage;

		throw tcu::NotSupportedError("Not supported point size", "", __FILE__, __LINE__);
	}

	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
	{
		gl.enable(GL_PROGRAM_POINT_SIZE);
	}

	/* Create program and shaders */
	m_program_object_id = gl.createProgram();

	m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
	m_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
	m_vertex_shader_id   = gl.createShader(GL_VERTEX_SHADER);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program");

	/* Build program */
	if (false == buildProgram(m_program_object_id, m_fragment_shader_id, 1 /* fragment shader parts number */,
							  &m_fragment_shader_code, m_geometry_shader_id, 1 /* geometry shader parts number */,
							  &m_geometry_shader_code, m_vertex_shader_id, 1 /* vertex shader parts number */,
							  &m_vertex_shader_code))
	{
		TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader");
	}

	/* Set up a texture object and a FBO */
	gl.genTextures(1, &m_color_texture_id);
	gl.genFramebuffers(1, &m_framebuffer_object_id);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create framebuffer");

	if (false == setupFramebufferWithTextureAsAttachment(m_framebuffer_object_id, m_color_texture_id, GL_RGBA8,
														 m_texture_width, m_texture_height))
	{
		TCU_FAIL("Failed to setup framebuffer");
	}

	/* Set up a vertex array object */
	gl.genVertexArrays(1, &m_vertex_array_object_id);
	gl.bindVertexArray(m_vertex_array_object_id);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object");
}

/** Executes the test.
 *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
 *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
 *  Note the function throws exception should an error occur!
 **/
tcu::TestCase::IterateResult GeometryShader_gl_Position_ValueTest::iterate()
{
	/* Variables used for image verification purposes */
	unsigned char result_image[m_texture_width * m_texture_height * m_texture_pixel_size];

	/* This test should only run if EXT_geometry_shader is supported */
	if (true != m_is_geometry_shader_extension_supported)
	{
		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
	}

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

	/* Render */
	gl.useProgram(m_program_object_id);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to use program");

	gl.clearColor(0 /* red */, 0 /* green */, 0 /* blue */, 0 /* alpha */);
	gl.clear(GL_COLOR_BUFFER_BIT);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not clear the color buffer");

	gl.drawArrays(GL_POINTS, 0 /* first */, 8 /* count */);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Call drawArrays() failed");

	/* Check if the data was modified during the rendering process */
	gl.readPixels(0 /* x */, 0 /* y */, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, result_image);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixels from color buffer");

	/* The test passes if centers of the rendered points are lit at expected locations. */
	for (unsigned int x = 4; x < m_texture_width; x += 8)
	{
		if (false == comparePixel(result_image, x, 32 /* y */, m_texture_width, m_texture_height, m_texture_pixel_size,
								  255 /* red */, 255 /* green */, 255 /* blue */, 255 /* alpha */))
		{
			const unsigned int texel_offset = 32 * m_texture_width * m_texture_pixel_size + x * m_texture_pixel_size;

			m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", "
							   << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", "
							   << result_image[texel_offset + 3] << "]"
							   << "is different from reference data [255, 255, 255, 255] !" << tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
			return STOP;
		}
	}

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

/** Deinitializes test case
 *
 **/
void GeometryShader_gl_Position_ValueTest::deinit()
{
	/* GL */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Bind default values */
	gl.useProgram(0);
	gl.bindVertexArray(0);
	gl.bindTexture(GL_TEXTURE_2D, 0);
	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
	{
		gl.disable(GL_PROGRAM_POINT_SIZE);
	}

	/* Delete everything */
	if (m_program_object_id != 0)
	{
		gl.deleteProgram(m_program_object_id);
	}

	if (m_fragment_shader_id != 0)
	{
		gl.deleteShader(m_fragment_shader_id);
	}

	if (m_geometry_shader_id != 0)
	{
		gl.deleteShader(m_geometry_shader_id);
	}

	if (m_vertex_shader_id != 0)
	{
		gl.deleteShader(m_vertex_shader_id);
	}

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

	if (m_color_texture_id != 0)
	{
		gl.deleteTextures(1, &m_color_texture_id);
	}

	if (m_framebuffer_object_id != 0)
	{
		gl.deleteFramebuffers(1, &m_framebuffer_object_id);
	}

	/* Release base class */
	TestCaseBase::deinit();
}

} /* glcts */
