• 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 
24 /**
25  */ /*!
26  * \file  gl3cCommonBugsTests.cpp
27  * \brief Short conformance tests which verify functionality which has either
28  *        been found to be broken on one publically available driver, or whose
29  *        behavior varies between vendors.
30  */ /*-------------------------------------------------------------------*/
31 
32 #include "gl3cCommonBugsTests.hpp"
33 #include "gluContextInfo.hpp"
34 #include "gluDefs.hpp"
35 #include "gluRenderContext.hpp"
36 #include "glwEnums.hpp"
37 #include "glwFunctions.hpp"
38 #include "tcuTestLog.hpp"
39 
40 #include <cstring>
41 #include <string>
42 #include <vector>
43 
44 #ifndef GL_SPARSE_BUFFER_PAGE_SIZE_ARB
45 #define GL_SPARSE_BUFFER_PAGE_SIZE_ARB 0x82F8
46 #endif
47 #ifndef GL_SPARSE_STORAGE_BIT_ARB
48 #define GL_SPARSE_STORAGE_BIT_ARB 0x0400
49 #endif
50 
51 namespace gl3cts
52 {
53 /** Constructor.
54  *
55  *  @param context     Rendering context
56  *  @param name        Test name
57  *  @param description Test description
58  */
GetProgramivActiveUniformBlockMaxNameLengthTest(deqp::Context & context)59 GetProgramivActiveUniformBlockMaxNameLengthTest::GetProgramivActiveUniformBlockMaxNameLengthTest(deqp::Context& context)
60 	: TestCase(context, "CommonBug_GetProgramivActiveUniformBlockMaxNameLength",
61 			   "Verifies GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH pname is recognized by glGetProgramiv()")
62 	, m_fs_id(0)
63 	, m_po_id(0)
64 	, m_vs_id(0)
65 {
66 	/* Left blank intentionally */
67 }
68 
69 /** Tears down any GL objects set up to run the test. */
deinit()70 void GetProgramivActiveUniformBlockMaxNameLengthTest::deinit()
71 {
72 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
73 
74 	if (m_fs_id != 0)
75 	{
76 		gl.deleteShader(m_fs_id);
77 
78 		m_fs_id = 0;
79 	}
80 
81 	if (m_po_id != 0)
82 	{
83 		gl.deleteProgram(m_po_id);
84 
85 		m_po_id = 0;
86 	}
87 
88 	if (m_vs_id != 0)
89 	{
90 		gl.deleteShader(m_vs_id);
91 
92 		m_vs_id = 0;
93 	}
94 }
95 
96 /** Stub init method */
init()97 void GetProgramivActiveUniformBlockMaxNameLengthTest::init()
98 {
99 	/* Nothing to do here */
100 }
101 
102 /** Initializes all GL objects required to run the test */
initTest()103 bool GetProgramivActiveUniformBlockMaxNameLengthTest::initTest()
104 {
105 	glw::GLint			  compile_status = false;
106 	const glw::Functions& gl			 = m_context.getRenderContext().getFunctions();
107 	glw::GLint			  link_status	= false;
108 	bool				  result		 = true;
109 
110 	const char* fs_body = "#version 140\n"
111 						  "\n"
112 						  "uniform data\n"
113 						  "{\n"
114 						  "    vec4 temp;\n"
115 						  "};\n"
116 						  "\n"
117 						  "out vec4 result;\n"
118 						  "\n"
119 						  "void main()\n"
120 						  "{\n"
121 						  "    result = temp;\n"
122 						  "}\n";
123 
124 	const char* vs_body = "#version 140\n"
125 						  "\n"
126 						  "uniform data2\n"
127 						  "{\n"
128 						  "    vec4 temp2;\n"
129 						  "};\n"
130 						  "\n"
131 						  "void main()\n"
132 						  "{\n"
133 						  "    gl_Position = temp2;\n"
134 						  "}\n";
135 
136 	m_po_id = gl.createProgram();
137 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
138 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
139 
140 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() / glCreateShader() call(s) failed.");
141 
142 	gl.attachShader(m_po_id, m_fs_id);
143 	gl.attachShader(m_po_id, m_vs_id);
144 
145 	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed.");
146 
147 	gl.shaderSource(m_fs_id, 1,			/* count */
148 					&fs_body, DE_NULL); /* length */
149 	gl.shaderSource(m_vs_id, 1,			/* count */
150 					&vs_body, DE_NULL); /* length */
151 
152 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call(s) failed.");
153 
154 	gl.compileShader(m_fs_id);
155 	gl.compileShader(m_vs_id);
156 
157 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call(s) failed.");
158 
159 	/* Have the shaders compiled successfully? */
160 	const glw::GLuint  shader_ids[] = { m_fs_id, m_vs_id };
161 	const unsigned int n_shader_ids = static_cast<unsigned int>(sizeof(shader_ids) / sizeof(shader_ids[0]));
162 
163 	for (unsigned int n_shader_id = 0; n_shader_id < n_shader_ids; ++n_shader_id)
164 	{
165 		gl.getShaderiv(shader_ids[n_shader_id], GL_COMPILE_STATUS, &compile_status);
166 
167 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
168 
169 		if (compile_status != GL_TRUE)
170 		{
171 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation failure"
172 												<< tcu::TestLog::EndMessage;
173 
174 			result = false;
175 			goto end;
176 		}
177 	} /* for (all shader IDs) */
178 
179 	/* Link the PO */
180 	gl.linkProgram(m_po_id);
181 
182 	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
183 
184 	gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
185 
186 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
187 
188 	if (link_status != GL_TRUE)
189 	{
190 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linking failure"
191 											<< tcu::TestLog::EndMessage;
192 
193 		result = false;
194 		goto end;
195 	}
196 
197 end:
198 	return result;
199 }
200 
201 /** Executes test iteration.
202  *
203  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
204  */
iterate()205 tcu::TestNode::IterateResult GetProgramivActiveUniformBlockMaxNameLengthTest::iterate()
206 {
207 	bool result = true;
208 
209 	/* Execute the query */
210 	glw::GLenum			  error_code			= GL_NO_ERROR;
211 	const glw::GLint	  expected_result_value = static_cast<glw::GLint>(strlen("data2") + 1 /* terminator */);
212 	const glw::Functions& gl					= m_context.getRenderContext().getFunctions();
213 	glw::GLint			  result_value			= 0;
214 
215 	/* Only execute if we're daeling with GL 3.1 or newer.. */
216 	if (!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 1)))
217 	{
218 		goto end;
219 	}
220 
221 	/* Set up the test program object */
222 	if (!initTest())
223 	{
224 		result = false;
225 
226 		goto end;
227 	}
228 
229 	gl.getProgramiv(m_po_id, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &result_value);
230 
231 	error_code = gl.getError();
232 
233 	if (error_code != GL_NO_ERROR)
234 	{
235 		m_testCtx.getLog() << tcu::TestLog::Message << "glGetIntegerv() generated error [" << error_code
236 						   << "] for GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH" << tcu::TestLog::EndMessage;
237 
238 		result = false;
239 	}
240 	else if (result_value != expected_result_value)
241 	{
242 		m_testCtx.getLog() << tcu::TestLog::Message << "glGetIntegerv() returned an invalid value of " << result_value
243 						   << " instead of the expected value of " << (strlen("data2") + 1 /* terminator */)
244 						   << " for the GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, "
245 							  "where the longest uniform block name is data2."
246 						   << tcu::TestLog::EndMessage;
247 
248 		result = false;
249 	}
250 end:
251 	m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
252 
253 	return STOP;
254 }
255 
256 /** Constructor.
257  *
258  *  @param context     Rendering context
259  *  @param name        Test name
260  *  @param description Test description
261  */
InputVariablesCannotBeModifiedTest(deqp::Context & context)262 InputVariablesCannotBeModifiedTest::InputVariablesCannotBeModifiedTest(deqp::Context& context)
263 	: TestCase(context, "CommonBug_InputVariablesCannotBeModified", "Verifies that input variables cannot be modified.")
264 	, m_fs_id(0)
265 	, m_gs_id(0)
266 	, m_tc_id(0)
267 	, m_te_id(0)
268 	, m_vs_id(0)
269 {
270 	/* Left blank on purpose */
271 }
272 
273 /** Deinitializes all GL objects created for the purpose of running the test,
274  *  as well as any client-side buffers allocated at initialization time
275  */
deinit()276 void InputVariablesCannotBeModifiedTest::deinit()
277 {
278 	const glw::Functions& gl		   = m_context.getRenderContext().getFunctions();
279 	glw::GLuint*		  so_id_ptrs[] = {
280 		&m_fs_id, &m_gs_id, &m_tc_id, &m_te_id, &m_vs_id,
281 	};
282 	const unsigned int n_so_id_ptrs = static_cast<unsigned int>(sizeof(so_id_ptrs) / sizeof(so_id_ptrs[0]));
283 
284 	for (unsigned int n_so_id_ptr = 0; n_so_id_ptr < n_so_id_ptrs; ++n_so_id_ptr)
285 	{
286 		gl.deleteShader(*so_id_ptrs[n_so_id_ptr]);
287 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteShader() call failed.");
288 
289 		*so_id_ptrs[n_so_id_ptr] = 0;
290 	} /* for (all created shader objects) */
291 }
292 
293 /** Empty init function */
init()294 void InputVariablesCannotBeModifiedTest::init()
295 {
296 	/* Left blank on purpose */
297 }
298 
299 /** Retrieves a literal corresponding to the test iteration enum.
300  *
301  *  @param iteration Enum to retrieve the string for.
302  *
303  *  @return Requested object.
304  **/
getIterationName(_test_iteration iteration) const305 std::string InputVariablesCannotBeModifiedTest::getIterationName(_test_iteration iteration) const
306 {
307 	std::string result;
308 
309 	switch (iteration)
310 	{
311 	case TEST_ITERATION_INPUT_FS_VARIABLE:
312 		result = "Fragment shader input variable";
313 		break;
314 	case TEST_ITERATION_INPUT_FS_VARIABLE_IN_INPUT_BLOCK:
315 		result = "Fragment shader input variable wrapped in an input block";
316 		break;
317 	case TEST_ITERATION_INPUT_FS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
318 		result = "Fragment shader input variable passed to an inout function parameter";
319 		break;
320 	case TEST_ITERATION_INPUT_FS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
321 		result = "Fragment shader input variable passed to an out function parameter";
322 		break;
323 	case TEST_ITERATION_INPUT_GS_VARIABLE:
324 		result = "Geometry shader input variable";
325 		break;
326 	case TEST_ITERATION_INPUT_GS_VARIABLE_IN_INPUT_BLOCK:
327 		result = "Geometry shader input variable wrapped in an input block";
328 		break;
329 	case TEST_ITERATION_INPUT_GS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
330 		result = "Geometry shader input variable passed to an inout function parameter";
331 		break;
332 	case TEST_ITERATION_INPUT_GS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
333 		result = "Geometry shader input variable passed to an out function parameter";
334 		break;
335 	case TEST_ITERATION_INPUT_TC_VARIABLE_IN_INPUT_BLOCK:
336 		result = "Tessellation control shader variable wrapped in an input block";
337 		break;
338 	case TEST_ITERATION_INPUT_TC_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
339 		result = "Tessellation control shader variable passed to an inout function parameter";
340 		break;
341 	case TEST_ITERATION_INPUT_TC_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
342 		result = "Tessellation control shader variable passed to an out function parameter";
343 		break;
344 	case TEST_ITERATION_INPUT_TE_PATCH_VARIABLE:
345 		result = "Tessellation evaluation shader patch input variable";
346 		break;
347 	case TEST_ITERATION_INPUT_TE_VARIABLE:
348 		result = "Tessellation evaluation shader input variable";
349 		break;
350 	case TEST_ITERATION_INPUT_TE_VARIABLE_IN_INPUT_BLOCK:
351 		result = "Tessellation evaluation shader patch input variable wrapped in an input block";
352 		break;
353 	case TEST_ITERATION_INPUT_TE_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
354 		result = "Tessellation evlauation shader patch input variable passed to an inout function parameter";
355 		break;
356 	case TEST_ITERATION_INPUT_TE_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
357 		result = "Tessellation evaluation shader patch input variable passed to an out function parameter";
358 		break;
359 	case TEST_ITERATION_INPUT_VS_VARIABLE:
360 		result = "Vertex shader input variable";
361 		break;
362 	case TEST_ITERATION_INPUT_VS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
363 		result = "Vertex shader input variable passed to an inout function parameter";
364 		break;
365 	case TEST_ITERATION_INPUT_VS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
366 		result = "Vertex shader input variable passed to an out function parameter";
367 		break;
368 
369 	default:
370 		TCU_FAIL("Unrecognized test iteration type.");
371 	} /* switch (iteration) */
372 
373 	return result;
374 }
375 
376 /** Retrieves a vertex shader body for the user-specified iteration enum.
377  *
378  *  @param iteration Iteration to retrieve the shader body for.
379  *
380  *  @return Requested string object.
381  */
getIterationData(_test_iteration iteration,glu::ApiType * out_required_min_context_type_ptr,_shader_stage * out_target_shader_stage_ptr,std::string * out_body_ptr) const382 void InputVariablesCannotBeModifiedTest::getIterationData(_test_iteration iteration,
383 														  glu::ApiType*   out_required_min_context_type_ptr,
384 														  _shader_stage*  out_target_shader_stage_ptr,
385 														  std::string*	out_body_ptr) const
386 {
387 	switch (iteration)
388 	{
389 	case TEST_ITERATION_INPUT_FS_VARIABLE:
390 	{
391 		*out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
392 		*out_target_shader_stage_ptr	   = SHADER_STAGE_FRAGMENT;
393 
394 		*out_body_ptr = "#version 140\n"
395 						"\n"
396 						"in  vec4 data;\n"
397 						"out vec4 result;\n"
398 						"\n"
399 						"void main()\n"
400 						"{\n"
401 						"    data   += vec4(1.0);\n"
402 						"    result  = data;\n"
403 						"}\n";
404 
405 		break;
406 	}
407 
408 	case TEST_ITERATION_INPUT_FS_VARIABLE_IN_INPUT_BLOCK:
409 	{
410 		*out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
411 		*out_target_shader_stage_ptr	   = SHADER_STAGE_FRAGMENT;
412 
413 		*out_body_ptr = "#version 400\n"
414 						"\n"
415 						"in inputBlock\n"
416 						"{\n"
417 						"    vec4 data;\n"
418 						"};\n"
419 						"\n"
420 						"out vec4 result;\n"
421 						"\n"
422 						"void main()\n"
423 						"{\n"
424 						"    data   += vec4(1.0);\n"
425 						"    result  = data;\n"
426 						"}\n";
427 
428 		break;
429 	}
430 
431 	case TEST_ITERATION_INPUT_FS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
432 	{
433 		*out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
434 		*out_target_shader_stage_ptr	   = SHADER_STAGE_FRAGMENT;
435 
436 		*out_body_ptr = "#version 140\n"
437 						"\n"
438 						"in  vec4 data;\n"
439 						"out vec4 result;\n"
440 						"\n"
441 						"void testFunc(inout vec4 arg)\n"
442 						"{\n"
443 						"    arg += vec4(1.0);\n"
444 						"}\n"
445 						"\n"
446 						"void main()\n"
447 						"{\n"
448 						"    testFunc(data);\n"
449 						"\n"
450 						"    result = data;\n"
451 						"}\n";
452 
453 		break;
454 	}
455 
456 	case TEST_ITERATION_INPUT_FS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
457 	{
458 		*out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
459 		*out_target_shader_stage_ptr	   = SHADER_STAGE_FRAGMENT;
460 
461 		*out_body_ptr = "#version 140\n"
462 						"\n"
463 						"in  vec4 data;\n"
464 						"out vec4 result;\n"
465 						"\n"
466 						"void testFunc(out vec4 arg)\n"
467 						"{\n"
468 						"    arg = vec4(1.0);\n"
469 						"}\n"
470 						"\n"
471 						"void main()\n"
472 						"{\n"
473 						"    testFunc(data);\n"
474 						"\n"
475 						"    result = data;\n"
476 						"}\n";
477 
478 		break;
479 	}
480 
481 	case TEST_ITERATION_INPUT_GS_VARIABLE:
482 	{
483 		*out_required_min_context_type_ptr = glu::ApiType::core(3, 2);
484 		*out_target_shader_stage_ptr	   = SHADER_STAGE_GEOMETRY;
485 
486 		*out_body_ptr = "#version 150\n"
487 						"\n"
488 						"layout(points)                   in;\n"
489 						"layout(points, max_vertices = 1) out;\n"
490 						"\n"
491 						"in vec4 data[];\n"
492 						"\n"
493 						"void main()\n"
494 						"{\n"
495 						"    data[0]     += vec4(1.0);\n"
496 						"    gl_Position  = data[0];\n"
497 						"\n"
498 						"    EmitVertex();\n"
499 						"}\n";
500 
501 		break;
502 	}
503 
504 	case TEST_ITERATION_INPUT_GS_VARIABLE_IN_INPUT_BLOCK:
505 	{
506 		*out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
507 		*out_target_shader_stage_ptr	   = SHADER_STAGE_GEOMETRY;
508 
509 		*out_body_ptr = "#version 400\n"
510 						"\n"
511 						"layout(points)                   in;\n"
512 						"layout(points, max_vertices = 1) out;\n"
513 						"\n"
514 						"in inputBlock\n"
515 						"{\n"
516 						"    vec4 data[];\n"
517 						"};\n"
518 						"\n"
519 						"void main()\n"
520 						"{\n"
521 						"    data[0]     += vec4(1.0);\n"
522 						"    gl_Position  = data[0];\n"
523 						"\n"
524 						"    EmitVertex();\n"
525 						"}\n";
526 
527 		break;
528 	}
529 
530 	case TEST_ITERATION_INPUT_GS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
531 	{
532 		*out_required_min_context_type_ptr = glu::ApiType::core(3, 2);
533 		*out_target_shader_stage_ptr	   = SHADER_STAGE_GEOMETRY;
534 
535 		*out_body_ptr = "#version 150\n"
536 						"\n"
537 						"layout(points)                   in;\n"
538 						"layout(points, max_vertices = 1) out;\n"
539 						"\n"
540 						"in vec4 data[];\n"
541 						"\n"
542 						"void testFunc(inout vec4 arg)\n"
543 						"{\n"
544 						"    arg += vec4(1.0);\n"
545 						"}\n"
546 						"\n"
547 						"void main()\n"
548 						"{\n"
549 						"    testFunc(data[0]);\n"
550 						"\n"
551 						"    gl_Position = data[0];\n"
552 						"\n"
553 						"    EmitVertex();\n"
554 						"}\n";
555 
556 		break;
557 	}
558 
559 	case TEST_ITERATION_INPUT_GS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
560 	{
561 		*out_required_min_context_type_ptr = glu::ApiType::core(3, 2);
562 		*out_target_shader_stage_ptr	   = SHADER_STAGE_GEOMETRY;
563 
564 		*out_body_ptr = "#version 150\n"
565 						"\n"
566 						"layout(points)                   in;\n"
567 						"layout(points, max_vertices = 1) out;\n"
568 						"\n"
569 						"in vec4 data[];\n"
570 						"\n"
571 						"void testFunc(out vec4 arg)\n"
572 						"{\n"
573 						"    arg = vec4(1.0);\n"
574 						"}\n"
575 						"\n"
576 						"void main()\n"
577 						"{\n"
578 						"    testFunc(data[0]);\n"
579 						"\n"
580 						"    gl_Position = data[0];\n"
581 						"\n"
582 						"    EmitVertex();\n"
583 						"}\n";
584 
585 		break;
586 	}
587 
588 	case TEST_ITERATION_INPUT_TC_VARIABLE:
589 	{
590 		*out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
591 		*out_target_shader_stage_ptr	   = SHADER_STAGE_TESSELLATION_CONTROL;
592 
593 		*out_body_ptr = "#version 400\n"
594 						"\n"
595 						"layout(vertices = 4) out;\n"
596 						"\n"
597 						"in  vec4 data[];\n"
598 						"out vec4 result;\n"
599 						"\n"
600 						"void main()\n"
601 						"{\n"
602 						"    data[0] += vec4(1.0);\n"
603 						"    result   = data[0];\n"
604 						"\n"
605 						"}\n";
606 
607 		break;
608 	}
609 
610 	case TEST_ITERATION_INPUT_TC_VARIABLE_IN_INPUT_BLOCK:
611 	{
612 		*out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
613 		*out_target_shader_stage_ptr	   = SHADER_STAGE_TESSELLATION_CONTROL;
614 
615 		*out_body_ptr = "#version 400\n"
616 						"\n"
617 						"layout(vertices = 4) out;\n"
618 						"\n"
619 						"in inputBlock\n"
620 						"{\n"
621 						"    vec4 data;\n"
622 						"} inData[];\n"
623 						"\n"
624 						"patch out vec4 result[];\n"
625 						"\n"
626 						"void main()\n"
627 						"{\n"
628 						"    inData[0].data          += vec4(1.0);\n"
629 						"    result[gl_InvocationID]  = inData[0].data;\n"
630 						"\n"
631 						"    gl_TessLevelInner[0] = 1.0;\n"
632 						"    gl_TessLevelInner[1] = 1.0;\n"
633 						"    gl_TessLevelOuter[0] = 1.0;\n"
634 						"    gl_TessLevelOuter[1] = 1.0;\n"
635 						"    gl_TessLevelOuter[2] = 1.0;\n"
636 						"    gl_TessLevelOuter[3] = 1.0;\n"
637 						"}\n";
638 
639 		break;
640 	}
641 
642 	case TEST_ITERATION_INPUT_TC_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
643 	{
644 		*out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
645 		*out_target_shader_stage_ptr	   = SHADER_STAGE_TESSELLATION_CONTROL;
646 
647 		*out_body_ptr = "#version 400\n"
648 						"\n"
649 						"layout(vertices = 4) out;\n"
650 						"\n"
651 						"in  vec4 data[];\n"
652 						"out vec4 result;\n"
653 						"\n"
654 						"void testFunc(inout vec4 arg)\n"
655 						"{\n"
656 						"    arg += vec4(1.0);\n"
657 						"}\n"
658 						"\n"
659 						"void main()\n"
660 						"{\n"
661 						"    testFunc(data[0]);\n"
662 						"\n"
663 						"    result = data[0];\n"
664 						"\n"
665 						"}\n";
666 
667 		break;
668 	}
669 
670 	case TEST_ITERATION_INPUT_TC_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
671 	{
672 		*out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
673 		*out_target_shader_stage_ptr	   = SHADER_STAGE_TESSELLATION_CONTROL;
674 
675 		*out_body_ptr = "#version 400\n"
676 						"\n"
677 						"layout(vertices = 4) out;\n"
678 						"\n"
679 						"in  vec4 data[];\n"
680 						"out vec4 result;\n"
681 						"\n"
682 						"void testFunc(out vec4 arg)\n"
683 						"{\n"
684 						"    arg = vec4(1.0);\n"
685 						"}\n"
686 						"\n"
687 						"void main()\n"
688 						"{\n"
689 						"    testFunc(data[0]);\n"
690 						"\n"
691 						"    result = data[0];\n"
692 						"\n"
693 						"}\n";
694 
695 		break;
696 	}
697 
698 	case TEST_ITERATION_INPUT_TE_PATCH_VARIABLE:
699 	case TEST_ITERATION_INPUT_TE_VARIABLE:
700 	{
701 		std::stringstream body_sstream;
702 
703 		*out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
704 		*out_target_shader_stage_ptr	   = SHADER_STAGE_TESSELLATION_EVALUATION;
705 
706 		body_sstream << "#version 400\n"
707 						"\n"
708 						"layout(triangles) in;\n"
709 						"\n"
710 					 << ((iteration == TEST_ITERATION_INPUT_TE_PATCH_VARIABLE) ? "patch " : "") << "in  vec4 data[];\n"
711 					 << "      out vec4 result;\n"
712 						"\n"
713 						"void main()\n"
714 						"{\n"
715 						"    data[0]     += vec4(1.0);\n"
716 						"    gl_Position  = data[0];\n"
717 						"}\n";
718 
719 		*out_body_ptr = body_sstream.str();
720 		break;
721 	}
722 
723 	case TEST_ITERATION_INPUT_TE_VARIABLE_IN_INPUT_BLOCK:
724 	{
725 		*out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
726 		*out_target_shader_stage_ptr	   = SHADER_STAGE_TESSELLATION_EVALUATION;
727 
728 		*out_body_ptr = "#version 400\n"
729 						"\n"
730 						"layout(triangles) in;\n"
731 						"\n"
732 						"in inputBlock\n"
733 						"{\n"
734 						"    vec4 data;\n"
735 						"} inData[];\n"
736 						"\n"
737 						"void main()\n"
738 						"{\n"
739 						"    inData[0].data += vec4(1.0);\n"
740 						"    gl_Position     = inData[0].data;\n"
741 						"}\n";
742 
743 		break;
744 	}
745 
746 	case TEST_ITERATION_INPUT_TE_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
747 	{
748 		*out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
749 		*out_target_shader_stage_ptr	   = SHADER_STAGE_TESSELLATION_EVALUATION;
750 
751 		*out_body_ptr = "#version 400\n"
752 						"\n"
753 						"layout(triangles) in;\n"
754 						"\n"
755 						"in  vec4 data[];\n"
756 						"out vec4 result;\n"
757 						"\n"
758 						"void testFunc(inout vec4 arg)\n"
759 						"{\n"
760 						"    arg += vec4(1.0);\n"
761 						"}\n"
762 						"\n"
763 						"void main()\n"
764 						"{\n"
765 						"    testFunc(data[0]);\n"
766 						"\n"
767 						"    gl_Position  = data[0];\n"
768 						"}\n";
769 
770 		break;
771 	}
772 
773 	case TEST_ITERATION_INPUT_TE_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
774 	{
775 		*out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
776 		*out_target_shader_stage_ptr	   = SHADER_STAGE_TESSELLATION_EVALUATION;
777 
778 		*out_body_ptr = "#version 400\n"
779 						"\n"
780 						"layout(triangles) in;\n"
781 						"\n"
782 						"in  vec4 data[];\n"
783 						"out vec4 result;\n"
784 						"\n"
785 						"void testFunc(out vec4 arg)\n"
786 						"{\n"
787 						"    arg = vec4(1.0);\n"
788 						"}\n"
789 						"\n"
790 						"void main()\n"
791 						"{\n"
792 						"    testFunc(data[0]);\n"
793 						"\n"
794 						"    gl_Position = data[0];\n"
795 						"}\n";
796 
797 		break;
798 	}
799 
800 	case TEST_ITERATION_INPUT_VS_VARIABLE:
801 	{
802 		*out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
803 		*out_target_shader_stage_ptr	   = SHADER_STAGE_VERTEX;
804 
805 		*out_body_ptr = "#version 140\n"
806 						"\n"
807 						"in vec4 data;\n"
808 						"\n"
809 						"void main()\n"
810 						"{\n"
811 						"    data        += vec4(1.0);\n"
812 						"    gl_Position  = data;\n"
813 						"}\n";
814 
815 		break;
816 	}
817 
818 	case TEST_ITERATION_INPUT_VS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
819 	{
820 		*out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
821 		*out_target_shader_stage_ptr	   = SHADER_STAGE_VERTEX;
822 
823 		*out_body_ptr = "#version 140\n"
824 						"\n"
825 						"in vec4 data;\n"
826 						"\n"
827 						"void testFunc(inout vec4 argument)\n"
828 						"{\n"
829 						"    argument += vec4(1.0);\n"
830 						"}\n"
831 						"\n"
832 						"void main()\n"
833 						"{\n"
834 						"    testFunc(data);\n"
835 						"\n"
836 						"    gl_Position = data;\n"
837 						"}\n";
838 
839 		break;
840 	}
841 
842 	case TEST_ITERATION_INPUT_VS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
843 	{
844 		*out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
845 		*out_target_shader_stage_ptr	   = SHADER_STAGE_VERTEX;
846 
847 		*out_body_ptr = "#version 140\n"
848 						"\n"
849 						"in vec4 data;\n"
850 						"\n"
851 						"void testFunc(out vec4 argument)\n"
852 						"{\n"
853 						"    argument = vec4(1.0);\n"
854 						"}\n"
855 						"\n"
856 						"void main()\n"
857 						"{\n"
858 						"    testFunc(data);\n"
859 						"\n"
860 						"    gl_Position = data;\n"
861 						"}\n";
862 
863 		break;
864 	}
865 
866 	default:
867 		TCU_FAIL("Unrecognized test iteration type");
868 	} /* switch (iteration) */
869 }
870 
871 /** Executes test iteration.
872  *
873  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
874  */
iterate()875 tcu::TestNode::IterateResult InputVariablesCannotBeModifiedTest::iterate()
876 {
877 	const glu::ContextType context_type = m_context.getRenderContext().getType();
878 	const glw::Functions&  gl			= m_context.getRenderContext().getFunctions();
879 	bool				   result		= true;
880 
881 	/* Create shader objects */
882 	if (glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
883 	{
884 		m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
885 	}
886 
887 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
888 	{
889 		m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
890 		m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
891 	}
892 
893 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
894 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
895 
896 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
897 
898 	/* Execute all test iterations.. */
899 	for (int current_iteration = static_cast<int>(TEST_ITERATION_FIRST);
900 		 current_iteration < static_cast<int>(TEST_ITERATION_COUNT); current_iteration++)
901 	{
902 		glw::GLint	compile_status = GL_FALSE;
903 		std::string   current_iteration_body;
904 		const char*   current_iteration_body_raw_ptr = NULL;
905 		glu::ApiType  current_iteration_min_context_type;
906 		_shader_stage current_iteration_shader_stage;
907 		glw::GLuint   so_id = 0;
908 
909 		getIterationData(static_cast<_test_iteration>(current_iteration), &current_iteration_min_context_type,
910 						 &current_iteration_shader_stage, &current_iteration_body);
911 
912 		current_iteration_body_raw_ptr = current_iteration_body.c_str();
913 
914 		/* Determine shader ID for the iteration. If the shader stage is not supported
915 		 * for the running context, skip it. */
916 		if (!glu::contextSupports(context_type, current_iteration_min_context_type))
917 		{
918 			continue;
919 		}
920 
921 		switch (current_iteration_shader_stage)
922 		{
923 		case SHADER_STAGE_FRAGMENT:
924 			so_id = m_fs_id;
925 			break;
926 		case SHADER_STAGE_GEOMETRY:
927 			so_id = m_gs_id;
928 			break;
929 		case SHADER_STAGE_TESSELLATION_CONTROL:
930 			so_id = m_tc_id;
931 			break;
932 		case SHADER_STAGE_TESSELLATION_EVALUATION:
933 			so_id = m_te_id;
934 			break;
935 		case SHADER_STAGE_VERTEX:
936 			so_id = m_vs_id;
937 			break;
938 
939 		default:
940 		{
941 			TCU_FAIL("Unrecognized shader stage type");
942 		}
943 		} /* switch (current_iteration_shader_stage) */
944 
945 		DE_ASSERT(so_id != 0);
946 
947 		/* Assign the source code to the SO */
948 		gl.shaderSource(so_id, 1,								   /* count */
949 						&current_iteration_body_raw_ptr, DE_NULL); /* length */
950 		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
951 
952 		/* Try to compile the shader object. */
953 		gl.compileShader(so_id);
954 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
955 
956 		gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
957 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
958 
959 		char temp[1024];
960 
961 		gl.getShaderInfoLog(so_id, 1024, NULL, temp);
962 
963 		if (compile_status == GL_TRUE)
964 		{
965 			m_testCtx.getLog() << tcu::TestLog::Message << "The following "
966 							   << getShaderStageName(current_iteration_shader_stage)
967 							   << " shader, used for test iteration ["
968 							   << getIterationName(static_cast<_test_iteration>(current_iteration))
969 							   << "] "
970 								  "was compiled successfully, even though it is invalid. Body:"
971 								  "\n>>\n"
972 							   << current_iteration_body << "\n<<\n"
973 							   << tcu::TestLog::EndMessage;
974 
975 			result = false;
976 		}
977 	} /* for (all test iterations) */
978 
979 	m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
980 
981 	return STOP;
982 }
983 
984 /** Returns a literal corresponding to the shader stage enum used by the test.
985  *
986  *  @param stage Shader stage to use for the query.
987  *
988  *  @return Requested string.
989  **/
getShaderStageName(_shader_stage stage) const990 std::string InputVariablesCannotBeModifiedTest::getShaderStageName(_shader_stage stage) const
991 {
992 	std::string result = "?!";
993 
994 	switch (stage)
995 	{
996 	case SHADER_STAGE_FRAGMENT:
997 		result = "fragment shader";
998 		break;
999 	case SHADER_STAGE_GEOMETRY:
1000 		result = "geometry shader";
1001 		break;
1002 	case SHADER_STAGE_TESSELLATION_CONTROL:
1003 		result = "tessellation control shader";
1004 		break;
1005 	case SHADER_STAGE_TESSELLATION_EVALUATION:
1006 		result = "tessellation evaluation shader";
1007 		break;
1008 	case SHADER_STAGE_VERTEX:
1009 		result = "vertex shader";
1010 		break;
1011 	} /* switch (stage) */
1012 
1013 	return result;
1014 }
1015 
1016 /** Constructor.
1017  *
1018  *  @param context     Rendering context
1019  *  @param name        Test name
1020  *  @param description Test description
1021  */
InvalidUseCasesForAllNotFuncsAndExclMarkOpTest(deqp::Context & context)1022 InvalidUseCasesForAllNotFuncsAndExclMarkOpTest::InvalidUseCasesForAllNotFuncsAndExclMarkOpTest(deqp::Context& context)
1023 	: deqp::TestCase(context, "CommonBug_InvalidUseCasesForAllNotFuncsAndExclMarkOp",
1024 					 "Verifies that ! operator does not accept bvec{2,3,4} arguments, "
1025 					 "all() and not() functions do not accept a bool argument.")
1026 	, m_vs_id(0)
1027 {
1028 	/* Left blank on purpose */
1029 }
1030 
1031 /** Deinitializes all GL objects created for the purpose of running the test,
1032  *  as well as any client-side buffers allocated at initialization time
1033  */
deinit()1034 void InvalidUseCasesForAllNotFuncsAndExclMarkOpTest::deinit()
1035 {
1036 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1037 
1038 	if (m_vs_id != 0)
1039 	{
1040 		gl.deleteShader(m_vs_id);
1041 
1042 		m_vs_id = 0;
1043 	}
1044 }
1045 
1046 /** Empty init function */
init()1047 void InvalidUseCasesForAllNotFuncsAndExclMarkOpTest::init()
1048 {
1049 	/* Left blank on purpose */
1050 }
1051 
1052 /** Retrieves a literal corresponding to the test iteration enum.
1053  *
1054  *  @param iteration Enum to retrieve the string for.
1055  *
1056  *  @return Requested object.
1057  **/
getIterationName(_test_iteration iteration) const1058 std::string InvalidUseCasesForAllNotFuncsAndExclMarkOpTest::getIterationName(_test_iteration iteration) const
1059 {
1060 	std::string result;
1061 
1062 	switch (iteration)
1063 	{
1064 	case TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC2:
1065 		result = "! operator must not accept bvec2 arg";
1066 		break;
1067 	case TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC3:
1068 		result = "! operator must not accept bvec3 arg";
1069 		break;
1070 	case TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC4:
1071 		result = "! operator must not accept bvec4 arg";
1072 		break;
1073 	case TEST_ITERATION_ALL_FUNC_MUST_NOT_ACCEPT_BOOL:
1074 		result = "all() function must not accept bool arg";
1075 		break;
1076 	case TEST_ITERATION_NOT_FUNC_MUST_NOT_ACCEPT_BOOL:
1077 		result = "not() function must not accept bool arg";
1078 		break;
1079 	default:
1080 	{
1081 		TCU_FAIL("Unrecognized test iteration type.");
1082 	}
1083 	} /* switch (iteration) */
1084 
1085 	return result;
1086 }
1087 
1088 /** Retrieves a vertex shader body for the user-specified iteration enum.
1089  *
1090  *  @param iteration Iteration to retrieve the shader body for.
1091  *
1092  *  @return Requested string object.
1093  */
getShaderBody(_test_iteration iteration) const1094 std::string InvalidUseCasesForAllNotFuncsAndExclMarkOpTest::getShaderBody(_test_iteration iteration) const
1095 {
1096 	std::string result;
1097 
1098 	switch (iteration)
1099 	{
1100 	case TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC2:
1101 	case TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC3:
1102 	case TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC4:
1103 	{
1104 		/* From GL SL spec:
1105 		 *
1106 		 * The logical unary operator not (!). It operates only on a Boolean expression and results in a Boolean
1107 		 * expression. To operate on a vector, use the built-in function not.
1108 		 */
1109 		std::stringstream result_sstream;
1110 		std::string		  type_string;
1111 
1112 		type_string = (iteration == TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC2) ?
1113 						  "bvec2" :
1114 						  (iteration == TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC3) ? "bvec3" : "bvec4";
1115 
1116 		result_sstream << "#version 140\n"
1117 						  "\n"
1118 						  "void main()\n"
1119 						  "{\n"
1120 						  "    if (!"
1121 					   << type_string << "(false))\n"
1122 										 "    {\n"
1123 										 "        gl_Position = vec4(1.0, 2.0, 3.0, 4.0);\n"
1124 										 "    }\n"
1125 										 "    else\n"
1126 										 "    {\n"
1127 										 "        gl_Position = vec4(2.0, 3.0, 4.0, 5.0);\n"
1128 										 "    }\n"
1129 										 "}\n";
1130 
1131 		result = result_sstream.str();
1132 		break;
1133 	}
1134 
1135 	case TEST_ITERATION_ALL_FUNC_MUST_NOT_ACCEPT_BOOL:
1136 	case TEST_ITERATION_NOT_FUNC_MUST_NOT_ACCEPT_BOOL:
1137 	{
1138 		std::string		  op_string;
1139 		std::stringstream result_sstream;
1140 
1141 		/* From GLSL spec, all() and not() functions are defined as:
1142 		 *
1143 		 * bool all(bvec x)
1144 		 * bvec not(bvec x)
1145 		 *
1146 		 * where bvec is bvec2, bvec3 or bvec4.
1147 		 */
1148 		op_string = (iteration == TEST_ITERATION_ALL_FUNC_MUST_NOT_ACCEPT_BOOL) ? "all" : "not";
1149 
1150 		result_sstream << "#version 140\n"
1151 						  "\n"
1152 						  "void main()\n"
1153 						  "{\n"
1154 						  "    gl_Position = vec4("
1155 					   << op_string << "(false, true) ? 1.0 : 2.0);\n"
1156 									   "}\n";
1157 
1158 		result = result_sstream.str();
1159 		break;
1160 	}
1161 
1162 	default:
1163 		TCU_FAIL("Unrecognized test iteration type");
1164 	} /* switch (iteration) */
1165 
1166 	return result;
1167 }
1168 
1169 /** Executes test iteration.
1170  *
1171  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1172  */
iterate()1173 tcu::TestNode::IterateResult InvalidUseCasesForAllNotFuncsAndExclMarkOpTest::iterate()
1174 {
1175 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
1176 	bool				  result = true;
1177 
1178 	/* Create a vertex shader object */
1179 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1180 
1181 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
1182 
1183 	/* Execute all test iterations.. */
1184 	for (int current_iteration = static_cast<int>(TEST_ITERATION_FIRST);
1185 		 current_iteration < static_cast<int>(TEST_ITERATION_COUNT); ++current_iteration)
1186 	{
1187 		const std::string body			 = getShaderBody(static_cast<_test_iteration>(current_iteration));
1188 		const char*		  body_raw_ptr   = body.c_str();
1189 		glw::GLint		  compile_status = GL_FALSE;
1190 
1191 		/* Assign the source code to the SO */
1192 		gl.shaderSource(m_vs_id, 1,				 /* count */
1193 						&body_raw_ptr, DE_NULL); /* length */
1194 		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
1195 
1196 		/* Try to compile the shader object. */
1197 		gl.compileShader(m_vs_id);
1198 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
1199 
1200 		gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
1201 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
1202 
1203 		if (compile_status == GL_TRUE)
1204 		{
1205 			m_testCtx.getLog() << tcu::TestLog::Message << "The following vertex shader, used for test iteration ["
1206 							   << getIterationName(static_cast<_test_iteration>(current_iteration))
1207 							   << "] "
1208 								  "was compiled successfully, even though it is invalid. Body:"
1209 								  "\n>>\n"
1210 							   << body << "\n<<\n"
1211 							   << tcu::TestLog::EndMessage;
1212 
1213 			result = false;
1214 		}
1215 	} /* for (all test iterations) */
1216 
1217 	m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
1218 
1219 	return STOP;
1220 }
1221 
InvalidVSInputsTest(deqp::Context & context)1222 InvalidVSInputsTest::InvalidVSInputsTest(deqp::Context& context)
1223 	: TestCase(context, "CommonBug_InvalidVSInputs",
1224 			   "Verifies that invalid types, as well as incompatible qualifiers, are "
1225 			   "not accepted for vertex shader input variable declarations")
1226 	, m_vs_id(0)
1227 {
1228 	/* Left blank on purpose */
1229 }
1230 
1231 /** Deinitializes all GL objects created for the purpose of running the test,
1232  *  as well as any client-side buffers allocated at initialization time
1233  */
deinit()1234 void InvalidVSInputsTest::deinit()
1235 {
1236 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1237 
1238 	if (m_vs_id != 0)
1239 	{
1240 		gl.deleteShader(m_vs_id);
1241 
1242 		m_vs_id = 0;
1243 	}
1244 }
1245 
1246 /** Empty init function */
init()1247 void InvalidVSInputsTest::init()
1248 {
1249 	/* Left blank on purpose */
1250 }
1251 
1252 /** Retrieves a literal corresponding to the test iteration enum.
1253  *
1254  *  @param iteration Enum to retrieve the string for.
1255  *
1256  *  @return Requested object.
1257  **/
getIterationName(_test_iteration iteration) const1258 std::string InvalidVSInputsTest::getIterationName(_test_iteration iteration) const
1259 {
1260 	std::string result;
1261 
1262 	switch (iteration)
1263 	{
1264 	case TEST_ITERATION_INVALID_BOOL_INPUT:
1265 		result = "Invalid bool input";
1266 		break;
1267 	case TEST_ITERATION_INVALID_BVEC2_INPUT:
1268 		result = "Invalid bvec2 input";
1269 		break;
1270 	case TEST_ITERATION_INVALID_BVEC3_INPUT:
1271 		result = "Invalid bvec3 input";
1272 		break;
1273 	case TEST_ITERATION_INVALID_BVEC4_INPUT:
1274 		result = "Invalid bvec4 input";
1275 		break;
1276 	case TEST_ITERATION_INVALID_CENTROID_QUALIFIED_INPUT:
1277 		result = "Invalid centroid-qualified input";
1278 		break;
1279 	case TEST_ITERATION_INVALID_PATCH_QUALIFIED_INPUT:
1280 		result = "Invalid patch-qualified input";
1281 		break;
1282 	case TEST_ITERATION_INVALID_OPAQUE_TYPE_INPUT:
1283 		result = "Invalid opaque type input";
1284 		break;
1285 	case TEST_ITERATION_INVALID_STRUCTURE_INPUT:
1286 		result = "Invalid structure input";
1287 		break;
1288 	case TEST_ITERATION_INVALID_SAMPLE_QUALIFIED_INPUT:
1289 		result = "Invalid sample-qualified input";
1290 		break;
1291 
1292 	default:
1293 		TCU_FAIL("Unrecognized test iteration type.");
1294 	} /* switch (iteration) */
1295 
1296 	return result;
1297 }
1298 
1299 /** Retrieves a vertex shader body for the user-specified iteration enum.
1300  *
1301  *  @param iteration Iteration to retrieve the shader body for.
1302  *
1303  *  @return Requested string object.
1304  */
getShaderBody(_test_iteration iteration) const1305 std::string InvalidVSInputsTest::getShaderBody(_test_iteration iteration) const
1306 {
1307 	std::string result;
1308 
1309 	switch (iteration)
1310 	{
1311 	case TEST_ITERATION_INVALID_BOOL_INPUT:
1312 	case TEST_ITERATION_INVALID_BVEC2_INPUT:
1313 	case TEST_ITERATION_INVALID_BVEC3_INPUT:
1314 	case TEST_ITERATION_INVALID_BVEC4_INPUT:
1315 	{
1316 		std::stringstream body_sstream;
1317 		const char*		  type = (iteration == TEST_ITERATION_INVALID_BOOL_INPUT) ?
1318 							   "bool" :
1319 							   (iteration == TEST_ITERATION_INVALID_BVEC2_INPUT) ?
1320 							   "bvec2" :
1321 							   (iteration == TEST_ITERATION_INVALID_BVEC3_INPUT) ? "bvec3" : "bvec4";
1322 
1323 		body_sstream << "#version 140\n"
1324 						"\n"
1325 						"in "
1326 					 << type << " data;\n"
1327 								"\n"
1328 								"void main()\n"
1329 								"{\n"
1330 								"}\n";
1331 
1332 		result = body_sstream.str();
1333 		break;
1334 	}
1335 
1336 	case TEST_ITERATION_INVALID_OPAQUE_TYPE_INPUT:
1337 	{
1338 		result = "#version 140\n"
1339 				 "\n"
1340 				 "in sampler2D data;\n"
1341 				 "\n"
1342 				 "void main()\n"
1343 				 "{\n"
1344 				 "}\n";
1345 
1346 		break;
1347 	}
1348 
1349 	case TEST_ITERATION_INVALID_STRUCTURE_INPUT:
1350 	{
1351 		result = "#version 140\n"
1352 				 "\n"
1353 				 "in struct\n"
1354 				 "{\n"
1355 				 "    vec4 test;\n"
1356 				 "} data;\n"
1357 				 "\n"
1358 				 "void main()\n"
1359 				 "{\n"
1360 				 "}\n";
1361 
1362 		break;
1363 	}
1364 
1365 	case TEST_ITERATION_INVALID_CENTROID_QUALIFIED_INPUT:
1366 	case TEST_ITERATION_INVALID_PATCH_QUALIFIED_INPUT:
1367 	case TEST_ITERATION_INVALID_SAMPLE_QUALIFIED_INPUT:
1368 	{
1369 		std::stringstream body_sstream;
1370 		const char*		  qualifier = (iteration == TEST_ITERATION_INVALID_CENTROID_QUALIFIED_INPUT) ?
1371 									"centroid" :
1372 									(iteration == TEST_ITERATION_INVALID_PATCH_QUALIFIED_INPUT) ? "patch" : "sample";
1373 
1374 		body_sstream << "#version 140\n"
1375 						"\n"
1376 					 << qualifier << " in vec4 data;\n"
1377 									 "\n"
1378 									 "void main()\n"
1379 									 "{\n"
1380 									 "}\n";
1381 
1382 		result = body_sstream.str();
1383 		break;
1384 	}
1385 
1386 	default:
1387 		TCU_FAIL("Unrecognized test iteration type");
1388 	} /* switch (iteration) */
1389 
1390 	return result;
1391 }
1392 
1393 /** Executes test iteration.
1394  *
1395  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1396  */
iterate()1397 tcu::TestNode::IterateResult InvalidVSInputsTest::iterate()
1398 {
1399 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
1400 	bool				  result = true;
1401 
1402 	/* Create a vertex shader object */
1403 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1404 
1405 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
1406 
1407 	/* Execute all test iterations.. */
1408 	for (int current_iteration = static_cast<int>(TEST_ITERATION_FIRST);
1409 		 current_iteration < static_cast<int>(TEST_ITERATION_COUNT); current_iteration++)
1410 	{
1411 		const std::string body			 = getShaderBody(static_cast<_test_iteration>(current_iteration));
1412 		const char*		  body_raw_ptr   = body.c_str();
1413 		glw::GLint		  compile_status = GL_FALSE;
1414 
1415 		/* Assign the source code to the SO */
1416 		gl.shaderSource(m_vs_id, 1,				 /* count */
1417 						&body_raw_ptr, DE_NULL); /* length */
1418 		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
1419 
1420 		/* Try to compile the shader object. */
1421 		gl.compileShader(m_vs_id);
1422 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
1423 
1424 		gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
1425 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
1426 
1427 		if (compile_status == GL_TRUE)
1428 		{
1429 			m_testCtx.getLog() << tcu::TestLog::Message << "The following vertex shader, used for test iteration ["
1430 							   << getIterationName(static_cast<_test_iteration>(current_iteration))
1431 							   << "] "
1432 								  "was compiled successfully, even though it is invalid. Body:"
1433 								  "\n>>\n"
1434 							   << body << "\n<<\n"
1435 							   << tcu::TestLog::EndMessage;
1436 
1437 			result = false;
1438 		}
1439 	} /* for (all test iterations) */
1440 
1441 	m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
1442 
1443 	return STOP;
1444 }
1445 
1446 /** Constructor.
1447  *
1448  *  @param context     Rendering context
1449  *  @param name        Test name
1450  *  @param description Test description
1451  */
ParenthesisInLayoutQualifierIntegerValuesTest(deqp::Context & context)1452 ParenthesisInLayoutQualifierIntegerValuesTest::ParenthesisInLayoutQualifierIntegerValuesTest(deqp::Context& context)
1453 	: TestCase(context, "CommonBug_ParenthesisInLayoutQualifierIntegerValue",
1454 			   "Verifies parenthesis are not accepted in compute shaders, prior to GL4.4, "
1455 			   "unless GL_ARB_enhanced_layouts is supported.")
1456 	, m_cs_id(0)
1457 	, m_po_id(0)
1458 {
1459 	/* Left blank on purpose */
1460 }
1461 
1462 /** Deinitializes all GL objects created for the purpose of running the test,
1463  *  as well as any client-side buffers allocated at initialization time
1464  */
deinit()1465 void ParenthesisInLayoutQualifierIntegerValuesTest::deinit()
1466 {
1467 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1468 
1469 	if (m_cs_id != 0)
1470 	{
1471 		gl.deleteShader(m_cs_id);
1472 
1473 		m_cs_id = 0;
1474 	}
1475 
1476 	if (m_po_id != 0)
1477 	{
1478 		gl.deleteProgram(m_po_id);
1479 
1480 		m_po_id = 0;
1481 	}
1482 }
1483 
1484 /** Empty init function */
init()1485 void ParenthesisInLayoutQualifierIntegerValuesTest::init()
1486 {
1487 	/* Left blank on purpose */
1488 }
1489 
1490 /** Executes test iteration.
1491  *
1492  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1493  */
iterate()1494 tcu::TestNode::IterateResult ParenthesisInLayoutQualifierIntegerValuesTest::iterate()
1495 {
1496 	/* Only execute the test on implementations supporting GL_ARB_compute_shader */
1497 	const glu::ContextType context_type = m_context.getRenderContext().getType();
1498 	const glw::Functions&  gl			= m_context.getRenderContext().getFunctions();
1499 	bool				   result		= true;
1500 
1501 	glw::GLint link_status		= GL_TRUE;
1502 	glw::GLint compile_status   = GL_TRUE;
1503 	bool	   expected_outcome = glu::contextSupports(context_type, glu::ApiType::core(4, 4));
1504 
1505 	/* Prepare a compute shader program */
1506 	static const char* cs_body_core = "\n"
1507 									  "layout(local_size_x = (4) ) in;\n"
1508 									  "\n"
1509 									  "void main()\n"
1510 									  "{\n"
1511 									  "}\n";
1512 
1513 	const char* cs_body_parts[] = { (!glu::contextSupports(context_type, glu::ApiType::core(4, 3))) ?
1514 										"#version 420 core\n"
1515 										"#extension GL_ARB_compute_shader : enable\n" :
1516 										(!glu::contextSupports(context_type, glu::ApiType::core(4, 4))) ?
1517 										"#version 430 core\n" :
1518 										"#version 440 core\n",
1519 									cs_body_core };
1520 	const unsigned int n_cs_body_parts =
1521 		static_cast<unsigned int>(sizeof(cs_body_parts) / sizeof(cs_body_parts[0]));
1522 
1523 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader"))
1524 	{
1525 		goto end;
1526 	}
1527 
1528 	m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
1529 	m_po_id = gl.createProgram();
1530 
1531 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() and/or glCraeteProgram() call(s) failed.");
1532 
1533 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1534 
1535 	gl.shaderSource(m_cs_id, n_cs_body_parts, cs_body_parts, DE_NULL); /* length */
1536 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
1537 
1538 	/* Try to compile the shader object.
1539 	 *
1540 	 * For GL contexts BEFORE 4.40, the test passes if either
1541 	 * the compilation or the linking process fails.
1542 	 *
1543 	 * For GL contexts OF VERSION 4.40 or newer, the test passes
1544 	 * if both the compilation and the linking process succeed.
1545 	 *
1546 	 * If GL_ARB_enhanced_layouts is supported, the latter holds for <= GL4.4 contexts.
1547 	 **/
1548 	if (m_context.getContextInfo().isExtensionSupported("GL_ARB_enhanced_layouts"))
1549 	{
1550 		expected_outcome = true;
1551 	}
1552 
1553 	gl.compileShader(m_cs_id);
1554 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
1555 
1556 	gl.getShaderiv(m_cs_id, GL_COMPILE_STATUS, &compile_status);
1557 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
1558 
1559 	if (compile_status == GL_FALSE && !expected_outcome)
1560 	{
1561 		goto end;
1562 	}
1563 
1564 	gl.attachShader(m_po_id, m_cs_id);
1565 	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
1566 
1567 	gl.linkProgram(m_po_id);
1568 	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
1569 
1570 	gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
1571 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
1572 
1573 	if (link_status == GL_FALSE && !expected_outcome)
1574 	{
1575 		goto end;
1576 	}
1577 
1578 	if (expected_outcome && (compile_status == GL_FALSE || link_status == GL_FALSE))
1579 	{
1580 		m_testCtx.getLog() << tcu::TestLog::Message
1581 						   << "A compute program was expected to link successfully, but either the "
1582 							  "compilation and/or linking process has/have failed"
1583 						   << tcu::TestLog::EndMessage;
1584 
1585 		result = false;
1586 	}
1587 	else if (!expected_outcome && (compile_status == GL_TRUE && link_status == GL_TRUE))
1588 	{
1589 		m_testCtx.getLog() << tcu::TestLog::Message
1590 						   << "A compute program was expected not to compile and link, but both processes "
1591 							  "have been executed successfully."
1592 						   << tcu::TestLog::EndMessage;
1593 
1594 		result = false;
1595 	}
1596 
1597 end:
1598 	m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
1599 
1600 	return STOP;
1601 }
1602 
1603 /** Constructor.
1604  *
1605  *  @param context     Rendering context
1606  *  @param name        Test name
1607  *  @param description Test description
1608  */
PerVertexValidationTest(deqp::Context & context)1609 PerVertexValidationTest::PerVertexValidationTest(deqp::Context& context)
1610 	: TestCase(context, "CommonBug_PerVertexValidation",
1611 			   "Conformance test which verifies that various requirements regarding gl_PerVertex block re-declarations,"
1612 			   " as described by the spec, are followed by the implementation")
1613 	, m_fs_id(0)
1614 	, m_fs_po_id(0)
1615 	, m_gs_id(0)
1616 	, m_gs_po_id(0)
1617 	, m_pipeline_id(0)
1618 	, m_tc_id(0)
1619 	, m_tc_po_id(0)
1620 	, m_te_id(0)
1621 	, m_te_po_id(0)
1622 	, m_vs_id(0)
1623 	, m_vs_po_id(0)
1624 {
1625 	/* Left blank on purpose */
1626 }
1627 
1628 /** Deinitializes all GL objects created for the purpose of running the test,
1629  *  as well as any client-side buffers allocated at initialization time
1630  */
deinit()1631 void PerVertexValidationTest::deinit()
1632 {
1633 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1634 
1635 	/* Release the pipeline object */
1636 	if (m_pipeline_id != 0)
1637 	{
1638 		gl.deleteProgramPipelines(1, &m_pipeline_id);
1639 
1640 		m_pipeline_id = 0;
1641 	}
1642 
1643 	/* Release all dangling shader and shader program objects */
1644 	destroyPOsAndSOs();
1645 }
1646 
1647 /** Releases any allocated program and shader objects. */
destroyPOsAndSOs()1648 void PerVertexValidationTest::destroyPOsAndSOs()
1649 {
1650 	const glw::Functions& gl		   = m_context.getRenderContext().getFunctions();
1651 	glw::GLuint*		  po_id_ptrs[] = { &m_fs_po_id, &m_gs_po_id, &m_tc_po_id, &m_te_po_id, &m_vs_po_id };
1652 	glw::GLuint*		  so_id_ptrs[] = { &m_fs_id, &m_gs_id, &m_tc_id, &m_te_id, &m_vs_id };
1653 	const unsigned int	n_po_id_ptrs = static_cast<unsigned int>(sizeof(po_id_ptrs) / sizeof(po_id_ptrs[0]));
1654 	const unsigned int	n_so_id_ptrs = static_cast<unsigned int>(sizeof(so_id_ptrs) / sizeof(so_id_ptrs[0]));
1655 
1656 	for (unsigned int n_po_id = 0; n_po_id < n_po_id_ptrs; ++n_po_id)
1657 	{
1658 		glw::GLuint* po_id_ptr = po_id_ptrs[n_po_id];
1659 
1660 		if (*po_id_ptr != 0)
1661 		{
1662 			gl.deleteProgram(*po_id_ptr);
1663 
1664 			*po_id_ptr = 0;
1665 		}
1666 	} /* for (all shader program object ids) */
1667 
1668 	for (unsigned int n_so_id = 0; n_so_id < n_so_id_ptrs; ++n_so_id)
1669 	{
1670 		glw::GLuint* so_id_ptr = so_id_ptrs[n_so_id];
1671 
1672 		if (*so_id_ptr != 0)
1673 		{
1674 			gl.deleteShader(*so_id_ptr);
1675 
1676 			*so_id_ptr = 0;
1677 		}
1678 	} /* for (all shader object ids) */
1679 }
1680 
1681 /** Tells whether the program pipeline validation process should fail for specified test iteration.
1682  *
1683  *  @return VALIDATION_RESULT_TRUE if the pipeline validation process should be positive,
1684  *          VALIDATION_RESULT_FALSE if the validation should be negative
1685  *          VALIDATION_RESULT_UNDEFINED when the validation result is not defined */
getProgramPipelineValidationExpectedResult(void) const1686 PerVertexValidationTest::_validation PerVertexValidationTest::getProgramPipelineValidationExpectedResult(void) const
1687 {
1688 	/** All "undeclared in.." and "undeclared out.." test shaders are expected not to link successfully
1689 	 *  when used as separate programs - which leaves pipeline in undefined state.
1690 	 *  All "declaration mismatch" shaders should link, but the results are undefined.
1691 	 *
1692 	 *  Currently the test does not exercise any defined case
1693 	 */
1694 	return VALIDATION_RESULT_UNDEFINED;
1695 }
1696 
1697 /** Returns a literal corresponding to the shader stage enum.
1698  *
1699  *  @param shader_stage Enum to return the string for.
1700  *
1701  *  @return As per description.
1702  */
getShaderStageName(_shader_stage shader_stage) const1703 std::string PerVertexValidationTest::getShaderStageName(_shader_stage shader_stage) const
1704 {
1705 	std::string result = "?!";
1706 
1707 	switch (shader_stage)
1708 	{
1709 	case SHADER_STAGE_FRAGMENT:
1710 		result = "fragment shader";
1711 		break;
1712 	case SHADER_STAGE_GEOMETRY:
1713 		result = "geometry shader";
1714 		break;
1715 	case SHADER_STAGE_TESSELLATION_CONTROL:
1716 		result = "tessellation control shader";
1717 		break;
1718 	case SHADER_STAGE_TESSELLATION_EVALUATION:
1719 		result = "tessellation evaluation shader";
1720 		break;
1721 	case SHADER_STAGE_VERTEX:
1722 		result = "vertex shader";
1723 		break;
1724 	}
1725 
1726 	return result;
1727 }
1728 
1729 /** Returns a literal corresponding to the test iteration enum.
1730  *
1731  *  @param iteration Enum to return the string for.
1732  *
1733  *  @return As per description.
1734  **/
getTestIterationName(_test_iteration iteration) const1735 std::string PerVertexValidationTest::getTestIterationName(_test_iteration iteration) const
1736 {
1737 	std::string result = "?!";
1738 
1739 	switch (iteration)
1740 	{
1741 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE:
1742 		result = "Input gl_ClipDistance usage in Geometry Shader without gl_PerVertex block redeclaration";
1743 		break;
1744 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CULLDISTANCE_USAGE:
1745 		result = "Input gl_CullDistance usage in Geometry Shader without gl_PerVertex block redeclaration";
1746 		break;
1747 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POINTSIZE_USAGE:
1748 		result = "Input gl_PointSize usage in a separable Geometry Shader without gl_PerVertex block redeclaration";
1749 		break;
1750 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POSITION_USAGE:
1751 		result = "Input gl_Position usage in a separable Geometry Shader without gl_PerVertex block redeclaration";
1752 		break;
1753 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE:
1754 		result = "Input gl_ClipDistance usage in a separable Tessellation Control Shader without gl_PerVertex block "
1755 				 "redeclaration";
1756 		break;
1757 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CULLDISTANCE_USAGE:
1758 		result = "Input gl_CullDistance usage in a separable Tessellation Control Shader without gl_PerVertex block "
1759 				 "redeclaration";
1760 		break;
1761 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POINTSIZE_USAGE:
1762 		result = "Input gl_PointSize usage in a separable Tessellation Control Shader without gl_PerVertex block "
1763 				 "redeclaration";
1764 		break;
1765 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POSITION_USAGE:
1766 		result = "Input gl_Position usage in a separable Tessellation Control Shader without gl_PerVertex block "
1767 				 "redeclaration";
1768 		break;
1769 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE:
1770 		result = "Input gl_ClipDistance usage in a separable Tessellation Evaluation Shader without gl_PerVertex block "
1771 				 "redeclaration";
1772 		break;
1773 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CULLDISTANCE_USAGE:
1774 		result = "Input gl_CullDistance usage in a separable Tessellation Evaluation Shader without gl_PerVertex block "
1775 				 "redeclaration";
1776 		break;
1777 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POINTSIZE_USAGE:
1778 		result = "Input gl_PointSize usage in a separable Tessellation Evaluation Shader without gl_PerVertex block "
1779 				 "redeclaration";
1780 		break;
1781 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POSITION_USAGE:
1782 		result = "Input gl_Position usage in a separable Tessellation Evaluation Shader without gl_PerVertex block "
1783 				 "redeclaration";
1784 		break;
1785 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE:
1786 		result = "Output gl_ClipDistance usage in Geometry Shader without gl_PerVertex block redeclaration";
1787 		break;
1788 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CULLDISTANCE_USAGE:
1789 		result = "Output gl_CullDistance usage in Geometry Shader without gl_PerVertex block redeclaration";
1790 		break;
1791 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POINTSIZE_USAGE:
1792 		result = "Output gl_PointSize usage in a separable Geometry Shader without gl_PerVertex block redeclaration";
1793 		break;
1794 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POSITION_USAGE:
1795 		result = "Output gl_Position usage in a separable Geometry Shader without gl_PerVertex block redeclaration";
1796 		break;
1797 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE:
1798 		result = "Output gl_ClipDistance usage in a separable Tessellation Control Shader without gl_PerVertex block "
1799 				 "redeclaration";
1800 		break;
1801 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CULLDISTANCE_USAGE:
1802 		result = "Output gl_CullDistance usage in a separable Tessellation Control Shader without gl_PerVertex block "
1803 				 "redeclaration";
1804 		break;
1805 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POINTSIZE_USAGE:
1806 		result = "Output gl_PointSize usage in a separable Tessellation Control Shader without gl_PerVertex block "
1807 				 "redeclaration";
1808 		break;
1809 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POSITION_USAGE:
1810 		result = "Output gl_Position usage in a separable Tessellation Control Shader without gl_PerVertex block "
1811 				 "redeclaration";
1812 		break;
1813 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE:
1814 		result = "Output gl_ClipDistance usage in a separable Tessellation Evaluation Shader without gl_PerVertex "
1815 				 "block redeclaration";
1816 		break;
1817 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CULLDISTANCE_USAGE:
1818 		result = "Output gl_CullDistance usage in a separable Tessellation Evaluation Shader without gl_PerVertex "
1819 				 "block redeclaration";
1820 		break;
1821 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POINTSIZE_USAGE:
1822 		result = "Output gl_PointSize usage in a separable Tessellation Evaluation Shader without gl_PerVertex block "
1823 				 "redeclaration";
1824 		break;
1825 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POSITION_USAGE:
1826 		result = "Output gl_Position usage in a separable Tessellation Evaluation Shader without gl_PerVertex block "
1827 				 "redeclaration";
1828 		break;
1829 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CLIPDISTANCE_USAGE:
1830 		result = "Output gl_ClipDistance usage in a separable Vertex Shader without gl_PerVertex block redeclaration";
1831 		break;
1832 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CULLDISTANCE_USAGE:
1833 		result = "Output gl_CullDistance usage in a separable Vertex Shader without gl_PerVertex block redeclaration";
1834 		break;
1835 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_POINTSIZE_USAGE:
1836 		result = "Output gl_PointSize usage in a separable Vertex Shader without gl_PerVertex block redeclaration";
1837 		break;
1838 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_POSITION_USAGE:
1839 		result = "Output gl_Position usage in a separable Vertex Shader without gl_PerVertex block redeclaration";
1840 		break;
1841 
1842 	case TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_GS_VS:
1843 		result = "Geometry and Vertex Shaders use different gl_PerVertex block redeclaration";
1844 		break;
1845 	case TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_GS_TC_TE_VS:
1846 		result = "Geometry, Tessellation Control, Tessellation Evaluation and Vertex Shaders use a different "
1847 				 "gl_PerVertex block redeclaration";
1848 		break;
1849 	case TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_TC_TE_VS:
1850 		result = "Tesselation Control, Tessellation Evaluation and Vertex Shaders use a different gl_PerVertex block "
1851 				 "redeclaration";
1852 		break;
1853 
1854 	case TEST_ITERATION_PERVERTEX_BLOCK_UNDEFINED:
1855 		result = "No gl_PerVertex block defined in shader programs for all shader stages supported by the running "
1856 				 "context";
1857 		break;
1858 	default:
1859 		result = "Unknown";
1860 		break;
1861 	}
1862 
1863 	return result;
1864 }
1865 
1866 /** Returns shader bodies, minimum context type and a bitfield describing shader stages used for the
1867  *  user-specified test iteration enum.
1868  *
1869  *  @param context_type               Running context's type.
1870  *  @param iteration                  Test iteration enum to return the properties for.
1871  *  @param out_min_context_type_ptr   Deref will be set to the minimum context type supported by the
1872  *                                    specified test iteration.
1873  *  @param out_used_shader_stages_ptr Deref will be set to a combination of _shader_stage enum values,
1874  *                                    describing which shader stages are used by the test iteration.
1875  *  @param out_gs_body_ptr            Deref will be updated with the geometry shader body, if used by the
1876  *                                    test iteration.
1877  *  @param out_tc_body_ptr            Deref will be updated with the tessellation control shader body, if
1878  *                                    used by the test iteration.
1879  *  @param out_te_body_ptr            Deref will be updated with the tessellation evaluation shader body, if
1880  *                                    used by the test iteration.
1881  *  @param out_vs_body_ptr            Deref will be updated with the vertex shader body, if used by the
1882  *                                    test iteration.
1883  *
1884  */
getTestIterationProperties(glu::ContextType context_type,_test_iteration iteration,glu::ContextType * out_min_context_type_ptr,_shader_stage * out_used_shader_stages_ptr,std::string * out_gs_body_ptr,std::string * out_tc_body_ptr,std::string * out_te_body_ptr,std::string * out_vs_body_ptr) const1885 void PerVertexValidationTest::getTestIterationProperties(glu::ContextType context_type, _test_iteration iteration,
1886 														 glu::ContextType* out_min_context_type_ptr,
1887 														 _shader_stage*	out_used_shader_stages_ptr,
1888 														 std::string* out_gs_body_ptr, std::string* out_tc_body_ptr,
1889 														 std::string* out_te_body_ptr,
1890 														 std::string* out_vs_body_ptr) const
1891 {
1892 	const bool include_cull_distance = glu::contextSupports(context_type, glu::ApiType::core(4, 5));
1893 
1894 	switch (iteration)
1895 	{
1896 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE:
1897 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CULLDISTANCE_USAGE:
1898 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POINTSIZE_USAGE:
1899 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POSITION_USAGE:
1900 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE:
1901 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CULLDISTANCE_USAGE:
1902 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POINTSIZE_USAGE:
1903 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POSITION_USAGE:
1904 	{
1905 		const bool is_cull_distance_iteration =
1906 			(iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CULLDISTANCE_USAGE ||
1907 			 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CULLDISTANCE_USAGE);
1908 		std::stringstream gs_body_sstream;
1909 
1910 		*out_min_context_type_ptr = (is_cull_distance_iteration) ? glu::ContextType(4, 5, glu::PROFILE_CORE) :
1911 																   glu::ContextType(4, 1, glu::PROFILE_CORE);
1912 		*out_used_shader_stages_ptr = (_shader_stage)(SHADER_STAGE_GEOMETRY | SHADER_STAGE_VERTEX);
1913 
1914 		/* Form the geometry shader body */
1915 		gs_body_sstream << ((!is_cull_distance_iteration) ? "#version 410\n" : "version 450\n")
1916 						<< "\n"
1917 						   "layout(points)                   in;\n"
1918 						   "layout(points, max_vertices = 1) out;\n"
1919 						   "\n"
1920 						   "in gl_PerVertex\n"
1921 						   "{\n";
1922 
1923 		gs_body_sstream << ((iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE &&
1924 							 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE) ?
1925 								"float gl_ClipDistance[];\n" :
1926 								"");
1927 		gs_body_sstream << ((iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POINTSIZE_USAGE &&
1928 							 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POINTSIZE_USAGE) ?
1929 								"float gl_PointSize;\n" :
1930 								"");
1931 		gs_body_sstream << ((iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POSITION_USAGE &&
1932 							 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POSITION_USAGE) ?
1933 								"vec4  gl_Position;\n" :
1934 								"");
1935 
1936 		if (include_cull_distance)
1937 		{
1938 			gs_body_sstream << "float gl_CullDistance[];\n";
1939 		}
1940 
1941 		gs_body_sstream << "} gl_in[];\n"
1942 						   "\n"
1943 						   "out gl_PerVertex\n"
1944 						   "{\n";
1945 
1946 		gs_body_sstream << ((iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE &&
1947 							 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE) ?
1948 								"float gl_ClipDistance[];\n" :
1949 								"");
1950 		gs_body_sstream << ((iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POINTSIZE_USAGE &&
1951 							 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POINTSIZE_USAGE) ?
1952 								"float gl_PointSize;\n" :
1953 								"");
1954 		gs_body_sstream << ((iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POSITION_USAGE &&
1955 							 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POSITION_USAGE) ?
1956 								"vec4  gl_Position;\n" :
1957 								"");
1958 
1959 		if (include_cull_distance)
1960 		{
1961 			gs_body_sstream << "float gl_CullDistance[];\n";
1962 		}
1963 
1964 		gs_body_sstream << "};\n"
1965 						   "\n"
1966 						   "void main()\n"
1967 						   "{\n";
1968 
1969 		switch (iteration)
1970 		{
1971 		case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE:
1972 			gs_body_sstream << "gl_Position = vec4(gl_in[0].gl_ClipDistance[0]);\n";
1973 			break;
1974 		case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CULLDISTANCE_USAGE:
1975 			gs_body_sstream << "gl_Position = vec4(gl_in[0].gl_CullDistance[0]);\n";
1976 			break;
1977 		case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POINTSIZE_USAGE:
1978 			gs_body_sstream << "gl_Position = vec4(gl_in[0].gl_PointSize);\n";
1979 			break;
1980 		case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POSITION_USAGE:
1981 			gs_body_sstream << "gl_Position = gl_in[0].gl_Position;\n";
1982 			break;
1983 		case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE:
1984 			gs_body_sstream << "gl_ClipDistance[0] = gl_in[0].gl_Position.x;\n";
1985 			break;
1986 		case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CULLDISTANCE_USAGE:
1987 			gs_body_sstream << "gl_CullDistance[0] = gl_in[0].gl_Position.x;\n";
1988 			break;
1989 		case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POINTSIZE_USAGE:
1990 			gs_body_sstream << "gl_PointSize = gl_in[0].gl_Position.x;\n";
1991 			break;
1992 		case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POSITION_USAGE:
1993 			gs_body_sstream << "gl_Position = vec4(gl_in[0].gl_PointSize);\n";
1994 			break;
1995 		default:
1996 			gs_body_sstream << "\n";
1997 			break;
1998 		} /* switch (iteration) */
1999 
2000 		gs_body_sstream << "    EmitVertex();\n"
2001 						   "}\n";
2002 
2003 		/* Store geometry & vertex shader bodies */
2004 		*out_gs_body_ptr = gs_body_sstream.str();
2005 		*out_vs_body_ptr = getVertexShaderBody(context_type, iteration);
2006 
2007 		break;
2008 	}
2009 
2010 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE:
2011 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CULLDISTANCE_USAGE:
2012 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POINTSIZE_USAGE:
2013 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POSITION_USAGE:
2014 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE:
2015 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CULLDISTANCE_USAGE:
2016 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POINTSIZE_USAGE:
2017 	case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POSITION_USAGE:
2018 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE:
2019 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CULLDISTANCE_USAGE:
2020 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POINTSIZE_USAGE:
2021 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POSITION_USAGE:
2022 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE:
2023 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CULLDISTANCE_USAGE:
2024 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POINTSIZE_USAGE:
2025 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POSITION_USAGE:
2026 	{
2027 		std::stringstream tc_sstream;
2028 		std::stringstream te_sstream;
2029 
2030 		const bool is_clip_distance_iteration =
2031 			(iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE ||
2032 			 iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE ||
2033 			 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE ||
2034 			 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE);
2035 		const bool is_cull_distance_iteration =
2036 			(iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CULLDISTANCE_USAGE ||
2037 			 iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CULLDISTANCE_USAGE ||
2038 			 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CULLDISTANCE_USAGE ||
2039 			 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CULLDISTANCE_USAGE);
2040 		const bool is_pointsize_iteration =
2041 			(iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POINTSIZE_USAGE ||
2042 			 iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POINTSIZE_USAGE ||
2043 			 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POINTSIZE_USAGE ||
2044 			 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POINTSIZE_USAGE);
2045 		const bool is_position_iteration = (iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POSITION_USAGE ||
2046 											iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POSITION_USAGE ||
2047 											iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POSITION_USAGE ||
2048 											iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POSITION_USAGE);
2049 
2050 		*out_min_context_type_ptr = (is_cull_distance_iteration) ? glu::ContextType(4, 5, glu::PROFILE_CORE) :
2051 																   glu::ContextType(4, 0, glu::PROFILE_CORE);
2052 		*out_used_shader_stages_ptr = (_shader_stage)(SHADER_STAGE_TESSELLATION_CONTROL |
2053 													  SHADER_STAGE_TESSELLATION_EVALUATION | SHADER_STAGE_VERTEX);
2054 
2055 		/* Form tessellation control & tessellation evaluation shader bodies */
2056 		for (unsigned int n_iteration = 0; n_iteration < 2; ++n_iteration)
2057 		{
2058 			const bool		   is_tc_stage		   = (n_iteration == 0);
2059 			std::stringstream* current_sstream_ptr = (is_tc_stage) ? &tc_sstream : &te_sstream;
2060 
2061 			*current_sstream_ptr << ((is_cull_distance_iteration) ? "#version 450 core\n" : "#version 410\n") << "\n";
2062 
2063 			if (is_tc_stage)
2064 			{
2065 				*current_sstream_ptr << "layout (vertices = 4) out;\n";
2066 			}
2067 			else
2068 			{
2069 				*current_sstream_ptr << "layout (isolines) in;\n";
2070 			}
2071 
2072 			*current_sstream_ptr << "\n"
2073 									"in gl_PerVertex\n"
2074 									"{\n";
2075 
2076 			if (is_position_iteration)
2077 			{
2078 				*current_sstream_ptr << "vec4 gl_Position;\n";
2079 			}
2080 
2081 			if (!is_pointsize_iteration)
2082 			{
2083 				*current_sstream_ptr << "float gl_PointSize\n";
2084 			}
2085 
2086 			if (!is_clip_distance_iteration)
2087 			{
2088 				*current_sstream_ptr << "float gl_ClipDistance[];\n";
2089 			}
2090 
2091 			if (!is_cull_distance_iteration && include_cull_distance)
2092 			{
2093 				*current_sstream_ptr << "float gl_CullDistance[];\n";
2094 			}
2095 
2096 			*current_sstream_ptr << "} gl_in[gl_MaxPatchVertices];\n"
2097 									"\n"
2098 									"out gl_PerVertex\n"
2099 									"{\n";
2100 
2101 			if (!is_position_iteration)
2102 			{
2103 				*current_sstream_ptr << "vec4 gl_Position;\n";
2104 			}
2105 
2106 			if (!is_pointsize_iteration)
2107 			{
2108 				*current_sstream_ptr << "float gl_PointSize\n";
2109 			}
2110 
2111 			if (!is_clip_distance_iteration)
2112 			{
2113 				*current_sstream_ptr << "float gl_ClipDistance[];\n";
2114 			}
2115 
2116 			if (!is_cull_distance_iteration && include_cull_distance)
2117 			{
2118 				*current_sstream_ptr << "float gl_CullDistance[];\n";
2119 			}
2120 
2121 			if (is_tc_stage)
2122 			{
2123 				*current_sstream_ptr << "} gl_out[];\n";
2124 			}
2125 			else
2126 			{
2127 				*current_sstream_ptr << "};\n";
2128 			}
2129 
2130 			*current_sstream_ptr << "\n"
2131 									"void main()\n"
2132 									"{\n";
2133 
2134 			if (is_tc_stage)
2135 			{
2136 				*current_sstream_ptr << "gl_out[gl_InvocationID].";
2137 			}
2138 
2139 			if (iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE ||
2140 				iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE)
2141 			{
2142 				*current_sstream_ptr << "gl_Position        = vec4(gl_in[0].gl_ClipDistance[0]);\n";
2143 			}
2144 			else if (iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CULLDISTANCE_USAGE ||
2145 					 iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CULLDISTANCE_USAGE)
2146 			{
2147 				*current_sstream_ptr << "gl_Position        = vec4(gl_in[0].gl_CullDistance[0]);\n";
2148 			}
2149 			else if (iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POINTSIZE_USAGE ||
2150 					 iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POINTSIZE_USAGE)
2151 			{
2152 				*current_sstream_ptr << "gl_Position        = vec4(gl_in[0].gl_PointSize);\n";
2153 			}
2154 			else if (iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POSITION_USAGE ||
2155 					 iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POSITION_USAGE)
2156 			{
2157 				*current_sstream_ptr << "gl_Position        = gl_in[0].gl_Position;\n";
2158 			}
2159 			else if (iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE ||
2160 					 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE)
2161 			{
2162 				*current_sstream_ptr << "gl_ClipDistance[0] = gl_in[0].gl_Position.x;\n";
2163 			}
2164 			else if (iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CULLDISTANCE_USAGE ||
2165 					 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CULLDISTANCE_USAGE)
2166 			{
2167 				*current_sstream_ptr << "gl_CullDistance[0] = gl_in[0].gl_Position.x;\n";
2168 			}
2169 			else if (iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POINTSIZE_USAGE ||
2170 					 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POINTSIZE_USAGE)
2171 			{
2172 				*current_sstream_ptr << "gl_PointSize       = gl_in[0].gl_Position.x;\n";
2173 			}
2174 			else if (iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POSITION_USAGE ||
2175 					 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POSITION_USAGE)
2176 			{
2177 				*current_sstream_ptr << "gl_Position        = vec4(gl_in[0].gl_PointSize);\n";
2178 			}
2179 
2180 			tc_sstream << "}\n";
2181 		} /* for (both TC and TE stages) */
2182 
2183 		/* Store the bodies */
2184 		*out_tc_body_ptr = tc_sstream.str();
2185 		*out_te_body_ptr = te_sstream.str();
2186 		*out_vs_body_ptr = getVertexShaderBody(context_type, iteration);
2187 
2188 		break;
2189 	}
2190 
2191 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CLIPDISTANCE_USAGE:
2192 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CULLDISTANCE_USAGE:
2193 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_POINTSIZE_USAGE:
2194 	case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_POSITION_USAGE:
2195 	{
2196 		const bool is_cull_distance_iteration =
2197 			(iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CULLDISTANCE_USAGE);
2198 
2199 		*out_min_context_type_ptr = (is_cull_distance_iteration) ? glu::ContextType(4, 5, glu::PROFILE_CORE) :
2200 																   glu::ContextType(4, 1, glu::PROFILE_CORE);
2201 		*out_used_shader_stages_ptr = (_shader_stage)(SHADER_STAGE_VERTEX);
2202 
2203 		/* Determine what the main() body contents should be. */
2204 		std::string vs_main_body;
2205 
2206 		switch (iteration)
2207 		{
2208 		case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CLIPDISTANCE_USAGE:
2209 			vs_main_body = "gl_ClipDistance[0] = 1.0;";
2210 			break;
2211 		case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CULLDISTANCE_USAGE:
2212 			vs_main_body = "gl_CullDistance[0] = 2.0;";
2213 			break;
2214 		case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_POINTSIZE_USAGE:
2215 			vs_main_body = "gl_PointSize = 1.0;";
2216 			break;
2217 		case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_POSITION_USAGE:
2218 			vs_main_body = "gl_Position = vec4(1.0f, 2.0, 3.0, 4.0);";
2219 			break;
2220 		default:
2221 			vs_main_body = "";
2222 			break;
2223 		}
2224 
2225 		/* Store the body */
2226 		*out_vs_body_ptr = getVertexShaderBody(context_type, iteration, vs_main_body);
2227 
2228 		break;
2229 	}
2230 
2231 	case TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_GS_VS:
2232 	case TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_GS_TC_TE_VS:
2233 	case TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_TC_TE_VS:
2234 	{
2235 		*out_min_context_type_ptr   = glu::ContextType(4, 1, glu::PROFILE_CORE);
2236 		int used_shader_stages = SHADER_STAGE_VERTEX;
2237 
2238 		if (iteration == TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_GS_TC_TE_VS ||
2239 			iteration == TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_GS_VS)
2240 		{
2241 			used_shader_stages |= SHADER_STAGE_GEOMETRY;
2242 		}
2243 
2244 		if (iteration == TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_GS_TC_TE_VS ||
2245 			iteration == TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_TC_TE_VS)
2246 		{
2247 			used_shader_stages |=
2248 				SHADER_STAGE_TESSELLATION_CONTROL | SHADER_STAGE_TESSELLATION_EVALUATION;
2249 		}
2250 
2251 		*out_used_shader_stages_ptr = (_shader_stage) used_shader_stages;
2252 
2253 		/* Shader bodies are predefined in this case. */
2254 		*out_gs_body_ptr = "#version 410\n"
2255 						   "\n"
2256 						   "layout (points)                   in;\n"
2257 						   "layout (points, max_vertices = 4) out;\n"
2258 						   "\n"
2259 						   "in gl_PerVertex\n"
2260 						   "{\n"
2261 						   "    float gl_ClipDistance[];\n"
2262 						   "} gl_in[];\n"
2263 						   "\n"
2264 						   "out gl_PerVertex\n"
2265 						   "{\n"
2266 						   "    float gl_ClipDistance[];\n"
2267 						   "};\n"
2268 						   "\n"
2269 						   "void main()\n"
2270 						   "{\n"
2271 						   "    gl_ClipDistance[0] = 0.5;\n"
2272 						   "    EmitVertex();\n"
2273 						   "}\n";
2274 		*out_tc_body_ptr = "#version 410\n"
2275 						   "\n"
2276 						   "layout (vertices = 4) out;\n"
2277 						   "\n"
2278 						   "in gl_PerVertex\n"
2279 						   "{\n"
2280 						   "    float gl_PointSize;\n"
2281 						   "} gl_in[];\n"
2282 						   "\n"
2283 						   "out gl_PerVertex\n"
2284 						   "{\n"
2285 						   "    float gl_PointSize;\n"
2286 						   "} gl_out[];\n"
2287 						   "\n"
2288 						   "void main()\n"
2289 						   "{\n"
2290 						   "    gl_out[gl_InvocationID].gl_PointSize = gl_in[0].gl_PointSize + 1.0;\n"
2291 						   "}\n";
2292 		*out_te_body_ptr = "#version 410\n"
2293 						   "\n"
2294 						   "layout (isolines) in;\n"
2295 						   "\n"
2296 						   "in gl_PerVertex\n"
2297 						   "{\n"
2298 						   "    float gl_PointSize;\n"
2299 						   "    vec4  gl_Position;\n"
2300 						   "} gl_in[gl_MaxPatchVertices];\n"
2301 						   "\n"
2302 						   "out gl_PerVertex\n"
2303 						   "{\n"
2304 						   "    float gl_PointSize;\n"
2305 						   "    vec4  gl_Position;\n"
2306 						   "};\n"
2307 						   "\n"
2308 						   "void main()\n"
2309 						   "{\n"
2310 						   "    gl_Position = vec4(gl_in[0].gl_PointSize) + gl_in[1].gl_Position;\n"
2311 						   "}\n";
2312 		*out_vs_body_ptr = "#version 410\n"
2313 						   "\n"
2314 						   "out gl_PerVertex\n"
2315 						   "{\n"
2316 						   "    vec4 gl_Position;\n"
2317 						   "};\n"
2318 						   "\n"
2319 						   "void main()\n"
2320 						   "{\n"
2321 						   "    gl_Position = vec4(2.0);\n"
2322 						   "}\n";
2323 
2324 		break;
2325 	}
2326 
2327 	case TEST_ITERATION_PERVERTEX_BLOCK_UNDEFINED:
2328 	{
2329 		*out_min_context_type_ptr   = glu::ContextType(4, 1, glu::PROFILE_CORE);
2330 		int used_shader_stages = SHADER_STAGE_VERTEX;
2331 
2332 		if (glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
2333 		{
2334 			used_shader_stages |= SHADER_STAGE_GEOMETRY;
2335 		}
2336 
2337 		if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
2338 		{
2339 			used_shader_stages |=
2340 				SHADER_STAGE_TESSELLATION_CONTROL | SHADER_STAGE_TESSELLATION_EVALUATION;
2341 		}
2342 
2343 		*out_used_shader_stages_ptr = (_shader_stage) used_shader_stages;
2344 
2345 		*out_gs_body_ptr = "#version 410\n"
2346 						   "\n"
2347 						   "layout (points)                   in;\n"
2348 						   "layout (points, max_vertices = 4) out;\n"
2349 						   "\n"
2350 						   "void main()\n"
2351 						   "{\n"
2352 						   "    gl_Position = vec4(1.0, 2.0, 3.0, 4.0);\n"
2353 						   "    EmitVertex();\n"
2354 						   "}\n";
2355 		*out_tc_body_ptr = "#version 410\n"
2356 						   "\n"
2357 						   "layout(vertices = 4) out;\n"
2358 						   "\n"
2359 						   "void main()\n"
2360 						   "{\n"
2361 						   "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
2362 						   "}\n";
2363 		*out_te_body_ptr = "#version 410\n"
2364 						   "\n"
2365 						   "layout (isolines) in;\n"
2366 						   "\n"
2367 						   "void main()\n"
2368 						   "{\n"
2369 						   "    gl_Position = gl_in[0].gl_Position;\n"
2370 						   "}\n";
2371 		*out_vs_body_ptr = "#version 410\n"
2372 						   "\n"
2373 						   "void main()\n"
2374 						   "{\n"
2375 						   "    gl_Position = vec4(1.0, 2.0, 3.0, 4.0);\n"
2376 						   "}\n";
2377 
2378 		break;
2379 	}
2380 
2381 	default:
2382 		TCU_FAIL("Unrecognized test iteration");
2383 	} /* switch (iteration) */
2384 }
2385 
2386 /** Returns a vertex shader body, with main() entry-point using code passed by
2387  *  the @param main_body argument.
2388  *
2389  *  @param context_type Running rendering context's type.
2390  *  @param iteration    Test iteration to return the vertex shader body for.
2391  *  @param main_body    Body to use for the main() entry-point.
2392  *
2393  *  @return Requested object.
2394  **/
getVertexShaderBody(glu::ContextType context_type,_test_iteration iteration,std::string main_body) const2395 std::string PerVertexValidationTest::getVertexShaderBody(glu::ContextType context_type, _test_iteration iteration,
2396 														 std::string main_body) const
2397 {
2398 	const bool include_clip_distance = (iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE &&
2399 										iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE &&
2400 										iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE &&
2401 										iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE &&
2402 										iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE &&
2403 										iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE &&
2404 										iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CLIPDISTANCE_USAGE);
2405 	const bool include_cull_distance = (iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CULLDISTANCE_USAGE &&
2406 										iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CULLDISTANCE_USAGE &&
2407 										iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CULLDISTANCE_USAGE &&
2408 										iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CULLDISTANCE_USAGE &&
2409 										iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CULLDISTANCE_USAGE &&
2410 										iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CULLDISTANCE_USAGE &&
2411 										iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CULLDISTANCE_USAGE &&
2412 										glu::contextSupports(context_type, glu::ApiType::core(4, 5)));
2413 	const bool include_pointsize = (iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POINTSIZE_USAGE &&
2414 									iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POINTSIZE_USAGE &&
2415 									iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POINTSIZE_USAGE &&
2416 									iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POINTSIZE_USAGE &&
2417 									iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POINTSIZE_USAGE &&
2418 									iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POINTSIZE_USAGE &&
2419 									iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_POINTSIZE_USAGE);
2420 	const bool include_position = (iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POSITION_USAGE &&
2421 								   iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POSITION_USAGE &&
2422 								   iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POSITION_USAGE &&
2423 								   iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POSITION_USAGE &&
2424 								   iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POSITION_USAGE &&
2425 								   iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POSITION_USAGE &&
2426 								   iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_POSITION_USAGE);
2427 	std::stringstream vs_body_sstream;
2428 
2429 	vs_body_sstream << "#version " << ((include_cull_distance) ? "450" : "410") << "\n"
2430 					<< "\n"
2431 					   "in gl_PerVertex\n"
2432 					   "{\n";
2433 
2434 	vs_body_sstream << ((include_clip_distance) ? "float gl_ClipDistance[];\n" : "");
2435 	vs_body_sstream << ((include_pointsize) ? "float gl_PointSize;\n" : "");
2436 	vs_body_sstream << ((include_position) ? "vec4  gl_Position;\n" : "");
2437 	vs_body_sstream << ((include_cull_distance) ? "float gl_CullDistance[];\n" : "");
2438 
2439 	vs_body_sstream << "};\n"
2440 					   "\n"
2441 					   "out gl_PerVertex\n"
2442 					   "{\n";
2443 
2444 	vs_body_sstream << ((include_clip_distance) ? "float gl_ClipDistance[];\n" : "");
2445 	vs_body_sstream << ((include_pointsize) ? "float gl_PointSize;\n" : "");
2446 	vs_body_sstream << ((include_position) ? "vec4  gl_Position;\n" : "");
2447 	vs_body_sstream << ((include_cull_distance) ? "float gl_CullDistance[];\n" : "");
2448 
2449 	vs_body_sstream << "};\n"
2450 					   "\n"
2451 					   "void main()\n"
2452 					   "{\n"
2453 					   "    "
2454 					<< main_body << "\n"
2455 									"}\n";
2456 
2457 	return vs_body_sstream.str();
2458 }
2459 
2460 /** Empty init function */
init()2461 void PerVertexValidationTest::init()
2462 {
2463 	/* Left blank on purpose */
2464 }
2465 
2466 /** Executes test iteration.
2467  *
2468  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2469  */
iterate()2470 tcu::TestNode::IterateResult PerVertexValidationTest::iterate()
2471 {
2472 	const glu::ContextType context_type = m_context.getRenderContext().getType();
2473 	const glw::Functions&  gl			= m_context.getRenderContext().getFunctions();
2474 	bool				   result		= true;
2475 
2476 	/* Separable program objects went into core in GL 4.1 */
2477 	if (!glu::contextSupports(context_type, glu::ApiType::core(4, 1)))
2478 	{
2479 		throw tcu::NotSupportedError("Test implemented for OpenGL 4.1 contexts or newer.");
2480 	}
2481 
2482 	/* Each test iteration is going to be executed in two different modes:
2483 	 *
2484 	 * 1) Create separate shader programs for each stage. They should link just fine.
2485 	 *    Then create a pipeline and attach to it all the programs. At this stage, the
2486 	 *    validation should report failure.
2487 	 *
2488 	 * 2) Create a single separate shader program, holding all stages. Try to link it.
2489 	 *    This process should report failure.
2490 	 */
2491 	for (int test_iteration = static_cast<int>(TEST_ITERATION_FIRST);
2492 		 test_iteration != static_cast<int>(TEST_ITERATION_COUNT); test_iteration++)
2493 	{
2494 		for (unsigned int n_test_mode = 0; n_test_mode < 2; ++n_test_mode)
2495 		{
2496 			/* Skip the second iteration if any of the shaders is expected not to compile. */
2497 			if (isShaderProgramLinkingFailureExpected(static_cast<_test_iteration>(test_iteration)))
2498 			{
2499 				continue;
2500 			}
2501 
2502 			/* Execute the actual test iteration */
2503 			switch (n_test_mode)
2504 			{
2505 			case 0:
2506 				result &= runPipelineObjectValidationTestMode(static_cast<_test_iteration>(test_iteration));
2507 				break;
2508 			case 1:
2509 				result &= runSeparateShaderTestMode(static_cast<_test_iteration>(test_iteration));
2510 				break;
2511 			}
2512 
2513 			/* Clean up */
2514 			destroyPOsAndSOs();
2515 
2516 			if (m_pipeline_id != 0)
2517 			{
2518 				gl.deleteProgramPipelines(1, /* n */
2519 										  &m_pipeline_id);
2520 
2521 				GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgramPipelines() call failed");
2522 			}
2523 		} /* for (both test modes) */
2524 	}	 /* for (all test iterations) */
2525 	m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
2526 
2527 	return STOP;
2528 }
2529 
2530 /** Tells whether the linking process should fail for specified test iteration.
2531  *
2532  *  @param iteration Test iteration to query.
2533  *
2534  *  @return true if the linking process should fail, false otherwise */
isShaderProgramLinkingFailureExpected(_test_iteration iteration) const2535 bool PerVertexValidationTest::isShaderProgramLinkingFailureExpected(_test_iteration iteration) const
2536 {
2537 	/** All "undeclared in.." and "undeclared out.." test shaders are expected not to link successfully
2538 	 *  when used as separate programs.
2539 	 *  Shaders built as a part of the remaining test iterations should compile and link successfully
2540 	 *  for separate programs implementing only a single shader stage. Later on, however, pipeline
2541 	 *  objects built of these programs should fail to validate, as they use incompatible gl_PerVertex
2542 	 *  block redeclarations.
2543 	 */
2544 	return (iteration < TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_GS_VS) ||
2545 		   iteration == TEST_ITERATION_PERVERTEX_BLOCK_UNDEFINED;
2546 }
2547 
2548 /** Runs the specified test iteration in the following mode:
2549  *
2550  *  >>
2551  *  A pipeline object is created and shader programs are attached to it. It is expected that validation
2552  *  should fail.
2553  *  <<
2554  *
2555  *  @param iteration Test iteration to execute.
2556  *
2557  *  @return true if the test passed, false otherwise.
2558  */
runPipelineObjectValidationTestMode(_test_iteration iteration)2559 bool PerVertexValidationTest::runPipelineObjectValidationTestMode(_test_iteration iteration)
2560 {
2561 	const glu::ContextType context_type = m_context.getRenderContext().getType();
2562 	const glw::Functions&  gl			= m_context.getRenderContext().getFunctions();
2563 	bool				   result		= false;
2564 
2565 	const char*		 body_raw_ptr	= NULL;
2566 	glw::GLenum		 expected_result = getProgramPipelineValidationExpectedResult();
2567 	std::string		 fs_body;
2568 	std::string		 gs_body;
2569 	glw::GLint		 link_status;
2570 	glu::ContextType min_context_type;
2571 	std::string		 tc_body;
2572 	std::string		 te_body;
2573 	_shader_stage	used_shader_stages;
2574 	glw::GLint		 validate_status;
2575 	glw::GLint		 validate_expected_status;
2576 	std::string		 vs_body;
2577 
2578 	struct _shader_program
2579 	{
2580 		std::string*  body_ptr;
2581 		glw::GLuint*  po_id_ptr;
2582 		_shader_stage shader_stage;
2583 		glw::GLenum   shader_stage_bit_gl;
2584 		glw::GLenum   shader_stage_gl;
2585 	} shader_programs[] = {
2586 		{ &fs_body, &m_fs_po_id, SHADER_STAGE_FRAGMENT, GL_FRAGMENT_SHADER_BIT, GL_FRAGMENT_SHADER },
2587 		{ &gs_body, &m_gs_po_id, SHADER_STAGE_GEOMETRY, GL_GEOMETRY_SHADER_BIT, GL_GEOMETRY_SHADER },
2588 		{ &tc_body, &m_tc_po_id, SHADER_STAGE_TESSELLATION_CONTROL, GL_TESS_CONTROL_SHADER_BIT,
2589 		  GL_TESS_CONTROL_SHADER },
2590 		{ &te_body, &m_te_po_id, SHADER_STAGE_TESSELLATION_EVALUATION, GL_TESS_EVALUATION_SHADER_BIT,
2591 		  GL_TESS_EVALUATION_SHADER },
2592 		{ &vs_body, &m_vs_po_id, SHADER_STAGE_VERTEX, GL_VERTEX_SHADER_BIT, GL_VERTEX_SHADER },
2593 	};
2594 	const unsigned int n_shader_programs =
2595 		static_cast<unsigned int>(sizeof(shader_programs) / sizeof(shader_programs[0]));
2596 
2597 	/* Make sure the test iteration can actually be run under the running rendering context
2598 	 * version.
2599 	 */
2600 	getTestIterationProperties(context_type, iteration, &min_context_type, &used_shader_stages, &gs_body, &tc_body,
2601 							   &te_body, &vs_body);
2602 
2603 	if (!glu::contextSupports(context_type, min_context_type.getAPI()))
2604 	{
2605 		result = true;
2606 
2607 		goto end;
2608 	}
2609 
2610 	/* Set up shader program objects. All shader bodies by themselves are valid, so all shaders should
2611 	 * link just fine. */
2612 	for (unsigned int n_shader_program = 0; n_shader_program < n_shader_programs; ++n_shader_program)
2613 	{
2614 		_shader_program& current_shader_program = shader_programs[n_shader_program];
2615 
2616 		if ((used_shader_stages & current_shader_program.shader_stage) != 0)
2617 		{
2618 			body_raw_ptr = current_shader_program.body_ptr->c_str();
2619 			*current_shader_program.po_id_ptr =
2620 				gl.createShaderProgramv(current_shader_program.shader_stage_gl, 1, /* count */
2621 										&body_raw_ptr);
2622 
2623 			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed.");
2624 
2625 			gl.getProgramiv(*current_shader_program.po_id_ptr, GL_LINK_STATUS, &link_status);
2626 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
2627 
2628 			if (link_status != GL_TRUE)
2629 			{
2630 				char info_log[4096];
2631 
2632 				if (!isShaderProgramLinkingFailureExpected(iteration))
2633 				{
2634 					gl.getProgramInfoLog(*current_shader_program.po_id_ptr, sizeof(info_log), DE_NULL, /* length */
2635 										 info_log);
2636 
2637 					m_testCtx.getLog() << tcu::TestLog::Message << "The separate "
2638 									   << getShaderStageName(current_shader_program.shader_stage)
2639 									   << " program "
2640 										  "failed to link, even though the shader body is valid.\n"
2641 										  "\n"
2642 										  "Body:\n>>\n"
2643 									   << *current_shader_program.body_ptr << "<<\nInfo log\n>>\n"
2644 									   << info_log << "<<\n"
2645 									   << tcu::TestLog::EndMessage;
2646 				}
2647 				else
2648 				{
2649 					result = true;
2650 				}
2651 
2652 				goto end;
2653 			} /* if (link_status != GL_TRUE) */
2654 		}	 /* for (all shader programs) */
2655 	}		  /* for (all shader stages) */
2656 
2657 	/* Now that all shader programs are ready, set up a test-specific pipeline object and validate it. */
2658 	gl.genProgramPipelines(1, &m_pipeline_id);
2659 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call failed.");
2660 
2661 	gl.bindProgramPipeline(m_pipeline_id);
2662 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed.");
2663 
2664 	for (unsigned int n_shader_program = 0; n_shader_program < n_shader_programs; ++n_shader_program)
2665 	{
2666 		_shader_program& current_shader_program = shader_programs[n_shader_program];
2667 
2668 		if ((used_shader_stages & current_shader_program.shader_stage) != 0)
2669 		{
2670 			gl.useProgramStages(m_pipeline_id, current_shader_program.shader_stage_bit_gl,
2671 								*current_shader_program.po_id_ptr);
2672 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
2673 		}
2674 	} /* for (all shader programs) */
2675 
2676 	gl.validateProgramPipeline(m_pipeline_id);
2677 	GLU_EXPECT_NO_ERROR(gl.getError(), "glValidateProgramPipeline() call failed.");
2678 
2679 	gl.getProgramPipelineiv(m_pipeline_id, GL_VALIDATE_STATUS, &validate_status);
2680 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramPipelineiv() call failed.");
2681 
2682 	if (VALIDATION_RESULT_UNDEFINED != expected_result)
2683 	{
2684 		switch (expected_result)
2685 		{
2686 		case VALIDATION_RESULT_FALSE:
2687 			validate_expected_status = GL_FALSE;
2688 			break;
2689 		case VALIDATION_RESULT_TRUE:
2690 			validate_expected_status = GL_TRUE;
2691 			break;
2692 		default:
2693 			TCU_FAIL("Invalid enum");
2694 		}
2695 
2696 		if (validate_status != validate_expected_status)
2697 		{
2698 			tcu::MessageBuilder message = m_testCtx.getLog().message();
2699 
2700 			if (GL_FALSE == validate_expected_status)
2701 			{
2702 				message << "A pipeline object was validated successfully, even though one";
2703 			}
2704 			else
2705 			{
2706 				message << "A pipeline object was validated negatively, even though none";
2707 			}
2708 
2709 			message << " of the failure reasons given by spec was applicable.\n"
2710 					<< "\n"
2711 					   "Fragment shader body:\n>>\n"
2712 					<< ((shader_programs[0].body_ptr->length() > 0) ? *shader_programs[0].body_ptr : "[not used]")
2713 					<< "\n<<\nGeometry shader body:\n>>\n"
2714 					<< ((shader_programs[1].body_ptr->length() > 0) ? *shader_programs[1].body_ptr : "[not used]")
2715 					<< "\n<<\nTessellation control shader body:\n>>\n"
2716 					<< ((shader_programs[2].body_ptr->length() > 0) ? *shader_programs[2].body_ptr : "[not used]")
2717 					<< "\n<<\nTessellation evaluation shader body:\n>>\n"
2718 					<< ((shader_programs[3].body_ptr->length() > 0) ? *shader_programs[3].body_ptr : "[not used]")
2719 					<< "\n<<\nVertex shader body:\n>>\n"
2720 					<< ((shader_programs[4].body_ptr->length() > 0) ? *shader_programs[4].body_ptr : "[not used]")
2721 					<< tcu::TestLog::EndMessage;
2722 		} /* if (validate_status != validate_expected_status) */
2723 		else
2724 		{
2725 			result = true;
2726 		}
2727 	}
2728 	else
2729 	{
2730 		result = true;
2731 	}
2732 
2733 end:
2734 	return result;
2735 }
2736 
2737 /** Runs the specified test iteration in the following mode:
2738  *
2739  *  >>
2740  *  A single separate shader program, to which all shader stages used by the test are attached, is linked.
2741  *  It is expected the linking process should fail.
2742  *  <<
2743  *
2744  *  @param iteration Test iteration to execute.
2745  *
2746  *  @return true if the test passed, false otherwise.
2747  */
runSeparateShaderTestMode(_test_iteration iteration)2748 bool PerVertexValidationTest::runSeparateShaderTestMode(_test_iteration iteration)
2749 {
2750 	glw::GLint			  compile_status;
2751 	glu::ContextType	  context_type = m_context.getRenderContext().getType();
2752 	const glw::Functions& gl		   = m_context.getRenderContext().getFunctions();
2753 	glw::GLint			  link_status;
2754 	glu::ContextType	  min_context_type;
2755 	bool				  result = false;
2756 	_shader_stage		  used_shader_stages;
2757 
2758 	std::string fs_body;
2759 	std::string gs_body;
2760 	std::string tc_body;
2761 	std::string te_body;
2762 	std::string vs_body;
2763 
2764 	struct _shader
2765 	{
2766 		std::string*  body_ptr;
2767 		glw::GLuint*  so_id_ptr;
2768 		_shader_stage shader_stage;
2769 		glw::GLenum   shader_stage_bit_gl;
2770 		glw::GLenum   shader_stage_gl;
2771 	} shaders[] = { { &fs_body, &m_fs_id, SHADER_STAGE_FRAGMENT, GL_FRAGMENT_SHADER_BIT, GL_FRAGMENT_SHADER },
2772 					{ &gs_body, &m_gs_id, SHADER_STAGE_GEOMETRY, GL_GEOMETRY_SHADER_BIT, GL_GEOMETRY_SHADER },
2773 					{ &tc_body, &m_tc_id, SHADER_STAGE_TESSELLATION_CONTROL, GL_TESS_CONTROL_SHADER_BIT,
2774 					  GL_TESS_CONTROL_SHADER },
2775 					{ &te_body, &m_te_id, SHADER_STAGE_TESSELLATION_EVALUATION, GL_TESS_EVALUATION_SHADER_BIT,
2776 					  GL_TESS_EVALUATION_SHADER },
2777 					{ &vs_body, &m_vs_id, SHADER_STAGE_VERTEX, GL_VERTEX_SHADER_BIT, GL_VERTEX_SHADER } };
2778 	const unsigned int n_shaders = static_cast<unsigned int>(sizeof(shaders) / sizeof(shaders[0]));
2779 
2780 	/* Retrieve iteration properties */
2781 	getTestIterationProperties(context_type, iteration, &min_context_type, &used_shader_stages, &gs_body, &tc_body,
2782 							   &te_body, &vs_body);
2783 
2784 	if (!glu::contextSupports(context_type, min_context_type.getAPI()))
2785 	{
2786 		result = true;
2787 
2788 		goto end;
2789 	}
2790 
2791 	/* Bake a single shader with separate programs defined for all shader stages defined by the iteration
2792 	 * and see what happens.
2793 	 *
2794 	 * For simplicity, we re-use m_vs_po_id to store the program object ID.
2795 	 */
2796 	m_vs_po_id = gl.createProgram();
2797 
2798 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
2799 
2800 	for (unsigned int n_shader = 0; n_shader < n_shaders; ++n_shader)
2801 	{
2802 		const char*			 body_raw_ptr		  = DE_NULL;
2803 		const std::string&   current_body		  = *shaders[n_shader].body_ptr;
2804 		const _shader_stage& current_shader_stage = shaders[n_shader].shader_stage;
2805 		glw::GLuint&		 current_so_id		  = *shaders[n_shader].so_id_ptr;
2806 		const glw::GLenum&   current_so_type_gl   = shaders[n_shader].shader_stage_gl;
2807 
2808 		if ((used_shader_stages & current_shader_stage) != 0)
2809 		{
2810 			body_raw_ptr  = current_body.c_str();
2811 			current_so_id = gl.createShader(current_so_type_gl);
2812 
2813 			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
2814 
2815 			gl.shaderSource(current_so_id, 1,		 /* count */
2816 							&body_raw_ptr, DE_NULL); /* length */
2817 			GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
2818 
2819 			/* Ensure the shader compiled successfully. */
2820 			gl.compileShader(current_so_id);
2821 
2822 			GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
2823 
2824 			gl.getShaderiv(current_so_id, GL_COMPILE_STATUS, &compile_status);
2825 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
2826 
2827 			if (compile_status != GL_TRUE)
2828 			{
2829 				m_testCtx.getLog() << tcu::TestLog::Message << getShaderStageName(current_shader_stage)
2830 								   << " unexpectedly failed to compile.\n"
2831 									  "\nBody:\n>>\n"
2832 								   << current_body << "\n<<\n"
2833 								   << tcu::TestLog::EndMessage;
2834 
2835 				goto end;
2836 			}
2837 
2838 			/* Attach the shader object to the test program object */
2839 			gl.attachShader(m_vs_po_id, current_so_id);
2840 			GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
2841 		} /* if ((used_shader_stages & current_shader_stage) != 0) */
2842 	}	 /* for (all shader objects) */
2843 
2844 	/* Mark the program as separable */
2845 	gl.programParameteri(m_vs_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2846 	GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed.");
2847 
2848 	/* Try to link the program and check the result. */
2849 	gl.linkProgram(m_vs_po_id);
2850 	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
2851 
2852 	gl.getProgramiv(m_vs_po_id, GL_LINK_STATUS, &link_status);
2853 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
2854 
2855 	if (link_status == GL_TRUE)
2856 	{
2857 		m_testCtx.getLog() << tcu::TestLog::Message
2858 						   << "Separable program, consisting of the following separate shaders, was linked "
2859 							  "successfully, despite incompatible or missing gl_PerVertex block re-declarations.\n"
2860 							  "\n"
2861 							  "Fragment shader program:\n>>\n"
2862 						   << ((fs_body.length() > 0) ? fs_body : "[not used]")
2863 						   << "\n<<\nGeometry shader program:\n>>\n"
2864 						   << ((gs_body.length() > 0) ? gs_body : "[not used]")
2865 						   << "\n<<\nTessellation control shader program:\n>>\n"
2866 						   << ((tc_body.length() > 0) ? tc_body : "[not used]")
2867 						   << "\n<<\nTessellation evaluation shader program:\n>>\n"
2868 						   << ((te_body.length() > 0) ? te_body : "[not used]") << "\n<<\nVertex shader program:\n>>\n"
2869 						   << ((vs_body.length() > 0) ? vs_body : "[not used]") << tcu::TestLog::EndMessage;
2870 
2871 		goto end;
2872 	} /* if (link_status == GL_TRUE) */
2873 
2874 	/* All done */
2875 	result = true;
2876 end:
2877 	if (!result)
2878 	{
2879 		m_testCtx.getLog() << tcu::TestLog::Message << "Failed test description: " << getTestIterationName(iteration)
2880 						   << tcu::TestLog::EndMessage;
2881 	}
2882 	return result;
2883 }
2884 
2885 /** Constructor.
2886  *
2887  *  @param context     Rendering context
2888  *  @param name        Test name
2889  *  @param description Test description
2890  */
ReservedNamesTest(deqp::Context & context)2891 ReservedNamesTest::ReservedNamesTest(deqp::Context& context)
2892 	: TestCase(context, "CommonBug_ReservedNames",
2893 			   "Verifies that reserved variable names are rejected by the GL SL compiler"
2894 			   " at the compilation time.")
2895 	, m_max_fs_ssbos(0)
2896 	, m_max_gs_acs(0)
2897 	, m_max_gs_ssbos(0)
2898 	, m_max_tc_acs(0)
2899 	, m_max_tc_ssbos(0)
2900 	, m_max_te_acs(0)
2901 	, m_max_te_ssbos(0)
2902 	, m_max_vs_acs(0)
2903 	, m_max_vs_ssbos(0)
2904 {
2905 	memset(m_so_ids, 0, sizeof(m_so_ids));
2906 }
2907 
2908 /** Deinitializes all GL objects created for the purpose of running the test,
2909  *  as well as any client-side buffers allocated at initialization time
2910  */
deinit()2911 void ReservedNamesTest::deinit()
2912 {
2913 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2914 
2915 	for (unsigned int n_so_id = 0; n_so_id < sizeof(m_so_ids) / sizeof(m_so_ids[0]); ++n_so_id)
2916 	{
2917 		const glw::GLuint current_so_id = m_so_ids[n_so_id];
2918 
2919 		if (current_so_id != 0)
2920 		{
2921 			gl.deleteShader(current_so_id);
2922 		}
2923 	} /* for (all usedshader object IDs) */
2924 }
2925 
2926 /** Returns a literal corresponding to the specified @param language_feature value.
2927  *
2928  *  @param language_feature Enum to return the string object for.
2929  *
2930  *  @return As specified.
2931  */
getLanguageFeatureName(_language_feature language_feature) const2932 std::string ReservedNamesTest::getLanguageFeatureName(_language_feature language_feature) const
2933 {
2934 	std::string result = "[?!]";
2935 
2936 	switch (language_feature)
2937 	{
2938 	case LANGUAGE_FEATURE_ATOMIC_COUNTER:
2939 		result = "atomic counter";
2940 		break;
2941 	case LANGUAGE_FEATURE_ATTRIBUTE:
2942 		result = "attribute";
2943 		break;
2944 	case LANGUAGE_FEATURE_CONSTANT:
2945 		result = "constant";
2946 		break;
2947 	case LANGUAGE_FEATURE_FUNCTION_ARGUMENT_NAME:
2948 		result = "function argument name";
2949 		break;
2950 	case LANGUAGE_FEATURE_FUNCTION_NAME:
2951 		result = "function name";
2952 		break;
2953 	case LANGUAGE_FEATURE_INPUT:
2954 		result = "input variable";
2955 		break;
2956 	case LANGUAGE_FEATURE_INPUT_BLOCK_INSTANCE_NAME:
2957 		result = "input block instance name";
2958 		break;
2959 	case LANGUAGE_FEATURE_INPUT_BLOCK_MEMBER_NAME:
2960 		result = "input block member name";
2961 		break;
2962 	case LANGUAGE_FEATURE_INPUT_BLOCK_NAME:
2963 		result = "input block name";
2964 		break;
2965 	case LANGUAGE_FEATURE_OUTPUT:
2966 		result = "output variable";
2967 		break;
2968 	case LANGUAGE_FEATURE_OUTPUT_BLOCK_INSTANCE_NAME:
2969 		result = "output block instance name";
2970 		break;
2971 	case LANGUAGE_FEATURE_OUTPUT_BLOCK_MEMBER_NAME:
2972 		result = "output block member name";
2973 		break;
2974 	case LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME:
2975 		result = "output block name";
2976 		break;
2977 	case LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_INSTANCE_NAME:
2978 		result = "shader storage block instance name";
2979 		break;
2980 	case LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_MEMBER_NAME:
2981 		result = "shader storage block member name";
2982 		break;
2983 	case LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_NAME:
2984 		result = "shader storage block name";
2985 		break;
2986 	case LANGUAGE_FEATURE_SHARED_VARIABLE:
2987 		result = "shared variable";
2988 		break;
2989 	case LANGUAGE_FEATURE_STRUCTURE_MEMBER:
2990 		result = "structure member";
2991 		break;
2992 	case LANGUAGE_FEATURE_STRUCTURE_INSTANCE_NAME:
2993 		result = "structure instance name";
2994 		break;
2995 	case LANGUAGE_FEATURE_STRUCTURE_NAME:
2996 		result = "structure name";
2997 		break;
2998 	case LANGUAGE_FEATURE_SUBROUTINE_FUNCTION_NAME:
2999 		result = "subroutine function name";
3000 		break;
3001 	case LANGUAGE_FEATURE_SUBROUTINE_TYPE:
3002 		result = "subroutine type";
3003 		break;
3004 	case LANGUAGE_FEATURE_SUBROUTINE_UNIFORM:
3005 		result = "subroutine uniform";
3006 		break;
3007 	case LANGUAGE_FEATURE_UNIFORM:
3008 		result = "uniform";
3009 		break;
3010 	case LANGUAGE_FEATURE_UNIFORM_BLOCK_INSTANCE_NAME:
3011 		result = "uniform block instance name";
3012 		break;
3013 	case LANGUAGE_FEATURE_UNIFORM_BLOCK_MEMBER_NAME:
3014 		result = "uniform block member name";
3015 		break;
3016 	case LANGUAGE_FEATURE_UNIFORM_BLOCK_NAME:
3017 		result = "uniform block name";
3018 		break;
3019 	case LANGUAGE_FEATURE_VARIABLE:
3020 		result = "variable";
3021 		break;
3022 	case LANGUAGE_FEATURE_VARYING:
3023 		result = "varying";
3024 		break;
3025 	default:
3026 		result = "unknown";
3027 		break;
3028 	} /* switch (language_feature) */
3029 
3030 	return result;
3031 }
3032 
3033 /** Returns keywords and reserved names, specific to the running context version. */
getReservedNames() const3034 std::vector<std::string> ReservedNamesTest::getReservedNames() const
3035 {
3036 	const glu::ContextType   context_type = m_context.getRenderContext().getType();
3037 	std::vector<std::string> result;
3038 
3039 	const char** context_keywords   = NULL;
3040 	unsigned int context_n_keywords = 0;
3041 	unsigned int context_n_reserved = 0;
3042 	const char** context_reserved   = NULL;
3043 
3044 	/* Keywords and reserved names were taken straight from relevant shading language specification documents */
3045 	static const char* keywords_gl31[] = {
3046 		"attribute",
3047 		"const",
3048 		"uniform",
3049 		"varying",
3050 		"layout",
3051 		"centroid",
3052 		"flat",
3053 		"smooth",
3054 		"noperspective",
3055 		"break",
3056 		"continue",
3057 		"do",
3058 		"for",
3059 		"while",
3060 		"switch",
3061 		"case",
3062 		"default",
3063 		"if",
3064 		"else",
3065 		"in",
3066 		"out",
3067 		"inout",
3068 		"float",
3069 		"int",
3070 		"void",
3071 		"bool",
3072 		"true",
3073 		"false",
3074 		"invariant",
3075 		"discard",
3076 		"return",
3077 		"mat2",
3078 		"mat3",
3079 		"mat4",
3080 		"mat2x2",
3081 		"mat2x3",
3082 		"mat2x4",
3083 		"mat3x2",
3084 		"mat3x3",
3085 		"mat3x4",
3086 		"mat4x2",
3087 		"mat4x3",
3088 		"mat4x4",
3089 		"vec2",
3090 		"vec3",
3091 		"vec4",
3092 		"ivec2",
3093 		"ivec3",
3094 		"ivec4",
3095 		"bvec2",
3096 		"bvec3",
3097 		"bvec4",
3098 		"uint",
3099 		"uvec2",
3100 		"uvec3",
3101 		"uvec4",
3102 		"lowp",
3103 		"mediump",
3104 		"highp",
3105 		"precision",
3106 		"sampler1D",
3107 		"sampler2D",
3108 		"sampler3D",
3109 		"samplerCube",
3110 		"sampler1DShadow",
3111 		"sampler2DShadow",
3112 		"samplerCubeShadow",
3113 		"sampler1DArray",
3114 		"sampler2DArray",
3115 		"sampler1DArrayShadow",
3116 		"sampler2DArrayShadow",
3117 		"isampler1D",
3118 		"isampler2D",
3119 		"isampler3D",
3120 		"isamplerCube",
3121 		"isampler1DArray",
3122 		"isampler2DArray",
3123 		"usampler1D",
3124 		"usampler2D",
3125 		"usampler3D",
3126 		"usamplerCube",
3127 		"usampler1DArray",
3128 		"usampler2DArray",
3129 		"sampler2DRect",
3130 		"sampler2DRectShadow",
3131 		"isampler2DRect",
3132 		"usampler2DRect",
3133 		"samplerBuffer",
3134 		"isamplerBuffer",
3135 		"usamplerBuffer",
3136 	};
3137 	static const char* keywords_gl32[] = {
3138 		"attribute",
3139 		"const",
3140 		"uniform",
3141 		"varying",
3142 		"layout",
3143 		"centroid",
3144 		"flat",
3145 		"smooth",
3146 		"noperspective",
3147 		"break",
3148 		"continue",
3149 		"do",
3150 		"for",
3151 		"while",
3152 		"switch",
3153 		"case",
3154 		"default",
3155 		"if",
3156 		"else",
3157 		"in",
3158 		"out",
3159 		"inout",
3160 		"float",
3161 		"int",
3162 		"void",
3163 		"bool",
3164 		"true",
3165 		"false",
3166 		"invariant",
3167 		"discard",
3168 		"return",
3169 		"mat2",
3170 		"mat3",
3171 		"mat4",
3172 		"mat2x2",
3173 		"mat2x3",
3174 		"mat2x4",
3175 		"mat3x2",
3176 		"mat3x3",
3177 		"mat3x4",
3178 		"mat4x2",
3179 		"mat4x3",
3180 		"mat4x4",
3181 		"vec2",
3182 		"vec3",
3183 		"vec4",
3184 		"ivec2",
3185 		"ivec3",
3186 		"ivec4",
3187 		"bvec2",
3188 		"bvec3",
3189 		"bvec4",
3190 		"uint",
3191 		"uvec2",
3192 		"uvec3",
3193 		"uvec4",
3194 		"lowp",
3195 		"mediump",
3196 		"highp",
3197 		"precision",
3198 		"sampler1D",
3199 		"sampler2D",
3200 		"sampler3D",
3201 		"samplerCube",
3202 		"sampler1DShadow",
3203 		"sampler2DShadow",
3204 		"samplerCubeShadow",
3205 		"sampler1DArray",
3206 		"sampler2DArray",
3207 		"sampler1DArrayShadow",
3208 		"sampler2DArrayShadow",
3209 		"isampler1D",
3210 		"isampler2D",
3211 		"isampler3D",
3212 		"isamplerCube",
3213 		"isampler1DArray",
3214 		"isampler2DArray",
3215 		"usampler1D",
3216 		"usampler2D",
3217 		"usampler3D",
3218 		"usamplerCube",
3219 		"usampler1DArray",
3220 		"usampler2DArray",
3221 		"sampler2DRect",
3222 		"sampler2DRectShadow",
3223 		"isampler2DRect",
3224 		"usampler2DRect",
3225 		"samplerBuffer",
3226 		"isamplerBuffer",
3227 		"usamplerBuffer",
3228 		"sampler2DMS",
3229 		"isampler2DMS",
3230 		"usampler2DMS",
3231 		"sampler2DMSArray",
3232 		"isampler2DMSArray",
3233 		"usampler2DMSArray",
3234 	};
3235 	static const char* keywords_gl33[] = {
3236 		"attribute",
3237 		"const",
3238 		"uniform",
3239 		"varying",
3240 		"layout",
3241 		"centroid",
3242 		"flat",
3243 		"smooth",
3244 		"noperspective",
3245 		"break",
3246 		"continue",
3247 		"do",
3248 		"for",
3249 		"while",
3250 		"switch",
3251 		"case",
3252 		"default",
3253 		"if",
3254 		"else",
3255 		"in",
3256 		"out",
3257 		"inout",
3258 		"float",
3259 		"int",
3260 		"void",
3261 		"bool",
3262 		"true",
3263 		"false",
3264 		"invariant",
3265 		"discard",
3266 		"return",
3267 		"mat2",
3268 		"mat3",
3269 		"mat4",
3270 		"mat2x2",
3271 		"mat2x3",
3272 		"mat2x4",
3273 		"mat3x2",
3274 		"mat3x3",
3275 		"mat3x4",
3276 		"mat4x2",
3277 		"mat4x3",
3278 		"mat4x4",
3279 		"vec2",
3280 		"vec3",
3281 		"vec4",
3282 		"ivec2",
3283 		"ivec3",
3284 		"ivec4",
3285 		"bvec2",
3286 		"bvec3",
3287 		"bvec4",
3288 		"uint",
3289 		"uvec2",
3290 		"uvec3",
3291 		"uvec4",
3292 		"lowp",
3293 		"mediump",
3294 		"highp",
3295 		"precision",
3296 		"sampler1D",
3297 		"sampler2D",
3298 		"sampler3D",
3299 		"samplerCube",
3300 		"sampler1DShadow",
3301 		"sampler2DShadow",
3302 		"samplerCubeShadow",
3303 		"sampler1DArray",
3304 		"sampler2DArray",
3305 		"sampler1DArrayShadow",
3306 		"sampler2DArrayShadow",
3307 		"isampler1D",
3308 		"isampler2D",
3309 		"isampler3D",
3310 		"isamplerCube",
3311 		"isampler1DArray",
3312 		"isampler2DArray",
3313 		"usampler1D",
3314 		"usampler2D",
3315 		"usampler3D",
3316 		"usamplerCube",
3317 		"usampler1DArray",
3318 		"usampler2DArray",
3319 		"sampler2DRect",
3320 		"sampler2DRectShadow",
3321 		"isampler2DRect",
3322 		"usampler2DRect",
3323 		"samplerBuffer",
3324 		"isamplerBuffer",
3325 		"usamplerBuffer",
3326 		"sampler2DMS",
3327 		"isampler2DMS",
3328 		"usampler2DMS",
3329 		"sampler2DMSArray",
3330 		"isampler2DMSArray",
3331 		"usampler2DMSArray",
3332 	};
3333 	static const char* keywords_gl40[] = {
3334 		"attribute",
3335 		"const",
3336 		"uniform",
3337 		"varying",
3338 		"layout",
3339 		"centroid",
3340 		"flat",
3341 		"smooth",
3342 		"noperspective",
3343 		"patch",
3344 		"sample",
3345 		"break",
3346 		"continue",
3347 		"do",
3348 		"for",
3349 		"while",
3350 		"switch",
3351 		"case",
3352 		"default",
3353 		"if",
3354 		"else",
3355 		"subroutine",
3356 		"in",
3357 		"out",
3358 		"inout",
3359 		"float",
3360 		"double",
3361 		"int",
3362 		"void",
3363 		"bool",
3364 		"true",
3365 		"false",
3366 		"invariant",
3367 		"discard",
3368 		"return",
3369 		"mat2",
3370 		"mat3",
3371 		"mat4",
3372 		"dmat2",
3373 		"dmat3",
3374 		"dmat4",
3375 		"mat2x2",
3376 		"mat2x3",
3377 		"mat2x4",
3378 		"dmat2x2",
3379 		"dmat2x3",
3380 		"dmat2x4",
3381 		"mat3x2",
3382 		"mat3x3",
3383 		"mat3x4",
3384 		"dmat3x2",
3385 		"dmat3x3",
3386 		"dmat3x4",
3387 		"mat4x2",
3388 		"mat4x3",
3389 		"mat4x4",
3390 		"dmat4x2",
3391 		"dmat4x3",
3392 		"dmat4x4",
3393 		"vec2",
3394 		"vec3",
3395 		"vec4",
3396 		"ivec2",
3397 		"ivec3",
3398 		"ivec4",
3399 		"bvec2",
3400 		"bvec3",
3401 		"bvec4",
3402 		"dvec2",
3403 		"dvec3",
3404 		"dvec4",
3405 		"uint",
3406 		"uvec2",
3407 		"uvec3",
3408 		"uvec4",
3409 		"lowp",
3410 		"mediump",
3411 		"highp",
3412 		"precision",
3413 		"sampler1D",
3414 		"sampler2D",
3415 		"sampler3D",
3416 		"samplerCube",
3417 		"sampler1DShadow",
3418 		"sampler2DShadow",
3419 		"samplerCubeShadow",
3420 		"sampler1DArray",
3421 		"sampler2DArray",
3422 		"sampler1DArrayShadow",
3423 		"sampler2DArrayShadow",
3424 		"isampler1D",
3425 		"isampler2D",
3426 		"isampler3D",
3427 		"isamplerCube",
3428 		"isampler1DArray",
3429 		"isampler2DArray",
3430 		"usampler1D",
3431 		"usampler2D",
3432 		"usampler3D",
3433 		"usamplerCube",
3434 		"usampler1DArray",
3435 		"usampler2DArray",
3436 		"sampler2DRect",
3437 		"sampler2DRectShadow",
3438 		"isampler2DRect",
3439 		"usampler2DRect",
3440 		"samplerBuffer",
3441 		"isamplerBuffer",
3442 		"usamplerBuffer",
3443 		"sampler2DMS",
3444 		"isampler2DMS",
3445 		"usampler2DMS",
3446 		"sampler2DMSArray",
3447 		"isampler2DMSArray",
3448 		"usampler2DMSArray",
3449 		"samplerCubeArray",
3450 		"samplerCubeArrayShadow",
3451 		"isamplerCubeArray",
3452 		"usamplerCubeArray",
3453 	};
3454 	static const char* keywords_gl41[] = {
3455 		"attribute",
3456 		"const",
3457 		"uniform",
3458 		"varying",
3459 		"layout",
3460 		"centroid",
3461 		"flat",
3462 		"smooth",
3463 		"noperspective",
3464 		"patch",
3465 		"sample",
3466 		"break",
3467 		"continue",
3468 		"do",
3469 		"for",
3470 		"while",
3471 		"switch",
3472 		"case",
3473 		"default",
3474 		"if",
3475 		"else",
3476 		"subroutine",
3477 		"in",
3478 		"out",
3479 		"inout",
3480 		"float",
3481 		"double",
3482 		"int",
3483 		"void",
3484 		"bool",
3485 		"true",
3486 		"false",
3487 		"invariant",
3488 		"discard",
3489 		"return",
3490 		"mat2",
3491 		"mat3",
3492 		"mat4",
3493 		"dmat2",
3494 		"dmat3",
3495 		"dmat4",
3496 		"mat2x2",
3497 		"mat2x3",
3498 		"mat2x4",
3499 		"dmat2x2",
3500 		"dmat2x3",
3501 		"dmat2x4",
3502 		"mat3x2",
3503 		"mat3x3",
3504 		"mat3x4",
3505 		"dmat3x2",
3506 		"dmat3x3",
3507 		"dmat3x4",
3508 		"mat4x2",
3509 		"mat4x3",
3510 		"mat4x4",
3511 		"dmat4x2",
3512 		"dmat4x3",
3513 		"dmat4x4",
3514 		"vec2",
3515 		"vec3",
3516 		"vec4",
3517 		"ivec2",
3518 		"ivec3",
3519 		"ivec4",
3520 		"bvec2",
3521 		"bvec3",
3522 		"bvec4",
3523 		"dvec2",
3524 		"dvec3",
3525 		"dvec4",
3526 		"uint",
3527 		"uvec2",
3528 		"uvec3",
3529 		"uvec4",
3530 		"lowp",
3531 		"mediump",
3532 		"highp",
3533 		"precision",
3534 		"sampler1D",
3535 		"sampler2D",
3536 		"sampler3D",
3537 		"samplerCube",
3538 		"sampler1DShadow",
3539 		"sampler2DShadow",
3540 		"samplerCubeShadow",
3541 		"sampler1DArray",
3542 		"sampler2DArray",
3543 		"sampler1DArrayShadow",
3544 		"sampler2DArrayShadow",
3545 		"isampler1D",
3546 		"isampler2D",
3547 		"isampler3D",
3548 		"isamplerCube",
3549 		"isampler1DArray",
3550 		"isampler2DArray",
3551 		"usampler1D",
3552 		"usampler2D",
3553 		"usampler3D",
3554 		"usamplerCube",
3555 		"usampler1DArray",
3556 		"usampler2DArray",
3557 		"sampler2DRect",
3558 		"sampler2DRectShadow",
3559 		"isampler2DRect",
3560 		"usampler2DRect",
3561 		"samplerBuffer",
3562 		"isamplerBuffer",
3563 		"usamplerBuffer",
3564 		"sampler2DMS",
3565 		"isampler2DMS",
3566 		"usampler2DMS",
3567 		"sampler2DMSArray",
3568 		"isampler2DMSArray",
3569 		"usampler2DMSArray",
3570 		"samplerCubeArray",
3571 		"samplerCubeArrayShadow",
3572 		"isamplerCubeArray",
3573 		"usamplerCubeArray",
3574 	};
3575 	static const char* keywords_gl42[] = {
3576 		"attribute",
3577 		"const",
3578 		"uniform",
3579 		"varying",
3580 		"coherent",
3581 		"volatile",
3582 		"restrict",
3583 		"readonly",
3584 		"writeonly",
3585 		"atomic_uint",
3586 		"layout",
3587 		"centroid",
3588 		"flat",
3589 		"smooth",
3590 		"noperspective",
3591 		"patch",
3592 		"sample",
3593 		"break",
3594 		"continue",
3595 		"do",
3596 		"for",
3597 		"while",
3598 		"switch",
3599 		"case",
3600 		"default",
3601 		"if",
3602 		"else",
3603 		"subroutine",
3604 		"in",
3605 		"out",
3606 		"inout",
3607 		"float",
3608 		"double",
3609 		"int",
3610 		"void",
3611 		"bool",
3612 		"true",
3613 		"false",
3614 		"invariant",
3615 		"discard",
3616 		"return",
3617 		"mat2",
3618 		"mat3",
3619 		"mat4",
3620 		"dmat2",
3621 		"dmat3",
3622 		"dmat4",
3623 		"mat2x2",
3624 		"mat2x3",
3625 		"mat2x4",
3626 		"dmat2x2",
3627 		"dmat2x3",
3628 		"dmat2x4",
3629 		"mat3x2",
3630 		"mat3x3",
3631 		"mat3x4",
3632 		"dmat3x2",
3633 		"dmat3x3",
3634 		"dmat3x4",
3635 		"mat4x2",
3636 		"mat4x3",
3637 		"mat4x4",
3638 		"dmat4x2",
3639 		"dmat4x3",
3640 		"dmat4x4",
3641 		"vec2",
3642 		"vec3",
3643 		"vec4",
3644 		"ivec2",
3645 		"ivec3",
3646 		"ivec4",
3647 		"bvec2",
3648 		"bvec3",
3649 		"bvec4",
3650 		"dvec2",
3651 		"dvec3",
3652 		"dvec4",
3653 		"uint",
3654 		"uvec2",
3655 		"uvec3",
3656 		"uvec4",
3657 		"lowp",
3658 		"mediump",
3659 		"highp",
3660 		"precision",
3661 		"sampler1D",
3662 		"sampler2D",
3663 		"sampler3D",
3664 		"samplerCube",
3665 		"sampler1DShadow",
3666 		"sampler2DShadow",
3667 		"samplerCubeShadow",
3668 		"sampler1DArray",
3669 		"sampler2DArray",
3670 		"sampler1DArrayShadow",
3671 		"sampler2DArrayShadow",
3672 		"isampler1D",
3673 		"isampler2D",
3674 		"isampler3D",
3675 		"isamplerCube",
3676 		"isampler1DArray",
3677 		"isampler2DArray",
3678 		"usampler1D",
3679 		"usampler2D",
3680 		"usampler3D",
3681 		"usamplerCube",
3682 		"usampler1DArray",
3683 		"usampler2DArray",
3684 		"sampler2DRect",
3685 		"sampler2DRectShadow",
3686 		"isampler2DRect",
3687 		"usampler2DRect",
3688 		"samplerBuffer",
3689 		"isamplerBuffer",
3690 		"usamplerBuffer",
3691 		"sampler2DMS",
3692 		"isampler2DMS",
3693 		"usampler2DMS",
3694 		"sampler2DMSArray",
3695 		"isampler2DMSArray",
3696 		"usampler2DMSArray",
3697 		"samplerCubeArray",
3698 		"samplerCubeArrayShadow",
3699 		"isamplerCubeArray",
3700 		"usamplerCubeArray",
3701 		"image1D",
3702 		"iimage1D",
3703 		"uimage1D",
3704 		"image2D",
3705 		"iimage2D",
3706 		"uimage2D",
3707 		"image3D",
3708 		"iimage3D",
3709 		"uimage3D",
3710 		"image2DRect",
3711 		"iimage2DRect",
3712 		"uimage2DRect",
3713 		"imageCube",
3714 		"iimageCube",
3715 		"uimageCube",
3716 		"imageBuffer",
3717 		"iimageBuffer",
3718 		"uimageBuffer",
3719 		"image1DArray",
3720 		"iimage1DArray",
3721 		"uimage1DArray",
3722 		"image2DArray",
3723 		"iimage2DArray",
3724 		"uimage2DArray",
3725 		"imageCubeArray",
3726 		"iimageCubeArray",
3727 		"uimageCubeArray",
3728 		"image2DMS",
3729 		"iimage2DMS",
3730 		"uimage2DMS",
3731 		"image2DMSArray",
3732 		"iimage2DMSArray",
3733 		"uimage2DMSArray",
3734 	};
3735 	static const char* keywords_gl43[] = {
3736 		"attribute",
3737 		"const",
3738 		"uniform",
3739 		"varying",
3740 		"buffer",
3741 		"shared",
3742 		"coherent",
3743 		"volatile",
3744 		"restrict",
3745 		"readonly",
3746 		"writeonly",
3747 		"atomic_uint",
3748 		"layout",
3749 		"centroid",
3750 		"flat",
3751 		"smooth",
3752 		"noperspective",
3753 		"patch",
3754 		"sample",
3755 		"break",
3756 		"continue",
3757 		"do",
3758 		"for",
3759 		"while",
3760 		"switch",
3761 		"case",
3762 		"default",
3763 		"if",
3764 		"else",
3765 		"subroutine",
3766 		"in",
3767 		"out",
3768 		"inout",
3769 		"float",
3770 		"double",
3771 		"int",
3772 		"void",
3773 		"bool",
3774 		"true",
3775 		"false",
3776 		"invariant",
3777 		"precise",
3778 		"discard",
3779 		"return",
3780 		"mat2",
3781 		"mat3",
3782 		"mat4",
3783 		"dmat2",
3784 		"dmat3",
3785 		"dmat4",
3786 		"mat2x2",
3787 		"mat2x3",
3788 		"mat2x4",
3789 		"dmat2x2",
3790 		"dmat2x3",
3791 		"dmat2x4",
3792 		"mat3x2",
3793 		"mat3x3",
3794 		"mat3x4",
3795 		"dmat3x2",
3796 		"dmat3x3",
3797 		"dmat3x4",
3798 		"mat4x2",
3799 		"mat4x3",
3800 		"mat4x4",
3801 		"dmat4x2",
3802 		"dmat4x3",
3803 		"dmat4x4",
3804 		"vec2",
3805 		"vec3",
3806 		"vec4",
3807 		"ivec2",
3808 		"ivec3",
3809 		"ivec4",
3810 		"bvec2",
3811 		"bvec3",
3812 		"bvec4",
3813 		"dvec2",
3814 		"dvec3",
3815 		"dvec4",
3816 		"uint",
3817 		"uvec2",
3818 		"uvec3",
3819 		"uvec4",
3820 		"lowp",
3821 		"mediump",
3822 		"highp",
3823 		"precision",
3824 		"sampler1D",
3825 		"sampler2D",
3826 		"sampler3D",
3827 		"samplerCube",
3828 		"sampler1DShadow",
3829 		"sampler2DShadow",
3830 		"samplerCubeShadow",
3831 		"sampler1DArray",
3832 		"sampler2DArray",
3833 		"sampler1DArrayShadow",
3834 		"sampler2DArrayShadow",
3835 		"isampler1D",
3836 		"isampler2D",
3837 		"isampler3D",
3838 		"isamplerCube",
3839 		"isampler1DArray",
3840 		"isampler2DArray",
3841 		"usampler1D",
3842 		"usampler2D",
3843 		"usampler3D",
3844 		"usamplerCube",
3845 		"usampler1DArray",
3846 		"usampler2DArray",
3847 		"sampler2DRect",
3848 		"sampler2DRectShadow",
3849 		"isampler2DRect",
3850 		"usampler2DRect",
3851 		"samplerBuffer",
3852 		"isamplerBuffer",
3853 		"usamplerBuffer",
3854 		"sampler2DMS",
3855 		"isampler2DMS",
3856 		"usampler2DMS",
3857 		"sampler2DMSArray",
3858 		"isampler2DMSArray",
3859 		"usampler2DMSArray",
3860 		"samplerCubeArray",
3861 		"samplerCubeArrayShadow",
3862 		"isamplerCubeArray",
3863 		"usamplerCubeArray",
3864 		"image1D",
3865 		"iimage1D",
3866 		"uimage1D",
3867 		"image2D",
3868 		"iimage2D",
3869 		"uimage2D",
3870 		"image3D",
3871 		"iimage3D",
3872 		"uimage3D",
3873 		"image2DRect",
3874 		"iimage2DRect",
3875 		"uimage2DRect",
3876 		"imageCube",
3877 		"iimageCube",
3878 		"uimageCube",
3879 		"imageBuffer",
3880 		"iimageBuffer",
3881 		"uimageBuffer",
3882 		"image1DArray",
3883 		"iimage1DArray",
3884 		"uimage1DArray",
3885 		"image2DArray",
3886 		"iimage2DArray",
3887 		"uimage2DArray",
3888 		"imageCubeArray",
3889 		"iimageCubeArray",
3890 		"uimageCubeArray",
3891 		"image2DMS",
3892 		"iimage2DMS",
3893 		"uimage2DMS",
3894 		"image2DMSArray",
3895 		"iimage2DMSArray",
3896 		"uimage2DMSArray",
3897 	};
3898 	static const char* keywords_gl44[] = {
3899 		"attribute",
3900 		"const",
3901 		"uniform",
3902 		"varying",
3903 		"buffer",
3904 		"shared",
3905 		"coherent",
3906 		"volatile",
3907 		"restrict",
3908 		"readonly",
3909 		"writeonly",
3910 		"atomic_uint",
3911 		"layout",
3912 		"centroid",
3913 		"flat",
3914 		"smooth",
3915 		"noperspective",
3916 		"patch",
3917 		"sample",
3918 		"break",
3919 		"continue",
3920 		"do",
3921 		"for",
3922 		"while",
3923 		"switch",
3924 		"case",
3925 		"default",
3926 		"if",
3927 		"else",
3928 		"subroutine",
3929 		"in",
3930 		"out",
3931 		"inout",
3932 		"float",
3933 		"double",
3934 		"int",
3935 		"void",
3936 		"bool",
3937 		"true",
3938 		"false",
3939 		"invariant",
3940 		"precise",
3941 		"discard",
3942 		"return",
3943 		"mat2",
3944 		"mat3",
3945 		"mat4",
3946 		"dmat2",
3947 		"dmat3",
3948 		"dmat4",
3949 		"mat2x2",
3950 		"mat2x3",
3951 		"mat2x4",
3952 		"dmat2x2",
3953 		"dmat2x3",
3954 		"dmat2x4",
3955 		"mat3x2",
3956 		"mat3x3",
3957 		"mat3x4",
3958 		"dmat3x2",
3959 		"dmat3x3",
3960 		"dmat3x4",
3961 		"mat4x2",
3962 		"mat4x3",
3963 		"mat4x4",
3964 		"dmat4x2",
3965 		"dmat4x3",
3966 		"dmat4x4",
3967 		"vec2",
3968 		"vec3",
3969 		"vec4",
3970 		"ivec2",
3971 		"ivec3",
3972 		"ivec4",
3973 		"bvec2",
3974 		"bvec3",
3975 		"bvec4",
3976 		"dvec2",
3977 		"dvec3",
3978 		"dvec4",
3979 		"uint",
3980 		"uvec2",
3981 		"uvec3",
3982 		"uvec4",
3983 		"lowp",
3984 		"mediump",
3985 		"highp",
3986 		"precision",
3987 		"sampler1D",
3988 		"sampler2D",
3989 		"sampler3D",
3990 		"samplerCube",
3991 		"sampler1DShadow",
3992 		"sampler2DShadow",
3993 		"samplerCubeShadow",
3994 		"sampler1DArray",
3995 		"sampler2DArray",
3996 		"sampler1DArrayShadow",
3997 		"sampler2DArrayShadow",
3998 		"isampler1D",
3999 		"isampler2D",
4000 		"isampler3D",
4001 		"isamplerCube",
4002 		"isampler1DArray",
4003 		"isampler2DArray",
4004 		"usampler1D",
4005 		"usampler2D",
4006 		"usampler3D",
4007 		"usamplerCube",
4008 		"usampler1DArray",
4009 		"usampler2DArray",
4010 		"sampler2DRect",
4011 		"sampler2DRectShadow",
4012 		"isampler2DRect",
4013 		"usampler2DRect",
4014 		"samplerBuffer",
4015 		"isamplerBuffer",
4016 		"usamplerBuffer",
4017 		"sampler2DMS",
4018 		"isampler2DMS",
4019 		"usampler2DMS",
4020 		"sampler2DMSArray",
4021 		"isampler2DMSArray",
4022 		"usampler2DMSArray",
4023 		"samplerCubeArray",
4024 		"samplerCubeArrayShadow",
4025 		"isamplerCubeArray",
4026 		"usamplerCubeArray",
4027 		"image1D",
4028 		"iimage1D",
4029 		"uimage1D",
4030 		"image2D",
4031 		"iimage2D",
4032 		"uimage2D",
4033 		"image3D",
4034 		"iimage3D",
4035 		"uimage3D",
4036 		"image2DRect",
4037 		"iimage2DRect",
4038 		"uimage2DRect",
4039 		"imageCube",
4040 		"iimageCube",
4041 		"uimageCube",
4042 		"imageBuffer",
4043 		"iimageBuffer",
4044 		"uimageBuffer",
4045 		"image1DArray",
4046 		"iimage1DArray",
4047 		"uimage1DArray",
4048 		"image2DArray",
4049 		"iimage2DArray",
4050 		"uimage2DArray",
4051 		"imageCubeArray",
4052 		"iimageCubeArray",
4053 		"uimageCubeArray",
4054 		"image2DMS",
4055 		"iimage2DMS",
4056 		"uimage2DMS",
4057 		"image2DMSArray",
4058 		"iimage2DMSArray",
4059 		"uimage2DMSArray",
4060 	};
4061 	static const char* keywords_gl45[] = {
4062 		"attribute",
4063 		"const",
4064 		"uniform",
4065 		"varying",
4066 		"buffer",
4067 		"shared",
4068 		"coherent",
4069 		"volatile",
4070 		"restrict",
4071 		"readonly",
4072 		"writeonly",
4073 		"atomic_uint",
4074 		"layout",
4075 		"centroid",
4076 		"flat",
4077 		"smooth",
4078 		"noperspective",
4079 		"patch",
4080 		"sample",
4081 		"break",
4082 		"continue",
4083 		"do",
4084 		"for",
4085 		"while",
4086 		"switch",
4087 		"case",
4088 		"default",
4089 		"if",
4090 		"else",
4091 		"subroutine",
4092 		"in",
4093 		"out",
4094 		"inout",
4095 		"float",
4096 		"double",
4097 		"int",
4098 		"void",
4099 		"bool",
4100 		"true",
4101 		"false",
4102 		"invariant",
4103 		"precise",
4104 		"discard",
4105 		"return",
4106 		"mat2",
4107 		"mat3",
4108 		"mat4",
4109 		"dmat2",
4110 		"dmat3",
4111 		"dmat4",
4112 		"mat2x2",
4113 		"mat2x3",
4114 		"mat2x4",
4115 		"dmat2x2",
4116 		"dmat2x3",
4117 		"dmat2x4",
4118 		"mat3x2",
4119 		"mat3x3",
4120 		"mat3x4",
4121 		"dmat3x2",
4122 		"dmat3x3",
4123 		"dmat3x4",
4124 		"mat4x2",
4125 		"mat4x3",
4126 		"mat4x4",
4127 		"dmat4x2",
4128 		"dmat4x3",
4129 		"dmat4x4",
4130 		"vec2",
4131 		"vec3",
4132 		"vec4",
4133 		"ivec2",
4134 		"ivec3",
4135 		"ivec4",
4136 		"bvec2",
4137 		"bvec3",
4138 		"bvec4",
4139 		"dvec2",
4140 		"dvec3",
4141 		"dvec4",
4142 		"uint",
4143 		"uvec2",
4144 		"uvec3",
4145 		"uvec4",
4146 		"lowp",
4147 		"mediump",
4148 		"highp",
4149 		"precision",
4150 		"sampler1D",
4151 		"sampler2D",
4152 		"sampler3D",
4153 		"samplerCube",
4154 		"sampler1DShadow",
4155 		"sampler2DShadow",
4156 		"samplerCubeShadow",
4157 		"sampler1DArray",
4158 		"sampler2DArray",
4159 		"sampler1DArrayShadow",
4160 		"sampler2DArrayShadow",
4161 		"isampler1D",
4162 		"isampler2D",
4163 		"isampler3D",
4164 		"isamplerCube",
4165 		"isampler1DArray",
4166 		"isampler2DArray",
4167 		"usampler1D",
4168 		"usampler2D",
4169 		"usampler3D",
4170 		"usamplerCube",
4171 		"usampler1DArray",
4172 		"usampler2DArray",
4173 		"sampler2DRect",
4174 		"sampler2DRectShadow",
4175 		"isampler2DRect",
4176 		"usampler2DRect",
4177 		"samplerBuffer",
4178 		"isamplerBuffer",
4179 		"usamplerBuffer",
4180 		"sampler2DMS",
4181 		"isampler2DMS",
4182 		"usampler2DMS",
4183 		"sampler2DMSArray",
4184 		"isampler2DMSArray",
4185 		"usampler2DMSArray",
4186 		"samplerCubeArray",
4187 		"samplerCubeArrayShadow",
4188 		"isamplerCubeArray",
4189 		"usamplerCubeArray",
4190 		"image1D",
4191 		"iimage1D",
4192 		"uimage1D",
4193 		"image2D",
4194 		"iimage2D",
4195 		"uimage2D",
4196 		"image3D",
4197 		"iimage3D",
4198 		"uimage3D",
4199 		"image2DRect",
4200 		"iimage2DRect",
4201 		"uimage2DRect",
4202 		"imageCube",
4203 		"iimageCube",
4204 		"uimageCube",
4205 		"imageBuffer",
4206 		"iimageBuffer",
4207 		"uimageBuffer",
4208 		"image1DArray",
4209 		"iimage1DArray",
4210 		"uimage1DArray",
4211 		"image2DArray",
4212 		"iimage2DArray",
4213 		"uimage2DArray",
4214 		"imageCubeArray",
4215 		"iimageCubeArray",
4216 		"uimageCubeArray",
4217 		"image2DMS",
4218 		"iimage2DMS",
4219 		"uimage2DMS",
4220 		"image2DMSArray",
4221 		"iimage2DMSArray",
4222 		"uimage2DMSArray",
4223 	};
4224 	static const char* keywords_gl46[] = {
4225 		"attribute",
4226 		"const",
4227 		"uniform",
4228 		"varying",
4229 		"buffer",
4230 		"shared",
4231 		"coherent",
4232 		"volatile",
4233 		"restrict",
4234 		"readonly",
4235 		"writeonly",
4236 		"atomic_uint",
4237 		"layout",
4238 		"centroid",
4239 		"flat",
4240 		"smooth",
4241 		"noperspective",
4242 		"patch",
4243 		"sample",
4244 		"break",
4245 		"continue",
4246 		"do",
4247 		"for",
4248 		"while",
4249 		"switch",
4250 		"case",
4251 		"default",
4252 		"if",
4253 		"else",
4254 		"subroutine",
4255 		"in",
4256 		"out",
4257 		"inout",
4258 		"float",
4259 		"double",
4260 		"int",
4261 		"void",
4262 		"bool",
4263 		"true",
4264 		"false",
4265 		"invariant",
4266 		"precise",
4267 		"discard",
4268 		"return",
4269 		"mat2",
4270 		"mat3",
4271 		"mat4",
4272 		"dmat2",
4273 		"dmat3",
4274 		"dmat4",
4275 		"mat2x2",
4276 		"mat2x3",
4277 		"mat2x4",
4278 		"dmat2x2",
4279 		"dmat2x3",
4280 		"dmat2x4",
4281 		"mat3x2",
4282 		"mat3x3",
4283 		"mat3x4",
4284 		"dmat3x2",
4285 		"dmat3x3",
4286 		"dmat3x4",
4287 		"mat4x2",
4288 		"mat4x3",
4289 		"mat4x4",
4290 		"dmat4x2",
4291 		"dmat4x3",
4292 		"dmat4x4",
4293 		"vec2",
4294 		"vec3",
4295 		"vec4",
4296 		"ivec2",
4297 		"ivec3",
4298 		"ivec4",
4299 		"bvec2",
4300 		"bvec3",
4301 		"bvec4",
4302 		"dvec2",
4303 		"dvec3",
4304 		"dvec4",
4305 		"uint",
4306 		"uvec2",
4307 		"uvec3",
4308 		"uvec4",
4309 		"lowp",
4310 		"mediump",
4311 		"highp",
4312 		"precision",
4313 		"sampler1D",
4314 		"sampler2D",
4315 		"sampler3D",
4316 		"samplerCube",
4317 		"sampler1DShadow",
4318 		"sampler2DShadow",
4319 		"samplerCubeShadow",
4320 		"sampler1DArray",
4321 		"sampler2DArray",
4322 		"sampler1DArrayShadow",
4323 		"sampler2DArrayShadow",
4324 		"isampler1D",
4325 		"isampler2D",
4326 		"isampler3D",
4327 		"isamplerCube",
4328 		"isampler1DArray",
4329 		"isampler2DArray",
4330 		"usampler1D",
4331 		"usampler2D",
4332 		"usampler3D",
4333 		"usamplerCube",
4334 		"usampler1DArray",
4335 		"usampler2DArray",
4336 		"sampler2DRect",
4337 		"sampler2DRectShadow",
4338 		"isampler2DRect",
4339 		"usampler2DRect",
4340 		"samplerBuffer",
4341 		"isamplerBuffer",
4342 		"usamplerBuffer",
4343 		"sampler2DMS",
4344 		"isampler2DMS",
4345 		"usampler2DMS",
4346 		"sampler2DMSArray",
4347 		"isampler2DMSArray",
4348 		"usampler2DMSArray",
4349 		"samplerCubeArray",
4350 		"samplerCubeArrayShadow",
4351 		"isamplerCubeArray",
4352 		"usamplerCubeArray",
4353 		"image1D",
4354 		"iimage1D",
4355 		"uimage1D",
4356 		"image2D",
4357 		"iimage2D",
4358 		"uimage2D",
4359 		"image3D",
4360 		"iimage3D",
4361 		"uimage3D",
4362 		"image2DRect",
4363 		"iimage2DRect",
4364 		"uimage2DRect",
4365 		"imageCube",
4366 		"iimageCube",
4367 		"uimageCube",
4368 		"imageBuffer",
4369 		"iimageBuffer",
4370 		"uimageBuffer",
4371 		"image1DArray",
4372 		"iimage1DArray",
4373 		"uimage1DArray",
4374 		"image2DArray",
4375 		"iimage2DArray",
4376 		"uimage2DArray",
4377 		"imageCubeArray",
4378 		"iimageCubeArray",
4379 		"uimageCubeArray",
4380 		"image2DMS",
4381 		"iimage2DMS",
4382 		"uimage2DMS",
4383 		"image2DMSArray",
4384 		"iimage2DMSArray",
4385 		"uimage2DMSArray",
4386 		"struct"
4387 	};
4388 	static const char* reserved_gl31[] = {
4389 		"common",
4390 		"partition",
4391 		"active",
4392 		"asm",
4393 		"class",
4394 		"union",
4395 		"enum",
4396 		"typedef",
4397 		"template",
4398 		"this",
4399 		"packed",
4400 		"goto",
4401 		"inline",
4402 		"noinline",
4403 		"volatile",
4404 		"public",
4405 		"static",
4406 		"extern",
4407 		"external",
4408 		"interface",
4409 		"long",
4410 		"short",
4411 		"double",
4412 		"half",
4413 		"fixed",
4414 		"unsigned",
4415 		"superp",
4416 		"input",
4417 		"output",
4418 		"hvec2",
4419 		"hvec3",
4420 		"hvec4",
4421 		"dvec2",
4422 		"dvec3",
4423 		"dvec4",
4424 		"fvec2",
4425 		"fvec3",
4426 		"fvec4",
4427 		"sampler3DRect",
4428 		"filter",
4429 		"image1D",
4430 		"image2D",
4431 		"image3D",
4432 		"imageCube",
4433 		"iimage1D",
4434 		"iimage2D",
4435 		"iimage3D",
4436 		"iimageCube",
4437 		"uimage1D",
4438 		"uimage2D",
4439 		"uimage3D",
4440 		"uimageCube",
4441 		"image1DArray",
4442 		"image2DArray",
4443 		"iimage1DArray",
4444 		"iimage2DArray",
4445 		"uimage1DArray",
4446 		"uimage2DArray",
4447 		"image1DShadow",
4448 		"image2DShadow",
4449 		"image1DArrayShadow",
4450 		"image2DArrayShadow",
4451 		"imageBuffer",
4452 		"iimageBuffer",
4453 		"uimageBuffer",
4454 		"sizeof",
4455 		"cast",
4456 		"namespace",
4457 		"using",
4458 		"row_major",
4459 	};
4460 	static const char* reserved_gl32[] = {
4461 		"common",
4462 		"partition",
4463 		"active",
4464 		"asm",
4465 		"class",
4466 		"union",
4467 		"enum",
4468 		"typedef",
4469 		"template",
4470 		"this",
4471 		"packed",
4472 		"goto",
4473 		"inline",
4474 		"noinline",
4475 		"volatile",
4476 		"public",
4477 		"static",
4478 		"extern",
4479 		"external",
4480 		"interface",
4481 		"long",
4482 		"short",
4483 		"double",
4484 		"half",
4485 		"fixed",
4486 		"unsigned",
4487 		"superp",
4488 		"input",
4489 		"output",
4490 		"hvec2",
4491 		"hvec3",
4492 		"hvec4",
4493 		"dvec2",
4494 		"dvec3",
4495 		"dvec4",
4496 		"fvec2",
4497 		"fvec3",
4498 		"fvec4",
4499 		"sampler3DRect",
4500 		"filter",
4501 		"image1D",
4502 		"image2D",
4503 		"image3D",
4504 		"imageCube",
4505 		"iimage1D",
4506 		"iimage2D",
4507 		"iimage3D",
4508 		"iimageCube",
4509 		"uimage1D",
4510 		"uimage2D",
4511 		"uimage3D",
4512 		"uimageCube",
4513 		"image1DArray",
4514 		"image2DArray",
4515 		"iimage1DArray",
4516 		"iimage2DArray",
4517 		"uimage1DArray",
4518 		"uimage2DArray",
4519 		"image1DShadow",
4520 		"image2DShadow",
4521 		"image1DArrayShadow",
4522 		"image2DArrayShadow",
4523 		"imageBuffer",
4524 		"iimageBuffer",
4525 		"uimageBuffer",
4526 		"sizeof",
4527 		"cast",
4528 		"namespace",
4529 		"using",
4530 		"row_major",
4531 	};
4532 	static const char* reserved_gl33[] = {
4533 		"common",
4534 		"partition",
4535 		"active",
4536 		"asm",
4537 		"class",
4538 		"union",
4539 		"enum",
4540 		"typedef",
4541 		"template",
4542 		"this",
4543 		"packed",
4544 		"goto",
4545 		"inline",
4546 		"noinline",
4547 		"volatile",
4548 		"public",
4549 		"static",
4550 		"extern",
4551 		"external",
4552 		"interface",
4553 		"long",
4554 		"short",
4555 		"double",
4556 		"half",
4557 		"fixed",
4558 		"unsigned",
4559 		"superp",
4560 		"input",
4561 		"output",
4562 		"hvec2",
4563 		"hvec3",
4564 		"hvec4",
4565 		"dvec2",
4566 		"dvec3",
4567 		"dvec4",
4568 		"fvec2",
4569 		"fvec3",
4570 		"fvec4",
4571 		"sampler3DRect",
4572 		"filter",
4573 		"image1D",
4574 		"image2D",
4575 		"image3D",
4576 		"imageCube",
4577 		"iimage1D",
4578 		"iimage2D",
4579 		"iimage3D",
4580 		"iimageCube",
4581 		"uimage1D",
4582 		"uimage2D",
4583 		"uimage3D",
4584 		"uimageCube",
4585 		"image1DArray",
4586 		"image2DArray",
4587 		"iimage1DArray",
4588 		"iimage2DArray",
4589 		"uimage1DArray",
4590 		"uimage2DArray",
4591 		"image1DShadow",
4592 		"image2DShadow",
4593 		"image1DArrayShadow",
4594 		"image2DArrayShadow",
4595 		"imageBuffer",
4596 		"iimageBuffer",
4597 		"uimageBuffer",
4598 		"sizeof",
4599 		"cast",
4600 		"namespace",
4601 		"using",
4602 		"row_major",
4603 	};
4604 	static const char* reserved_gl40[] = {
4605 		"common",
4606 		"partition",
4607 		"active",
4608 		"asm",
4609 		"class",
4610 		"union",
4611 		"enum",
4612 		"typedef",
4613 		"template",
4614 		"this",
4615 		"packed",
4616 		"goto",
4617 		"inline",
4618 		"noinline",
4619 		"volatile",
4620 		"public",
4621 		"static",
4622 		"extern",
4623 		"external",
4624 		"interface",
4625 		"long",
4626 		"short",
4627 		"half",
4628 		"fixed",
4629 		"unsigned",
4630 		"superp",
4631 		"input",
4632 		"output",
4633 		"hvec2",
4634 		"hvec3",
4635 		"hvec4",
4636 		"fvec2",
4637 		"fvec3",
4638 		"fvec4",
4639 		"sampler3DRect",
4640 		"filter",
4641 		"image1D",
4642 		"image2D",
4643 		"image3D",
4644 		"imageCube",
4645 		"iimage1D",
4646 		"iimage2D",
4647 		"iimage3D",
4648 		"iimageCube",
4649 		"uimage1D",
4650 		"uimage2D",
4651 		"uimage3D",
4652 		"uimageCube",
4653 		"image1DArray",
4654 		"image2DArray",
4655 		"iimage1DArray",
4656 		"iimage2DArray",
4657 		"uimage1DArray",
4658 		"uimage2DArray",
4659 		"image1DShadow",
4660 		"image2DShadow",
4661 		"image1DArrayShadow",
4662 		"image2DArrayShadow",
4663 		"imageBuffer",
4664 		"iimageBuffer",
4665 		"uimageBuffer",
4666 		"sizeof",
4667 		"cast",
4668 		"namespace",
4669 		"using",
4670 		"row_major",
4671 	};
4672 	static const char* reserved_gl41[] = {
4673 		"common",
4674 		"partition",
4675 		"active",
4676 		"asm",
4677 		"class",
4678 		"union",
4679 		"enum",
4680 		"typedef",
4681 		"template",
4682 		"this",
4683 		"packed",
4684 		"goto",
4685 		"inline",
4686 		"noinline",
4687 		"volatile",
4688 		"public",
4689 		"static",
4690 		"extern",
4691 		"external",
4692 		"interface",
4693 		"long",
4694 		"short",
4695 		"half",
4696 		"fixed",
4697 		"unsigned",
4698 		"superp",
4699 		"input",
4700 		"output",
4701 		"hvec2",
4702 		"hvec3",
4703 		"hvec4",
4704 		"fvec2",
4705 		"fvec3",
4706 		"fvec4",
4707 		"sampler3DRect",
4708 		"filter",
4709 		"image1D",
4710 		"image2D",
4711 		"image3D",
4712 		"imageCube",
4713 		"iimage1D",
4714 		"iimage2D",
4715 		"iimage3D",
4716 		"iimageCube",
4717 		"uimage1D",
4718 		"uimage2D",
4719 		"uimage3D",
4720 		"uimageCube",
4721 		"image1DArray",
4722 		"image2DArray",
4723 		"iimage1DArray",
4724 		"iimage2DArray",
4725 		"uimage1DArray",
4726 		"uimage2DArray",
4727 		"image1DShadow",
4728 		"image2DShadow",
4729 		"image1DArrayShadow",
4730 		"image2DArrayShadow",
4731 		"imageBuffer",
4732 		"iimageBuffer",
4733 		"uimageBuffer",
4734 		"sizeof",
4735 		"cast",
4736 		"namespace",
4737 		"using",
4738 		"row_major",
4739 	};
4740 	static const char* reserved_gl42[] = {
4741 		"common",   "partition", "active",	"asm",   "class",		"union",	"enum",		"typedef",		 "template",
4742 		"this",		"packed",	"resource",  "goto",  "inline",	"noinline", "public",   "static",		 "extern",
4743 		"external", "interface", "long",	  "short", "half",		"fixed",	"unsigned", "superp",		 "input",
4744 		"output",   "hvec2",	 "hvec3",	 "hvec4", "fvec2",		"fvec3",	"fvec4",	"sampler3DRect", "filter",
4745 		"sizeof",   "cast",		 "namespace", "using", "row_major",
4746 	};
4747 	static const char* reserved_gl43[] = {
4748 		"common",   "partition", "active",	"asm",   "class",		"union",	"enum",		"typedef",		 "template",
4749 		"this",		"packed",	"resource",  "goto",  "inline",	"noinline", "public",   "static",		 "extern",
4750 		"external", "interface", "long",	  "short", "half",		"fixed",	"unsigned", "superp",		 "input",
4751 		"output",   "hvec2",	 "hvec3",	 "hvec4", "fvec2",		"fvec3",	"fvec4",	"sampler3DRect", "filter",
4752 		"sizeof",   "cast",		 "namespace", "using", "row_major",
4753 	};
4754 	static const char* reserved_gl44[] = {
4755 		"common",   "partition",	 "active",	"asm",	"class",  "union",	 "enum",   "typedef",
4756 		"template", "this",			 "resource",  "goto",   "inline", "noinline",  "public", "static",
4757 		"extern",   "external",		 "interface", "long",   "short",  "half",	  "fixed",  "unsigned",
4758 		"superp",   "input",		 "output",	"hvec2",  "hvec3",  "hvec4",	 "fvec2",  "fvec3",
4759 		"fvec4",	"sampler3DRect", "filter",	"sizeof", "cast",   "namespace", "using",
4760 	};
4761 	static const char* reserved_gl45[] = {
4762 		"common",   "partition",	 "active",	"asm",	"class",  "union",	 "enum",   "typedef",
4763 		"template", "this",			 "resource",  "goto",   "inline", "noinline",  "public", "static",
4764 		"extern",   "external",		 "interface", "long",   "short",  "half",	  "fixed",  "unsigned",
4765 		"superp",   "input",		 "output",	"hvec2",  "hvec3",  "hvec4",	 "fvec2",  "fvec3",
4766 		"fvec4",	"sampler3DRect", "filter",	"sizeof", "cast",   "namespace", "using",
4767 	};
4768 	static const char* reserved_gl46[] = {
4769 		"common",   "partition",	 "active",	"asm",	"class",  "union",	 "enum",   "typedef",
4770 		"template", "this",			 "resource",  "goto",   "inline", "noinline",  "public", "static",
4771 		"extern",   "external",		 "interface", "long",   "short",  "half",	  "fixed",  "unsigned",
4772 		"superp",   "input",		 "output",	"hvec2",  "hvec3",  "hvec4",	 "fvec2",  "fvec3",
4773 		"fvec4",	"sampler3DRect", "filter",	"sizeof", "cast",   "namespace", "using",
4774 	};
4775 
4776 	glu::ApiType apiType = context_type.getAPI();
4777 	if (apiType == glu::ApiType::core(3, 1))
4778 	{
4779 		context_keywords   = keywords_gl31;
4780 		context_reserved   = reserved_gl31;
4781 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl31) / sizeof(keywords_gl31[0]));
4782 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl31) / sizeof(reserved_gl31[0]));
4783 	}
4784 	else if (apiType == glu::ApiType::core(3, 2))
4785 	{
4786 		context_keywords   = keywords_gl32;
4787 		context_reserved   = reserved_gl32;
4788 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl32) / sizeof(keywords_gl32[0]));
4789 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl32) / sizeof(reserved_gl32[0]));
4790 	}
4791 	else if (apiType == glu::ApiType::core(3, 3))
4792 	{
4793 		context_keywords   = keywords_gl33;
4794 		context_reserved   = reserved_gl33;
4795 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl33) / sizeof(keywords_gl33[0]));
4796 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl33) / sizeof(reserved_gl33[0]));
4797 	}
4798 	else if (apiType == glu::ApiType::core(4, 0))
4799 	{
4800 		context_keywords   = keywords_gl40;
4801 		context_reserved   = reserved_gl40;
4802 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl40) / sizeof(keywords_gl40[0]));
4803 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl40) / sizeof(reserved_gl40[0]));
4804 	}
4805 	else if (apiType == glu::ApiType::core(4, 1))
4806 	{
4807 		context_keywords   = keywords_gl41;
4808 		context_reserved   = reserved_gl41;
4809 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl41) / sizeof(keywords_gl41[0]));
4810 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl41) / sizeof(reserved_gl41[0]));
4811 	}
4812 	else if (apiType == glu::ApiType::core(4, 2))
4813 	{
4814 		context_keywords   = keywords_gl42;
4815 		context_reserved   = reserved_gl42;
4816 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl42) / sizeof(keywords_gl42[0]));
4817 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl42) / sizeof(reserved_gl42[0]));
4818 	}
4819 	else if (apiType == glu::ApiType::core(4, 3))
4820 	{
4821 		context_keywords   = keywords_gl43;
4822 		context_reserved   = reserved_gl43;
4823 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl43) / sizeof(keywords_gl43[0]));
4824 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl43) / sizeof(reserved_gl43[0]));
4825 	}
4826 	else if (apiType == glu::ApiType::core(4, 4))
4827 	{
4828 		context_keywords   = keywords_gl44;
4829 		context_reserved   = reserved_gl44;
4830 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl44) / sizeof(keywords_gl44[0]));
4831 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl44) / sizeof(reserved_gl44[0]));
4832 	}
4833 	else if (apiType == glu::ApiType::core(4, 5))
4834 	{
4835 		context_keywords   = keywords_gl45;
4836 		context_reserved   = reserved_gl45;
4837 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl45) / sizeof(keywords_gl45[0]));
4838 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl45) / sizeof(reserved_gl45[0]));
4839 	}
4840 	else if (apiType == glu::ApiType::core(4, 6))
4841 	{
4842 		context_keywords   = keywords_gl46;
4843 		context_reserved   = reserved_gl46;
4844 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl46) / sizeof(keywords_gl46[0]));
4845 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl46) / sizeof(reserved_gl46[0]));
4846 	}
4847 	else
4848 	{
4849 		TCU_FAIL("Unsupported GL context version - please implement.");
4850 	}
4851 
4852 	for (unsigned int n_current_context_keyword = 0; n_current_context_keyword < context_n_keywords;
4853 		 ++n_current_context_keyword)
4854 	{
4855 		const char* current_context_keyword = context_keywords[n_current_context_keyword];
4856 
4857 		result.push_back(current_context_keyword);
4858 	} /* for (all context keywords) */
4859 
4860 	for (unsigned int n_current_context_reserved = 0; n_current_context_reserved < context_n_reserved;
4861 		 ++n_current_context_reserved)
4862 	{
4863 		const char* current_context_reserved = context_reserved[n_current_context_reserved];
4864 
4865 		result.push_back(current_context_reserved);
4866 	} /* for (all context reserved names) */
4867 
4868 	/* All done! */
4869 	return result;
4870 }
4871 
4872 /** Returns a shader body to use for the test. The body is formed, according to the user-specified
4873  *  requirements.
4874  *
4875  *  @param shader_type      Shader stage the shader body should be returned for.
4876  *  @param language_feature Language feature to test.
4877  *  @param invalid_name     Name to use for the language feature instance. The string should come
4878  *                          from the list of keywords or reserved names, specific to the currently
4879  *                          running rendering context's version.
4880  *
4881  *  @return Requested shader body.
4882  */
getShaderBody(_shader_type shader_type,_language_feature language_feature,const char * invalid_name) const4883 std::string ReservedNamesTest::getShaderBody(_shader_type shader_type, _language_feature language_feature,
4884 											 const char* invalid_name) const
4885 {
4886 	std::stringstream	  body_sstream;
4887 	const glu::ContextType context_type = m_context.getRenderContext().getType();
4888 
4889 	/* Preamble: shader language version */
4890 	body_sstream << "#version ";
4891 
4892 	glu::ApiType apiType = context_type.getAPI();
4893 	if (apiType == glu::ApiType::core(3, 1))
4894 		body_sstream << "140";
4895 	else if (apiType == glu::ApiType::core(3, 2))
4896 		body_sstream << "150";
4897 	else if (apiType == glu::ApiType::core(3, 3))
4898 		body_sstream << "330";
4899 	else if (apiType == glu::ApiType::core(4, 0))
4900 		body_sstream << "400";
4901 	else if (apiType == glu::ApiType::core(4, 1))
4902 		body_sstream << "410";
4903 	else if (apiType == glu::ApiType::core(4, 2))
4904 		body_sstream << "420";
4905 	else if (apiType == glu::ApiType::core(4, 3))
4906 		body_sstream << "430";
4907 	else if (apiType == glu::ApiType::core(4, 4))
4908 		body_sstream << "440";
4909 	else if (apiType == glu::ApiType::core(4, 5))
4910 		body_sstream << "450";
4911 	else if (apiType == glu::ApiType::core(4, 6))
4912 		body_sstream << "460";
4913 	else
4914 	{
4915 		TCU_FAIL("Unsupported GL context version - please implement");
4916 	}
4917 
4918 	body_sstream << "\n\n";
4919 
4920 	/* Preamble: layout qualifiers - required for CS, TC and TE shader stages */
4921 	if (shader_type == SHADER_TYPE_COMPUTE)
4922 	{
4923 		body_sstream << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n";
4924 	}
4925 	else if (shader_type == SHADER_TYPE_TESS_CONTROL)
4926 	{
4927 		body_sstream << "layout(vertices = 3) out;\n";
4928 	}
4929 	else if (shader_type == SHADER_TYPE_TESS_EVALUATION)
4930 	{
4931 		body_sstream << "layout(triangles) in;\n";
4932 	}
4933 
4934 	body_sstream << "\n\n";
4935 
4936 	/* Language feature: insert incorrectly named atomic counter declaration if needed */
4937 	if (language_feature == LANGUAGE_FEATURE_ATOMIC_COUNTER)
4938 	{
4939 		body_sstream << "layout(binding = 0, offset = 0) uniform atomic_uint " << invalid_name << ";\n";
4940 	}
4941 
4942 	/* Language feature: insert incorrectly named attribute declaration if needed */
4943 	if (language_feature == LANGUAGE_FEATURE_ATTRIBUTE)
4944 	{
4945 		body_sstream << "attribute vec4 " << invalid_name << ";\n";
4946 	}
4947 
4948 	/* Language feature: insert incorrectly name constant declaration if needed */
4949 	if (language_feature == LANGUAGE_FEATURE_CONSTANT)
4950 	{
4951 		body_sstream << "const vec4 " << invalid_name << " = vec4(2.0, 3.0, 4.0, 5.0);\n";
4952 	}
4953 
4954 	/* Language feature: insert a function with incorrectly named argument if needed */
4955 	if (language_feature == LANGUAGE_FEATURE_FUNCTION_ARGUMENT_NAME)
4956 	{
4957 		body_sstream << "void test(in vec4 " << invalid_name << ")\n"
4958 																"{\n"
4959 																"}\n";
4960 	}
4961 
4962 	/* Language feature: insert incorrectly named function if needed */
4963 	if (language_feature == LANGUAGE_FEATURE_FUNCTION_NAME)
4964 	{
4965 		body_sstream << "void " << invalid_name << "(in vec4 test)\n"
4966 												   "{\n"
4967 												   "}\n";
4968 	}
4969 
4970 	/* Language feature: insert incorrectly named input variable if needed */
4971 	if (language_feature == LANGUAGE_FEATURE_INPUT)
4972 	{
4973 		body_sstream << "in vec4 " << invalid_name;
4974 
4975 		if (shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
4976 			shader_type == SHADER_TYPE_TESS_EVALUATION)
4977 		{
4978 			body_sstream << "[]";
4979 		}
4980 
4981 		body_sstream << ";\n";
4982 	}
4983 
4984 	/* Language feature: insert declaration of an incorrectly named input block instance if needed */
4985 	if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_INSTANCE_NAME)
4986 	{
4987 		body_sstream << "in testBlock\n"
4988 						"{\n"
4989 						"    vec4 test;\n"
4990 						"} "
4991 					 << invalid_name;
4992 
4993 		if (shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
4994 			shader_type == SHADER_TYPE_TESS_EVALUATION)
4995 		{
4996 			body_sstream << "[]";
4997 		}
4998 
4999 		body_sstream << ";\n";
5000 	}
5001 
5002 	/* Language feature: insert declaration of an input block holding an incorrectly named member variable */
5003 	if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_MEMBER_NAME)
5004 	{
5005 		body_sstream << "in testBlock\n"
5006 						"{\n"
5007 						"    vec4 "
5008 					 << invalid_name << ";\n"
5009 										"} testBlockInstance";
5010 
5011 		if (shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
5012 			shader_type == SHADER_TYPE_TESS_EVALUATION)
5013 		{
5014 			body_sstream << "[]";
5015 		}
5016 
5017 		body_sstream << ";\n";
5018 	}
5019 
5020 	/* Language feature: insert declaration of an incorrectly named input block */
5021 	if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_NAME)
5022 	{
5023 		body_sstream << "in " << invalid_name << "\n"
5024 												 "{\n"
5025 												 "    vec4 test;\n"
5026 												 "} testBlockInstance";
5027 
5028 		if (shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
5029 			shader_type == SHADER_TYPE_TESS_EVALUATION)
5030 		{
5031 			body_sstream << "[]";
5032 		}
5033 
5034 		body_sstream << ";\n";
5035 	}
5036 
5037 	/* Language feature: insert incorrectly named output variable if needed */
5038 	if (language_feature == LANGUAGE_FEATURE_OUTPUT)
5039 	{
5040 		body_sstream << "out vec4 " << invalid_name;
5041 
5042 		if (shader_type == SHADER_TYPE_TESS_CONTROL)
5043 		{
5044 			body_sstream << "[]";
5045 		}
5046 
5047 		body_sstream << ";\n";
5048 	}
5049 
5050 	/* Language feature: insert declaration of an incorrectly named output block instance if needed */
5051 	if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_INSTANCE_NAME)
5052 	{
5053 		body_sstream << "out testBlock\n"
5054 						"{\n"
5055 						"    vec4 test;\n"
5056 						"} "
5057 					 << invalid_name;
5058 
5059 		if (shader_type == SHADER_TYPE_TESS_CONTROL)
5060 		{
5061 			body_sstream << "[]";
5062 		}
5063 
5064 		body_sstream << ";\n";
5065 	}
5066 
5067 	/* Language feature: insert declaration of an output block holding an incorrectly named member variable */
5068 	if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_MEMBER_NAME)
5069 	{
5070 		body_sstream << "out testBlock\n"
5071 						"{\n"
5072 						"    vec4 "
5073 					 << invalid_name << ";\n"
5074 										"} testBlockInstance";
5075 
5076 		if (shader_type == SHADER_TYPE_TESS_CONTROL)
5077 		{
5078 			body_sstream << "[]";
5079 		}
5080 
5081 		body_sstream << ";\n";
5082 	}
5083 
5084 	/* Language feature: insert declaration of an incorrectly named output block */
5085 	if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME)
5086 	{
5087 		body_sstream << "out " << invalid_name << "\n"
5088 												  "{\n"
5089 												  "    vec4 test;\n"
5090 												  "} testBlockInstance";
5091 
5092 		if (shader_type == SHADER_TYPE_TESS_CONTROL)
5093 		{
5094 			body_sstream << "[]";
5095 		}
5096 
5097 		body_sstream << ";\n";
5098 	}
5099 
5100 	/* Language feature: insert declaration of an incorrectly named shader storage block instance if needed */
5101 	if (language_feature == LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_INSTANCE_NAME)
5102 	{
5103 		body_sstream << "buffer testBlock\n"
5104 						"{\n"
5105 						"    vec4 test;\n"
5106 						"} "
5107 					 << invalid_name << ";\n";
5108 	}
5109 
5110 	/* Language feature: insert declaration of a shader storage block holding an incorrectly named member variable */
5111 	if (language_feature == LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_MEMBER_NAME)
5112 	{
5113 		body_sstream << "buffer testBlock\n"
5114 						"{\n"
5115 						"    vec4 "
5116 					 << invalid_name << ";\n"
5117 										"};\n";
5118 	}
5119 
5120 	/* Language feature: insert declaration of an incorrectly named shader storage block */
5121 	if (language_feature == LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_NAME)
5122 	{
5123 		body_sstream << "buffer " << invalid_name << "\n"
5124 													 "{\n"
5125 													 "    vec4 test;\n"
5126 													 "};\n";
5127 	}
5128 
5129 	/* Language feature: insert declaration of a subroutine function with invalid name */
5130 	if (language_feature == LANGUAGE_FEATURE_SUBROUTINE_FUNCTION_NAME)
5131 	{
5132 		body_sstream << "subroutine void exampleSubroutine(inout vec4 " << invalid_name
5133 					 << ");\n"
5134 						"\n"
5135 						"subroutine (exampleSubroutine) void invert(inout vec4 "
5136 					 << invalid_name << ")\n"
5137 										"{\n"
5138 										"    "
5139 					 << invalid_name << " += vec4(0.0, 1.0, 2.0, 3.0);\n"
5140 										"}\n"
5141 										"\n"
5142 										"subroutine uniform exampleSubroutine testSubroutine;\n";
5143 	}
5144 
5145 	/* Language feature: insert declaration of a subroutine of incorrectly named type */
5146 	if (language_feature == LANGUAGE_FEATURE_SUBROUTINE_TYPE)
5147 	{
5148 		body_sstream << "subroutine void " << invalid_name << "(inout vec4 arg);\n"
5149 															  "\n"
5150 															  "subroutine ("
5151 					 << invalid_name << ") void invert(inout vec4 arg)\n"
5152 										"{\n"
5153 										"    arg += vec4(0.0, 1.0, 2.0, 3.0);\n"
5154 										"}\n"
5155 										"\n"
5156 										"subroutine uniform "
5157 					 << invalid_name << " testSubroutine;\n";
5158 	}
5159 
5160 	/* Language feature: insert declaration of a subroutine, followed by a declaration of
5161 	 *                   an incorrectly named subroutine uniform.
5162 	 */
5163 	if (language_feature == LANGUAGE_FEATURE_SUBROUTINE_UNIFORM)
5164 	{
5165 		body_sstream << "subroutine void exampleSubroutine(inout vec4 arg);\n"
5166 						"\n"
5167 						"subroutine (exampleSubroutine) void invert(inout vec4 arg)\n"
5168 						"{\n"
5169 						"    arg += vec4(0.0, 1.0, 2.0, 3.0);\n"
5170 						"}\n"
5171 						"\n"
5172 						"subroutine uniform exampleSubroutine "
5173 					 << invalid_name << ";\n";
5174 	}
5175 
5176 	/* Language feature: insert declaration of an incorrectly named uniform. */
5177 	if (language_feature == LANGUAGE_FEATURE_UNIFORM)
5178 	{
5179 		body_sstream << "uniform sampler2D " << invalid_name << ";\n";
5180 	}
5181 
5182 	/* Language feature: insert declaration of an incorrectly named uniform block instance if needed */
5183 	if (language_feature == LANGUAGE_FEATURE_UNIFORM_BLOCK_INSTANCE_NAME)
5184 	{
5185 		body_sstream << "uniform testBlock\n"
5186 						"{\n"
5187 						"    vec4 test;\n"
5188 						"} "
5189 					 << invalid_name << ";\n";
5190 	}
5191 
5192 	/* Language feature: insert declaration of an uniform block holding an incorrectly named member variable */
5193 	if (language_feature == LANGUAGE_FEATURE_UNIFORM_BLOCK_MEMBER_NAME)
5194 	{
5195 		body_sstream << "uniform testBlock\n"
5196 						"{\n"
5197 						"    vec4 "
5198 					 << invalid_name << ";\n"
5199 										"};\n";
5200 	}
5201 
5202 	/* Language feature: insert declaration of an incorrectly named uniform block */
5203 	if (language_feature == LANGUAGE_FEATURE_UNIFORM_BLOCK_NAME)
5204 	{
5205 		body_sstream << "uniform " << invalid_name << "\n"
5206 													  "{\n"
5207 													  "    vec4 test;\n"
5208 													  "};\n";
5209 	}
5210 
5211 	/* Language feature: insert declaration of an incorrectly named varying */
5212 	if (language_feature == LANGUAGE_FEATURE_VARYING)
5213 	{
5214 		body_sstream << "varying vec4 " << invalid_name << ";\n";
5215 	}
5216 
5217 	/* Start implementation of the main entry-point. */
5218 	body_sstream << "void main()\n"
5219 					"{\n";
5220 
5221 	/* Language feature: insert declaration of an incorrectly named shared variable. */
5222 	if (language_feature == LANGUAGE_FEATURE_SHARED_VARIABLE)
5223 	{
5224 		body_sstream << "shared vec4 " << invalid_name << ";\n";
5225 	}
5226 
5227 	/* Language feature: insert declaration of a structure, whose instance name is incorrect */
5228 	if (language_feature == LANGUAGE_FEATURE_STRUCTURE_INSTANCE_NAME)
5229 	{
5230 		body_sstream << "struct\n"
5231 						"{\n"
5232 						"    vec4 test;\n"
5233 						"} "
5234 					 << invalid_name << ";\n";
5235 	}
5236 
5237 	/* Language feature: insert declaration of a structure with one of its member variables being incorrectly named. */
5238 	if (language_feature == LANGUAGE_FEATURE_STRUCTURE_MEMBER)
5239 	{
5240 		body_sstream << "struct\n"
5241 						"{\n"
5242 						"    vec4 "
5243 					 << invalid_name << ";\n"
5244 										"} testInstance;\n";
5245 	}
5246 
5247 	/* Language feature: insert declaration of a structure whose name is incorrect */
5248 	if (language_feature == LANGUAGE_FEATURE_STRUCTURE_NAME)
5249 	{
5250 		body_sstream << "struct " << invalid_name << "{\n"
5251 													 "    vec4 test;\n"
5252 					 << "};\n";
5253 	}
5254 
5255 	/* Language feature: insert declaration of a variable with incorrect name. */
5256 	if (language_feature == LANGUAGE_FEATURE_VARIABLE)
5257 	{
5258 		body_sstream << "vec4 " << invalid_name << ";\n";
5259 	}
5260 
5261 	/* Close the main entry-point implementation */
5262 	body_sstream << "}\n";
5263 
5264 	return body_sstream.str();
5265 }
5266 
5267 /** Retrieves a literal corresponding to the user-specified shader type value.
5268  *
5269  *  @param shader_type Enum to return the string for.
5270  *
5271  *  @return As specified.
5272  */
getShaderTypeName(_shader_type shader_type) const5273 std::string ReservedNamesTest::getShaderTypeName(_shader_type shader_type) const
5274 {
5275 	std::string result = "[?!]";
5276 
5277 	switch (shader_type)
5278 	{
5279 	case SHADER_TYPE_COMPUTE:
5280 		result = "compute shader";
5281 		break;
5282 	case SHADER_TYPE_FRAGMENT:
5283 		result = "fragment shader";
5284 		break;
5285 	case SHADER_TYPE_GEOMETRY:
5286 		result = "geometry shader";
5287 		break;
5288 	case SHADER_TYPE_TESS_CONTROL:
5289 		result = "tessellation control shader";
5290 		break;
5291 	case SHADER_TYPE_TESS_EVALUATION:
5292 		result = "tessellation evaluation shader";
5293 		break;
5294 	case SHADER_TYPE_VERTEX:
5295 		result = "vertex shader";
5296 		break;
5297 	default:
5298 		result = "unknown";
5299 		break;
5300 	} /* switch (shader_type) */
5301 
5302 	return result;
5303 }
5304 
5305 /** Returns a vector of _language_feature enums, telling which language features are supported, given running context's
5306  *  version and shader type, in which the features are planned to be used.
5307  *
5308  *  @param shader_type Shader stage the language features will be used in.
5309  *
5310  *  @return As specified.
5311  **/
getSupportedLanguageFeatures(_shader_type shader_type) const5312 std::vector<ReservedNamesTest::_language_feature> ReservedNamesTest::getSupportedLanguageFeatures(
5313 	_shader_type shader_type) const
5314 {
5315 	const glu::ContextType		   context_type = m_context.getRenderContext().getType();
5316 	std::vector<_language_feature> result;
5317 
5318 	/* Atomic counters are available, starting with GL 4.2. Availability for each shader stage
5319 	 * depends on the reported GL constant values, apart from CS & FS, for which AC support is guaranteed.
5320 	 */
5321 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 2)))
5322 	{
5323 		if (shader_type == SHADER_TYPE_COMPUTE || shader_type == SHADER_TYPE_FRAGMENT ||
5324 			(shader_type == SHADER_TYPE_GEOMETRY && m_max_gs_acs > 0) ||
5325 			(shader_type == SHADER_TYPE_TESS_CONTROL && m_max_tc_acs > 0) ||
5326 			(shader_type == SHADER_TYPE_TESS_EVALUATION && m_max_te_acs > 0) ||
5327 			(shader_type == SHADER_TYPE_VERTEX && m_max_vs_acs))
5328 		{
5329 			result.push_back(LANGUAGE_FEATURE_ATOMIC_COUNTER);
5330 		}
5331 	} /* if (context_type >= glu::CONTEXTTYPE_GL43_CORE) */
5332 
5333 	/* Attributes are only supported until GL 4.1, for VS shader stage only. */
5334 	if (shader_type == SHADER_TYPE_VERTEX && !glu::contextSupports(context_type, glu::ApiType::core(4, 2)))
5335 	{
5336 		result.push_back(LANGUAGE_FEATURE_ATTRIBUTE);
5337 	}
5338 
5339 	/* Constants are always supported */
5340 	result.push_back(LANGUAGE_FEATURE_CONSTANT);
5341 
5342 	/* Functions are supported in all GL SL versions for all shader types. */
5343 	result.push_back(LANGUAGE_FEATURE_FUNCTION_ARGUMENT_NAME);
5344 	result.push_back(LANGUAGE_FEATURE_FUNCTION_NAME);
5345 
5346 	/* Inputs are supported in all GL SL versions for FS, GS, TC, TE and VS stages */
5347 	if (shader_type == SHADER_TYPE_FRAGMENT || shader_type == SHADER_TYPE_GEOMETRY ||
5348 		shader_type == SHADER_TYPE_TESS_CONTROL || shader_type == SHADER_TYPE_TESS_EVALUATION ||
5349 		shader_type == SHADER_TYPE_VERTEX)
5350 	{
5351 		result.push_back(LANGUAGE_FEATURE_INPUT);
5352 	}
5353 
5354 	/* Input blocks are available, starting with GL 3.2 for FS, GS, TC and TE stages. */
5355 	if ((shader_type == SHADER_TYPE_FRAGMENT || shader_type == SHADER_TYPE_GEOMETRY ||
5356 		 shader_type == SHADER_TYPE_TESS_CONTROL || shader_type == SHADER_TYPE_TESS_EVALUATION ||
5357 		 shader_type == SHADER_TYPE_VERTEX) &&
5358 		glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
5359 	{
5360 		result.push_back(LANGUAGE_FEATURE_INPUT_BLOCK_INSTANCE_NAME);
5361 		result.push_back(LANGUAGE_FEATURE_INPUT_BLOCK_MEMBER_NAME);
5362 		result.push_back(LANGUAGE_FEATURE_INPUT_BLOCK_NAME);
5363 	}
5364 
5365 	/* Outputs are supported in all GL SL versions for all shader stages expect CS */
5366 	if (shader_type != SHADER_TYPE_COMPUTE)
5367 	{
5368 		result.push_back(LANGUAGE_FEATURE_OUTPUT);
5369 	}
5370 
5371 	/* Output blocks are available, starting with GL 3.2 for GS, TC, TE and VS stages. */
5372 	if ((shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
5373 		 shader_type == SHADER_TYPE_TESS_EVALUATION || shader_type == SHADER_TYPE_VERTEX) &&
5374 		glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
5375 	{
5376 		result.push_back(LANGUAGE_FEATURE_OUTPUT_BLOCK_INSTANCE_NAME);
5377 		result.push_back(LANGUAGE_FEATURE_OUTPUT_BLOCK_MEMBER_NAME);
5378 		result.push_back(LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME);
5379 	}
5380 
5381 	/* Shader storage blocks are available, starting with GL 4.3. Availability for each shader stage
5382 	 * depends on the reported GL constant values, apart from CS, for which SSBO support is guaranteed.
5383 	 */
5384 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5385 	{
5386 		if (shader_type == SHADER_TYPE_COMPUTE || (shader_type == SHADER_TYPE_FRAGMENT && m_max_fs_ssbos > 0) ||
5387 			(shader_type == SHADER_TYPE_GEOMETRY && m_max_gs_ssbos > 0) ||
5388 			(shader_type == SHADER_TYPE_TESS_CONTROL && m_max_tc_ssbos > 0) ||
5389 			(shader_type == SHADER_TYPE_TESS_EVALUATION && m_max_te_ssbos > 0) ||
5390 			(shader_type == SHADER_TYPE_VERTEX && m_max_vs_ssbos))
5391 		{
5392 			result.push_back(LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_INSTANCE_NAME);
5393 			result.push_back(LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_MEMBER_NAME);
5394 			result.push_back(LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_NAME);
5395 		}
5396 	} /* if (context_type >= glu::CONTEXTTYPE_GL43_CORE) */
5397 
5398 	/* Shared variables are only supported for compute shaders */
5399 	if (shader_type == SHADER_TYPE_COMPUTE)
5400 	{
5401 		result.push_back(LANGUAGE_FEATURE_SHARED_VARIABLE);
5402 	}
5403 
5404 	/* Structures are available everywhere, and so are structures. */
5405 	result.push_back(LANGUAGE_FEATURE_STRUCTURE_INSTANCE_NAME);
5406 	result.push_back(LANGUAGE_FEATURE_STRUCTURE_MEMBER);
5407 	result.push_back(LANGUAGE_FEATURE_STRUCTURE_NAME);
5408 
5409 	/* Subroutines are available, starting with GL 4.0, for all shader stages except CS */
5410 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
5411 	{
5412 		if (shader_type != SHADER_TYPE_COMPUTE)
5413 		{
5414 			result.push_back(LANGUAGE_FEATURE_SUBROUTINE_FUNCTION_NAME);
5415 			result.push_back(LANGUAGE_FEATURE_SUBROUTINE_TYPE);
5416 			result.push_back(LANGUAGE_FEATURE_SUBROUTINE_UNIFORM);
5417 		}
5418 	} /* if (context_type >= glu::CONTEXTTYPE_GL40_CORE) */
5419 
5420 	/* Uniform blocks and uniforms are available everywhere, for all shader stages except CS */
5421 	if (shader_type != SHADER_TYPE_COMPUTE)
5422 	{
5423 		result.push_back(LANGUAGE_FEATURE_UNIFORM_BLOCK_INSTANCE_NAME);
5424 		result.push_back(LANGUAGE_FEATURE_UNIFORM_BLOCK_MEMBER_NAME);
5425 		result.push_back(LANGUAGE_FEATURE_UNIFORM_BLOCK_NAME);
5426 
5427 		result.push_back(LANGUAGE_FEATURE_UNIFORM);
5428 	}
5429 
5430 	/* Variables are available, well, everywhere. */
5431 	result.push_back(LANGUAGE_FEATURE_VARIABLE);
5432 
5433 	/* Varyings are supported until GL 4.2 for FS and VS shader stages. Starting with GL 4.3,
5434 	 * they are no longer legal. */
5435 	if ((shader_type == SHADER_TYPE_FRAGMENT || shader_type == SHADER_TYPE_VERTEX) &&
5436 		!glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5437 	{
5438 		result.push_back(LANGUAGE_FEATURE_VARYING);
5439 	}
5440 
5441 	return result;
5442 }
5443 
5444 /** Returns a vector of _shader_type enums, telling which shader stages are supported
5445  *  under running rendering context. For simplicity, the function ignores any extensions
5446  *  which extend the core functionality
5447  *
5448  * @return As specified.
5449  */
getSupportedShaderTypes() const5450 std::vector<ReservedNamesTest::_shader_type> ReservedNamesTest::getSupportedShaderTypes() const
5451 {
5452 	const glu::ContextType	context_type = m_context.getRenderContext().getType();
5453 	std::vector<_shader_type> result;
5454 
5455 	/* CS: Available, starting with GL 4.3 */
5456 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5457 	{
5458 		result.push_back(SHADER_TYPE_COMPUTE);
5459 	}
5460 
5461 	/* FS: Always supported */
5462 	result.push_back(SHADER_TYPE_FRAGMENT);
5463 
5464 	/* GS: Available, starting with GL 3.2 */
5465 	if (glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
5466 	{
5467 		result.push_back(SHADER_TYPE_GEOMETRY);
5468 	}
5469 
5470 	/* TC: Available, starting with GL 4.0 */
5471 	/* TE: Available, starting with GL 4.0 */
5472 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
5473 	{
5474 		result.push_back(SHADER_TYPE_TESS_CONTROL);
5475 		result.push_back(SHADER_TYPE_TESS_EVALUATION);
5476 	}
5477 
5478 	/* VS: Always supported */
5479 	result.push_back(SHADER_TYPE_VERTEX);
5480 
5481 	return result;
5482 }
5483 
isStructAllowed(_shader_type shader_type,_language_feature language_feature) const5484 bool ReservedNamesTest::isStructAllowed(_shader_type shader_type, _language_feature language_feature) const
5485 {
5486 	bool structAllowed = false;
5487 
5488 	if (language_feature == LANGUAGE_FEATURE_UNIFORM || language_feature == LANGUAGE_FEATURE_UNIFORM_BLOCK_NAME)
5489 	{
5490 		return true;
5491 	}
5492 
5493 	switch (shader_type)
5494 	{
5495 	case SHADER_TYPE_FRAGMENT:
5496 	{
5497 		if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_NAME)
5498 		{
5499 			structAllowed = true;
5500 		}
5501 	}
5502 	break;
5503 	case SHADER_TYPE_GEOMETRY:
5504 	case SHADER_TYPE_TESS_CONTROL:
5505 	case SHADER_TYPE_TESS_EVALUATION:
5506 	{
5507 		if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME)
5508 		{
5509 			structAllowed = true;
5510 		}
5511 		else if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_NAME)
5512 		{
5513 			structAllowed = true;
5514 		}
5515 	}
5516 	break;
5517 	case SHADER_TYPE_VERTEX:
5518 	{
5519 		if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME)
5520 		{
5521 			structAllowed = true;
5522 		}
5523 	}
5524 	break;
5525 	case SHADER_TYPE_COMPUTE:
5526 	default:
5527 		break;
5528 	}
5529 
5530 	return structAllowed;
5531 }
5532 
5533 /** Empty init function */
init()5534 void ReservedNamesTest::init()
5535 {
5536 	/* Left blank on purpose */
5537 }
5538 
5539 /** Executes test iteration.
5540  *
5541  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
5542  */
iterate()5543 tcu::TestNode::IterateResult ReservedNamesTest::iterate()
5544 {
5545 	glw::GLint					   compile_status = GL_TRUE;
5546 	glu::ContextType			   context_type   = m_context.getRenderContext().getType();
5547 	const glw::Functions&		   gl			  = m_context.getRenderContext().getFunctions();
5548 	std::vector<_language_feature> language_features;
5549 	std::vector<std::string>	   reserved_names;
5550 	bool						   result = true;
5551 	std::vector<_shader_type>	  shader_types;
5552 
5553 	/* Retrieve important GL constant values */
5554 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 2)))
5555 	{
5556 		gl.getIntegerv(GL_MAX_GEOMETRY_ATOMIC_COUNTERS, &m_max_gs_acs);
5557 		gl.getIntegerv(GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS, &m_max_tc_acs);
5558 		gl.getIntegerv(GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS, &m_max_te_acs);
5559 		gl.getIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTERS, &m_max_vs_acs);
5560 	}
5561 
5562 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5563 	{
5564 		gl.getIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &m_max_fs_ssbos);
5565 		gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &m_max_gs_ssbos);
5566 		gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &m_max_tc_ssbos);
5567 		gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &m_max_te_ssbos);
5568 		gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &m_max_vs_ssbos);
5569 
5570 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call(s) failed.");
5571 	}
5572 
5573 	/* Create the shader objects */
5574 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
5575 	{
5576 		m_so_ids[SHADER_TYPE_TESS_CONTROL]	= gl.createShader(GL_TESS_CONTROL_SHADER);
5577 		m_so_ids[SHADER_TYPE_TESS_EVALUATION] = gl.createShader(GL_TESS_EVALUATION_SHADER);
5578 	}
5579 
5580 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5581 	{
5582 		m_so_ids[SHADER_TYPE_COMPUTE] = gl.createShader(GL_COMPUTE_SHADER);
5583 	}
5584 
5585 	m_so_ids[SHADER_TYPE_FRAGMENT] = gl.createShader(GL_FRAGMENT_SHADER);
5586 	m_so_ids[SHADER_TYPE_GEOMETRY] = gl.createShader(GL_GEOMETRY_SHADER);
5587 	m_so_ids[SHADER_TYPE_VERTEX]   = gl.createShader(GL_VERTEX_SHADER);
5588 
5589 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
5590 
5591 	/* Retrieve context version-specific data */
5592 	reserved_names = getReservedNames();
5593 	shader_types   = getSupportedShaderTypes();
5594 
5595 	/* Iterate over all supported shader stages.. */
5596 	for (std::vector<_shader_type>::const_iterator shader_type_it = shader_types.begin();
5597 		 shader_type_it != shader_types.end(); ++shader_type_it)
5598 	{
5599 		_shader_type current_shader_type = *shader_type_it;
5600 
5601 		if (m_so_ids[current_shader_type] == 0)
5602 		{
5603 			/* Skip stages not supported by the currently running context version. */
5604 			continue;
5605 		}
5606 
5607 		language_features = getSupportedLanguageFeatures(current_shader_type);
5608 
5609 		/* ..and all language features we can test for the running context */
5610 		for (std::vector<_language_feature>::const_iterator language_feature_it = language_features.begin();
5611 			 language_feature_it != language_features.end(); ++language_feature_it)
5612 		{
5613 			_language_feature current_language_feature = *language_feature_it;
5614 
5615 			bool structAllowed = isStructAllowed(current_shader_type, current_language_feature);
5616 
5617 			/* Finally, all the reserved names we need to test - loop over them at this point */
5618 			for (std::vector<std::string>::const_iterator reserved_name_it = reserved_names.begin();
5619 				 reserved_name_it != reserved_names.end(); ++reserved_name_it)
5620 			{
5621 				std::string current_invalid_name = *reserved_name_it;
5622 				std::string so_body_string;
5623 				const char* so_body_string_raw = NULL;
5624 
5625 				// There are certain shader types that allow struct for in/out declarations
5626 				if (structAllowed && current_invalid_name.compare("struct") == 0)
5627 				{
5628 					continue;
5629 				}
5630 
5631 				/* Form the shader body */
5632 				so_body_string =
5633 					getShaderBody(current_shader_type, current_language_feature, current_invalid_name.c_str());
5634 				so_body_string_raw = so_body_string.c_str();
5635 
5636 				/* Try to compile the shader */
5637 				gl.shaderSource(m_so_ids[current_shader_type], 1, /* count */
5638 								&so_body_string_raw, NULL);		  /* length */
5639 				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
5640 
5641 				gl.compileShader(m_so_ids[current_shader_type]);
5642 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
5643 
5644 				gl.getShaderiv(m_so_ids[current_shader_type], GL_COMPILE_STATUS, &compile_status);
5645 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
5646 
5647 /* Left for the debugging purposes for those in need .. */
5648 #if 0
5649 				char temp[4096];
5650 
5651 				gl.getShaderInfoLog(m_so_ids[current_shader_type],
5652 					4096,
5653 					NULL,
5654 					temp);
5655 
5656 				m_testCtx.getLog() << tcu::TestLog::Message
5657 					<< "\n"
5658 					"-----------------------------\n"
5659 					"Shader:\n"
5660 					">>\n"
5661 					<< so_body_string_raw
5662 					<< "\n<<\n"
5663 					"\n"
5664 					"Info log:\n"
5665 					">>\n"
5666 					<< temp
5667 					<< "\n<<\n\n"
5668 					<< tcu::TestLog::EndMessage;
5669 #endif
5670 
5671 				if (compile_status != GL_FALSE)
5672 				{
5673 					m_testCtx.getLog() << tcu::TestLog::Message << "A "
5674 									   << getLanguageFeatureName(current_language_feature) << " named ["
5675 									   << current_invalid_name << "]"
5676 									   << ", defined in " << getShaderTypeName(current_shader_type)
5677 									   << ", was accepted by the compiler, "
5678 										  "which is prohibited by the spec. Offending source code:\n"
5679 										  ">>\n"
5680 									   << so_body_string_raw << "\n<<\n\n"
5681 									   << tcu::TestLog::EndMessage;
5682 
5683 					result = false;
5684 				}
5685 
5686 			} /* for (all reserved names for the current context) */
5687 		}	 /* for (all language features supported by the context) */
5688 	}		  /* for (all shader types supported by the context) */
5689 
5690 	m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
5691 
5692 	return STOP;
5693 }
5694 
5695 /** Constructor.
5696  *
5697  *  @param context     Rendering context
5698  *  @param name        Test name
5699  *  @param description Test description
5700  */
SparseBuffersWithCopyOpsTest(deqp::Context & context)5701 SparseBuffersWithCopyOpsTest::SparseBuffersWithCopyOpsTest(deqp::Context& context)
5702 	: TestCase(context, "CommonBug_SparseBuffersWithCopyOps",
5703 			   "Verifies sparse buffer functionality works correctly when CPU->GPU and GPU->GPU"
5704 			   " memory transfers are involved.")
5705 	, m_bo_id(0)
5706 	, m_bo_read_id(0)
5707 	, m_clear_buffer(DE_NULL)
5708 	, m_page_size(0)
5709 	, m_result_data_storage_size(0)
5710 	, m_n_iterations_to_run(16)
5711 	, m_n_pages_to_test(16)
5712 	, m_virtual_bo_size(512 /* MB */ * 1024768)
5713 {
5714 	for (unsigned int n = 0; n < sizeof(m_reference_data) / sizeof(m_reference_data[0]); ++n)
5715 	{
5716 		m_reference_data[n] = static_cast<unsigned char>(n);
5717 	}
5718 }
5719 
5720 /** Deinitializes all GL objects created for the purpose of running the test,
5721  *  as well as any client-side buffers allocated at initialization time
5722  */
deinit()5723 void SparseBuffersWithCopyOpsTest::deinit()
5724 {
5725 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5726 
5727 	if (m_bo_id != 0)
5728 	{
5729 		gl.deleteBuffers(1, &m_bo_id);
5730 
5731 		m_bo_id = 0;
5732 	}
5733 
5734 	if (m_bo_read_id != 0)
5735 	{
5736 		gl.deleteBuffers(1, &m_bo_read_id);
5737 
5738 		m_bo_read_id = 0;
5739 	}
5740 
5741 	if (m_clear_buffer != DE_NULL)
5742 	{
5743 		delete[] m_clear_buffer;
5744 
5745 		m_clear_buffer = DE_NULL;
5746 	}
5747 }
5748 
5749 /** Empty init function */
init()5750 void SparseBuffersWithCopyOpsTest::init()
5751 {
5752 	/* Nothing to do here */
5753 }
5754 
5755 /** Initializes all buffers and GL objects required to run the test. */
initTest()5756 bool SparseBuffersWithCopyOpsTest::initTest()
5757 {
5758 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
5759 	bool				  result = true;
5760 
5761 	/* Retrieve the platform-specific page size */
5762 	gl.getIntegerv(GL_SPARSE_BUFFER_PAGE_SIZE_ARB, &m_page_size);
5763 
5764 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_SPARSE_BUFFER_PAGE_SIZE_ARB query");
5765 
5766 	/* Retrieve the func ptr */
5767 	if (gl.bufferPageCommitmentARB == NULL)
5768 	{
5769 		m_testCtx.getLog() << tcu::TestLog::Message
5770 						   << "Could not retrieve function pointer for the glBufferPageCommitmentARB() entry-point."
5771 						   << tcu::TestLog::EndMessage;
5772 
5773 		result = false;
5774 		goto end;
5775 	}
5776 
5777 	/* Set up the test sparse buffer object */
5778 	gl.genBuffers(1, &m_bo_id);
5779 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
5780 
5781 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id);
5782 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
5783 
5784 	gl.bufferStorage(GL_ARRAY_BUFFER, m_virtual_bo_size, DE_NULL, /* data */
5785 					 GL_DYNAMIC_STORAGE_BIT | GL_SPARSE_STORAGE_BIT_ARB);
5786 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage() call failed.");
5787 
5788 	/* Set up the buffer object that will be used to read the result data */
5789 	m_result_data_storage_size = static_cast<unsigned int>(
5790 		(m_page_size * m_n_pages_to_test / sizeof(m_reference_data)) * sizeof(m_reference_data));
5791 	m_clear_buffer = new unsigned char[m_result_data_storage_size];
5792 
5793 	memset(m_clear_buffer, 0, m_result_data_storage_size);
5794 
5795 	gl.genBuffers(1, &m_bo_read_id);
5796 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
5797 
5798 	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bo_read_id);
5799 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
5800 
5801 	gl.bufferStorage(GL_ELEMENT_ARRAY_BUFFER, m_result_data_storage_size, NULL, /* data */
5802 					 GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT);
5803 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage() call failed.");
5804 
5805 end:
5806 	return result;
5807 }
5808 
5809 /** Executes test iteration.
5810  *
5811  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
5812  */
iterate()5813 tcu::TestNode::IterateResult SparseBuffersWithCopyOpsTest::iterate()
5814 {
5815 	bool result = true;
5816 
5817 	/* Execute the test */
5818 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5819 
5820 	/* Only execute if we're dealing with an OpenGL implementation which supports both:
5821 	 *
5822 	 * 1. GL_ARB_sparse_buffer extension
5823 	 * 2. GL_ARB_buffer_storage extension
5824 	 */
5825 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_buffer") ||
5826 		!m_context.getContextInfo().isExtensionSupported("GL_ARB_buffer_storage"))
5827 	{
5828 		goto end;
5829 	}
5830 
5831 	/* Set up the test objects */
5832 	if (!initTest())
5833 	{
5834 		result = false;
5835 
5836 		goto end;
5837 	}
5838 	for (unsigned int n_test_case = 0; n_test_case < 2; ++n_test_case)
5839 	{
5840 		for (unsigned int n_iteration = 0; n_iteration < m_n_iterations_to_run; ++n_iteration)
5841 		{
5842 			if (n_iteration != 0)
5843 			{
5844 				gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0, /* offset */
5845 										   m_n_pages_to_test * m_page_size, GL_FALSE);
5846 				GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferPageCommitmentARB() call failed.");
5847 			}
5848 
5849 			gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0, /* offset */
5850 									   m_page_size, GL_TRUE);
5851 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferPageCommitmentARB() call failed.");
5852 
5853 			gl.bufferSubData(GL_ARRAY_BUFFER, 0, /* offset */
5854 							 sizeof(m_reference_data), m_reference_data);
5855 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
5856 
5857 			for (unsigned int n_page = 0; n_page < m_n_pages_to_test; ++n_page)
5858 			{
5859 				/* Try committing pages in a redundant manner. This is a legal behavior in light of
5860 				 * the GL_ARB_sparse_buffer spec */
5861 				gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, n_page * m_page_size, m_page_size, GL_TRUE);
5862 				GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferPageCommitmentARB() call failed.");
5863 
5864 				for (int copy_dst_page_offset = static_cast<int>((n_page == 0) ? sizeof(m_reference_data) : 0);
5865 					 copy_dst_page_offset < static_cast<int>(m_page_size);
5866 					 copy_dst_page_offset += static_cast<int>(sizeof(m_reference_data)))
5867 				{
5868 					const int copy_src_page_offset =
5869 						static_cast<int>(copy_dst_page_offset - sizeof(m_reference_data));
5870 
5871 					switch (n_test_case)
5872 					{
5873 					case 0:
5874 					{
5875 						gl.copyBufferSubData(GL_ARRAY_BUFFER, GL_ARRAY_BUFFER,
5876 											 n_page * m_page_size + copy_src_page_offset,
5877 											 n_page * m_page_size + copy_dst_page_offset, sizeof(m_reference_data));
5878 						GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyBufferSubData() call failed.");
5879 
5880 						break;
5881 					}
5882 
5883 					case 1:
5884 					{
5885 						gl.bufferSubData(GL_ARRAY_BUFFER, n_page * m_page_size + copy_dst_page_offset,
5886 										 sizeof(m_reference_data), m_reference_data);
5887 						GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
5888 
5889 						break;
5890 					}
5891 
5892 					default:
5893 						TCU_FAIL("Unrecognized test case index");
5894 					} /* switch (n_test_case) */
5895 				}	 /* for (all valid destination copy op offsets) */
5896 			}		  /* for (all test pages) */
5897 
5898 			/* Copy data from the sparse buffer to a mappable immutable buffer storage */
5899 			gl.copyBufferSubData(GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, 0, /* readOffset */
5900 								 0,											  /* writeOffset */
5901 								 m_result_data_storage_size);
5902 			GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyBufferSubData() call failed.");
5903 
5904 			/* Map the data we have obtained */
5905 			char* mapped_data = (char*)gl.mapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, /* offset */
5906 														 m_page_size * m_n_pages_to_test, GL_MAP_READ_BIT);
5907 
5908 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
5909 
5910 			/* Verify the data is valid */
5911 			for (unsigned int n_temp_copy = 0; n_temp_copy < m_result_data_storage_size / sizeof(m_reference_data);
5912 				 ++n_temp_copy)
5913 			{
5914 				const unsigned int cmp_offset = static_cast<unsigned int>(n_temp_copy * sizeof(m_reference_data));
5915 
5916 				if (memcmp(mapped_data + cmp_offset, m_reference_data, sizeof(m_reference_data)) != 0)
5917 				{
5918 					m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data found for page index "
5919 																   "["
5920 									   << (cmp_offset / m_page_size) << "]"
5921 																		", BO data offset:"
5922 																		"["
5923 									   << cmp_offset << "]." << tcu::TestLog::EndMessage;
5924 
5925 					result = false;
5926 					goto end;
5927 				}
5928 			} /* for (all datasets) */
5929 
5930 			/* Clean up */
5931 			gl.unmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
5932 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
5933 
5934 			/* Also, zero out the other buffer object we copy the result data to, in case
5935 			 * the glCopyBufferSubData() call does not modify it at all */
5936 			gl.bufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, /* offset */
5937 							 m_result_data_storage_size, m_clear_buffer);
5938 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
5939 
5940 			/* NOTE: This test passes fine on the misbehaving driver *if* the swapbuffers operation
5941 			 *       issued as a part of the call below is not executed. */
5942 			m_context.getRenderContext().postIterate();
5943 		} /* for (all test iterations) */
5944 	}	 /* for (all test cases) */
5945 
5946 end:
5947 	m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
5948 
5949 	return STOP;
5950 }
5951 
5952 /** Constructor.
5953  *
5954  *  @param context Rendering context.
5955  */
CommonBugsTests(deqp::Context & context)5956 CommonBugsTests::CommonBugsTests(deqp::Context& context)
5957 	: TestCaseGroup(context, "CommonBugs", "Contains conformance tests that verify various pieces of functionality"
5958 										   " which were found broken in public drivers.")
5959 {
5960 }
5961 
5962 /** Initializes the test group contents. */
init()5963 void CommonBugsTests::init()
5964 {
5965 	addChild(new GetProgramivActiveUniformBlockMaxNameLengthTest(m_context));
5966 	addChild(new InputVariablesCannotBeModifiedTest(m_context));
5967 	addChild(new InvalidUseCasesForAllNotFuncsAndExclMarkOpTest(m_context));
5968 	addChild(new InvalidVSInputsTest(m_context));
5969 	addChild(new ParenthesisInLayoutQualifierIntegerValuesTest(m_context));
5970 	addChild(new PerVertexValidationTest(m_context));
5971 	addChild(new ReservedNamesTest(m_context));
5972 	addChild(new SparseBuffersWithCopyOpsTest(m_context));
5973 }
5974 } /* glcts namespace */
5975