• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2015-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 #include "esextcGeometryShaderLinking.hpp"
24 
25 #include "gluDefs.hpp"
26 #include "glwEnums.hpp"
27 #include "glwFunctions.hpp"
28 #include "tcuTestLog.hpp"
29 #include <cstring>
30 
31 namespace glcts
32 {
33 
34 static const char* dummy_fs_code = "${VERSION}\n"
35 								   "\n"
36 								   "precision highp float;\n"
37 								   "\n"
38 								   "out vec4 result;\n"
39 								   "\n"
40 								   "void main()\n"
41 								   "{\n"
42 								   "    result = vec4(1.0);\n"
43 								   "}\n";
44 
45 static const char* dummy_gs_code = "${VERSION}\n"
46 								   "${GEOMETRY_SHADER_REQUIRE}\n"
47 								   "\n"
48 								   "layout (points)                   in;\n"
49 								   "layout (points, max_vertices = 1) out;\n"
50 								   "\n"
51 								   "${OUT_PER_VERTEX_DECL}"
52 								   "${IN_DATA_DECL}"
53 								   "\n"
54 								   "void main()\n"
55 								   "{\n"
56 								   "${POSITION_WITH_IN_DATA}"
57 								   "    EmitVertex();\n"
58 								   "}\n";
59 
60 static const char* dummy_vs_code = "${VERSION}\n"
61 								   "\n"
62 								   "${OUT_PER_VERTEX_DECL}"
63 								   "\n"
64 								   "void main()\n"
65 								   "{\n"
66 								   "    gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
67 								   "}\n";
68 
69 /** Constructor
70  *
71  * @param context       Test context
72  * @param extParams     Not used.
73  * @param name          Test case's name
74  * @param description   Test case's description
75  **/
GeometryShaderIncompleteProgramObjectsTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)76 GeometryShaderIncompleteProgramObjectsTest::GeometryShaderIncompleteProgramObjectsTest(Context&				context,
77 																					   const ExtParameters& extParams,
78 																					   const char*			name,
79 																					   const char*			description)
80 	: TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_po_id(0)
81 {
82 }
83 
84 /** Deinitializes GLES objects created during the test. */
deinit()85 void GeometryShaderIncompleteProgramObjectsTest::deinit()
86 {
87 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
88 
89 	if (m_fs_id != 0)
90 	{
91 		gl.deleteShader(m_fs_id);
92 
93 		m_fs_id = 0;
94 	}
95 
96 	if (m_gs_id != 0)
97 	{
98 		gl.deleteShader(m_gs_id);
99 
100 		m_gs_id = 0;
101 	}
102 
103 	if (m_po_id != 0)
104 	{
105 		gl.deleteProgram(m_po_id);
106 
107 		m_po_id = 0;
108 	}
109 
110 	/* Release base class */
111 	TestCaseBase::deinit();
112 }
113 
114 /** Initializes shader objects for the conformance test */
initShaderObjects()115 void GeometryShaderIncompleteProgramObjectsTest::initShaderObjects()
116 {
117 	const glw::Functions& gl					  = m_context.getRenderContext().getFunctions();
118 	std::string			  specialized_fs_code	 = specializeShader(1, &dummy_fs_code);
119 	const char*			  specialized_fs_code_raw = specialized_fs_code.c_str();
120 	std::string			  specialized_gs_code	 = specializeShader(1, &dummy_gs_code);
121 	const char*			  specialized_gs_code_raw = specialized_gs_code.c_str();
122 
123 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
124 	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
125 
126 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
127 
128 	for (unsigned int n_shader_type = 0; n_shader_type < 2; /* fs, gs */
129 		 n_shader_type++)
130 	{
131 		glw::GLint  compile_status = GL_FALSE;
132 		const char* so_code		   = (n_shader_type == 0) ? specialized_fs_code_raw : specialized_gs_code_raw;
133 		glw::GLuint so_id		   = (n_shader_type == 0) ? m_fs_id : m_gs_id;
134 
135 		gl.shaderSource(so_id, 1,			/* count */
136 						&so_code, DE_NULL); /* length */
137 
138 		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed");
139 
140 		gl.compileShader(so_id);
141 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed");
142 
143 		gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
144 
145 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed");
146 
147 		if (compile_status != GL_TRUE)
148 		{
149 			TCU_FAIL("Shader compilation process failed.");
150 		}
151 	} /* for (both shader stages) */
152 }
153 
154 /** Initializes test runs, to be executed by the conformance test. */
initTestRuns()155 void GeometryShaderIncompleteProgramObjectsTest::initTestRuns()
156 {
157 	/*                         use_fs| use_gs| use_separable_po
158 	 *                         ------|-------|-----------------*/
159 	m_test_runs.push_back(_run(false, true, false));
160 	m_test_runs.push_back(_run(false, true, true));
161 	m_test_runs.push_back(_run(true, true, false));
162 	m_test_runs.push_back(_run(true, true, true));
163 }
164 
165 /** Executes the test.
166  *
167  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
168  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
169  *  Note the function throws exception should an error occur!
170  **/
iterate()171 tcu::TestNode::IterateResult GeometryShaderIncompleteProgramObjectsTest::iterate()
172 {
173 	bool result = true;
174 
175 	/* This test should only run if EXT_geometry_shader is supported. */
176 	if (!m_is_geometry_shader_extension_supported)
177 	{
178 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
179 	}
180 
181 	/* Initialize test runs */
182 	initTestRuns();
183 
184 	/* Set up shader objects */
185 	initShaderObjects();
186 
187 	/* Iterate over the test run set */
188 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
189 
190 	for (unsigned int run_index = 0; run_index < m_test_runs.size(); ++run_index)
191 	{
192 		const _run& current_run = m_test_runs[run_index];
193 
194 		/* Set up a program object */
195 		m_po_id = gl.createProgram();
196 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed");
197 
198 		if (current_run.use_separable_po)
199 		{
200 			gl.programParameteri(m_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
201 			GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed");
202 		} /* if (current_run.use_separable_po) */
203 
204 		if (current_run.use_fs)
205 		{
206 			gl.attachShader(m_po_id, m_fs_id);
207 		}
208 
209 		if (current_run.use_gs)
210 		{
211 			gl.attachShader(m_po_id, m_gs_id);
212 		}
213 
214 		GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed");
215 
216 		/* Try to link the PO */
217 		gl.linkProgram(m_po_id);
218 		GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
219 
220 		/* Verify the link status */
221 		glw::GLint link_status = GL_FALSE;
222 
223 		gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
224 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed");
225 
226 		if ((current_run.use_separable_po && link_status != GL_TRUE) ||
227 			(!current_run.use_separable_po && link_status == GL_TRUE))
228 		{
229 			m_testCtx.getLog() << tcu::TestLog::Message << "Invalid link status reported for a "
230 							   << ((current_run.use_separable_po) ? "separable" : "")
231 							   << " program object, to which the following SOs were attached: "
232 							   << "FS:" << ((current_run.use_fs) ? "YES" : "NO")
233 							   << ", GS:" << ((current_run.use_gs) ? "YES" : "NO") << tcu::TestLog::EndMessage;
234 
235 			result = false;
236 		}
237 
238 		/* Clean up for the next iteration */
239 		gl.deleteProgram(m_po_id);
240 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram() call failed");
241 	} /* for (all test runs) */
242 
243 	if (result)
244 	{
245 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
246 	}
247 	else
248 	{
249 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
250 	}
251 
252 	return STOP;
253 }
254 
255 /** Constructor
256  *
257  * @param context       Test context
258  * @param extParams     Not used.
259  * @param name          Test case's name
260  * @param description   Test case's description
261  **/
GeometryShaderIncompleteGSTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)262 GeometryShaderIncompleteGSTest::GeometryShaderIncompleteGSTest(Context& context, const ExtParameters& extParams,
263 															   const char* name, const char* description)
264 	: TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_po_id(0), m_vs_id(0)
265 {
266 }
267 
268 /** Deinitializes GLES objects created during the test. */
deinit()269 void GeometryShaderIncompleteGSTest::deinit()
270 {
271 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
272 
273 	deinitSOs();
274 
275 	if (m_po_id != 0)
276 	{
277 		gl.deleteProgram(m_po_id);
278 
279 		m_po_id = 0;
280 	}
281 
282 	/* Release base class */
283 	TestCaseBase::deinit();
284 }
285 
286 /** Deinitializes shader objects created for the conformance test. */
deinitSOs()287 void GeometryShaderIncompleteGSTest::deinitSOs()
288 {
289 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
290 
291 	if (m_fs_id != 0)
292 	{
293 		gl.deleteShader(m_fs_id);
294 
295 		m_fs_id = 0;
296 	}
297 
298 	if (m_gs_id != 0)
299 	{
300 		gl.deleteShader(m_gs_id);
301 
302 		m_gs_id = 0;
303 	}
304 
305 	if (m_vs_id != 0)
306 	{
307 		gl.deleteShader(m_vs_id);
308 
309 		m_vs_id = 0;
310 	}
311 }
312 
313 /** Returns geometry shader's source code, built according to the test run's settings.
314  *
315  *  @param current_run Test run descriptor.
316  *
317  *  @return Requested string.
318  */
getGeometryShaderCode(const _run & current_run)319 std::string GeometryShaderIncompleteGSTest::getGeometryShaderCode(const _run& current_run)
320 {
321 	std::stringstream gs_code_sstream;
322 
323 	gs_code_sstream << "${VERSION}\n"
324 					   "${GEOMETRY_SHADER_REQUIRE}\n"
325 					   "\n";
326 
327 	if (current_run.is_input_primitive_type_defined)
328 	{
329 		gs_code_sstream << "layout(points) in;\n";
330 	}
331 
332 	if (current_run.is_max_vertices_defined || current_run.is_output_primitive_type_defined)
333 	{
334 		gs_code_sstream << "layout(";
335 
336 		if (current_run.is_max_vertices_defined)
337 		{
338 			gs_code_sstream << "max_vertices = 1";
339 
340 			if (current_run.is_output_primitive_type_defined)
341 			{
342 				gs_code_sstream << ", ";
343 			}
344 		} /* if (current_run.is_max_vertices_defined) */
345 
346 		if (current_run.is_output_primitive_type_defined)
347 		{
348 			gs_code_sstream << "points";
349 		}
350 
351 		gs_code_sstream << ") out;\n";
352 	}
353 
354 	gs_code_sstream << "\n"
355 					   "void main()\n"
356 					   "{\n"
357 					   "    gl_Position = gl_in[0].gl_Position;\n"
358 					   "    EmitVertex();\n"
359 					   "}\n";
360 
361 	return gs_code_sstream.str();
362 }
363 
364 /** Initializes fragment / geometry / vertex shader objects, according to the test run descriptor.
365  *
366  *  @param current_run                      Test run descriptor.
367  *  @param out_has_fs_compiled_successfully Deref will be set to false, if FS has failed to compile
368  *                                          successfully. Otherwise, it will be set to true.
369  *  @param out_has_gs_compiled_successfully Deref will be set to false, if GS has failed to compile
370  *                                          successfully. Otherwise, it will be set to true.
371  *  @param out_has_vs_compiled_successfully Deref will be set to false, if VS has failed to compile
372  *                                          successfully. Otherwise, it will be set to true.
373  *
374  */
initShaderObjects(const _run & current_run,bool * out_has_fs_compiled_successfully,bool * out_has_gs_compiled_successfully,bool * out_has_vs_compiled_successfully)375 void GeometryShaderIncompleteGSTest::initShaderObjects(const _run& current_run, bool* out_has_fs_compiled_successfully,
376 													   bool* out_has_gs_compiled_successfully,
377 													   bool* out_has_vs_compiled_successfully)
378 {
379 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
380 
381 	std::string specialized_fs_code = specializeShader(1, &dummy_fs_code);
382 	std::string gs_code				= getGeometryShaderCode(current_run);
383 	const char* gs_code_raw			= gs_code.c_str();
384 	std::string specialized_gs_code = specializeShader(1, &gs_code_raw);
385 	std::string specialized_vs_code = specializeShader(1, &dummy_vs_code);
386 
387 	const char* specialized_fs_code_raw = specialized_fs_code.c_str();
388 	const char* specialized_gs_code_raw = specialized_gs_code.c_str();
389 	const char* specialized_vs_code_raw = specialized_vs_code.c_str();
390 
391 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
392 	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
393 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
394 
395 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
396 
397 	for (unsigned int n_shader_type = 0; n_shader_type < 3; /* fs, gs, vs */
398 		 n_shader_type++)
399 	{
400 		glw::GLint compile_status = GL_FALSE;
401 		bool*	  out_current_compile_result =
402 			(n_shader_type == 0) ?
403 				out_has_fs_compiled_successfully :
404 				(n_shader_type == 1) ? out_has_gs_compiled_successfully : out_has_vs_compiled_successfully;
405 
406 		const char* so_code = (n_shader_type == 0) ?
407 								  specialized_fs_code_raw :
408 								  (n_shader_type == 1) ? specialized_gs_code_raw : specialized_vs_code_raw;
409 
410 		glw::GLuint so_id = (n_shader_type == 0) ? m_fs_id : (n_shader_type == 1) ? m_gs_id : m_vs_id;
411 
412 		gl.shaderSource(so_id, 1,			/* count */
413 						&so_code, DE_NULL); /* length */
414 
415 		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed");
416 
417 		gl.compileShader(so_id);
418 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed");
419 
420 		gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
421 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed");
422 
423 		*out_current_compile_result = (compile_status == GL_TRUE);
424 	} /* for (both shader stages) */
425 }
426 
427 /** Initializes all test runs */
initTestRuns()428 void GeometryShaderIncompleteGSTest::initTestRuns()
429 {
430 	/*                         input_primitive_defined | max_vertices_defined | output_primitive_defined
431 	 *                         ------------------------|----------------------|-------------------------*/
432 	m_test_runs.push_back(_run(false, false, false));
433 	m_test_runs.push_back(_run(false, false, true));
434 	m_test_runs.push_back(_run(false, true, false));
435 	m_test_runs.push_back(_run(true, true, false));
436 	m_test_runs.push_back(_run(false, true, true));
437 }
438 
439 /** Executes the test.
440  *
441  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
442  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
443  *  Note the function throws exception should an error occur!
444  **/
iterate()445 tcu::TestNode::IterateResult GeometryShaderIncompleteGSTest::iterate()
446 {
447 	bool result = true;
448 
449 	/* This test should only run if EXT_geometry_shader is supported. */
450 	if (!m_is_geometry_shader_extension_supported)
451 	{
452 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
453 	}
454 
455 	/* Initialize test runs */
456 	initTestRuns();
457 
458 	/* Iterate over the test run set */
459 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
460 
461 	for (unsigned int run_index = 0; run_index < m_test_runs.size(); ++run_index)
462 	{
463 		const _run& current_run = m_test_runs[run_index];
464 
465 		/* Release shader objects initialized in previous iterations */
466 		deinitSOs();
467 
468 		/* Set up shader objects */
469 		bool has_fs_compiled = false;
470 		bool has_gs_compiled = false;
471 		bool has_vs_compiled = false;
472 
473 		initShaderObjects(current_run, &has_fs_compiled, &has_gs_compiled, &has_vs_compiled);
474 
475 		if (!has_fs_compiled || !has_vs_compiled)
476 		{
477 			m_testCtx.getLog() << tcu::TestLog::Message << "Dummy FS and/or dummy VS failed to compile"
478 							   << tcu::TestLog::EndMessage;
479 
480 			result = false;
481 			break;
482 		}
483 
484 		/* Set up a program object */
485 		m_po_id = gl.createProgram();
486 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed");
487 
488 		gl.attachShader(m_po_id, m_fs_id);
489 		gl.attachShader(m_po_id, m_gs_id);
490 		gl.attachShader(m_po_id, m_vs_id);
491 
492 		GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed");
493 
494 		/* Try to link the PO */
495 		gl.linkProgram(m_po_id);
496 		GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
497 
498 		/* Verify the link status */
499 		glw::GLint link_status = GL_FALSE;
500 
501 		gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
502 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed");
503 
504 		if (link_status == GL_TRUE)
505 		{
506 			m_testCtx.getLog() << tcu::TestLog::Message
507 							   << "PO with a malformed Geometry Shader was linked successfully."
508 							   << " [input primitive type]:"
509 							   << ((current_run.is_input_primitive_type_defined) ? "DEFINED" : "NOT DEFINED")
510 							   << " [output primitive type]:"
511 							   << ((current_run.is_output_primitive_type_defined) ? "DEFINED" : "NOT DEFINED")
512 							   << " [max_vertices]:"
513 							   << ((current_run.is_max_vertices_defined) ? "DEFINED" : "NOT DEFINED")
514 							   << tcu::TestLog::EndMessage;
515 
516 			result = false;
517 		}
518 
519 		/* Clean up for the next iteration */
520 		gl.deleteProgram(m_po_id);
521 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram() call failed");
522 	} /* for (all test runs) */
523 
524 	if (result)
525 	{
526 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
527 	}
528 	else
529 	{
530 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
531 	}
532 
533 	return STOP;
534 }
535 
536 /** Constructor
537  *
538  * @param context       Test context
539  * @param extParams     Not used.
540  * @param name          Test case's name
541  * @param description   Test case's description
542  **/
GeometryShaderInvalidArrayedInputVariablesTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)543 GeometryShaderInvalidArrayedInputVariablesTest::GeometryShaderInvalidArrayedInputVariablesTest(
544 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
545 	: TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_po_id(0), m_vs_id(0)
546 {
547 }
548 
549 /** Deinitializes GLES objects created during the test. */
deinit()550 void GeometryShaderInvalidArrayedInputVariablesTest::deinit()
551 {
552 	deinitSOs();
553 
554 	/* Release the PO */
555 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
556 
557 	if (m_po_id != 0)
558 	{
559 		gl.deleteProgram(m_po_id);
560 
561 		m_po_id = 0;
562 	}
563 
564 	/* Release base class */
565 	TestCaseBase::deinit();
566 }
567 
568 /** Deinitializes shader objects created for the conformance test. */
deinitSOs()569 void GeometryShaderInvalidArrayedInputVariablesTest::deinitSOs()
570 {
571 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
572 
573 	if (m_fs_id != 0)
574 	{
575 		gl.deleteShader(m_fs_id);
576 
577 		m_fs_id = 0;
578 	}
579 
580 	if (m_gs_id != 0)
581 	{
582 		gl.deleteShader(m_gs_id);
583 
584 		m_gs_id = 0;
585 	}
586 
587 	if (m_vs_id != 0)
588 	{
589 		gl.deleteShader(m_vs_id);
590 
591 		m_vs_id = 0;
592 	}
593 }
594 
595 /** Returns test-specific geometry shader source code, built for caller-specified input primitive type.
596  *
597  *  @param gs_input_primitive_type Input primitive type to be used for the process.
598  *
599  *  @return Requested shader source code.
600  **/
getGSCode(glw::GLenum gs_input_primitive_type) const601 std::string GeometryShaderInvalidArrayedInputVariablesTest::getGSCode(glw::GLenum gs_input_primitive_type) const
602 {
603 	std::stringstream  code_sstream;
604 	const unsigned int valid_array_size = getValidInputVariableArraySize(gs_input_primitive_type);
605 
606 	code_sstream << "${VERSION}\n"
607 					"${GEOMETRY_SHADER_REQUIRE}\n"
608 					"\n"
609 					"layout ("
610 				 << getInputPrimitiveTypeQualifier(gs_input_primitive_type)
611 				 << ") in;\n"
612 					"layout (points, max_vertices = 1) out;\n"
613 					"\n"
614 					"in vec4 data["
615 				 << (valid_array_size + 1) << "];\n"
616 											  "\n"
617 											  "void main()\n"
618 											  "{\n"
619 											  "    gl_Position = data["
620 				 << valid_array_size << "];\n"
621 										"    EmitVertex();\n"
622 										"}\n";
623 
624 	return code_sstream.str();
625 }
626 
627 /** Returns a string holding the ES SL layout qualifier corresponding to user-specified input primitive type
628  *  expressed as a GLenum value.
629  *
630  *  @param gs_input_primitive_type Geometry Shader's input primitive type, expressed as a GLenum value.
631  *
632  *  @return Requested string
633  */
getInputPrimitiveTypeQualifier(glw::GLenum gs_input_primitive_type) const634 std::string GeometryShaderInvalidArrayedInputVariablesTest::getInputPrimitiveTypeQualifier(
635 	glw::GLenum gs_input_primitive_type) const
636 {
637 	std::string result;
638 
639 	switch (gs_input_primitive_type)
640 	{
641 	case GL_POINTS:
642 		result = "points";
643 		break;
644 	case GL_LINES:
645 		result = "lines";
646 		break;
647 	case GL_LINES_ADJACENCY:
648 		result = "lines_adjacency";
649 		break;
650 	case GL_TRIANGLES:
651 		result = "triangles";
652 		break;
653 	case GL_TRIANGLES_ADJACENCY:
654 		result = "triangles_adjacency";
655 		break;
656 
657 	default:
658 	{
659 		DE_ASSERT(0);
660 	}
661 	} /* switch (gs_input_primitive_type) */
662 
663 	return result;
664 }
665 
666 /** Retrieves a specialized version of the vertex shader to be used for the conformance test. */
getSpecializedVSCode() const667 std::string GeometryShaderInvalidArrayedInputVariablesTest::getSpecializedVSCode() const
668 {
669 	std::string vs_code = "${VERSION}\n"
670 						  "\n"
671 						  "out vec4 data;\n"
672 						  "\n"
673 						  "void main()\n"
674 						  "{\n"
675 						  "    data = vec4(gl_VertexID, 0, 0, 1);\n"
676 						  "}\n";
677 	const char* vs_code_raw			= vs_code.c_str();
678 	std::string specialized_vs_code = specializeShader(1, /* parts */
679 													   &vs_code_raw);
680 
681 	return specialized_vs_code;
682 }
683 
684 /** Returns array size that should be used for input variable declaration in GS, specific to
685  *  to the caller-specified input primitive type.
686  *
687  *  @param gs_input_primitive_type Input primitive type to use for the query.
688  *
689  *  @return Requested value.
690  */
getValidInputVariableArraySize(glw::GLenum gs_input_primitive_type) const691 glw::GLuint GeometryShaderInvalidArrayedInputVariablesTest::getValidInputVariableArraySize(
692 	glw::GLenum gs_input_primitive_type) const
693 {
694 	glw::GLuint result = 0;
695 
696 	switch (gs_input_primitive_type)
697 	{
698 	case GL_POINTS:
699 		result = 1;
700 		break;
701 	case GL_LINES:
702 		result = 2;
703 		break;
704 	case GL_LINES_ADJACENCY:
705 		result = 4;
706 		break;
707 	case GL_TRIANGLES:
708 		result = 3;
709 		break;
710 	case GL_TRIANGLES_ADJACENCY:
711 		result = 6;
712 		break;
713 
714 	default:
715 	{
716 		DE_ASSERT(0);
717 	}
718 	} /* switch (gs_input_primitive_type) */
719 
720 	return result;
721 }
722 
723 /** Initializes fragment / geometry / vertex shader objects, according to the user-specified GS input primitive type.
724  *
725  *  @param gs_input_primitive_type          Input primitive type, to be used for GS.
726  *  @param out_has_fs_compiled_successfully Deref will be set to false, if FS has failed to compile
727  *                                          successfully. Otherwise, it will be set to true.
728  *  @param out_has_gs_compiled_successfully Deref will be set to false, if GS has failed to compile
729  *                                          successfully. Otherwise, it will be set to true.
730  *  @param out_has_vs_compiled_successfully Deref will be set to false, if VS has failed to compile
731  *                                          successfully. Otherwise, it will be set to true.
732  *
733  */
initShaderObjects(glw::GLenum gs_input_primitive_type,bool * out_has_fs_compiled_successfully,bool * out_has_gs_compiled_successfully,bool * out_has_vs_compiled_successfully)734 void GeometryShaderInvalidArrayedInputVariablesTest::initShaderObjects(glw::GLenum gs_input_primitive_type,
735 																	   bool*	   out_has_fs_compiled_successfully,
736 																	   bool*	   out_has_gs_compiled_successfully,
737 																	   bool*	   out_has_vs_compiled_successfully)
738 {
739 	const glw::Functions& gl					  = m_context.getRenderContext().getFunctions();
740 	std::string			  specialized_fs_code	 = specializeShader(1, &dummy_fs_code);
741 	const char*			  specialized_fs_code_raw = specialized_fs_code.c_str();
742 	std::string			  gs_code				  = getGSCode(gs_input_primitive_type);
743 	const char*			  gs_code_raw			  = gs_code.c_str();
744 	std::string			  specialized_gs_code	 = specializeShader(1, &gs_code_raw);
745 	const char*			  specialized_gs_code_raw = specialized_gs_code.c_str();
746 	std::string			  specialized_vs_code	 = getSpecializedVSCode();
747 	const char*			  specialized_vs_code_raw = specialized_vs_code.c_str();
748 
749 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
750 	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
751 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
752 
753 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
754 
755 	for (unsigned int n_shader_type = 0; n_shader_type < 3; /* fs, gs, vs */
756 		 n_shader_type++)
757 	{
758 		glw::GLint compile_status	 = GL_FALSE;
759 		bool*	  out_compile_result = (n_shader_type == 0) ? out_has_fs_compiled_successfully :
760 														  (n_shader_type == 1) ? out_has_gs_compiled_successfully :
761 																				 out_has_vs_compiled_successfully;
762 
763 		const char* so_code = (n_shader_type == 0) ?
764 								  specialized_fs_code_raw :
765 								  (n_shader_type == 1) ? specialized_gs_code_raw : specialized_vs_code_raw;
766 
767 		glw::GLuint so_id = (n_shader_type == 0) ? m_fs_id : (n_shader_type == 1) ? m_gs_id : m_vs_id;
768 
769 		gl.shaderSource(so_id, 1,			/* count */
770 						&so_code, DE_NULL); /* length */
771 
772 		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed");
773 
774 		gl.compileShader(so_id);
775 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed");
776 
777 		gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
778 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed");
779 
780 		*out_compile_result = (compile_status == GL_TRUE);
781 	} /* for (both shader stages) */
782 }
783 
784 /** Executes the test.
785  *
786  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
787  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
788  *  Note the function throws exception should an error occur!
789  **/
iterate()790 tcu::TestNode::IterateResult GeometryShaderInvalidArrayedInputVariablesTest::iterate()
791 {
792 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
793 	bool				  result = true;
794 
795 	/* This test should only run if EXT_geometry_shader is supported. */
796 	if (!m_is_geometry_shader_extension_supported)
797 	{
798 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
799 	}
800 
801 	/* Iterate over all valid input primitive types */
802 	const glw::GLenum input_primitive_types[] = { GL_POINTS, GL_LINES, GL_LINES_ADJACENCY, GL_TRIANGLES,
803 												  GL_TRIANGLES_ADJACENCY };
804 	const unsigned int n_input_primitive_types = sizeof(input_primitive_types) / sizeof(input_primitive_types[0]);
805 
806 	for (unsigned int n_input_primitive_type = 0; n_input_primitive_type < n_input_primitive_types;
807 		 ++n_input_primitive_type)
808 	{
809 		const glw::GLenum input_primitive_type = input_primitive_types[n_input_primitive_type];
810 
811 		/* Release shader objects initialized in previous iterations */
812 		deinitSOs();
813 
814 		/* Set up shader objects */
815 		bool has_fs_compiled = false;
816 		bool has_gs_compiled = false;
817 		bool has_vs_compiled = false;
818 
819 		initShaderObjects(input_primitive_type, &has_fs_compiled, &has_gs_compiled, &has_vs_compiled);
820 
821 		if (!has_fs_compiled || !has_gs_compiled || !has_vs_compiled)
822 		{
823 			m_testCtx.getLog()
824 				<< tcu::TestLog::Message
825 				<< "One of the shaders failed to compile (but shouldn't have). Shaders that failed to compile:"
826 				<< ((!has_fs_compiled) ? "FS " : "") << ((!has_gs_compiled) ? "GS " : "")
827 				<< ((!has_vs_compiled) ? "VS" : "") << ". Input primitive type: ["
828 				<< getInputPrimitiveTypeQualifier(input_primitive_type) << "]" << tcu::TestLog::EndMessage;
829 
830 			continue;
831 		}
832 
833 		/* Set up a program object */
834 		m_po_id = gl.createProgram();
835 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed");
836 
837 		gl.attachShader(m_po_id, m_fs_id);
838 		gl.attachShader(m_po_id, m_gs_id);
839 		gl.attachShader(m_po_id, m_vs_id);
840 
841 		GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed");
842 
843 		/* Try to link the PO */
844 		gl.linkProgram(m_po_id);
845 		GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
846 
847 		/* Verify the link status */
848 		glw::GLint link_status = GL_FALSE;
849 
850 		gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
851 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed");
852 
853 		if (link_status == GL_TRUE)
854 		{
855 			m_testCtx.getLog() << tcu::TestLog::Message << "A PO using a malformed GS has linked successfully. "
856 							   << "Test input primitive type: " << getInputPrimitiveTypeQualifier(input_primitive_type)
857 							   << tcu::TestLog::EndMessage;
858 
859 			result = false;
860 		}
861 	} /* for (all input primitive types) */
862 
863 	if (result)
864 	{
865 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
866 	}
867 	else
868 	{
869 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
870 	}
871 
872 	return STOP;
873 }
874 
875 /** Constructor
876  *
877  * @param context       Test context
878  * @param extParams     Not used.
879  * @param name          Test case's name
880  * @param description   Test case's description
881  **/
GeometryShaderVSGSVariableTypeMismatchTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)882 GeometryShaderVSGSVariableTypeMismatchTest::GeometryShaderVSGSVariableTypeMismatchTest(Context&				context,
883 																					   const ExtParameters& extParams,
884 																					   const char*			name,
885 																					   const char*			description)
886 	: TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_po_id(0), m_vs_id(0)
887 {
888 }
889 
890 /** Deinitializes GLES objects created during the test. */
deinit()891 void GeometryShaderVSGSVariableTypeMismatchTest::deinit()
892 {
893 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
894 
895 	if (m_fs_id != 0)
896 	{
897 		gl.deleteShader(m_fs_id);
898 
899 		m_fs_id = 0;
900 	}
901 
902 	if (m_gs_id != 0)
903 	{
904 		gl.deleteShader(m_gs_id);
905 
906 		m_gs_id = 0;
907 	}
908 
909 	if (m_po_id != 0)
910 	{
911 		gl.deleteProgram(m_po_id);
912 
913 		m_po_id = 0;
914 	}
915 
916 	if (m_vs_id != 0)
917 	{
918 		gl.deleteShader(m_vs_id);
919 
920 		m_vs_id = 0;
921 	}
922 
923 	/* Release base class */
924 	TestCaseBase::deinit();
925 }
926 
927 /** Executes the test.
928  *
929  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
930  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
931  *  Note the function throws exception should an error occur!
932  **/
iterate()933 tcu::TestNode::IterateResult GeometryShaderVSGSVariableTypeMismatchTest::iterate()
934 {
935 	bool has_shader_compilation_failed = true;
936 	bool result						   = true;
937 
938 	/* This test should only run if EXT_geometry_shader is supported. */
939 	if (!m_is_geometry_shader_extension_supported)
940 	{
941 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
942 	}
943 
944 	/* Create a program object */
945 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
946 
947 	m_po_id = gl.createProgram();
948 
949 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
950 
951 	/* Create shader objects */
952 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
953 	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
954 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
955 
956 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
957 
958 	/* Try to link the test program object */
959 	const char* gs_code_raw = "${VERSION}\n"
960 							  "${GEOMETRY_SHADER_REQUIRE}\n"
961 							  "\n"
962 							  "layout (points)                   in;\n"
963 							  "layout (points, max_vertices = 1) out;\n"
964 							  "\n"
965 							  "in vec4 test[];\n"
966 							  "\n"
967 							  "void main()\n"
968 							  "{\n"
969 							  "    gl_Position = test[0];\n"
970 							  "    EmitVertex();\n"
971 							  "}\n";
972 
973 	const char* vs_code_raw = "${VERSION}\n"
974 							  "\n"
975 							  "out vec3 test;\n"
976 							  "\n"
977 							  "void main()\n"
978 							  "{\n"
979 							  "    test = vec3(gl_VertexID);\n"
980 							  "}\n";
981 
982 	std::string fs_code_specialized		= specializeShader(1, &dummy_fs_code);
983 	const char* fs_code_specialized_raw = fs_code_specialized.c_str();
984 	std::string gs_code_specialized		= specializeShader(1, &gs_code_raw);
985 	const char* gs_code_specialized_raw = gs_code_specialized.c_str();
986 	std::string vs_code_specialized		= specializeShader(1, &vs_code_raw);
987 	const char* vs_code_specialized_raw = vs_code_specialized.c_str();
988 
989 	if (TestCaseBase::buildProgram(m_po_id, m_gs_id, 1,					 /* n_sh1_body_parts */
990 								   &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
991 								   &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
992 								   &fs_code_specialized_raw, &has_shader_compilation_failed))
993 	{
994 		m_testCtx.getLog() << tcu::TestLog::Message
995 						   << "Program object was linked successfully, whereas a failure was expected."
996 						   << tcu::TestLog::EndMessage;
997 
998 		result = false;
999 	}
1000 
1001 	if (has_shader_compilation_failed)
1002 	{
1003 		m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failed unexpectedly."
1004 						   << tcu::TestLog::EndMessage;
1005 
1006 		result = false;
1007 	}
1008 
1009 	if (result)
1010 	{
1011 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1012 	}
1013 	else
1014 	{
1015 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1016 	}
1017 
1018 	return STOP;
1019 }
1020 
1021 /** Constructor
1022  *
1023  * @param context       Test context
1024  * @param extParams     Not used.
1025  * @param name          Test case's name
1026  * @param description   Test case's description
1027  **/
GeometryShaderVSGSVariableQualifierMismatchTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1028 GeometryShaderVSGSVariableQualifierMismatchTest::GeometryShaderVSGSVariableQualifierMismatchTest(
1029 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
1030 	: TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_po_id(0), m_vs_id(0)
1031 {
1032 }
1033 
1034 /** Deinitializes GLES objects created during the test. */
deinit()1035 void GeometryShaderVSGSVariableQualifierMismatchTest::deinit()
1036 {
1037 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1038 
1039 	if (m_fs_id != 0)
1040 	{
1041 		gl.deleteShader(m_fs_id);
1042 
1043 		m_fs_id = 0;
1044 	}
1045 
1046 	if (m_gs_id != 0)
1047 	{
1048 		gl.deleteShader(m_gs_id);
1049 
1050 		m_gs_id = 0;
1051 	}
1052 
1053 	if (m_po_id != 0)
1054 	{
1055 		gl.deleteProgram(m_po_id);
1056 
1057 		m_po_id = 0;
1058 	}
1059 
1060 	if (m_vs_id != 0)
1061 	{
1062 		gl.deleteShader(m_vs_id);
1063 
1064 		m_vs_id = 0;
1065 	}
1066 
1067 	/* Release base class */
1068 	TestCaseBase::deinit();
1069 }
1070 
1071 /** Executes the test.
1072  *
1073  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1074  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1075  *  Note the function throws exception should an error occur!
1076  **/
iterate()1077 tcu::TestNode::IterateResult GeometryShaderVSGSVariableQualifierMismatchTest::iterate()
1078 {
1079 	bool has_shader_compilation_failed = true;
1080 	bool result						   = true;
1081 
1082 	/* This test should only run if EXT_geometry_shader is supported. */
1083 	if (!m_is_geometry_shader_extension_supported)
1084 	{
1085 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1086 	}
1087 
1088 	/* Create a program object */
1089 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1090 
1091 	m_po_id = gl.createProgram();
1092 
1093 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1094 
1095 	/* Create shader objects */
1096 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1097 	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1098 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1099 
1100 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
1101 
1102 	/* Try to link the test program object */
1103 	const char* gs_code_raw = "${VERSION}\n"
1104 							  "${GEOMETRY_SHADER_REQUIRE}\n"
1105 							  "\n"
1106 							  "layout (points)                   in;\n"
1107 							  "layout (points, max_vertices = 1) out;\n"
1108 							  "\n"
1109 							  "in flat vec4 test[];\n"
1110 							  "\n"
1111 							  "void main()\n"
1112 							  "{\n"
1113 							  "    gl_Position = test[0];\n"
1114 							  "    EmitVertex();\n"
1115 							  "}\n";
1116 
1117 	const char* vs_code_raw = "${VERSION}\n"
1118 							  "${GEOMETRY_SHADER_REQUIRE}\n"
1119 							  "\n"
1120 							  "out vec4 test;\n"
1121 							  "\n"
1122 							  "void main()\n"
1123 							  "{\n"
1124 							  "    test = vec4(gl_VertexID);\n"
1125 							  "}\n";
1126 
1127 	std::string fs_code_specialized		= specializeShader(1, &dummy_fs_code);
1128 	const char* fs_code_specialized_raw = fs_code_specialized.c_str();
1129 	std::string gs_code_specialized		= specializeShader(1, &gs_code_raw);
1130 	const char* gs_code_specialized_raw = gs_code_specialized.c_str();
1131 	std::string vs_code_specialized		= specializeShader(1, &vs_code_raw);
1132 	const char* vs_code_specialized_raw = vs_code_specialized.c_str();
1133 
1134 	bool buildSuccess = TestCaseBase::buildProgram(m_po_id, m_gs_id, 1,					 /* n_sh1_body_parts */
1135 												   &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
1136 												   &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
1137 												   &fs_code_specialized_raw, &has_shader_compilation_failed);
1138 
1139 	if (!buildSuccess && glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)))
1140 	{
1141 		m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed. Success was expected."
1142 						   << tcu::TestLog::EndMessage;
1143 
1144 		result = false;
1145 	}
1146 
1147 	if (buildSuccess && !glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)))
1148 	{
1149 		m_testCtx.getLog() << tcu::TestLog::Message
1150 						   << "Program object was linked successfully, whereas a failure was expected."
1151 						   << tcu::TestLog::EndMessage;
1152 		result = false;
1153 	}
1154 
1155 	if (has_shader_compilation_failed)
1156 	{
1157 		m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failed unexpectedly."
1158 						   << tcu::TestLog::EndMessage;
1159 
1160 		result = false;
1161 	}
1162 
1163 	if (result)
1164 	{
1165 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1166 	}
1167 	else
1168 	{
1169 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1170 	}
1171 
1172 	return STOP;
1173 }
1174 
1175 /** Constructor
1176  *
1177  * @param context       Test context
1178  * @param extParams     Not used.
1179  * @param name          Test case's name
1180  * @param description   Test case's description
1181  **/
GeometryShaderVSGSArrayedVariableSizeMismatchTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1182 GeometryShaderVSGSArrayedVariableSizeMismatchTest::GeometryShaderVSGSArrayedVariableSizeMismatchTest(
1183 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
1184 	: TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_po_id(0), m_vs_id(0)
1185 {
1186 }
1187 
1188 /** Deinitializes GLES objects created during the test. */
deinit()1189 void GeometryShaderVSGSArrayedVariableSizeMismatchTest::deinit()
1190 {
1191 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1192 
1193 	if (m_fs_id != 0)
1194 	{
1195 		gl.deleteShader(m_fs_id);
1196 
1197 		m_fs_id = 0;
1198 	}
1199 
1200 	if (m_gs_id != 0)
1201 	{
1202 		gl.deleteShader(m_gs_id);
1203 
1204 		m_gs_id = 0;
1205 	}
1206 
1207 	if (m_po_id != 0)
1208 	{
1209 		gl.deleteProgram(m_po_id);
1210 
1211 		m_po_id = 0;
1212 	}
1213 
1214 	if (m_vs_id != 0)
1215 	{
1216 		gl.deleteShader(m_vs_id);
1217 
1218 		m_vs_id = 0;
1219 	}
1220 
1221 	/* Release base class */
1222 	TestCaseBase::deinit();
1223 }
1224 
1225 /** Executes the test.
1226  *
1227  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1228  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1229  *  Note the function throws exception should an error occur!
1230  **/
iterate()1231 tcu::TestNode::IterateResult GeometryShaderVSGSArrayedVariableSizeMismatchTest::iterate()
1232 {
1233 	bool has_shader_compilation_failed = true;
1234 	bool result						   = true;
1235 
1236 	/* This test should only run if EXT_geometry_shader is supported. */
1237 	if (!m_is_geometry_shader_extension_supported)
1238 	{
1239 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1240 	}
1241 
1242 	/* Create a program object */
1243 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1244 
1245 	m_po_id = gl.createProgram();
1246 
1247 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1248 
1249 	/* Create shader objects */
1250 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1251 	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1252 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1253 
1254 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
1255 
1256 	/* Try to link the test program object */
1257 	const char* gs_code_raw = "${VERSION}\n"
1258 							  "${GEOMETRY_SHADER_REQUIRE}\n"
1259 							  "\n"
1260 							  "layout (points)                   in;\n"
1261 							  "layout (points, max_vertices = 1) out;\n"
1262 							  "\n"
1263 							  "in vec4 Color1[];\n"
1264 							  "in vec4 Color2[2];\n"
1265 							  "in vec4 Color3[3];\n"
1266 							  "\n"
1267 							  "void main()\n"
1268 							  "{\n"
1269 							  "    gl_Position = Color1[0] + Color2[1] + Color3[2];\n"
1270 							  "    EmitVertex();\n"
1271 							  "}\n";
1272 
1273 	const char* vs_code_raw = "${VERSION}\n"
1274 							  "${GEOMETRY_SHADER_REQUIRE}\n"
1275 							  "\n"
1276 							  "out vec4 Color1;\n"
1277 							  "out vec4 Color2;\n"
1278 							  "out vec4 Color3;\n"
1279 							  "\n"
1280 							  "void main()\n"
1281 							  "{\n"
1282 							  "    Color1 = vec4(gl_VertexID, 0.0,         0.0,         0.0);\n"
1283 							  "    Color2 = vec4(0.0,         gl_VertexID, 0.0,         0.0);\n"
1284 							  "    Color3 = vec4(0.0,         0.0,         gl_VertexID, 0.0);\n"
1285 							  "}\n";
1286 
1287 	std::string fs_code_specialized		= specializeShader(1, &dummy_fs_code);
1288 	const char* fs_code_specialized_raw = fs_code_specialized.c_str();
1289 	std::string gs_code_specialized		= specializeShader(1, &gs_code_raw);
1290 	const char* gs_code_specialized_raw = gs_code_specialized.c_str();
1291 	std::string vs_code_specialized		= specializeShader(1, &vs_code_raw);
1292 	const char* vs_code_specialized_raw = vs_code_specialized.c_str();
1293 
1294 	if (TestCaseBase::buildProgram(m_po_id, m_gs_id, 1,					 /* n_sh1_body_parts */
1295 								   &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
1296 								   &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
1297 								   &fs_code_specialized_raw, &has_shader_compilation_failed))
1298 	{
1299 		m_testCtx.getLog() << tcu::TestLog::Message
1300 						   << "Program object was linked successfully, whereas a failure was expected."
1301 						   << tcu::TestLog::EndMessage;
1302 
1303 		result = false;
1304 	}
1305 
1306 	if (result)
1307 	{
1308 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1309 	}
1310 	else
1311 	{
1312 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1313 	}
1314 
1315 	return STOP;
1316 }
1317 
1318 /** Constructor
1319  *
1320  * @param context       Test context
1321  * @param extParams     Not used.
1322  * @param name          Test case's name
1323  * @param description   Test case's description
1324  **/
GeometryShaderFragCoordRedeclarationTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1325 GeometryShaderFragCoordRedeclarationTest::GeometryShaderFragCoordRedeclarationTest(Context&				context,
1326 																				   const ExtParameters& extParams,
1327 																				   const char*			name,
1328 																				   const char*			description)
1329 	: TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_po_id(0), m_vs_id(0)
1330 {
1331 }
1332 
1333 /** Deinitializes GLES objects created during the test. */
deinit()1334 void GeometryShaderFragCoordRedeclarationTest::deinit()
1335 {
1336 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1337 
1338 	if (m_fs_id != 0)
1339 	{
1340 		gl.deleteShader(m_fs_id);
1341 
1342 		m_fs_id = 0;
1343 	}
1344 
1345 	if (m_gs_id != 0)
1346 	{
1347 		gl.deleteShader(m_gs_id);
1348 
1349 		m_gs_id = 0;
1350 	}
1351 
1352 	if (m_po_id != 0)
1353 	{
1354 		gl.deleteProgram(m_po_id);
1355 
1356 		m_po_id = 0;
1357 	}
1358 
1359 	if (m_vs_id != 0)
1360 	{
1361 		gl.deleteShader(m_vs_id);
1362 
1363 		m_vs_id = 0;
1364 	}
1365 
1366 	/* Release base class */
1367 	TestCaseBase::deinit();
1368 }
1369 
1370 /** Executes the test.
1371  *
1372  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1373  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1374  *  Note the function throws exception should an error occur!
1375  **/
iterate()1376 tcu::TestNode::IterateResult GeometryShaderFragCoordRedeclarationTest::iterate()
1377 {
1378 	bool has_shader_compilation_failed = true;
1379 	bool result						   = true;
1380 
1381 	/* This test should only run if EXT_geometry_shader is supported. */
1382 	if (!m_is_geometry_shader_extension_supported)
1383 	{
1384 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1385 	}
1386 
1387 	/* Create a program object */
1388 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1389 
1390 	m_po_id = gl.createProgram();
1391 
1392 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1393 
1394 	/* Create shader objects */
1395 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1396 	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1397 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1398 
1399 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
1400 
1401 	/* Try to link the test program object */
1402 	const char* gs_code_raw = "${VERSION}\n"
1403 							  "${GEOMETRY_SHADER_REQUIRE}\n"
1404 							  "\n"
1405 							  "layout (points)                   in;\n"
1406 							  "layout (points, max_vertices = 1) out;\n"
1407 							  "\n"
1408 							  "in vec4 gl_FragCoord;\n"
1409 							  "\n"
1410 							  "void main()\n"
1411 							  "{\n"
1412 							  "    gl_Position = gl_FragCoord;\n"
1413 							  "    EmitVertex();\n"
1414 							  "}\n";
1415 
1416 	std::string fs_code_specialized		= specializeShader(1, &dummy_fs_code);
1417 	const char* fs_code_specialized_raw = fs_code_specialized.c_str();
1418 	std::string gs_code_specialized		= specializeShader(1, &gs_code_raw);
1419 	const char* gs_code_specialized_raw = gs_code_specialized.c_str();
1420 	std::string vs_code_specialized		= specializeShader(1, &dummy_vs_code);
1421 	const char* vs_code_specialized_raw = vs_code_specialized.c_str();
1422 
1423 	if (TestCaseBase::buildProgram(m_po_id, m_gs_id, 1,					 /* n_sh1_body_parts */
1424 								   &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
1425 								   &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
1426 								   &fs_code_specialized_raw, &has_shader_compilation_failed))
1427 	{
1428 		m_testCtx.getLog() << tcu::TestLog::Message
1429 						   << "Program object was linked successfully, whereas a failure was expected."
1430 						   << tcu::TestLog::EndMessage;
1431 
1432 		result = false;
1433 	}
1434 
1435 	if (result)
1436 	{
1437 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1438 	}
1439 	else
1440 	{
1441 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1442 	}
1443 
1444 	return STOP;
1445 }
1446 
1447 /** Constructor
1448  *
1449  * @param context       Test context
1450  * @param extParams     Not used.
1451  * @param name          Test case's name
1452  * @param description   Test case's description
1453  **/
GeometryShaderLocationAliasingTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1454 GeometryShaderLocationAliasingTest::GeometryShaderLocationAliasingTest(Context& context, const ExtParameters& extParams,
1455 																	   const char* name, const char* description)
1456 	: TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_po_id(0), m_vs_id(0)
1457 {
1458 }
1459 
1460 /** Deinitializes GLES objects created during the test. */
deinit()1461 void GeometryShaderLocationAliasingTest::deinit()
1462 {
1463 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1464 
1465 	if (m_fs_id != 0)
1466 	{
1467 		gl.deleteShader(m_fs_id);
1468 
1469 		m_fs_id = 0;
1470 	}
1471 
1472 	if (m_gs_id != 0)
1473 	{
1474 		gl.deleteShader(m_gs_id);
1475 
1476 		m_gs_id = 0;
1477 	}
1478 
1479 	if (m_po_id != 0)
1480 	{
1481 		gl.deleteProgram(m_po_id);
1482 
1483 		m_po_id = 0;
1484 	}
1485 
1486 	if (m_vs_id != 0)
1487 	{
1488 		gl.deleteShader(m_vs_id);
1489 
1490 		m_vs_id = 0;
1491 	}
1492 
1493 	/* Release base class */
1494 	TestCaseBase::deinit();
1495 }
1496 
1497 /** Executes the test.
1498  *
1499  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1500  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1501  *  Note the function throws exception should an error occur!
1502  **/
iterate()1503 tcu::TestNode::IterateResult GeometryShaderLocationAliasingTest::iterate()
1504 {
1505 	bool has_program_link_succeeded	= true;
1506 	bool result						   = true;
1507 
1508 	/* This test should only run if EXT_geometry_shader is supported. */
1509 	if (!m_is_geometry_shader_extension_supported)
1510 	{
1511 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1512 	}
1513 
1514 	/* Create a program object */
1515 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1516 
1517 	m_po_id = gl.createProgram();
1518 
1519 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1520 
1521 	/* Create shader objects */
1522 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1523 	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1524 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1525 
1526 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
1527 
1528 	/* Try to link the test program object */
1529 	const char* gs_code_raw = "${VERSION}\n"
1530 							  "${GEOMETRY_SHADER_REQUIRE}\n"
1531 							  "\n"
1532 							  "layout (points)                   in;\n"
1533 							  "layout (points, max_vertices = 1) out;\n"
1534 							  "\n"
1535 							  "layout (location = 2) out vec4 test;\n"
1536 							  "layout (location = 2) out vec4 test2;\n"
1537 							  "\n"
1538 							  "void main()\n"
1539 							  "{\n"
1540 							  "    gl_Position = gl_in[0].gl_Position;\n"
1541 							  "    test = vec4(1.0, 0.0, 0.0, 1.0);\n"
1542 							  "    test2 = vec4(1.0, 0.0, 0.0, 1.0);\n"
1543 							  "    EmitVertex();\n"
1544 							  "}\n";
1545 
1546 	std::string fs_code_specialized		= specializeShader(1, &dummy_fs_code);
1547 	const char* fs_code_specialized_raw = fs_code_specialized.c_str();
1548 	std::string gs_code_specialized		= specializeShader(1, &gs_code_raw);
1549 	const char* gs_code_specialized_raw = gs_code_specialized.c_str();
1550 	std::string vs_code_specialized		= specializeShader(1, &dummy_vs_code);
1551 	const char* vs_code_specialized_raw = vs_code_specialized.c_str();
1552 
1553 	has_program_link_succeeded = TestCaseBase::buildProgram(
1554 		m_po_id, m_gs_id, 1 /* n_sh1_body_parts */, &gs_code_specialized_raw, m_vs_id, 1 /* n_sh2_body_parts */,
1555 		&vs_code_specialized_raw, m_fs_id, 1 /* n_sh3_body_parts */, &fs_code_specialized_raw, NULL);
1556 	if (has_program_link_succeeded)
1557 	{
1558 		m_testCtx.getLog() << tcu::TestLog::Message
1559 						   << "Program object was compiled and linked successfully, whereas a failure was expected."
1560 						   << tcu::TestLog::EndMessage;
1561 
1562 		result = false;
1563 	}
1564 
1565 	if (result)
1566 	{
1567 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1568 	}
1569 	else
1570 	{
1571 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1572 	}
1573 
1574 	return STOP;
1575 }
1576 
1577 /** Constructor
1578  *
1579  * @param context       Test context
1580  * @param extParams     Not used.
1581  * @param name          Test case's name
1582  * @param description   Test case's description
1583  **/
GeometryShaderMoreACsInGSThanSupportedTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1584 GeometryShaderMoreACsInGSThanSupportedTest::GeometryShaderMoreACsInGSThanSupportedTest(Context&				context,
1585 																					   const ExtParameters& extParams,
1586 																					   const char*			name,
1587 																					   const char*			description)
1588 	: TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_po_id(0), m_vs_id(0)
1589 {
1590 }
1591 
1592 /** Deinitializes GLES objects created during the test. */
deinit()1593 void GeometryShaderMoreACsInGSThanSupportedTest::deinit()
1594 {
1595 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1596 
1597 	if (m_fs_id != 0)
1598 	{
1599 		gl.deleteShader(m_fs_id);
1600 
1601 		m_fs_id = 0;
1602 	}
1603 
1604 	if (m_gs_id != 0)
1605 	{
1606 		gl.deleteShader(m_gs_id);
1607 
1608 		m_gs_id = 0;
1609 	}
1610 
1611 	if (m_po_id != 0)
1612 	{
1613 		gl.deleteProgram(m_po_id);
1614 
1615 		m_po_id = 0;
1616 	}
1617 
1618 	if (m_vs_id != 0)
1619 	{
1620 		gl.deleteShader(m_vs_id);
1621 
1622 		m_vs_id = 0;
1623 	}
1624 
1625 	/* Release base class */
1626 	TestCaseBase::deinit();
1627 }
1628 
1629 /* Retrieves test-specific geometry shader source code.
1630  *
1631  * @return Requested string.
1632  */
getGSCode()1633 std::string GeometryShaderMoreACsInGSThanSupportedTest::getGSCode()
1634 {
1635 	std::stringstream	 code_sstream;
1636 	const glw::Functions& gl			   = m_context.getRenderContext().getFunctions();
1637 	glw::GLint			  gl_max_ACs_value = 0;
1638 
1639 	/* Retrieve GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT pname value */
1640 	gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTERS, &gl_max_ACs_value);
1641 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT pname");
1642 
1643 	/* Form the GS */
1644 	code_sstream << "${VERSION}\n"
1645 					"${GEOMETRY_SHADER_REQUIRE}\n"
1646 					"\n"
1647 					"layout (points)                   in;\n"
1648 					"layout (points, max_vertices = 1) out;\n"
1649 					"\n";
1650 
1651 	for (glw::GLint n_ac = 0; n_ac < (gl_max_ACs_value + 1); ++n_ac)
1652 	{
1653 		code_sstream << "layout(binding = 0) uniform atomic_uint counter" << n_ac << ";\n";
1654 	}
1655 
1656 	code_sstream << "\n"
1657 					"void main()\n"
1658 					"{\n";
1659 
1660 	for (glw::GLint n_ac = 0; n_ac < (gl_max_ACs_value + 1); ++n_ac)
1661 	{
1662 		code_sstream << "    if ((gl_PrimitiveIDIn % " << (n_ac + 1) << ") == 0) atomicCounterIncrement(counter" << n_ac
1663 					 << ");\n";
1664 	}
1665 
1666 	code_sstream << "\n"
1667 					"    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
1668 					"    EmitVertex();\n"
1669 					"}\n";
1670 
1671 	/* Form a specialized version of the GS source code */
1672 	std::string gs_code				= code_sstream.str();
1673 	const char* gs_code_raw			= gs_code.c_str();
1674 	std::string gs_code_specialized = specializeShader(1, /* parts */
1675 													   &gs_code_raw);
1676 
1677 	return gs_code_specialized;
1678 }
1679 
1680 /** Executes the test.
1681  *
1682  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1683  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1684  *  Note the function throws exception should an error occur!
1685  **/
iterate()1686 tcu::TestNode::IterateResult GeometryShaderMoreACsInGSThanSupportedTest::iterate()
1687 {
1688 	bool has_shader_compilation_failed = true;
1689 	bool result						   = true;
1690 
1691 	/* This test should only run if EXT_geometry_shader is supported. */
1692 	if (!m_is_geometry_shader_extension_supported)
1693 	{
1694 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1695 	}
1696 
1697 	/* Create a program object */
1698 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1699 
1700 	m_po_id = gl.createProgram();
1701 
1702 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1703 
1704 	/* Create shader objects */
1705 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1706 	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1707 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1708 
1709 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
1710 
1711 	/* Try to link the test program object */
1712 	std::string fs_code_specialized		= specializeShader(1, &dummy_fs_code);
1713 	const char* fs_code_specialized_raw = fs_code_specialized.c_str();
1714 	std::string gs_code_specialized		= getGSCode();
1715 	const char* gs_code_specialized_raw = gs_code_specialized.c_str();
1716 	std::string vs_code_specialized		= specializeShader(1, &dummy_vs_code);
1717 	const char* vs_code_specialized_raw = vs_code_specialized.c_str();
1718 
1719 	if (TestCaseBase::buildProgram(m_po_id, m_gs_id, 1,					 /* n_sh1_body_parts */
1720 								   &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
1721 								   &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
1722 								   &fs_code_specialized_raw, &has_shader_compilation_failed))
1723 	{
1724 		m_testCtx.getLog() << tcu::TestLog::Message
1725 						   << "Program object was linked successfully, whereas a failure was expected."
1726 						   << tcu::TestLog::EndMessage;
1727 
1728 		result = false;
1729 	}
1730 
1731 	if (result)
1732 	{
1733 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1734 	}
1735 	else
1736 	{
1737 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1738 	}
1739 
1740 	return STOP;
1741 }
1742 
1743 /** Constructor
1744  *
1745  * @param context       Test context
1746  * @param extParams     Not used.
1747  * @param name          Test case's name
1748  * @param description   Test case's description
1749  **/
GeometryShaderMoreACBsInGSThanSupportedTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1750 GeometryShaderMoreACBsInGSThanSupportedTest::GeometryShaderMoreACBsInGSThanSupportedTest(Context&			  context,
1751 																						 const ExtParameters& extParams,
1752 																						 const char*		  name,
1753 																						 const char* description)
1754 	: TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_po_id(0), m_vs_id(0)
1755 {
1756 }
1757 
1758 /** Deinitializes GLES objects created during the test. */
deinit()1759 void GeometryShaderMoreACBsInGSThanSupportedTest::deinit()
1760 {
1761 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1762 
1763 	if (m_fs_id != 0)
1764 	{
1765 		gl.deleteShader(m_fs_id);
1766 
1767 		m_fs_id = 0;
1768 	}
1769 
1770 	if (m_gs_id != 0)
1771 	{
1772 		gl.deleteShader(m_gs_id);
1773 
1774 		m_gs_id = 0;
1775 	}
1776 
1777 	if (m_po_id != 0)
1778 	{
1779 		gl.deleteProgram(m_po_id);
1780 
1781 		m_po_id = 0;
1782 	}
1783 
1784 	if (m_vs_id != 0)
1785 	{
1786 		gl.deleteShader(m_vs_id);
1787 
1788 		m_vs_id = 0;
1789 	}
1790 
1791 	/* Release base class */
1792 	TestCaseBase::deinit();
1793 }
1794 
1795 /* Retrieves test-specific geometry shader source code.
1796  *
1797  * @return Requested string.
1798  */
getGSCode()1799 std::string GeometryShaderMoreACBsInGSThanSupportedTest::getGSCode()
1800 {
1801 	std::stringstream	 code_sstream;
1802 	const glw::Functions& gl				= m_context.getRenderContext().getFunctions();
1803 	glw::GLint			  gl_max_ACBs_value = 0;
1804 
1805 	/* Retrieve GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT pname value */
1806 	gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS, &gl_max_ACBs_value);
1807 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT pname");
1808 
1809 	/* Form the GS */
1810 	code_sstream << "${VERSION}\n"
1811 					"${GEOMETRY_SHADER_REQUIRE}\n"
1812 					"\n"
1813 					"layout (points)                   in;\n"
1814 					"layout (points, max_vertices = 1) out;\n"
1815 					"\n";
1816 
1817 	for (glw::GLint n_acb = 0; n_acb < (gl_max_ACBs_value + 1); ++n_acb)
1818 	{
1819 		code_sstream << "layout(binding = " << n_acb << ") uniform atomic_uint counter" << n_acb << ";\n";
1820 	}
1821 
1822 	code_sstream << "\n"
1823 					"void main()\n"
1824 					"{\n";
1825 
1826 	for (glw::GLint n_acb = 0; n_acb < (gl_max_ACBs_value + 1); ++n_acb)
1827 	{
1828 		code_sstream << "    if ((gl_PrimitiveIDIn % " << (n_acb + 1) << ") == 0) atomicCounterIncrement(counter"
1829 					 << n_acb << ");\n";
1830 	}
1831 
1832 	code_sstream << "\n"
1833 					"    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
1834 					"    EmitVertex();\n"
1835 					"}\n";
1836 
1837 	/* Form a specialized version of the GS source code */
1838 	std::string gs_code				= code_sstream.str();
1839 	const char* gs_code_raw			= gs_code.c_str();
1840 	std::string gs_code_specialized = specializeShader(1, /* parts */
1841 													   &gs_code_raw);
1842 
1843 	return gs_code_specialized;
1844 }
1845 
1846 /** Executes the test.
1847  *
1848  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1849  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1850  *  Note the function throws exception should an error occur!
1851  **/
iterate()1852 tcu::TestNode::IterateResult GeometryShaderMoreACBsInGSThanSupportedTest::iterate()
1853 {
1854 	bool has_shader_compilation_failed = true;
1855 	bool result						   = true;
1856 
1857 	/* This test should only run if EXT_geometry_shader is supported. */
1858 	if (!m_is_geometry_shader_extension_supported)
1859 	{
1860 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1861 	}
1862 
1863 	/* Create a program object */
1864 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1865 
1866 	m_po_id = gl.createProgram();
1867 
1868 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1869 
1870 	/* Create shader objects */
1871 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1872 	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1873 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1874 
1875 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
1876 
1877 	/* Try to link the test program object */
1878 	std::string fs_code_specialized		= specializeShader(1, &dummy_fs_code);
1879 	const char* fs_code_specialized_raw = fs_code_specialized.c_str();
1880 	std::string gs_code_specialized		= getGSCode();
1881 	const char* gs_code_specialized_raw = gs_code_specialized.c_str();
1882 	std::string vs_code_specialized		= specializeShader(1, &dummy_vs_code);
1883 	const char* vs_code_specialized_raw = vs_code_specialized.c_str();
1884 
1885 	if (TestCaseBase::buildProgram(m_po_id, m_gs_id, 1,					 /* n_sh1_body_parts */
1886 								   &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
1887 								   &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
1888 								   &fs_code_specialized_raw, &has_shader_compilation_failed))
1889 	{
1890 		m_testCtx.getLog() << tcu::TestLog::Message
1891 						   << "Program object was linked successfully, whereas a failure was expected."
1892 						   << tcu::TestLog::EndMessage;
1893 
1894 		result = false;
1895 	}
1896 
1897 	if (result)
1898 	{
1899 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1900 	}
1901 	else
1902 	{
1903 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1904 	}
1905 
1906 	return STOP;
1907 }
1908 
1909 /** Constructor
1910  *
1911  * @param context       Test context
1912  * @param extParams     Not used.
1913  * @param name          Test case's name
1914  * @param description   Test case's description
1915  **/
GeometryShaderCompilationFailTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1916 GeometryShaderCompilationFailTest::GeometryShaderCompilationFailTest(Context& context, const ExtParameters& extParams,
1917 																	 const char* name, const char* description)
1918 	: TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_po_id(0), m_vs_id(0)
1919 {
1920 }
1921 
1922 /** Deinitializes GLES objects created during the test. */
deinit()1923 void GeometryShaderCompilationFailTest::deinit()
1924 {
1925 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1926 
1927 	if (m_fs_id != 0)
1928 	{
1929 		gl.deleteShader(m_fs_id);
1930 
1931 		m_fs_id = 0;
1932 	}
1933 
1934 	if (m_gs_id != 0)
1935 	{
1936 		gl.deleteShader(m_gs_id);
1937 
1938 		m_gs_id = 0;
1939 	}
1940 
1941 	if (m_po_id != 0)
1942 	{
1943 		gl.deleteProgram(m_po_id);
1944 
1945 		m_po_id = 0;
1946 	}
1947 
1948 	if (m_vs_id != 0)
1949 	{
1950 		gl.deleteShader(m_vs_id);
1951 
1952 		m_vs_id = 0;
1953 	}
1954 
1955 	/* Release base class */
1956 	TestCaseBase::deinit();
1957 }
1958 
1959 /** Executes the test.
1960  *
1961  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1962  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1963  *  Note the function throws exception should an error occur!
1964  **/
iterate()1965 tcu::TestNode::IterateResult GeometryShaderCompilationFailTest::iterate()
1966 {
1967 	/* Define Vertex Shader's code for the purpose of this test. */
1968 	const char* gs_code = "${VERSION}\n"
1969 						  "${GEOMETRY_SHADER_REQUIRE}\n"
1970 						  "\n"
1971 						  "layout (points)                   in;\n"
1972 						  "layout (points, max_vertices = 1) out;\n"
1973 						  "\n"
1974 						  "void main()\n"
1975 						  "{\n"
1976 						  "    gl_Position = gl_in[0].gl_Position;\n"
1977 						  "    mitVertex();\n"
1978 						  "}\n";
1979 
1980 	bool has_shader_compilation_failed = true;
1981 	bool result						   = true;
1982 
1983 	/* This test should only run if EXT_geometry_shader is supported. */
1984 	if (!m_is_geometry_shader_extension_supported)
1985 	{
1986 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1987 	}
1988 
1989 	/* Create a program object */
1990 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1991 
1992 	m_po_id = gl.createProgram();
1993 
1994 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1995 
1996 	/* Create shader objects */
1997 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1998 	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1999 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
2000 
2001 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
2002 
2003 	/* Try to link the test program object */
2004 	std::string fs_code_specialized		= specializeShader(1, &dummy_fs_code);
2005 	const char* fs_code_specialized_raw = fs_code_specialized.c_str();
2006 
2007 	std::string gs_code_specialized		= specializeShader(1, &gs_code);
2008 	const char* gs_code_specialized_raw = gs_code_specialized.c_str();
2009 
2010 	std::string vs_code_specialized		= specializeShader(1, &dummy_vs_code);
2011 	const char* vs_code_specialized_raw = vs_code_specialized.c_str();
2012 
2013 	if (TestCaseBase::buildProgram(m_po_id, m_gs_id, 1,					 /* n_sh1_body_parts */
2014 								   &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
2015 								   &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
2016 								   &fs_code_specialized_raw, &has_shader_compilation_failed))
2017 	{
2018 		m_testCtx.getLog() << tcu::TestLog::Message
2019 						   << "Program object was linked successfully, whereas a failure was expected."
2020 						   << tcu::TestLog::EndMessage;
2021 
2022 		result = false;
2023 	}
2024 
2025 	if (!has_shader_compilation_failed)
2026 	{
2027 		m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation succeeded, whereas a failure was expected."
2028 						   << tcu::TestLog::EndMessage;
2029 
2030 		result = false;
2031 	}
2032 
2033 	if (result)
2034 	{
2035 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2036 	}
2037 	else
2038 	{
2039 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2040 	}
2041 
2042 	return STOP;
2043 }
2044 
2045 /** Constructor
2046  *
2047  * @param context       Test context
2048  * @param extParams     Not used.
2049  * @param name          Test case's name
2050  * @param description   Test case's description
2051  **/
GeometryShaderMoreInputVerticesThanAvailableTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)2052 GeometryShaderMoreInputVerticesThanAvailableTest::GeometryShaderMoreInputVerticesThanAvailableTest(
2053 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
2054 	: TestCaseBase(context, extParams, name, description)
2055 	, m_fs_id(0)
2056 	, m_gs_ids(NULL)
2057 	, m_number_of_gs(5 /*taken from test spec*/)
2058 	, m_po_ids(NULL)
2059 	, m_vs_id(0)
2060 	, m_vao_id(0)
2061 {
2062 }
2063 
2064 /** Deinitializes GLES objects created during the test. */
deinit()2065 void GeometryShaderMoreInputVerticesThanAvailableTest::deinit()
2066 {
2067 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2068 
2069 	if (m_fs_id != 0)
2070 	{
2071 		gl.deleteShader(m_fs_id);
2072 		m_fs_id = 0;
2073 	}
2074 
2075 	if (m_gs_ids != 0)
2076 	{
2077 		for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
2078 		{
2079 			gl.deleteShader(m_gs_ids[i]);
2080 			m_gs_ids[i] = 0;
2081 		}
2082 
2083 		delete[] m_gs_ids;
2084 		m_gs_ids = NULL;
2085 	}
2086 
2087 	if (m_po_ids != 0)
2088 	{
2089 		for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
2090 		{
2091 			gl.deleteProgram(m_po_ids[i]);
2092 			m_po_ids[i] = 0;
2093 		}
2094 
2095 		delete[] m_po_ids;
2096 		m_po_ids = NULL;
2097 	}
2098 
2099 	if (m_vs_id != 0)
2100 	{
2101 		gl.deleteShader(m_vs_id);
2102 		m_vs_id = 0;
2103 	}
2104 
2105 	if (m_vao_id != 0)
2106 	{
2107 		gl.deleteVertexArrays(1, &m_vao_id);
2108 		m_vao_id = 0;
2109 	}
2110 
2111 	/* Release base class */
2112 	TestCaseBase::deinit();
2113 }
2114 
2115 /** Executes the test.
2116  *
2117  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
2118  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
2119  *  Note the function throws exception should an error occur!
2120  **/
iterate()2121 tcu::TestNode::IterateResult GeometryShaderMoreInputVerticesThanAvailableTest::iterate()
2122 {
2123 	/* Define 5 Geometry Shaders for purpose of this test. */
2124 	const char* gs_code_points = "${VERSION}\n"
2125 								 "${GEOMETRY_SHADER_REQUIRE}\n"
2126 								 "\n"
2127 								 "layout (points)                   in;\n"
2128 								 "layout (points, max_vertices = 1) out;\n"
2129 								 "\n"
2130 								 "void main()\n"
2131 								 "{\n"
2132 								 "    gl_Position = gl_in[1].gl_Position;\n"
2133 								 "    EmitVertex();\n"
2134 								 "}\n";
2135 
2136 	const char* gs_code_lines = "${VERSION}\n"
2137 								"${GEOMETRY_SHADER_REQUIRE}\n"
2138 								"\n"
2139 								"layout (lines)                    in;\n"
2140 								"layout (points, max_vertices = 1) out;\n"
2141 								"\n"
2142 								"void main()\n"
2143 								"{\n"
2144 								"    gl_Position = gl_in[2].gl_Position;\n"
2145 								"    EmitVertex();\n"
2146 								"}\n";
2147 
2148 	const char* gs_code_lines_adjacency = "${VERSION}\n"
2149 										  "${GEOMETRY_SHADER_REQUIRE}\n"
2150 										  "\n"
2151 										  "layout (lines_adjacency)          in;\n"
2152 										  "layout (points, max_vertices = 1) out;\n"
2153 										  "\n"
2154 										  "void main()\n"
2155 										  "{\n"
2156 										  "    gl_Position = gl_in[4].gl_Position;\n"
2157 										  "    EmitVertex();\n"
2158 										  "}\n";
2159 
2160 	const char* gs_code_triangles = "${VERSION}\n"
2161 									"${GEOMETRY_SHADER_REQUIRE}\n"
2162 									"\n"
2163 									"layout (triangles)                in;\n"
2164 									"layout (points, max_vertices = 1) out;\n"
2165 									"\n"
2166 									"void main()\n"
2167 									"{\n"
2168 									"    gl_Position = gl_in[3].gl_Position;\n"
2169 									"    EmitVertex();\n"
2170 									"}\n";
2171 
2172 	const char* gs_code_triangles_adjacency = "${VERSION}\n"
2173 											  "${GEOMETRY_SHADER_REQUIRE}\n"
2174 											  "\n"
2175 											  "layout (triangles_adjacency)      in;\n"
2176 											  "layout (points, max_vertices = 1) out;\n"
2177 											  "\n"
2178 											  "void main()\n"
2179 											  "{\n"
2180 											  "    gl_Position = gl_in[6].gl_Position;\n"
2181 											  "    EmitVertex();\n"
2182 											  "}\n";
2183 
2184 	bool has_shader_compilation_failed = true;
2185 	bool result						   = true;
2186 
2187 	m_gs_ids = new glw::GLuint[m_number_of_gs];
2188 	m_po_ids = new glw::GLuint[m_number_of_gs];
2189 
2190 	/* This test should only run if EXT_geometry_shader is supported. */
2191 	if (!m_is_geometry_shader_extension_supported)
2192 	{
2193 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
2194 	}
2195 
2196 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2197 
2198 	/* Create program objects & geometry shader objects. */
2199 	for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
2200 	{
2201 		m_gs_ids[i] = gl.createShader(GL_GEOMETRY_SHADER);
2202 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
2203 
2204 		m_po_ids[i] = gl.createProgram();
2205 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
2206 	}
2207 
2208 	/* Create shader object. */
2209 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
2210 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
2211 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
2212 
2213 	/* Try to link the test program object */
2214 	std::string fs_code_specialized		= specializeShader(1, &dummy_fs_code);
2215 	const char* fs_code_specialized_raw = fs_code_specialized.c_str();
2216 
2217 	std::string gs_codes_specialized[] = { specializeShader(1, &gs_code_points), specializeShader(1, &gs_code_lines),
2218 										   specializeShader(1, &gs_code_lines_adjacency),
2219 										   specializeShader(1, &gs_code_triangles),
2220 										   specializeShader(1, &gs_code_triangles_adjacency) };
2221 
2222 	const char* gs_codes_specialized_raw[] = { gs_codes_specialized[0].c_str(), gs_codes_specialized[1].c_str(),
2223 											   gs_codes_specialized[2].c_str(), gs_codes_specialized[3].c_str(),
2224 											   gs_codes_specialized[4].c_str() };
2225 
2226 	std::string vs_code_specialized		= specializeShader(1, &dummy_vs_code);
2227 	const char* vs_code_specialized_raw = vs_code_specialized.c_str();
2228 
2229 	for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
2230 	{
2231 		if (TestCaseBase::buildProgram(m_po_ids[i], m_fs_id, 1,					 /* n_sh1_body_parts */
2232 									   &fs_code_specialized_raw, m_gs_ids[i], 1, /* n_sh2_body_parts */
2233 									   &gs_codes_specialized_raw[i], m_vs_id, 1, /* n_sh3_body_parts */
2234 									   &vs_code_specialized_raw, &has_shader_compilation_failed))
2235 		{
2236 			m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking successful for i = "
2237 							   << "[" << i << "], whereas a failure was expected." << tcu::TestLog::EndMessage;
2238 
2239 			result = false;
2240 			break;
2241 		}
2242 	}
2243 
2244 	if (result)
2245 	{
2246 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2247 	}
2248 	else
2249 	{
2250 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2251 	}
2252 
2253 	return STOP;
2254 }
2255 
2256 /** Constructor
2257  *
2258  * @param context       Test context
2259  * @param extParams     Not used.
2260  * @param name          Test case's name
2261  * @param description   Test case's description
2262  **/
2263 GeometryShaderTransformFeedbackVertexAndGeometryShaderCaptureTest::
GeometryShaderTransformFeedbackVertexAndGeometryShaderCaptureTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)2264 	GeometryShaderTransformFeedbackVertexAndGeometryShaderCaptureTest(Context& context, const ExtParameters& extParams,
2265 																	  const char* name, const char* description)
2266 	: TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_po_id(0), m_vs_id(0)
2267 {
2268 }
2269 
2270 /** Deinitializes GLES objects created during the test. */
deinit()2271 void GeometryShaderTransformFeedbackVertexAndGeometryShaderCaptureTest::deinit()
2272 {
2273 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2274 
2275 	if (m_fs_id != 0)
2276 	{
2277 		gl.deleteShader(m_fs_id);
2278 		m_fs_id = 0;
2279 	}
2280 
2281 	if (m_gs_id != 0)
2282 	{
2283 		gl.deleteShader(m_gs_id);
2284 		m_gs_id = 0;
2285 	}
2286 
2287 	if (m_po_id != 0)
2288 	{
2289 		gl.deleteProgram(m_po_id);
2290 		m_po_id = 0;
2291 	}
2292 
2293 	if (m_vs_id != 0)
2294 	{
2295 		gl.deleteShader(m_vs_id);
2296 		m_vs_id = 0;
2297 	}
2298 
2299 	/* Release base class */
2300 	TestCaseBase::deinit();
2301 }
2302 
2303 /** Executes the test.
2304  *
2305  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
2306  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
2307  *  Note the function throws exception should an error occur!
2308  **/
iterate()2309 tcu::TestNode::IterateResult GeometryShaderTransformFeedbackVertexAndGeometryShaderCaptureTest::iterate()
2310 {
2311 	/* Define Geometry Shader for purpose of this test. */
2312 	const char* gs_code =
2313 		"${VERSION}\n"
2314 		"${GEOMETRY_SHADER_REQUIRE}\n"
2315 		"\n"
2316 		"layout (points)                   in;\n"
2317 		"layout (points, max_vertices = 1) out;\n"
2318 		"\n"
2319 		"in int vertexID;\n"
2320 		"out vec4 out_gs_1;\n"
2321 		"\n"
2322 		"void main()\n"
2323 		"{\n"
2324 		"    out_gs_1 = vec4(vertexID[0] * 2, vertexID[0] * 2 + 1, vertexID[0] * 2 + 2, vertexID[0] * 2 + 3);\n"
2325 		"    gl_Position = vec4(0, 0, 0, 1);\n"
2326 		"    EmitVertex();\n"
2327 		"}\n";
2328 
2329 	/* Define Vertex Shader for purpose of this test. */
2330 	const char* vs_code = "${VERSION}\n"
2331 						  "\n"
2332 						  "flat out ivec4 out_vs_1;\n"
2333 						  "flat out int vertexID;\n"
2334 						  "\n"
2335 						  "void main()\n"
2336 						  "{\n"
2337 						  "    vertexID = gl_VertexID;\n"
2338 						  "    out_vs_1 = ivec4(gl_VertexID, gl_VertexID + 1, gl_VertexID + 2, gl_VertexID + 3);\n"
2339 						  "    gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
2340 						  "}\n";
2341 
2342 	bool has_shader_compilation_failed = true;
2343 	bool result						   = true;
2344 
2345 	/* This test should only run if EXT_geometry_shader is supported. */
2346 	if (!m_is_geometry_shader_extension_supported)
2347 	{
2348 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
2349 	}
2350 
2351 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2352 
2353 	/* Create program object. */
2354 	m_po_id = gl.createProgram();
2355 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed.");
2356 
2357 	/* Specify output variables to be captured. */
2358 	const char* tf_varyings[] = { "out_vs_1", "out_gs_1" };
2359 
2360 	gl.transformFeedbackVaryings(m_po_id, 2 /*count*/, tf_varyings, GL_INTERLEAVED_ATTRIBS);
2361 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call(s) failed.");
2362 
2363 	/* Create shader objects. */
2364 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
2365 	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
2366 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
2367 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
2368 
2369 	/* Try to link the test program object */
2370 	std::string fs_code_specialized		= specializeShader(1, &dummy_fs_code);
2371 	const char* fs_code_specialized_raw = fs_code_specialized.c_str();
2372 
2373 	std::string gs_code_specialized		= specializeShader(1, &gs_code);
2374 	const char* gs_code_specialized_raw = fs_code_specialized.c_str();
2375 
2376 	std::string vs_code_specialized		= specializeShader(1, &vs_code);
2377 	const char* vs_code_specialized_raw = vs_code_specialized.c_str();
2378 
2379 	if (TestCaseBase::buildProgram(m_po_id, m_fs_id, 1,					 /* n_sh1_body_parts */
2380 								   &fs_code_specialized_raw, m_gs_id, 1, /* n_sh2_body_parts */
2381 								   &gs_code_specialized_raw, m_vs_id, 1, /* n_sh3_body_parts */
2382 								   &vs_code_specialized_raw, &has_shader_compilation_failed))
2383 	{
2384 		m_testCtx.getLog() << tcu::TestLog::Message
2385 						   << "Program object linking successful, whereas a failure was expected."
2386 						   << tcu::TestLog::EndMessage;
2387 
2388 		result = false;
2389 	}
2390 
2391 	if (result)
2392 	{
2393 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2394 	}
2395 	else
2396 	{
2397 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2398 	}
2399 
2400 	return STOP;
2401 }
2402 
2403 } // namespace glcts
2404