• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  **/
GeometryShader_gl_in_ArrayContentsTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)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  **/
initTest()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  **/
iterate()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  */
deinit()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  **/
GeometryShader_gl_in_ArrayLengthTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)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  **/
init()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  **/
iterate()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  **/
deinit()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 	/* Delete everything */
733 	if (0 != m_vertex_array_object_id)
734 	{
735 		gl.deleteVertexArrays(1, &m_vertex_array_object_id);
736 	}
737 
738 	if (0 != m_buffer_object_id)
739 	{
740 		gl.deleteBuffers(1, &m_buffer_object_id);
741 	}
742 
743 	/* Deinit test cases */
744 	for (testContainer::iterator it = m_tests.begin(); it != m_tests.end(); ++it)
745 	{
746 		Case* test = *it;
747 
748 		deinitCase(*test);
749 	}
750 
751 	m_tests.clear();
752 
753 	/* Deinitialize Base */
754 	TestCaseBase::deinit();
755 }
756 
757 /** Deinitialize test case instance
758  *
759  * @param info Case instance
760  **/
deinitCase(Case & info)761 void GeometryShader_gl_in_ArrayLengthTest::deinitCase(Case& info)
762 {
763 	/* GL */
764 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
765 
766 	/* Delete everything */
767 	if (0 != info.po_id)
768 	{
769 		gl.deleteProgram(info.po_id);
770 	}
771 
772 	if (0 != info.vs_id)
773 	{
774 		gl.deleteShader(info.vs_id);
775 	}
776 
777 	if (0 != info.gs_id)
778 	{
779 		gl.deleteShader(info.gs_id);
780 	}
781 
782 	if (0 != info.fs_id)
783 	{
784 		gl.deleteShader(info.fs_id);
785 	}
786 
787 	/* Clear case */
788 	resetCase(info);
789 }
790 
791 /** Initialize test case instance with provided data.
792  *
793  * @param info                  Case instance;
794  * @param draw_call_mode        Primitive type used by a draw call;
795  * @param draw_call_n_vertices  Number of vertices used by a draw call;
796  * @param expected_array_length Expected size of gl_in array;
797  * @param tf_mode               Primitive type used by transform feedback;
798  * @param input_body_part       Part of geometry shader which specifies input layout;
799  * @param output_body_part      Part of geometry shader which specifies output layout;
800  **/
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)801 void GeometryShader_gl_in_ArrayLengthTest::initCase(Case& info, glw::GLenum draw_call_mode,
802 													glw::GLint draw_call_n_vertices, glw::GLint expected_array_length,
803 													glw::GLenum tf_mode, const glw::GLchar* input_body_part,
804 													const glw::GLchar* output_body_part)
805 {
806 	/* Reset case descriptor */
807 	resetCase(info);
808 
809 	/* Set fields */
810 	info.draw_call_mode		   = draw_call_mode;
811 	info.draw_call_n_vertices  = draw_call_n_vertices;
812 	info.expected_array_length = expected_array_length;
813 	info.input_body_part	   = input_body_part;
814 	info.output_body_part	  = output_body_part;
815 	info.tf_mode			   = tf_mode;
816 }
817 
818 /** Creates and build program for given Case
819  *
820  * @param info                     Case instance
821  * @param captured_varyings        Name of varyings captured by transform feedback
822  * @param n_captured_varyings_size Number of varyings captured by transform feedback
823  **/
initCaseProgram(Case & info,const glw::GLchar ** captured_varyings,glw::GLuint n_captured_varyings_size)824 void GeometryShader_gl_in_ArrayLengthTest::initCaseProgram(Case& info, const glw::GLchar** captured_varyings,
825 														   glw::GLuint n_captured_varyings_size)
826 {
827 	/* GL */
828 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
829 
830 	/* Create program and shader objects */
831 	info.po_id = gl.createProgram();
832 
833 	info.vs_id = gl.createShader(GL_VERTEX_SHADER);
834 	info.gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
835 	info.fs_id = gl.createShader(GL_FRAGMENT_SHADER);
836 
837 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create program object");
838 
839 	/* Prepare geometry shader parts */
840 	const char* const geometry_shader_parts[] = { m_geometry_shader_code_preamble, info.input_body_part,
841 												  info.output_body_part, m_geometry_shader_code_main };
842 
843 	/* Set up transform feedback */
844 	gl.transformFeedbackVaryings(info.po_id, n_captured_varyings_size, captured_varyings, GL_SEPARATE_ATTRIBS);
845 
846 	/* Build program */
847 	if (false == buildProgram(info.po_id, info.fs_id, 1 /* number of fragment shader code parts */,
848 							  &m_fragment_shader_code, info.gs_id, DE_LENGTH_OF_ARRAY(geometry_shader_parts),
849 							  geometry_shader_parts, info.vs_id, 1 /* number of vertex shader code parts */,
850 							  &m_vertex_shader_code))
851 	{
852 		TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader");
853 	}
854 }
855 
856 /** Reset Case instance descriptor's contents.
857  *
858  * @param info Case instance
859  **/
resetCase(Case & info)860 void GeometryShader_gl_in_ArrayLengthTest::resetCase(Case& info)
861 {
862 	memset(&info, 0, sizeof(info));
863 }
864 
865 /** Constructor
866  *
867  * @param context     Test context
868  * @param name        Test case's name
869  * @param description Test case's desricption
870  **/
GeometryShader_gl_PointSize_ValueTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)871 GeometryShader_gl_PointSize_ValueTest::GeometryShader_gl_PointSize_ValueTest(Context&			  context,
872 																			 const ExtParameters& extParams,
873 																			 const char* name, const char* description)
874 	: TestCaseBase(context, extParams, name, description)
875 	, m_fragment_shader_id(0)
876 	, m_geometry_shader_id(0)
877 	, m_program_object_id(0)
878 	, m_vertex_shader_id(0)
879 	, m_vertex_array_object_id(0)
880 	, m_color_texture_id(0)
881 	, m_framebuffer_object_id(0)
882 {
883 	/* Nothing to be done here */
884 }
885 
886 /** Initialize test case
887  *
888  **/
init()889 void GeometryShader_gl_PointSize_ValueTest::init()
890 {
891 	/* Initialize Base */
892 	TestCaseBase::init();
893 
894 	/* This test should only run if EXT_geometry_shader and EXT_geometry_point_size both are supported */
895 	if (true != m_is_geometry_shader_extension_supported)
896 	{
897 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
898 	}
899 
900 	if (true != m_is_geometry_shader_point_size_supported)
901 	{
902 		throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__);
903 	}
904 
905 	/* GL */
906 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
907 
908 	/* Verify that point size range is supported */
909 	glw::GLfloat point_size_range[2] = { 0 };
910 
911 	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
912 	{
913 		gl.getFloatv(GL_POINT_SIZE_RANGE, point_size_range);
914 	}
915 	else
916 	{
917 		gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, point_size_range);
918 	}
919 
920 	if (8.0f > point_size_range[1])
921 	{
922 		m_testCtx.getLog() << tcu::TestLog::Message
923 						   << "Test requires a minimum maximum point size of 8, implementation reports a maximum of : "
924 						   << point_size_range[1] << tcu::TestLog::EndMessage;
925 
926 		throw tcu::NotSupportedError("Not supported point size", "", __FILE__, __LINE__);
927 	}
928 
929 	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
930 	{
931 		gl.enable(GL_PROGRAM_POINT_SIZE);
932 	}
933 
934 	/* Create program and shaders */
935 	m_program_object_id = gl.createProgram();
936 
937 	m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
938 	m_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
939 	m_vertex_shader_id   = gl.createShader(GL_VERTEX_SHADER);
940 
941 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program");
942 
943 	/* Build program */
944 	if (false == buildProgram(m_program_object_id, m_fragment_shader_id, 1 /* fragment shader parts number */,
945 							  &m_fragment_shader_code, m_geometry_shader_id, 1 /* geometry shader parts number */,
946 							  &m_geometry_shader_code, m_vertex_shader_id, 1 /* vertex shader parts number */,
947 							  &m_vertex_shader_code))
948 	{
949 		TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader");
950 	}
951 
952 	/* Set up texture object and a FBO */
953 	gl.genTextures(1, &m_color_texture_id);
954 	gl.genFramebuffers(1, &m_framebuffer_object_id);
955 
956 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create framebuffer");
957 
958 	if (false == setupFramebufferWithTextureAsAttachment(m_framebuffer_object_id, m_color_texture_id, GL_RGBA8,
959 														 m_texture_width, m_texture_height))
960 	{
961 		TCU_FAIL("Failed to setup framebuffer");
962 	}
963 
964 	/* Set up a vertex array object */
965 	gl.genVertexArrays(1, &m_vertex_array_object_id);
966 	gl.bindVertexArray(m_vertex_array_object_id);
967 
968 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object");
969 }
970 
971 /** Executes the test.
972  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
973  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
974  *  Note the function throws exception should an error occur!
975  **/
iterate()976 tcu::TestCase::IterateResult GeometryShader_gl_PointSize_ValueTest::iterate()
977 {
978 	/* Buffer to store results of rendering */
979 	unsigned char result_image[m_texture_width * m_texture_height * m_texture_pixel_size];
980 
981 	/* This test should only run if EXT_geometry_shader is supported */
982 	if (true != m_is_geometry_shader_extension_supported)
983 	{
984 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
985 	}
986 
987 	if (true != m_is_geometry_shader_point_size_supported)
988 	{
989 		throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__);
990 	}
991 
992 	/* GL  */
993 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
994 
995 	/* Render */
996 	gl.useProgram(m_program_object_id);
997 
998 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to use program");
999 
1000 	gl.clearColor(0 /* red */, 0 /* green */, 0 /* blue */, 0 /* alpha */);
1001 	gl.clear(GL_COLOR_BUFFER_BIT);
1002 
1003 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not clear the color buffer");
1004 
1005 	gl.drawArrays(GL_POINTS, 0 /* first */, 2 /* count */);
1006 
1007 	GLU_EXPECT_NO_ERROR(gl.getError(), "Call drawArrays() failed");
1008 
1009 	/* Check if the data was modified during the rendering process */
1010 	gl.readPixels(0 /* x */, 0 /* y */, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, result_image);
1011 
1012 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixels from color buffer");
1013 
1014 	/* 1) pixel at (2,  8) is (255, 255, 255, 255) */
1015 	unsigned int referencePixelCoordinates[2] = { 2, 8 };
1016 
1017 	if (false == comparePixel(result_image, referencePixelCoordinates[0] /* x */, referencePixelCoordinates[1] /* y */,
1018 							  m_texture_width, m_texture_height, m_texture_pixel_size, 255 /* red */, 255 /* green */,
1019 							  255 /* blue */, 255 /* alpha */))
1020 	{
1021 		const unsigned int texel_offset = referencePixelCoordinates[1] * m_texture_width * m_texture_pixel_size +
1022 										  referencePixelCoordinates[0] * m_texture_pixel_size;
1023 
1024 		m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", "
1025 						   << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", "
1026 						   << result_image[texel_offset + 3] << "]"
1027 						   << " is different from reference data [255, 255, 255, 255]!" << tcu::TestLog::EndMessage;
1028 
1029 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1030 		return STOP;
1031 	}
1032 
1033 	/* 2) pixel at (14, 8) is (255, 255, 255, 255) */
1034 	referencePixelCoordinates[0] = 14;
1035 	referencePixelCoordinates[1] = 8;
1036 
1037 	if (false == comparePixel(result_image, referencePixelCoordinates[0] /* x */, referencePixelCoordinates[1] /* y */,
1038 							  m_texture_width, m_texture_height, m_texture_pixel_size, 255 /* red */, 255 /* green */,
1039 							  255 /* blue */, 255 /* alpha */))
1040 	{
1041 		const unsigned int texel_offset = referencePixelCoordinates[1] * m_texture_width * m_texture_pixel_size +
1042 										  referencePixelCoordinates[0] * m_texture_pixel_size;
1043 
1044 		m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", "
1045 						   << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", "
1046 						   << result_image[texel_offset + 3] << "]"
1047 						   << " is different from reference data [255, 255, 255, 255]!" << tcu::TestLog::EndMessage;
1048 
1049 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1050 		return STOP;
1051 	}
1052 
1053 	/* 3) pixel at (6,  8) is (0,   0,   0,   0) */
1054 	referencePixelCoordinates[0] = 6;
1055 	referencePixelCoordinates[1] = 8;
1056 
1057 	if (false == comparePixel(result_image, referencePixelCoordinates[0] /* x */, referencePixelCoordinates[1] /* y */,
1058 							  m_texture_width, m_texture_height, m_texture_pixel_size, 0 /* red */, 0 /* green */,
1059 							  0 /* blue */, 0 /* alpha */))
1060 	{
1061 		const unsigned int texel_offset = referencePixelCoordinates[1] * m_texture_width * m_texture_pixel_size +
1062 										  referencePixelCoordinates[0] * m_texture_pixel_size;
1063 
1064 		m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", "
1065 						   << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", "
1066 						   << result_image[texel_offset + 3] << "]"
1067 						   << "is different from reference data [0, 0, 0, 0]!" << tcu::TestLog::EndMessage;
1068 
1069 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1070 		return STOP;
1071 	}
1072 
1073 	/* Done */
1074 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1075 	return STOP;
1076 }
1077 
1078 /** Deinitializes test case
1079  *
1080  **/
deinit()1081 void GeometryShader_gl_PointSize_ValueTest::deinit()
1082 {
1083 	/* GL */
1084 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1085 
1086 	/* Bind defaults */
1087 	gl.useProgram(0);
1088 	gl.bindVertexArray(0);
1089 	gl.bindTexture(GL_TEXTURE_2D, 0);
1090 	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1091 	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
1092 	{
1093 		gl.disable(GL_PROGRAM_POINT_SIZE);
1094 	}
1095 
1096 	/* Delete everything */
1097 	if (m_program_object_id != 0)
1098 	{
1099 		gl.deleteProgram(m_program_object_id);
1100 	}
1101 
1102 	if (m_fragment_shader_id != 0)
1103 	{
1104 		gl.deleteShader(m_fragment_shader_id);
1105 	}
1106 
1107 	if (m_geometry_shader_id != 0)
1108 	{
1109 		gl.deleteShader(m_geometry_shader_id);
1110 	}
1111 
1112 	if (m_vertex_shader_id != 0)
1113 	{
1114 		gl.deleteShader(m_vertex_shader_id);
1115 	}
1116 
1117 	if (m_vertex_array_object_id != 0)
1118 	{
1119 		gl.deleteVertexArrays(1, &m_vertex_array_object_id);
1120 	}
1121 
1122 	if (m_color_texture_id != 0)
1123 	{
1124 		gl.deleteTextures(1, &m_color_texture_id);
1125 	}
1126 
1127 	if (m_framebuffer_object_id != 0)
1128 	{
1129 		gl.deleteFramebuffers(1, &m_framebuffer_object_id);
1130 	}
1131 
1132 	/* Release base class */
1133 	TestCaseBase::deinit();
1134 }
1135 
1136 /** Constructor
1137  *
1138  * @param context     Test context
1139  * @param name        Test case's name
1140  * @param description Test case's desricption
1141  **/
GeometryShader_gl_Position_ValueTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1142 GeometryShader_gl_Position_ValueTest::GeometryShader_gl_Position_ValueTest(Context&				context,
1143 																		   const ExtParameters& extParams,
1144 																		   const char* name, const char* description)
1145 	: TestCaseBase(context, extParams, name, description)
1146 	, m_fragment_shader_id(0)
1147 	, m_geometry_shader_id(0)
1148 	, m_program_object_id(0)
1149 	, m_vertex_shader_id(0)
1150 	, m_vertex_array_object_id(0)
1151 	, m_color_texture_id(0)
1152 	, m_framebuffer_object_id(0)
1153 {
1154 	/* Nothing to be done here */
1155 }
1156 
1157 /** Initialize test case
1158  *
1159  **/
init()1160 void GeometryShader_gl_Position_ValueTest::init()
1161 {
1162 	/* Initialize base */
1163 	TestCaseBase::init();
1164 
1165 	/* This test should only run if EXT_geometry_shader is supported */
1166 	if (true != m_is_geometry_shader_extension_supported)
1167 	{
1168 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1169 	}
1170 
1171 	if (true != m_is_geometry_shader_point_size_supported)
1172 	{
1173 		throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__);
1174 	}
1175 
1176 	/* GL */
1177 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1178 
1179 	/* Verify that point size range is supported */
1180 	glw::GLfloat point_size_range[2] = { 0 };
1181 
1182 	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
1183 	{
1184 		gl.getFloatv(GL_POINT_SIZE_RANGE, point_size_range);
1185 	}
1186 	else
1187 	{
1188 		gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, point_size_range);
1189 	}
1190 
1191 	if (8.0f > point_size_range[1])
1192 	{
1193 		m_testCtx.getLog() << tcu::TestLog::Message
1194 						   << "Test requires a minimum maximum point size of 8, implementation reports a maximum of : "
1195 						   << point_size_range[1] << tcu::TestLog::EndMessage;
1196 
1197 		throw tcu::NotSupportedError("Not supported point size", "", __FILE__, __LINE__);
1198 	}
1199 
1200 	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
1201 	{
1202 		gl.enable(GL_PROGRAM_POINT_SIZE);
1203 	}
1204 
1205 	/* Create program and shaders */
1206 	m_program_object_id = gl.createProgram();
1207 
1208 	m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
1209 	m_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
1210 	m_vertex_shader_id   = gl.createShader(GL_VERTEX_SHADER);
1211 
1212 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program");
1213 
1214 	/* Build program */
1215 	if (false == buildProgram(m_program_object_id, m_fragment_shader_id, 1 /* fragment shader parts number */,
1216 							  &m_fragment_shader_code, m_geometry_shader_id, 1 /* geometry shader parts number */,
1217 							  &m_geometry_shader_code, m_vertex_shader_id, 1 /* vertex shader parts number */,
1218 							  &m_vertex_shader_code))
1219 	{
1220 		TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader");
1221 	}
1222 
1223 	/* Set up a texture object and a FBO */
1224 	gl.genTextures(1, &m_color_texture_id);
1225 	gl.genFramebuffers(1, &m_framebuffer_object_id);
1226 
1227 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create framebuffer");
1228 
1229 	if (false == setupFramebufferWithTextureAsAttachment(m_framebuffer_object_id, m_color_texture_id, GL_RGBA8,
1230 														 m_texture_width, m_texture_height))
1231 	{
1232 		TCU_FAIL("Failed to setup framebuffer");
1233 	}
1234 
1235 	/* Set up a vertex array object */
1236 	gl.genVertexArrays(1, &m_vertex_array_object_id);
1237 	gl.bindVertexArray(m_vertex_array_object_id);
1238 
1239 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object");
1240 }
1241 
1242 /** Executes the test.
1243  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1244  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1245  *  Note the function throws exception should an error occur!
1246  **/
iterate()1247 tcu::TestCase::IterateResult GeometryShader_gl_Position_ValueTest::iterate()
1248 {
1249 	/* Variables used for image verification purposes */
1250 	unsigned char result_image[m_texture_width * m_texture_height * m_texture_pixel_size];
1251 
1252 	/* This test should only run if EXT_geometry_shader is supported */
1253 	if (true != m_is_geometry_shader_extension_supported)
1254 	{
1255 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1256 	}
1257 
1258 	/* GL  */
1259 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1260 
1261 	/* Render */
1262 	gl.useProgram(m_program_object_id);
1263 
1264 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to use program");
1265 
1266 	gl.clearColor(0 /* red */, 0 /* green */, 0 /* blue */, 0 /* alpha */);
1267 	gl.clear(GL_COLOR_BUFFER_BIT);
1268 
1269 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not clear the color buffer");
1270 
1271 	gl.drawArrays(GL_POINTS, 0 /* first */, 8 /* count */);
1272 
1273 	GLU_EXPECT_NO_ERROR(gl.getError(), "Call drawArrays() failed");
1274 
1275 	/* Check if the data was modified during the rendering process */
1276 	gl.readPixels(0 /* x */, 0 /* y */, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, result_image);
1277 
1278 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixels from color buffer");
1279 
1280 	/* The test passes if centers of the rendered points are lit at expected locations. */
1281 	for (unsigned int x = 4; x < m_texture_width; x += 8)
1282 	{
1283 		if (false == comparePixel(result_image, x, 32 /* y */, m_texture_width, m_texture_height, m_texture_pixel_size,
1284 								  255 /* red */, 255 /* green */, 255 /* blue */, 255 /* alpha */))
1285 		{
1286 			const unsigned int texel_offset = 32 * m_texture_width * m_texture_pixel_size + x * m_texture_pixel_size;
1287 
1288 			m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << result_image[texel_offset + 0] << ", "
1289 							   << result_image[texel_offset + 1] << ", " << result_image[texel_offset + 2] << ", "
1290 							   << result_image[texel_offset + 3] << "]"
1291 							   << "is different from reference data [255, 255, 255, 255] !" << tcu::TestLog::EndMessage;
1292 
1293 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1294 			return STOP;
1295 		}
1296 	}
1297 
1298 	/* Done */
1299 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1300 	return STOP;
1301 }
1302 
1303 /** Deinitializes test case
1304  *
1305  **/
deinit()1306 void GeometryShader_gl_Position_ValueTest::deinit()
1307 {
1308 	/* GL */
1309 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1310 
1311 	/* Bind default values */
1312 	gl.useProgram(0);
1313 	gl.bindVertexArray(0);
1314 	gl.bindTexture(GL_TEXTURE_2D, 0);
1315 	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1316 	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
1317 	{
1318 		gl.disable(GL_PROGRAM_POINT_SIZE);
1319 	}
1320 
1321 	/* Delete everything */
1322 	if (m_program_object_id != 0)
1323 	{
1324 		gl.deleteProgram(m_program_object_id);
1325 	}
1326 
1327 	if (m_fragment_shader_id != 0)
1328 	{
1329 		gl.deleteShader(m_fragment_shader_id);
1330 	}
1331 
1332 	if (m_geometry_shader_id != 0)
1333 	{
1334 		gl.deleteShader(m_geometry_shader_id);
1335 	}
1336 
1337 	if (m_vertex_shader_id != 0)
1338 	{
1339 		gl.deleteShader(m_vertex_shader_id);
1340 	}
1341 
1342 	if (m_vertex_array_object_id != 0)
1343 	{
1344 		gl.deleteVertexArrays(1, &m_vertex_array_object_id);
1345 	}
1346 
1347 	if (m_color_texture_id != 0)
1348 	{
1349 		gl.deleteTextures(1, &m_color_texture_id);
1350 	}
1351 
1352 	if (m_framebuffer_object_id != 0)
1353 	{
1354 		gl.deleteFramebuffers(1, &m_framebuffer_object_id);
1355 	}
1356 
1357 	/* Release base class */
1358 	TestCaseBase::deinit();
1359 }
1360 
1361 } /* glcts */
1362