Home | History | Annotate | Download | only in geometry_shader
      1 /*-------------------------------------------------------------------------
      2  * OpenGL Conformance Test Suite
      3  * -----------------------------
      4  *
      5  * Copyright (c) 2014-2016 The Khronos Group Inc.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  */ /*!
     20  * \file
     21  * \brief
     22  */ /*-------------------------------------------------------------------*/
     23 
     24 #include "esextcGeometryShaderInput.hpp"
     25 
     26 #include "gluContextInfo.hpp"
     27 #include "glwEnums.hpp"
     28 #include "glwFunctions.hpp"
     29 #include "tcuTestLog.hpp"
     30 #include <cstring>
     31 
     32 namespace glcts
     33 {
     34 /* Vertex shader for GeometryShader_gl_in_ArrayContents */
     35 const char* const GeometryShader_gl_in_ArrayContentsTest::m_vertex_shader_code =
     36 	"${VERSION}\n"
     37 	"\n"
     38 	"     out  vec2 vs_gs_a;\n"
     39 	"flat out ivec4 vs_gs_b;\n"
     40 	"\n"
     41 	"void main()\n"
     42 	"{\n"
     43 	"    vs_gs_a = vec2 (gl_VertexID, 0);\n"
     44 	"    vs_gs_b = ivec4(0,           gl_VertexID, 0, 1);\n"
     45 	"}\n";
     46 
     47 /* Geometry shader for GeometryShader_gl_in_ArrayContents */
     48 const char* const GeometryShader_gl_in_ArrayContentsTest::m_geometry_shader_preamble_code =
     49 	"${VERSION}\n"
     50 	"\n"
     51 	"${GEOMETRY_SHADER_REQUIRE}\n"
     52 	"\n"
     53 	"layout(triangles)                      in;\n"
     54 	"layout(triangle_strip, max_vertices=3) out;\n"
     55 	"\n";
     56 
     57 const char* const GeometryShader_gl_in_ArrayContentsTest::m_geometry_shader_code =
     58 	"#ifdef USE_UNSIZED_ARRAYS\n"
     59 	"         in  vec2 vs_gs_a[];\n"
     60 	"    flat in ivec4 vs_gs_b[];\n"
     61 	"#else\n"
     62 	"         in  vec2 vs_gs_a[3];\n"
     63 	"    flat in ivec4 vs_gs_b[3];\n"
     64 	"#endif\n"
     65 	"\n"
     66 	"     out  vec2 gs_fs_a;\n"
     67 	"flat out ivec4 gs_fs_b;\n"
     68 	"\n"
     69 	"void main()\n"
     70 	"{\n"
     71 	"    gl_Position = vec4(-1, -1, 0, 1);\n"
     72 	"    gs_fs_a     = vs_gs_a[0];\n"
     73 	"    gs_fs_b     = vs_gs_b[0];\n"
     74 	"    EmitVertex();\n"
     75 	"    \n"
     76 	"    gl_Position = vec4(-1, 1, 0, 1);\n"
     77 	"    gs_fs_a     = vs_gs_a[1];\n"
     78 	"    gs_fs_b     = vs_gs_b[1];\n"
     79 	"    EmitVertex();\n"
     80 	"    \n"
     81 	"    gl_Position = vec4(1, 1, 0, 1);\n"
     82 	"    gs_fs_a     = vs_gs_a[2];\n"
     83 	"    gs_fs_b     = vs_gs_b[2];\n"
     84 	"    EmitVertex();\n"
     85 	"    \n"
     86 	"    EndPrimitive();\n"
     87 	"}\n";
     88 
     89 /* Fragment shader for GeometryShader_gl_in_ArrayContents */
     90 const char* const GeometryShader_gl_in_ArrayContentsTest::m_fragment_shader_code =
     91 	"${VERSION}\n"
     92 	"\n"
     93 	"precision highp float;\n"
     94 	"\n"
     95 	"layout(location = 0) out vec4 fs_out_color;\n"
     96 	"\n"
     97 	"void main()\n"
     98 	"{\n"
     99 	"    fs_out_color = vec4(1, 1, 1, 1);\n"
    100 	"}\n";
    101 
    102 /* Vertex Shader for GeometryShader_gl_in_ArrayLengthTest*/
    103 const char* const GeometryShader_gl_in_ArrayLengthTest::m_vertex_shader_code =
    104 	"${VERSION}\n"
    105 	"\n"
    106 	"void main()\n"
    107 	"{\n"
    108 	"    gl_Position = vec4(gl_VertexID, 0, 0, 1);\n"
    109 	"}\n";
    110 
    111 /* Geometry shader body parts for GeometryShader_gl_in_ArrayLengthTest */
    112 const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_preamble = "${VERSION}\n"
    113 																						  "\n"
    114 																						  "${GEOMETRY_SHADER_REQUIRE}\n"
    115 																						  "\n";
    116 
    117 const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_points =
    118 	"layout(points)                     in;\n";
    119 
    120 const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_lines =
    121 	"layout(lines)                      in;\n";
    122 
    123 const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_lines_with_adjacency =
    124 	"layout(lines_adjacency)            in;\n";
    125 
    126 const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_triangles =
    127 	"layout(triangles)                  in;\n";
    128 
    129 const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_input_triangles_with_adjacency =
    130 	"layout(triangles_adjacency)        in;\n";
    131 
    132 const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_output_points =
    133 	"layout(points, max_vertices=1)     out;\n"
    134 	"\n"
    135 	"#define N_OUT_VERTICES (1)\n";
    136 
    137 const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_output_line_strip =
    138 	"layout(line_strip, max_vertices=2) out;\n"
    139 	"\n"
    140 	"#define N_OUT_VERTICES (2)\n";
    141 
    142 const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_output_triangle_strip =
    143 	"layout(triangle_strip, max_vertices=3) out;\n"
    144 	"\n"
    145 	"#define N_OUT_VERTICES (3)\n";
    146 
    147 const char* const GeometryShader_gl_in_ArrayLengthTest::m_geometry_shader_code_main =
    148 	"\n"
    149 	"flat out int in_array_size;\n"
    150 	"\n"
    151 	"void main()\n"
    152 	"{\n"
    153 	"    for (int n = 0; n < N_OUT_VERTICES; n++)\n"
    154 	"    {\n"
    155 	"        in_array_size = gl_in.length();\n"
    156 	"        EmitVertex();\n"
    157 	"    }\n"
    158 	"\n"
    159 	"    EndPrimitive();\n"
    160 	"}\n";
    161 
    162 /* Fragment Shader for GeometryShader_gl_in_ArrayLengthTest */
    163 const char* const GeometryShader_gl_in_ArrayLengthTest::m_fragment_shader_code = "${VERSION}\n"
    164 																				 "\n"
    165 																				 "precision highp float;\n"
    166 																				 "\n"
    167 																				 "void main()\n"
    168 																				 "{\n"
    169 																				 "}\n";
    170 
    171 /* Vertex Shader for GeometryShader_gl_PointSize_ValueTest */
    172 const char* const GeometryShader_gl_PointSize_ValueTest::m_vertex_shader_code =
    173 	"${VERSION}\n"
    174 	"\n"
    175 	"void main()\n"
    176 	"{\n"
    177 	"    // See test description for explanation of magic numbers\n"
    178 	"    switch (gl_VertexID)\n"
    179 	"    {\n"
    180 	"        case 0:\n"
    181 	"        {\n"
    182 	"            gl_Position = vec4(-7.0/8.0, 0, 0, 1);\n"
    183 	"\n"
    184 	"            break;\n"
    185 	"        }\n"
    186 	"\n"
    187 	"        case 1:\n"
    188 	"        {\n"
    189 	"            gl_Position = vec4(6.0/8.0, 0, 0, 1);\n"
    190 	"\n"
    191 	"            break;\n"
    192 	"        }\n"
    193 	"    }\n"
    194 	"\n"
    195 	"    gl_PointSize = float(2 * (gl_VertexID + 1));\n"
    196 	"}\n";
    197 
    198 /* Geometry Shader for GeometryShader_gl_PointSize_ValueTest */
    199 const char* const GeometryShader_gl_PointSize_ValueTest::m_geometry_shader_code =
    200 	"${VERSION}\n"
    201 	"\n"
    202 	"${GEOMETRY_SHADER_REQUIRE}\n"
    203 	"${GEOMETRY_POINT_SIZE_REQUIRE}\n"
    204 	"\n"
    205 	"layout(points)                 in;\n"
    206 	"layout(points, max_vertices=1) out;\n"
    207 	"\n"
    208 	"void main()\n"
    209 	"{\n"
    210 	"    gl_Position  = gl_in[0].gl_Position;\n"
    211 	"    gl_PointSize = gl_in[0].gl_PointSize * 2.0;\n"
    212 	"    EmitVertex();\n"
    213 	"    \n"
    214 	"    EndPrimitive();\n"
    215 	"}\n";
    216 
    217 /* Fragment Shader for GeometryShader_gl_PointSize_ValueTest */
    218 const char* const GeometryShader_gl_PointSize_ValueTest::m_fragment_shader_code =
    219 	"${VERSION}\n"
    220 	"\n"
    221 	"precision highp float;\n"
    222 	"\n"
    223 	"layout(location = 0) out vec4 fs_out_color;\n"
    224 	"\n"
    225 	"void main()\n"
    226 	"{\n"
    227 	"    fs_out_color = vec4(1, 1, 1, 1);\n"
    228 	"}\n";
    229 
    230 /* Vertex Shader for GeometryShader_gl_Position_ValueTest */
    231 const char* const GeometryShader_gl_Position_ValueTest::m_vertex_shader_code =
    232 	"${VERSION}\n"
    233 	"\n"
    234 	"void main()\n"
    235 	"{\n"
    236 	"    gl_Position = vec4(gl_VertexID, gl_VertexID, 0, 1);\n"
    237 	"\n"
    238 	"}\n";
    239 
    240 /* Geometry Shader for GeometryShader_gl_Position_ValueTest */
    241 const char* const GeometryShader_gl_Position_ValueTest::m_geometry_shader_code =
    242 	"${VERSION}\n"
    243 	"\n"
    244 	"${GEOMETRY_SHADER_REQUIRE}\n"
    245 	"${GEOMETRY_POINT_SIZE_REQUIRE}\n"
    246 	"\n"
    247 	"layout(points)                 in;\n"
    248 	"layout(points, max_vertices=1) out;\n"
    249 	"\n"
    250 	"void main()\n"
    251 	"{\n"
    252 	"    // See test description for discussion on the magic numbers\n"
    253 	"    gl_Position  = vec4(-1.0 + 4.0/32.0 + gl_in[0].gl_Position.x / 4.0, 0, 0, 1);\n"
    254 	"    gl_PointSize = 8.0;\n"
    255 	"    EmitVertex();\n"
    256 	"\n"
    257 	"    EndPrimitive();\n"
    258 	"}\n";
    259 
    260 /* Fragment Shader for GeometryShader_gl_Position_ValueTest */
    261 const char* const GeometryShader_gl_Position_ValueTest::m_fragment_shader_code =
    262 	"${VERSION}\n"
    263 	"\n"
    264 	"precision highp float;\n"
    265 	"\n"
    266 	"layout(location = 0) out vec4 fs_out_color;\n"
    267 	"\n"
    268 	"void main()\n"
    269 	"{\n"
    270 	"    fs_out_color = vec4(1, 1, 1, 1);\n"
    271 	"}\n";
    272 
    273 /* Constants for GeometryShader_gl_in_ArrayContentsTest */
    274 const unsigned int GeometryShader_gl_in_ArrayContentsTest::m_n_bytes_emitted_per_vertex =
    275 	2 * sizeof(glw::GLfloat) + 4 * sizeof(glw::GLint);
    276 const unsigned int GeometryShader_gl_in_ArrayContentsTest::m_n_emitted_primitives			  = 1;
    277 const unsigned int GeometryShader_gl_in_ArrayContentsTest::m_n_vertices_emitted_per_primitive = 3;
    278 
    279 const unsigned int GeometryShader_gl_in_ArrayContentsTest::m_buffer_size =
    280 	GeometryShader_gl_in_ArrayContentsTest::m_n_bytes_emitted_per_vertex *
    281 	GeometryShader_gl_in_ArrayContentsTest::m_n_vertices_emitted_per_primitive *
    282 	GeometryShader_gl_in_ArrayContentsTest::m_n_emitted_primitives;
    283 
    284 /* Constants for GeometryShader_gl_in_ArrayLengthTest */
    285 const glw::GLuint GeometryShader_gl_in_ArrayLengthTest::m_max_primitive_emitted = 6;
    286 const glw::GLuint GeometryShader_gl_in_ArrayLengthTest::m_buffer_size = sizeof(glw::GLint) * m_max_primitive_emitted;
    287 
    288 /* Constants for GeometryShader_gl_PointSize_ValueTest */
    289 const glw::GLuint GeometryShader_gl_PointSize_ValueTest::m_texture_height	 = 16;
    290 const glw::GLuint GeometryShader_gl_PointSize_ValueTest::m_texture_pixel_size = 4;
    291 const glw::GLuint GeometryShader_gl_PointSize_ValueTest::m_texture_width	  = 16;
    292 
    293 /* Constants for GeometryShader_gl_Position_ValueTest */
    294 const glw::GLuint GeometryShader_gl_Position_ValueTest::m_texture_height	 = 64;
    295 const glw::GLuint GeometryShader_gl_Position_ValueTest::m_texture_pixel_size = 4;
    296 const glw::GLuint GeometryShader_gl_Position_ValueTest::m_texture_width		 = 64;
    297 
    298 /** Constructor
    299  *
    300  * @param context       Test context
    301  * @param name          Test case's name
    302  * @param description   Test case's desricption
    303  **/
    304 GeometryShader_gl_in_ArrayContentsTest::GeometryShader_gl_in_ArrayContentsTest(Context&				context,
    305 																			   const ExtParameters& extParams,
    306 																			   const char*			name,
    307 																			   const char*			description)
    308 	: TestCaseBase(context, extParams, name, description)
    309 	, m_fragment_shader_id(0)
    310 	, m_geometry_shader_sized_arrays_id(0)
    311 	, m_geometry_shader_unsized_arrays_id(0)
    312 	, m_program_object_sized_arrays_id(0)
    313 	, m_program_object_unsized_arrays_id(0)
    314 	, m_vertex_shader_id(0)
    315 	, m_buffer_object_id(0)
    316 	, m_vertex_array_object_id(0)
    317 {
    318 	/* Nothing to be done here */
    319 }
    320 
    321 /** Initializes GLES objects used during the test.
    322  *
    323  **/
    324 void GeometryShader_gl_in_ArrayContentsTest::initTest()
    325 {
    326 	/* Varing names */
    327 	const glw::GLchar* const captured_varyings[] = {
    328 		"gs_fs_a", "gs_fs_b",
    329 	};
    330 
    331 	/* Number of varings */
    332 	const glw::GLuint n_captured_varyings_size = sizeof(captured_varyings) / sizeof(captured_varyings[0]);
    333 
    334 	/* GL */
    335 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    336 
    337 	/* Create program and shaders */
    338 	m_program_object_sized_arrays_id   = gl.createProgram();
    339 	m_program_object_unsized_arrays_id = gl.createProgram();
    340 
    341 	m_fragment_shader_id				= gl.createShader(GL_FRAGMENT_SHADER);
    342 	m_geometry_shader_unsized_arrays_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
    343 	m_geometry_shader_sized_arrays_id   = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
    344 	m_vertex_shader_id					= gl.createShader(GL_VERTEX_SHADER);
    345 
    346 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program");
    347 
    348 	/* Set up transform feedback */
    349 	gl.transformFeedbackVaryings(m_program_object_sized_arrays_id, n_captured_varyings_size, captured_varyings,
    350 								 GL_INTERLEAVED_ATTRIBS);
    351 	gl.transformFeedbackVaryings(m_program_object_unsized_arrays_id, n_captured_varyings_size, captured_varyings,
    352 								 GL_INTERLEAVED_ATTRIBS);
    353 
    354 	/* Build programs */
    355 	const char* geometry_shader_unsized_arrays_code[] = { m_geometry_shader_preamble_code,
    356 														  "#define USE_UNSIZED_ARRAYS\n", m_geometry_shader_code };
    357 	const char* geometry_shader_sized_arrays_code[] = { m_geometry_shader_preamble_code, m_geometry_shader_code };
    358 
    359 	if (false ==
    360 		buildProgram(m_program_object_unsized_arrays_id, m_fragment_shader_id, 1 /* number of fragment shader parts */,
    361 					 &m_fragment_shader_code, m_geometry_shader_unsized_arrays_id,
    362 					 DE_LENGTH_OF_ARRAY(geometry_shader_unsized_arrays_code), geometry_shader_unsized_arrays_code,
    363 					 m_vertex_shader_id, 1 /* number of vertex shader parts */, &m_vertex_shader_code))
    364 	{
    365 		TCU_FAIL("Could not create a program from valid vertex/geometry (unsized arrays version)/fragment shaders");
    366 	}
    367 
    368 	if (false == buildProgram(m_program_object_sized_arrays_id, m_fragment_shader_id,
    369 							  1 /* number of fragment shader parts */, &m_fragment_shader_code,
    370 							  m_geometry_shader_sized_arrays_id, DE_LENGTH_OF_ARRAY(geometry_shader_sized_arrays_code),
    371 							  geometry_shader_sized_arrays_code, m_vertex_shader_id,
    372 							  1 /* number of vertex shader parts */, &m_vertex_shader_code))
    373 	{
    374 		TCU_FAIL("Could not create a program from valid vertex/geometry (sized arrays version)/fragment shaders");
    375 	}
    376 
    377 	/* Generate, bind and allocate buffer */
    378 	gl.genBuffers(1, &m_buffer_object_id);
    379 	gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer_object_id);
    380 	gl.bufferData(GL_ARRAY_BUFFER, m_buffer_size, 0 /* no start data */, GL_STATIC_DRAW);
    381 
    382 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create buffer object");
    383 
    384 	/* Generate and bind VAO */
    385 	gl.genVertexArrays(1, &m_vertex_array_object_id);
    386 	gl.bindVertexArray(m_vertex_array_object_id);
    387 
    388 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object");
    389 }
    390 
    391 /** Executes the test.
    392  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
    393  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
    394  *  Note the function throws exception should an error occur!
    395  **/
    396 tcu::TestCase::IterateResult GeometryShader_gl_in_ArrayContentsTest::iterate()
    397 {
    398 	/* This test should only run if EXT_geometry_shader is supported */
    399 	if (true != m_is_geometry_shader_extension_supported)
    400 	{
    401 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
    402 	}
    403 
    404 	initTest();
    405 
    406 	const glw::Functions& gl							= m_context.getRenderContext().getFunctions();
    407 	unsigned char		  reference_data[m_buffer_size] = { 0 };
    408 	bool				  result						= true;
    409 
    410 	/* Prepare reference data */
    411 	{
    412 		glw::GLint*   ivec4_data_ptr;
    413 		glw::GLfloat* vec2_data_ptr;
    414 
    415 		const unsigned int ivec4_offset_from_vertex = 2 * sizeof(glw::GLfloat);
    416 		const unsigned int vec2_offset_from_vertex  = 0;
    417 
    418 		/* Expected data for vertex:
    419 		 * vec2  = {VertexID, 0.0f}
    420 		 * ivec4 = {0,        VertexID, 0, 1}
    421 		 */
    422 		for (unsigned int vertex_id = 0; vertex_id < m_n_vertices_emitted_per_primitive * m_n_emitted_primitives;
    423 			 ++vertex_id)
    424 		{
    425 			const unsigned int vertex_offset = vertex_id * m_n_bytes_emitted_per_vertex;
    426 			const unsigned int ivec4_offset  = vertex_offset + ivec4_offset_from_vertex;
    427 			const unsigned int vec2_offset   = vertex_offset + vec2_offset_from_vertex;
    428 
    429 			ivec4_data_ptr = (glw::GLint*)(reference_data + ivec4_offset);
    430 			vec2_data_ptr  = (glw::GLfloat*)(reference_data + vec2_offset);
    431 
    432 			ivec4_data_ptr[0] = 0;
    433 			ivec4_data_ptr[1] = vertex_id;
    434 			ivec4_data_ptr[2] = 0;
    435 			ivec4_data_ptr[3] = 1;
    436 
    437 			vec2_data_ptr[0] = (float)vertex_id;
    438 			vec2_data_ptr[1] = 0.0f;
    439 		}
    440 	}
    441 
    442 	/* Setup transform feedback */
    443 	gl.enable(GL_RASTERIZER_DISCARD);
    444 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_object_id);
    445 
    446 	/* Draw the geometry */
    447 	for (int n_case = 0; n_case < 2 /* unsized/sized array cases */; ++n_case)
    448 	{
    449 		glw::GLuint po_id = (n_case == 0) ? m_program_object_unsized_arrays_id : m_program_object_sized_arrays_id;
    450 
    451 		gl.useProgram(po_id);
    452 		gl.beginTransformFeedback(GL_TRIANGLES);
    453 		{
    454 			gl.drawArrays(GL_TRIANGLES, 0 /* first */, 3 /* one triangle */);
    455 		}
    456 		gl.endTransformFeedback();
    457 
    458 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error doing a draw call");
    459 
    460 		/* Map buffer object storage holding XFB result into process space. */
    461 		glw::GLchar* transform_feedback_data = (glw::GLchar*)gl.mapBufferRange(
    462 			GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */, m_buffer_size, GL_MAP_READ_BIT);
    463 
    464 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not map the buffer object into process space");
    465 
    466 		/* Verify data extracted from transform feedback */
    467 		if (0 != memcmp(transform_feedback_data, reference_data, m_buffer_size))
    468 		{
    469 			m_testCtx.getLog() << tcu::TestLog::Message << "Data extracted from transform feedback is invalid."
    470 							   << tcu::TestLog::EndMessage;
    471 
    472 			result = false;
    473 		}
    474 
    475 		/* Unmap the buffer object. */
    476 		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    477 
    478 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error unmapping the buffer object");
    479 
    480 		/* Verify results */
    481 		if (true != result)
    482 		{
    483 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    484 			return STOP;
    485 		}
    486 	}
    487 
    488 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    489 	return STOP;
    490 }
    491 
    492 /** Deinitializes GLES objects created during the test.
    493  *
    494  */
    495 void GeometryShader_gl_in_ArrayContentsTest::deinit()
    496 {
    497 	/* GL */
    498 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    499 
    500 	/* Bind default values */
    501 	gl.useProgram(0);
    502 	gl.bindVertexArray(0);
    503 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */, 0 /* id */);
    504 	gl.bindBuffer(GL_ARRAY_BUFFER, 0);
    505 
    506 	/* Delete everything */
    507 	if (0 != m_vertex_array_object_id)
    508 	{
    509 		gl.deleteVertexArrays(1, &m_vertex_array_object_id);
    510 	}
    511 
    512 	if (0 != m_buffer_object_id)
    513 	{
    514 		gl.deleteBuffers(1, &m_buffer_object_id);
    515 	}
    516 
    517 	if (0 != m_program_object_sized_arrays_id)
    518 	{
    519 		gl.deleteProgram(m_program_object_sized_arrays_id);
    520 	}
    521 
    522 	if (0 != m_program_object_unsized_arrays_id)
    523 	{
    524 		gl.deleteProgram(m_program_object_unsized_arrays_id);
    525 	}
    526 
    527 	if (0 != m_fragment_shader_id)
    528 	{
    529 		gl.deleteShader(m_fragment_shader_id);
    530 	}
    531 
    532 	if (0 != m_geometry_shader_sized_arrays_id)
    533 	{
    534 		gl.deleteShader(m_geometry_shader_sized_arrays_id);
    535 	}
    536 
    537 	if (0 != m_geometry_shader_unsized_arrays_id)
    538 	{
    539 		gl.deleteShader(m_geometry_shader_unsized_arrays_id);
    540 	}
    541 
    542 	if (0 != m_vertex_shader_id)
    543 	{
    544 		gl.deleteShader(m_vertex_shader_id);
    545 	}
    546 
    547 	/* Deinitialize Base */
    548 	TestCaseBase::deinit();
    549 }
    550 
    551 /** Constructor
    552  *
    553  * @param context       Test context
    554  * @param name          Test case's name
    555  * @param description   Test case's desricption
    556  **/
    557 GeometryShader_gl_in_ArrayLengthTest::GeometryShader_gl_in_ArrayLengthTest(Context&				context,
    558 																		   const ExtParameters& extParams,
    559 																		   const char* name, const char* description)
    560 	: TestCaseBase(context, extParams, name, description), m_buffer_object_id(0), m_vertex_array_object_id(0)
    561 {
    562 	/* Nothing to be done here */
    563 }
    564 
    565 /** Initialize test case
    566  *
    567  **/
    568 void GeometryShader_gl_in_ArrayLengthTest::init()
    569 {
    570 	/* Initialize Base */
    571 	TestCaseBase::init();
    572 
    573 	/* Captured variables */
    574 	const char* captured_varyings[] = { "in_array_size" };
    575 
    576 	/* This test should only run if EXT_geometry_shader is supported */
    577 	if (true != m_is_geometry_shader_extension_supported)
    578 	{
    579 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
    580 	}
    581 
    582 	/* GL */
    583 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    584 
    585 	/* Set up test descriptors */
    586 	initCase(m_test_lines, GL_LINES, 2, /* number of vertices */
    587 			 2,							/* as per spec */
    588 			 GL_POINTS, m_geometry_shader_code_input_lines, m_geometry_shader_code_output_points);
    589 
    590 	m_tests.push_back(&m_test_lines);
    591 
    592 	initCase(m_test_lines_adjacency, m_glExtTokens.LINES_ADJACENCY, 4, /* number of vertices */
    593 			 4,														   /* as per spec */
    594 			 GL_POINTS, m_geometry_shader_code_input_lines_with_adjacency, m_geometry_shader_code_output_points);
    595 
    596 	m_tests.push_back(&m_test_lines_adjacency);
    597 
    598 	initCase(m_test_points, GL_POINTS, 1, /* number of vertices */
    599 			 1,							  /* as per spec */
    600 			 GL_POINTS, m_geometry_shader_code_input_points, m_geometry_shader_code_output_points);
    601 
    602 	m_tests.push_back(&m_test_points);
    603 
    604 	initCase(m_test_triangles, GL_TRIANGLES, 3, /* number of vertices */
    605 			 3,									/* as per spec */
    606 			 GL_POINTS, m_geometry_shader_code_input_triangles, m_geometry_shader_code_output_points);
    607 
    608 	m_tests.push_back(&m_test_triangles);
    609 
    610 	initCase(m_test_triangles_adjacency, m_glExtTokens.TRIANGLE_STRIP_ADJACENCY, 6, /* number of vertices */
    611 			 6,																		/* as per spec */
    612 			 GL_POINTS, m_geometry_shader_code_input_triangles_with_adjacency, m_geometry_shader_code_output_points);
    613 
    614 	m_tests.push_back(&m_test_triangles_adjacency);
    615 
    616 	initCase(m_test_lines_adjacency_to_line_strip, m_glExtTokens.LINES_ADJACENCY, 4 /* number of vertices */,
    617 			 4 /* expected array length */, GL_LINES, m_geometry_shader_code_input_lines_with_adjacency,
    618 			 m_geometry_shader_code_output_line_strip);
    619 
    620 	m_tests.push_back(&m_test_lines_adjacency_to_line_strip);
    621 
    622 	initCase(m_test_triangles_adjacency_to_triangle_strip, m_glExtTokens.TRIANGLE_STRIP_ADJACENCY,
    623 			 6 /* number of vertices */, 6 /* expected array length */, GL_TRIANGLES,
    624 			 m_geometry_shader_code_input_triangles_with_adjacency, m_geometry_shader_code_output_triangle_strip);
    625 
    626 	m_tests.push_back(&m_test_triangles_adjacency_to_triangle_strip);
    627 
    628 	/* Initialize program objects */
    629 	for (testContainer::iterator it = m_tests.begin(); it != m_tests.end(); ++it)
    630 	{
    631 		/* Case instance */
    632 		Case* test = *it;
    633 
    634 		/* Init program */
    635 		initCaseProgram(*test, captured_varyings, sizeof(captured_varyings) / sizeof(captured_varyings[0]));
    636 	}
    637 
    638 	/* Generate, bind and allocate buffer */
    639 	gl.genBuffers(1, &m_buffer_object_id);
    640 	gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer_object_id);
    641 	gl.bufferData(GL_ARRAY_BUFFER, m_buffer_size, 0 /* no start data */, GL_STATIC_DRAW);
    642 
    643 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create buffer object");
    644 
    645 	/* Generate and bind VAO */
    646 	gl.genVertexArrays(1, &m_vertex_array_object_id);
    647 	gl.bindVertexArray(m_vertex_array_object_id);
    648 
    649 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object");
    650 }
    651 
    652 /** Executes the test.
    653  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
    654  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
    655  *  Note the function throws exception should an error occur!
    656  **/
    657 tcu::TestCase::IterateResult GeometryShader_gl_in_ArrayLengthTest::iterate()
    658 {
    659 	/* GL */
    660 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    661 
    662 	/* This test should only run if EXT_geometry_shader is supported */
    663 	if (true != m_is_geometry_shader_extension_supported)
    664 	{
    665 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
    666 	}
    667 
    668 	/* Setup transform feedback */
    669 	gl.enable(GL_RASTERIZER_DISCARD);
    670 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_object_id);
    671 
    672 	/* Execute tests */
    673 	for (testContainer::iterator it = m_tests.begin(); it != m_tests.end(); ++it)
    674 	{
    675 		glw::GLint result_value = 0;
    676 		Case*	  test			= *it;
    677 
    678 		/* Execute */
    679 		gl.useProgram(test->po_id);
    680 
    681 		gl.beginTransformFeedback(test->tf_mode);
    682 		{
    683 			gl.drawArrays(test->draw_call_mode, 0, /* first */
    684 						  test->draw_call_n_vertices);
    685 		}
    686 		gl.endTransformFeedback();
    687 
    688 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error doing a draw call");
    689 
    690 		/* Map transform feedback results */
    691 		glw::GLint* result = (glw::GLint*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */,
    692 															sizeof(glw::GLint), GL_MAP_READ_BIT);
    693 
    694 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not map the buffer object into process space");
    695 
    696 		/* Extract value from transform feedback */
    697 		result_value = *result;
    698 
    699 		/* Unmap transform feedback buffer */
    700 		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    701 
    702 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error unmapping the buffer object");
    703 
    704 		/* Verify results */
    705 		if (result_value != test->expected_array_length)
    706 		{
    707 			m_testCtx.getLog() << tcu::TestLog::Message << "Expected array length: " << test->expected_array_length
    708 							   << " but found: " << result_value << tcu::TestLog::EndMessage;
    709 
    710 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    711 			return STOP;
    712 		}
    713 	}
    714 
    715 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    716 	return STOP;
    717 }
    718 
    719 /** Deinitializes test case
    720  *
    721  **/
    722 void GeometryShader_gl_in_ArrayLengthTest::deinit()
    723 {
    724 	/* GL */
    725 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    726 
    727 	/* Bind default values */
    728 	gl.useProgram(0);
    729 	gl.bindVertexArray(0);
    730 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */, 0 /* id */);
    731 	gl.bindBuffer(GL_ARRAY_BUFFER, 0);
    732 
    733 	/* Delete everything */
    734 	if (0 != m_vertex_array_object_id)
    735 	{
    736 		gl.deleteVertexArrays(1, &m_vertex_array_object_id);
    737 	}
    738 
    739 	if (0 != m_buffer_object_id)
    740 	{
    741 		gl.deleteBuffers(1, &m_buffer_object_id);
    742 	}
    743 
    744 	/* Deinit test cases */
    745 	for (testContainer::iterator it = m_tests.begin(); it != m_tests.end(); ++it)
    746 	{
    747 		Case* test = *it;
    748 
    749 		deinitCase(*test);
    750 	}
    751 
    752 	m_tests.clear();
    753 
    754 	/* Deinitialize Base */
    755 	TestCaseBase::deinit();
    756 }
    757 
    758 /** Deinitialize test case instance
    759  *
    760  * @param info Case instance
    761  **/
    762 void GeometryShader_gl_in_ArrayLengthTest::deinitCase(Case& info)
    763 {
    764 	/* GL */
    765 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    766 
    767 	/* Delete everything */
    768 	if (0 != info.po_id)
    769 	{
    770 		gl.deleteProgram(info.po_id);
    771 	}
    772 
    773 	if (0 != info.vs_id)
    774 	{
    775 		gl.deleteShader(info.vs_id);
    776 	}
    777 
    778 	if (0 != info.gs_id)
    779 	{
    780 		gl.deleteShader(info.gs_id);
    781 	}
    782 
    783 	if (0 != info.fs_id)
    784 	{
    785 		gl.deleteShader(info.fs_id);
    786 	}
    787 
    788 	/* Clear case */
    789 	resetCase(info);
    790 }
    791 
    792 /** Initialize test case instance with provided data.
    793  *
    794  * @param info                  Case instance;
    795  * @param draw_call_mode        Primitive type used by a draw call;
    796  * @param draw_call_n_vertices  Number of vertices used by a draw call;
    797  * @param expected_array_length Expected size of gl_in array;
    798  * @param tf_mode               Primitive type used by transform feedback;
    799  * @param input_body_part       Part of geometry shader which specifies input layout;
    800  * @param output_body_part      Part of geometry shader which specifies output layout;
    801  **/
    802 void GeometryShader_gl_in_ArrayLengthTest::initCase(Case& info, glw::GLenum draw_call_mode,
    803 													glw::GLint draw_call_n_vertices, glw::GLint expected_array_length,
    804 													glw::GLenum tf_mode, const glw::GLchar* input_body_part,
    805 													const glw::GLchar* output_body_part)
    806 {
    807 	/* Reset case descriptor */
    808 	resetCase(info);
    809 
    810 	/* Set fields */
    811 	info.draw_call_mode		   = draw_call_mode;
    812 	info.draw_call_n_vertices  = draw_call_n_vertices;
    813 	info.expected_array_length = expected_array_length;
    814 	info.input_body_part	   = input_body_part;
    815 	info.output_body_part	  = output_body_part;
    816 	info.tf_mode			   = tf_mode;
    817 }
    818 
    819 /** Creates and build program for given Case
    820  *
    821  * @param info                     Case instance
    822  * @param captured_varyings        Name of varyings captured by transform feedback
    823  * @param n_captured_varyings_size Number of varyings captured by transform feedback
    824  **/
    825 void GeometryShader_gl_in_ArrayLengthTest::initCaseProgram(Case& info, const glw::GLchar** captured_varyings,
    826 														   glw::GLuint n_captured_varyings_size)
    827 {
    828 	/* GL */
    829 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    830 
    831 	/* Create program and shader objects */
    832 	info.po_id = gl.createProgram();
    833 
    834 	info.vs_id = gl.createShader(GL_VERTEX_SHADER);
    835 	info.gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
    836 	info.fs_id = gl.createShader(GL_FRAGMENT_SHADER);
    837 
    838 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create program object");
    839 
    840 	/* Prepare geometry shader parts */
    841 	const char* const geometry_shader_parts[] = { m_geometry_shader_code_preamble, info.input_body_part,
    842 												  info.output_body_part, m_geometry_shader_code_main };
    843 
    844 	/* Set up transform feedback */
    845 	gl.transformFeedbackVaryings(info.po_id, n_captured_varyings_size, captured_varyings, GL_SEPARATE_ATTRIBS);
    846 
    847 	/* Build program */
    848 	if (false == buildProgram(info.po_id, info.fs_id, 1 /* number of fragment shader code parts */,
    849 							  &m_fragment_shader_code, info.gs_id, DE_LENGTH_OF_ARRAY(geometry_shader_parts),
    850 							  geometry_shader_parts, info.vs_id, 1 /* number of vertex shader code parts */,
    851 							  &m_vertex_shader_code))
    852 	{
    853 		TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader");
    854 	}
    855 }
    856 
    857 /** Reset Case instance descriptor's contents.
    858  *
    859  * @param info Case instance
    860  **/
    861 void GeometryShader_gl_in_ArrayLengthTest::resetCase(Case& info)
    862 {
    863 	memset(&info, 0, sizeof(info));
    864 }
    865 
    866 /** Constructor
    867  *
    868  * @param context     Test context
    869  * @param name        Test case's name
    870  * @param description Test case's desricption
    871  **/
    872 GeometryShader_gl_PointSize_ValueTest::GeometryShader_gl_PointSize_ValueTest(Context&			  context,
    873 																			 const ExtParameters& extParams,
    874 																			 const char* name, const char* description)
    875 	: TestCaseBase(context, extParams, name, description)
    876 	, m_fragment_shader_id(0)
    877 	, m_geometry_shader_id(0)
    878 	, m_program_object_id(0)
    879 	, m_vertex_shader_id(0)
    880 	, m_vertex_array_object_id(0)
    881 	, m_color_texture_id(0)
    882 	, m_framebuffer_object_id(0)
    883 {
    884 	/* Nothing to be done here */
    885 }
    886 
    887 /** Initialize test case
    888  *
    889  **/
    890 void GeometryShader_gl_PointSize_ValueTest::init()
    891 {
    892 	/* Initialize Base */
    893 	TestCaseBase::init();
    894 
    895 	/* This test should only run if EXT_geometry_shader and EXT_geometry_point_size both are supported */
    896 	if (true != m_is_geometry_shader_extension_supported)
    897 	{
    898 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
    899 	}
    900 
    901 	if (true != m_is_geometry_shader_point_size_supported)
    902 	{
    903 		throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__);
    904 	}
    905 
    906 	/* GL */
    907 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    908 
    909 	/* Verify that point size range is supported */
    910 	glw::GLfloat point_size_range[2] = { 0 };
    911 
    912 	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
    913 	{
    914 		gl.getFloatv(GL_POINT_SIZE_RANGE, point_size_range);
    915 	}
    916 	else
    917 	{
    918 		gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, point_size_range);
    919 	}
    920 
    921 	if (8.0f > point_size_range[1])
    922 	{
    923 		m_testCtx.getLog() << tcu::TestLog::Message
    924 						   << "Test requires a minimum maximum point size of 8, implementation reports a maximum of : "
    925 						   << point_size_range[1] << tcu::TestLog::EndMessage;
    926 
    927 		throw tcu::NotSupportedError("Not supported point size", "", __FILE__, __LINE__);
    928 	}
    929 
    930 	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
    931 	{
    932 		gl.enable(GL_PROGRAM_POINT_SIZE);
    933 	}
    934 
    935 	/* Create program and shaders */
    936 	m_program_object_id = gl.createProgram();
    937 
    938 	m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
    939 	m_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
    940 	m_vertex_shader_id   = gl.createShader(GL_VERTEX_SHADER);
    941 
    942 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program");
    943 
    944 	/* Build program */
    945 	if (false == buildProgram(m_program_object_id, m_fragment_shader_id, 1 /* fragment shader parts number */,
    946 							  &m_fragment_shader_code, m_geometry_shader_id, 1 /* geometry shader parts number */,
    947 							  &m_geometry_shader_code, m_vertex_shader_id, 1 /* vertex shader parts number */,
    948 							  &m_vertex_shader_code))
    949 	{
    950 		TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader");
    951 	}
    952 
    953 	/* Set up texture object and a FBO */
    954 	gl.genTextures(1, &m_color_texture_id);
    955 	gl.genFramebuffers(1, &m_framebuffer_object_id);
    956 
    957 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create framebuffer");
    958 
    959 	if (false == setupFramebufferWithTextureAsAttachment(m_framebuffer_object_id, m_color_texture_id, GL_RGBA8,
    960 														 m_texture_width, m_texture_height))
    961 	{
    962 		TCU_FAIL("Failed to setup framebuffer");
    963 	}
    964 
    965 	/* Set up a vertex array object */
    966 	gl.genVertexArrays(1, &m_vertex_array_object_id);
    967 	gl.bindVertexArray(m_vertex_array_object_id);
    968 
    969 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object");
    970 }
    971 
    972 /** Executes the test.
    973  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
    974  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
    975  *  Note the function throws exception should an error occur!
    976  **/
    977 tcu::TestCase::IterateResult GeometryShader_gl_PointSize_ValueTest::iterate()
    978 {
    979 	/* Buffer to store results of rendering */
    980 	unsigned char result_image[m_texture_width * m_texture_height * m_texture_pixel_size];
    981 
    982 	/* This test should only run if EXT_geometry_shader is supported */
    983 	if (true != m_is_geometry_shader_extension_supported)
    984 	{
    985 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
    986 	}
    987 
    988 	if (true != m_is_geometry_shader_point_size_supported)
    989 	{
    990 		throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__);
    991 	}
    992 
    993 	/* GL  */
    994 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    995 
    996 	/* Render */
    997 	gl.useProgram(m_program_object_id);
    998 
    999 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to use program");
   1000 
   1001 	gl.clearColor(0 /* red */, 0 /* green */, 0 /* blue */, 0 /* alpha */);
   1002 	gl.clear(GL_COLOR_BUFFER_BIT);
   1003 
   1004 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not clear the color buffer");
   1005 
   1006 	gl.drawArrays(GL_POINTS, 0 /* first */, 2 /* count */);
   1007 
   1008 	GLU_EXPECT_NO_ERROR(gl.getError(), "Call drawArrays() failed");
   1009 
   1010 	/* Check if the data was modified during the rendering process */
   1011 	gl.readPixels(0 /* x */, 0 /* y */, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, result_image);
   1012 
   1013 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixels from color buffer");
   1014 
   1015 	/* 1) pixel at (2,  8) is (255, 255, 255, 255) */
   1016 	unsigned int referencePixelCoordinates[2] = { 2, 8 };
   1017 
   1018 	if (false == comparePixel(result_image, referencePixelCoordinates[0] /* x */, referencePixelCoordinates[1] /* y */,
   1019 							  m_texture_width, m_texture_height, m_texture_pixel_size, 255 /* red */, 255 /* green */,
   1020 							  255 /* blue */, 255 /* alpha */))
   1021 	{
   1022 		const unsigned int texel_offset = referencePixelCoordinates[1] * m_texture_width * m_texture_pixel_size +
   1023 										  referencePixelCoordinates[0] * m_texture_pixel_size;
   1024 
   1025 		m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", "
   1026 						   << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", "
   1027 						   << result_image[texel_offset + 3] << "]"
   1028 						   << " is different from reference data [255, 255, 255, 255]!" << tcu::TestLog::EndMessage;
   1029 
   1030 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1031 		return STOP;
   1032 	}
   1033 
   1034 	/* 2) pixel at (14, 8) is (255, 255, 255, 255) */
   1035 	referencePixelCoordinates[0] = 14;
   1036 	referencePixelCoordinates[1] = 8;
   1037 
   1038 	if (false == comparePixel(result_image, referencePixelCoordinates[0] /* x */, referencePixelCoordinates[1] /* y */,
   1039 							  m_texture_width, m_texture_height, m_texture_pixel_size, 255 /* red */, 255 /* green */,
   1040 							  255 /* blue */, 255 /* alpha */))
   1041 	{
   1042 		const unsigned int texel_offset = referencePixelCoordinates[1] * m_texture_width * m_texture_pixel_size +
   1043 										  referencePixelCoordinates[0] * m_texture_pixel_size;
   1044 
   1045 		m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", "
   1046 						   << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", "
   1047 						   << result_image[texel_offset + 3] << "]"
   1048 						   << " is different from reference data [255, 255, 255, 255]!" << tcu::TestLog::EndMessage;
   1049 
   1050 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1051 		return STOP;
   1052 	}
   1053 
   1054 	/* 3) pixel at (6,  8) is (0,   0,   0,   0) */
   1055 	referencePixelCoordinates[0] = 6;
   1056 	referencePixelCoordinates[1] = 8;
   1057 
   1058 	if (false == comparePixel(result_image, referencePixelCoordinates[0] /* x */, referencePixelCoordinates[1] /* y */,
   1059 							  m_texture_width, m_texture_height, m_texture_pixel_size, 0 /* red */, 0 /* green */,
   1060 							  0 /* blue */, 0 /* alpha */))
   1061 	{
   1062 		const unsigned int texel_offset = referencePixelCoordinates[1] * m_texture_width * m_texture_pixel_size +
   1063 										  referencePixelCoordinates[0] * m_texture_pixel_size;
   1064 
   1065 		m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", "
   1066 						   << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", "
   1067 						   << result_image[texel_offset + 3] << "]"
   1068 						   << "is different from reference data [0, 0, 0, 0]!" << tcu::TestLog::EndMessage;
   1069 
   1070 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1071 		return STOP;
   1072 	}
   1073 
   1074 	/* Done */
   1075 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1076 	return STOP;
   1077 }
   1078 
   1079 /** Deinitializes test case
   1080  *
   1081  **/
   1082 void GeometryShader_gl_PointSize_ValueTest::deinit()
   1083 {
   1084 	/* GL */
   1085 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1086 
   1087 	/* Bind defaults */
   1088 	gl.useProgram(0);
   1089 	gl.bindVertexArray(0);
   1090 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0 /* texture */, 0 /* level */);
   1091 	gl.bindTexture(GL_TEXTURE_2D, 0);
   1092 	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
   1093 	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
   1094 	{
   1095 		gl.disable(GL_PROGRAM_POINT_SIZE);
   1096 	}
   1097 
   1098 	/* Delete everything */
   1099 	if (m_program_object_id != 0)
   1100 	{
   1101 		gl.deleteProgram(m_program_object_id);
   1102 	}
   1103 
   1104 	if (m_fragment_shader_id != 0)
   1105 	{
   1106 		gl.deleteShader(m_fragment_shader_id);
   1107 	}
   1108 
   1109 	if (m_geometry_shader_id != 0)
   1110 	{
   1111 		gl.deleteShader(m_geometry_shader_id);
   1112 	}
   1113 
   1114 	if (m_vertex_shader_id != 0)
   1115 	{
   1116 		gl.deleteShader(m_vertex_shader_id);
   1117 	}
   1118 
   1119 	if (m_vertex_array_object_id != 0)
   1120 	{
   1121 		gl.deleteVertexArrays(1, &m_vertex_array_object_id);
   1122 	}
   1123 
   1124 	if (m_color_texture_id != 0)
   1125 	{
   1126 		gl.deleteTextures(1, &m_color_texture_id);
   1127 	}
   1128 
   1129 	if (m_framebuffer_object_id != 0)
   1130 	{
   1131 		gl.deleteFramebuffers(1, &m_framebuffer_object_id);
   1132 	}
   1133 
   1134 	/* Release base class */
   1135 	TestCaseBase::deinit();
   1136 }
   1137 
   1138 /** Constructor
   1139  *
   1140  * @param context     Test context
   1141  * @param name        Test case's name
   1142  * @param description Test case's desricption
   1143  **/
   1144 GeometryShader_gl_Position_ValueTest::GeometryShader_gl_Position_ValueTest(Context&				context,
   1145 																		   const ExtParameters& extParams,
   1146 																		   const char* name, const char* description)
   1147 	: TestCaseBase(context, extParams, name, description)
   1148 	, m_fragment_shader_id(0)
   1149 	, m_geometry_shader_id(0)
   1150 	, m_program_object_id(0)
   1151 	, m_vertex_shader_id(0)
   1152 	, m_vertex_array_object_id(0)
   1153 	, m_color_texture_id(0)
   1154 	, m_framebuffer_object_id(0)
   1155 {
   1156 	/* Nothing to be done here */
   1157 }
   1158 
   1159 /** Initialize test case
   1160  *
   1161  **/
   1162 void GeometryShader_gl_Position_ValueTest::init()
   1163 {
   1164 	/* Initialize base */
   1165 	TestCaseBase::init();
   1166 
   1167 	/* This test should only run if EXT_geometry_shader is supported */
   1168 	if (true != m_is_geometry_shader_extension_supported)
   1169 	{
   1170 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
   1171 	}
   1172 
   1173 	if (true != m_is_geometry_shader_point_size_supported)
   1174 	{
   1175 		throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__);
   1176 	}
   1177 
   1178 	/* GL */
   1179 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1180 
   1181 	/* Verify that point size range is supported */
   1182 	glw::GLfloat point_size_range[2] = { 0 };
   1183 
   1184 	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
   1185 	{
   1186 		gl.getFloatv(GL_POINT_SIZE_RANGE, point_size_range);
   1187 	}
   1188 	else
   1189 	{
   1190 		gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, point_size_range);
   1191 	}
   1192 
   1193 	if (8.0f > point_size_range[1])
   1194 	{
   1195 		m_testCtx.getLog() << tcu::TestLog::Message
   1196 						   << "Test requires a minimum maximum point size of 8, implementation reports a maximum of : "
   1197 						   << point_size_range[1] << tcu::TestLog::EndMessage;
   1198 
   1199 		throw tcu::NotSupportedError("Not supported point size", "", __FILE__, __LINE__);
   1200 	}
   1201 
   1202 	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
   1203 	{
   1204 		gl.enable(GL_PROGRAM_POINT_SIZE);
   1205 	}
   1206 
   1207 	/* Create program and shaders */
   1208 	m_program_object_id = gl.createProgram();
   1209 
   1210 	m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
   1211 	m_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
   1212 	m_vertex_shader_id   = gl.createShader(GL_VERTEX_SHADER);
   1213 
   1214 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program");
   1215 
   1216 	/* Build program */
   1217 	if (false == buildProgram(m_program_object_id, m_fragment_shader_id, 1 /* fragment shader parts number */,
   1218 							  &m_fragment_shader_code, m_geometry_shader_id, 1 /* geometry shader parts number */,
   1219 							  &m_geometry_shader_code, m_vertex_shader_id, 1 /* vertex shader parts number */,
   1220 							  &m_vertex_shader_code))
   1221 	{
   1222 		TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader");
   1223 	}
   1224 
   1225 	/* Set up a texture object and a FBO */
   1226 	gl.genTextures(1, &m_color_texture_id);
   1227 	gl.genFramebuffers(1, &m_framebuffer_object_id);
   1228 
   1229 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create framebuffer");
   1230 
   1231 	if (false == setupFramebufferWithTextureAsAttachment(m_framebuffer_object_id, m_color_texture_id, GL_RGBA8,
   1232 														 m_texture_width, m_texture_height))
   1233 	{
   1234 		TCU_FAIL("Failed to setup framebuffer");
   1235 	}
   1236 
   1237 	/* Set up a vertex array object */
   1238 	gl.genVertexArrays(1, &m_vertex_array_object_id);
   1239 	gl.bindVertexArray(m_vertex_array_object_id);
   1240 
   1241 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object");
   1242 }
   1243 
   1244 /** Executes the test.
   1245  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
   1246  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
   1247  *  Note the function throws exception should an error occur!
   1248  **/
   1249 tcu::TestCase::IterateResult GeometryShader_gl_Position_ValueTest::iterate()
   1250 {
   1251 	/* Variables used for image verification purposes */
   1252 	unsigned char result_image[m_texture_width * m_texture_height * m_texture_pixel_size];
   1253 
   1254 	/* This test should only run if EXT_geometry_shader is supported */
   1255 	if (true != m_is_geometry_shader_extension_supported)
   1256 	{
   1257 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
   1258 	}
   1259 
   1260 	/* GL  */
   1261 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1262 
   1263 	/* Render */
   1264 	gl.useProgram(m_program_object_id);
   1265 
   1266 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to use program");
   1267 
   1268 	gl.clearColor(0 /* red */, 0 /* green */, 0 /* blue */, 0 /* alpha */);
   1269 	gl.clear(GL_COLOR_BUFFER_BIT);
   1270 
   1271 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not clear the color buffer");
   1272 
   1273 	gl.drawArrays(GL_POINTS, 0 /* first */, 8 /* count */);
   1274 
   1275 	GLU_EXPECT_NO_ERROR(gl.getError(), "Call drawArrays() failed");
   1276 
   1277 	/* Check if the data was modified during the rendering process */
   1278 	gl.readPixels(0 /* x */, 0 /* y */, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, result_image);
   1279 
   1280 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixels from color buffer");
   1281 
   1282 	/* The test passes if centers of the rendered points are lit at expected locations. */
   1283 	for (unsigned int x = 4; x < m_texture_width; x += 8)
   1284 	{
   1285 		if (false == comparePixel(result_image, x, 32 /* y */, m_texture_width, m_texture_height, m_texture_pixel_size,
   1286 								  255 /* red */, 255 /* green */, 255 /* blue */, 255 /* alpha */))
   1287 		{
   1288 			const unsigned int texel_offset = 32 * m_texture_width * m_texture_pixel_size + x * m_texture_pixel_size;
   1289 
   1290 			m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", "
   1291 							   << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", "
   1292 							   << result_image[texel_offset + 3] << "]"
   1293 							   << "is different from reference data [255, 255, 255, 255] !" << tcu::TestLog::EndMessage;
   1294 
   1295 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1296 			return STOP;
   1297 		}
   1298 	}
   1299 
   1300 	/* Done */
   1301 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1302 	return STOP;
   1303 }
   1304 
   1305 /** Deinitializes test case
   1306  *
   1307  **/
   1308 void GeometryShader_gl_Position_ValueTest::deinit()
   1309 {
   1310 	/* GL */
   1311 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1312 
   1313 	/* Bind default values */
   1314 	gl.useProgram(0);
   1315 	gl.bindVertexArray(0);
   1316 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0 /* texture */, 0 /* level */);
   1317 	gl.bindTexture(GL_TEXTURE_2D, 0);
   1318 	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
   1319 	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
   1320 	{
   1321 		gl.disable(GL_PROGRAM_POINT_SIZE);
   1322 	}
   1323 
   1324 	/* Delete everything */
   1325 	if (m_program_object_id != 0)
   1326 	{
   1327 		gl.deleteProgram(m_program_object_id);
   1328 	}
   1329 
   1330 	if (m_fragment_shader_id != 0)
   1331 	{
   1332 		gl.deleteShader(m_fragment_shader_id);
   1333 	}
   1334 
   1335 	if (m_geometry_shader_id != 0)
   1336 	{
   1337 		gl.deleteShader(m_geometry_shader_id);
   1338 	}
   1339 
   1340 	if (m_vertex_shader_id != 0)
   1341 	{
   1342 		gl.deleteShader(m_vertex_shader_id);
   1343 	}
   1344 
   1345 	if (m_vertex_array_object_id != 0)
   1346 	{
   1347 		gl.deleteVertexArrays(1, &m_vertex_array_object_id);
   1348 	}
   1349 
   1350 	if (m_color_texture_id != 0)
   1351 	{
   1352 		gl.deleteTextures(1, &m_color_texture_id);
   1353 	}
   1354 
   1355 	if (m_framebuffer_object_id != 0)
   1356 	{
   1357 		gl.deleteFramebuffers(1, &m_framebuffer_object_id);
   1358 	}
   1359 
   1360 	/* Release base class */
   1361 	TestCaseBase::deinit();
   1362 }
   1363 
   1364 } /* glcts */
   1365